Index: itignore
===================================================================
--- .gitignore	(revision ee0574ce7974a45c8080d1215db912b8f3e1444c)
+++ 	(revision )
@@ -1,25 +1,0 @@
-*~
-*.a
-autom4te.cache
-barnowl
-blib
-config.cache
-config.h
-config.log
-config.status
-configure
-core
-jabber.log
-libfaim/rxhandlers.c.orig
-Makefile
-META.yml
-*.o
-owl_prototypes.h
-owl_prototypes.h.new
-*.par
-perlglue.c
-perlwrap.c
-pm_to_blib
-TAGS
-tester
-varstubs.c
Index: THORS
===================================================================
--- AUTHORS	(revision 1d2c4c3b5a65c0876340b3505cc91f8d873970be)
+++ 	(revision )
@@ -1,42 +1,0 @@
-BarnOwl was primarily written by Nelson Elhage and Alejandro Sedeno at
-the Massachusetts Institute of Technology.
-
-The following people have provided patches or other contributions:
-  Sam Hartman
-  Alex Vandiver
-  Geoffrey Thomas
-  Derrick Brashear
-  David Glasser
-  Matthew Goldstein
-  Arun Tharuvai
-  Kevin Chen
-  Eric Price
-
-BarnOwl is based on code from Owl, which was originally primarly
-written by James Kretchmar.  Erik Nygren also made substantial
-contributions and improvemnts to the program.
-
-The following people provided patches and other techincal support for
-Owl:
-
-  Stephen Gildea
-  Greg Hudson
-  David Resnick
-  Marc Horowitz
-  Jeremy Daniel
-  Roman Mitz
-  Derrick J Brashear
-  David Glasser
-  Mark Eichin
-
-Mark Eichin is also maintaining the debian package of Owl.
-
-The following people helped with beta testing the earliest versions of
-Owl:
-
-  Andy Ellis, Erin Panttaja, Gisele Proulx
-  Ron Hoffmann, Jag Patel, Tara Holm
-  Heather Wakefield, Emiliy Havens,
-  Matt Braun, Jeff Schiller
-
-The ASCII art owl was created by Anne LaVin.
Index: GS
===================================================================
--- BUGS	(revision 0337203892fe43f7fb4b3c665641143859a26954)
+++ 	(revision )
@@ -1,6 +1,0 @@
-* We generate jwrite -i command lines, but don't do the right thing
-  with them yet. [nelhage]
-* The jabber roster looks ugly with multiline status messages and
-  long JIDs [nelhage]
-* reply to resource names from ichat (foo's computer) fails badly [hartmans]
-* viewuser doesn't work with AIM or Jabber
Index: PYING
===================================================================
--- COPYING	(revision 17e2357daea5ed171ca060fa9d35c1d0d5e3d9df)
+++ 	(revision )
@@ -1,550 +1,0 @@
-Copyright (c) 2006-2008 The BarnOwl Developers. All rights reserved.
-Copyright (c) 2004 James Kretchmar. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-  * Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-  * Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in
-    the documentation and/or other materials provided with the
-    distribution.
-
-  * Redistributions in any form must be accompanied by information on
-    how to obtain complete source code for the BarnOwl software and
-    any accompanying software that uses the BarnOwl software. The
-    source code must either be included in the distribution or be
-    available for no more than the cost of distribution plus a nominal
-    fee, and must be freely redistributable under reasonable
-    conditions. For an executable file, complete source code means the
-    source code for all modules it contains. It does not include
-    source code for modules or files that typically accompany the
-    major components of the operating system on which the executable
-    file runs.
-
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-======================================================================
-
-Files under perl/modules/Jabber/lib/Net and perl/modules/lib/XML are
-Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public
-   License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with this library; if not, write to the
-   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA  02111-1307, USA.
-
-		  GNU LIBRARY GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1991 Free Software Foundation, Inc.
-		    51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the library GPL.  It is
- numbered 2 because it goes with version 2 of the ordinary GPL.]
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Library General Public License, applies to some
-specially designated Free Software Foundation software, and to any
-other libraries whose authors decide to use it.  You can use it for
-your libraries, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if
-you distribute copies of the library, or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link a program with the library, you must provide
-complete object files to the recipients so that they can relink them
-with the library, after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  Our method of protecting your rights has two steps: (1) copyright
-the library, and (2) offer you this license which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  Also, for each distributor's protection, we want to make certain
-that everyone understands that there is no warranty for this free
-library.  If the library is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original
-version, so that any problems introduced by others will not reflect on
-the original authors' reputations.
-
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that companies distributing free
-software will individually obtain patent licenses, thus in effect
-transforming the program into proprietary software.  To prevent this,
-we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
-  Most GNU software, including some libraries, is covered by the ordinary
-GNU General Public License, which was designed for utility programs.  This
-license, the GNU Library General Public License, applies to certain
-designated libraries.  This license is quite different from the ordinary
-one; be sure to read it in full, and don't assume that anything in it is
-the same as in the ordinary license.
-
-  The reason we have a separate public license for some libraries is that
-they blur the distinction we usually make between modifying or adding to a
-program and simply using it.  Linking a program with a library, without
-changing the library, is in some sense simply using the library, and is
-analogous to running a utility program or application program.  However, in
-a textual and legal sense, the linked executable is a combined work, a
-derivative of the original library, and the ordinary General Public License
-treats it as such.
-
-  Because of this blurred distinction, using the ordinary General
-Public License for libraries did not effectively promote software
-sharing, because most developers did not use the libraries.  We
-concluded that weaker conditions might promote sharing better.
-
-  However, unrestricted linking of non-free programs would deprive the
-users of those programs of all benefit from the free status of the
-libraries themselves.  This Library General Public License is intended to
-permit developers of non-free programs to use free libraries, while
-preserving your freedom as a user of such programs to change the free
-libraries that are incorporated in them.  (We have not seen how to achieve
-this as regards changes in header files, but we have achieved it as regards
-changes in the actual functions of the Library.)  The hope is that this
-will lead to faster development of free libraries.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, while the latter only
-works together with the library.
-
-  Note that it is possible for a library to be covered by the ordinary
-General Public License rather than by this special one.
-
-
-		  GNU LIBRARY GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library which
-contains a notice placed by the copyright holder or other authorized
-party saying it may be distributed under the terms of this Library
-General Public License (also called "this License").  Each licensee is
-addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-
-  6. As an exception to the Sections above, you may also compile or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    c) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    d) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the source code distributed need not include anything that is normally
-distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Library General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-			    NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-
-           How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
Index: angeLog
===================================================================
--- ChangeLog	(revision b940b91e7aa126759387aa2da6dd5b353accdd32)
+++ 	(revision )
@@ -1,1431 +1,0 @@
-1.0.4
- * Added a ':show quickstart' command. -geofft
- * Allow filters that reference a sub filter more than once non-cyclically. -nelhage
- * Make 'version' return 'BarnOwl' not 'Owl'
- * Escape interpolated regexes in filters. -andersk
- * Various code cleanups. -andersk
- * Fix format string injection bugs. -andersk
- * Clean up various code warnings. -nelhage
- * Replace questionable sprintf(buf, "%s...", buf, ...) pattern. -andersk
- * Show IRC /me messages with the conventional * instead of bold. -andersk
- * Rip out the openurl function and webbrowser variable. -andersk
-
-1.0.3
- * Moved BarnOwl source control to git on github.
- * Only call the zsig proc when we actually send a message. -asedeno
- * Strip out BOMs from Jabber messages. -asedeno
- * Fix logging of personal jabbers from JIDs containing / -nelhage
- * Fix Jabber breakage under reload-modules. -asedeno
- * Make reload-moduled correctly re-run startup hooks. -asedeno
- * Squelch Jabbers with no bodies, such as typing notifications. -asedeno
- * Various small spelling and grammar fixes. -geofft
- * Fix a segfault when sending short zcrypted messages. -asedeno
-
-1.0.2.1
- * Fix :reload-module's interactions with PAR modules
-
-1.0.2
- * Fix a segfault on retrieving zephyr subs when the user doesn't
-   have any or has expired tickets. -asedeno
- * Don't complain about non-existant ~/.owl/startup when starting. -asedeno
- * Fix narrowing to personals in IRC. -alexmv
- * Don't segfault retrieving subscriptions without valid tickets. -asedeno
- * Load modules even if .owlconf doesn't run successfully. -nelhage
- * Update the manpage for barnowl. -nelhage
- * Better support for irc-names, irc-topic, and irc-whois. -geofft
- * Display /quit messages in IRC -geofft.
- * Add a new perl hook for all new messages. -geofft
- * Fix a bug causing corrupted input in the editwin on end-of-line. -nelhage
- * Add better support for adding hooks in perl that behave correctly
-       on module reload. -nelhage
- * Added a :reload-module command to reload a single module. -nelhage
- * Fixed quoting issues replying to jabber users or MUCs containing
-        whitespace or quites. -nelhage
-
-1.0.1
- * Remove an unneeded .orig file from libfaim/ - hartmans
- * Update the copyright notice in ':show license' - nelhage
- * Add a jabber:spew variable that controls whether unrecognized
-   Jabber messages (such as pubsub requests) are displayed. - nelhage
- * Make the 'style' command assume the main:: package for
-   unqualified subroutine references. Reported by Jesse Vincent. - nelhage
- * Rename doc/contributors to the more canonical AUTHORS - nelson
-
-1.0.0
- * Don't fail silently when sourcing a file; actually let the user know. - asedeno
- * Only hang for 1s, rather than 10s, if there is no zhm - nelhage
- * Merge the unicode branch to trunk. BarnOwl is now unicode aware
-   and can send, receive, input and display UTF-8 encoded
-   messages. Unicode changelog:
-   * Put glib's CFLAGS and LDFLAGS at the beginning of the corresponding
-     variables. - nelhage
-   * Unicode branch: Fix building without zephyr. - asedeno
-   * Fix a unicode branch wordwrap problem. - asedeno
-   * Fixing an obscure wrapping bug that nelhage and I tracked down. - asedeno
-   * Rename configure.in to configure.ac so Debian autoconf DTRT. - nelhage
-   *  Fix a bug in owl_editwin_move_to_previousword() which would skip over
-       single letter words. - asedeno
-   * I think I like this better. - asedeno
-   * Fix nelhage's key_left bug. Don't spin at the locktext boundary. - asedeno
-   * fix a typo in OWL_FMTEXT_UTF8_BGDEFAULT
-   * fix a parsing issue for attributes - asedeno
-   * Better compliance with UTF-8 processing. Stop trying
-     to pull in a UTF-8 character as soon as we know something has gone
-     wrong. - asedeno
-   * Removing more hackery I left behind after doing things
-     the right way. - asedeno
-   * editwin.c - fix a wrapping bug I introduced in the
-     last revision. It could leave us with a buffer that was not valid UTF-
-     8 - asedeno
-   * editwin.c - lots of utf-8 cleanup that I had been
-     putting off. util.c - a can we break here'' function based on perl's
-     Text::WrapI18N - asedeno
-   * Remove more bad hacks. - asedeno
-   * Remove a debug message I accidentally left in. Remove
-     the hours old check_utf8 hackery in favor of actually marking strings as
-     UTF-8 from the C side. - asedeno
-   * editwin.c: make locktext deal with UTF-8
-   * Jabber - More utf-8 sanitizing.
-   * Pet peeve - tabs. That should be the end of it for
-     now. - asedeno
-   * Shuffling a line of code to where it actually should
-     be. - asedeno
-   * Patches to jabber libraries for better UTF-8
-     handling. - asedeno
-   * fix a typo that was causing background problems
-   * pass defaults attributes through in the truncate functions - asedeno
-   * Eliminating a warning by un-internalizing a new fmtext
-     function. - asedeno
-   * Do not use bit 0x80 to indicate meta. We have other uses for that bit.
-   * shift it above ncurses's KEY_MAX instead. - asedeno
-   * drop unused struct member
-   * fixing post-processing in the editwin. - asedeno
-   * Preserve colors when highlighting search terms. - asedeno
-   * ignore KEY_RESIZE if we know what that is. We don't need an
-     unhandled keypress every time we resize the terminal. - asedeno
-   * more strict utf-8 byte fetching.
-     This probably still needs more work. - asedeno
-   * Strip formmating characters when dumping to
-     file. - asedeno
-   * fixing bugs in editwin bufflen calculations. - asedeno
-   * Fix search code so higlighting actually works. - asedeno
-   * Remove options for libcurses and libncurses. This really only works with
-     libncursesw. - asedeno
-   * text entry:
-    first pass at utf-8 text entry. 
-   * Change wcwidth() calls to mk_wcwidth() - asedeno
-   * First pass at outbound zephyr -> iso-8859-1 sanitizing.
-     Not that we can input anything other than ascii yet...
-   * Fixing bug encountered when last field was not null-
-     terminated. - asedeno
-   * First pass at incoming zephyr -> UTF-8 sanitizing.
-     This only operates on incoming data so far. We still need to clean outgoing
-     data -- the plan is to attempt conversion to ISO-8859-1, and use that if it
-     works. - asedeno
-   * Reworked the fmtext format to use in-line formatting.  Characters used
-     for formatting are part of Unicode Supplemental Private Area-B, or
-     Plane 16.
-   * include wchar.h
-   * replace hand-rolled width detection with wcswidth.
-   * pad with space if we end up halfway into a character at the start of a line.
-   * UTF-8 - first pass
-   * make owl_text_truncate_cols() and owl_fmtext_truncate_cols() understand character width.
-     This may need more work. Some code duplication - see if we can refactor.
-   * stristr() rewritten to yse g_utf_casefold() instead of downstr(), and restructured to have a single return.
-   * only_whitespace() rewritten for unicode.
- * Fix sending jabbers to JIDs beginning with `+' - nelhage
- * Compile zcrypt.c with -w so I don't get all these warnings in my compile
-   output whenever I change any headers - nelhage
- * Implement /me for outgoing IRC messages - geofft
- * Add a makefile rule to support emacs flymake-mode - nelhage
- * Bind the combinations the iPhone sends for arrow keys [probably other
-   terminals, too] - nelhage
- * avoid null pointer dereference if msg is NULL (or a 0 length is
-   claimed) - shadow
- * Move styles from the current mishmash of different options to a unified
-   perl object interface. - nelhage
- * Refactor default style code somewhat to be more easily extensible - nelhage
- * Put glib's CFLAGS and LDFLAGS at the beginning of the corresponding
-   variables. - nelhage
- * IRC: /list, /who, and /stats commands - geofft
- * IRC: Make M-N mostly, rather than completely, useless. - geofft
- * Fix two small bugs in styling pointed out by broder - nelhage
- * Document create_style - nelhage
- * Move time_hhmm into a format_time method - nelhage
- * Remove prototypes from perlwrap.pm - nelhage
- * Quote regexp filter elements with spaces in them. - asedeno
- * Deal with smart-narrowing when the user's screenname has spaces in it. - asedeno
- * Add a new struct member to the global to hold an escaped aim screenname.
-    populate the aforementioned new struct member. - asedeno
- * Removed our debian subdirectory, per Debian guidelines, at broder's
-   request. - geofft
- * Make `all' the first target so we build the modules by default - nelhage
- * Commit inc/ under IRC so we build on systems with too old a M::I - nelhage
- * updating contributors - nelhage
- * Clean up licensing information and add a COPYING file - nelhage
- * Update bugs email to a more professional looking address, and remove the
-   Development build warning. - nelhage
-
-BarnOwl r989 (2008-03-21)
- * Stick modules on the beginning of @INC, not the end - nelhage
- * Merge in the select branch. BarnOwl's main loop now uses a select()
-   based event loop rather than continually polling, and uses much less
-   CPU. - asedeno
- * Fix a bug where an explicit (local) realm foiled
-   owl_message_get_cc_without_recipient(). (per quentin) - geofft
- * HTML Filtering fix for BODY tag - austein
- * Add parenthesis to fix a perl error in IRC - nelhage
- * Make IRC admin messages actually display their content - nelhage
- * Fix a file descriptor leak. - asedeno
- * Fix loading PAR modules that weren't present at startup - nelhage
- * Update perlwrap.pm documentation for the select() BarnOwl - nelhage
- * Render IRC notices as normal messages - nelhage
- * ensure that even if ioctl(,TIOCGWINSZ,) returns 0s we never set g->lines
-   (and g->cols) to 0 - shadow
- * Generate less ugly error spew if a module fails to load - nelhage
- * Added :webzephyr command with keybinding W. - geofft
- * Fix a race condition in which zephyrs received during init are not noticed
-   until the next zephyr after entering the mainloop. - asedeno
-
-BarnOwl r941 (2008-02-18)
- * unicode/glib branch Remove a debug message I accidentally left in. Remove
-   the hours old check_utf8 hackery in favor of actually marking strings as
-   UTF-8 from the C side. - asedeno
- * unicode/glib branch Remove more bad hacks. - asedeno
- * Rewrite ::Connection to not subclass Net::IRC::Connection to avoid stupid
-   namespace conflicts - nelhage
- * svn:ignore for great justice - nelhage
- * Attempt to load BarnOwl::MessageList::SQL and error if it fails. Note that
-   the aforementioned class n'existe pas - nelhage
- * unicode/glib branch editwin.c - lots of utf-8 cleanup that I had been
-   putting off. util.c - a can we break here'' function based on perl's
-   Text::WrapI18N - asedeno
- * unicode/glib branch editwin.c - fix a wrapping bug I introduced in the
-   last revision. It could leave us with a buffer that was not valid UTF-
-   8 - asedeno
- * dropping one unnecessary time(NULL) call. - asedeno
- * unicode/glib branch removing more hackery I left behind after doing things
-   the right way. - asedeno
- * unicode/glib branch better compliance with UTF-8 processing. Stop trying
-   to pull in a UTF-8 character as soon as we know something has gone
-   wrong. - asedeno
-*        First prototype of a SQL-backed message list. This is probably
-        horribly broken, and is painfully slow at the moment. - nelhage
- * minor changes to IRC
- * Resizing should not leave the current message off screen. - asedeno
- * Added initial IRC support. Not built or installed by default. - geofft
- * Preserve colors when highlighting search terms. - asedeno
- * Handle zephyrs to users on non -c message better [trac #39] - nelhage
- * Make :reload-modules work correctly with PARs - nelhage
- * Document (nearly) every public function in the BarnOwl:: namespace -
-   nelhage
- * strip IRC coloring from IRC messages - nelhage
- * Document ::Hook and ::Hooks - nelhage
- * Nuke the stylefunc_default C code - nelhage
- * Nuke some refs to owl_message_get_notice - nelhage
- * Clearing the line should preserve the echochar. - asedeno
- * Fix logins to jabber.org - reported by gendalia - asedeno
- * Move oneline style to perl. [trac #43] - nelhage
- * Fix the error messages sending to users who don't exist or aren't signed
-   on. - nelhage
- * Jabber Buddy Lists:
-  * Query the jabber:show_offline_buddies once when invoking onGetBuddyList()
-  * Don't bold online roster entries when hiding offline ones - asedeno
- * Portability - removing C++ style comments. - asedeno
- * Add the variable 'zsender' to customize the outgoing Zephyr
-   username. - geofft
- * Bind M-left and M-right by default in the editor - nelhage
- * eliminate a segfault. - asedeno
-
-BarnOwl r796 (2008-01-08)
- * Define variables at the top of blocks for better ANSI C-ness (patch by
-   Chris Laas) [trac #18] - nelhage
- * Implement :punt and :unpunt to punt arbitrary filters, rather than just z-
-   triplets. [trac #6] - nelhage
- * Show non-personal pings like stock owl does. [trac #12] - nelhage
- * Fix problems with jabber servers keeping the same stream id when
-   negotiating TLS tracked down by Greg Hudson. - asedeno
- * When we're narrowing to an instance, properly include un-instances. This
-   fixes narrowing to any instance that starts with ``un-'' - nelhage
- * Don't read before the start of the string for an instance - nelhage
- * Adding an explicit -f - to the tar commands for FreeBSD compatibility
-   (reported by ecprice) - nelhage
- * Some fixes for FreeBSD. - ecprice
- * Do ~-expansion in :loadsubs. [trac #26] - nelhage
- * Validate JIDs passed to jmuc join. [trac #25] - nelhage
- * Show full JIDs for users in non-anonymous JIDs in :jmuc presence. [trac
-   #24] - nelhage
- * Don't crash if we hit `i' on a zephyr containing non-ASCII iso-8859-
-   *. - nelhage
- * added -m flag to aimwrite - matt
- * aimwrite -m displays according to displayoutgoing - austein
- * Make the usleep call more reasonable for less CPU usage - asedeno
- * Add zip as build-depends - nelhage
- * bind END in popless windows. [trac #41] - nelhage
- * Allow C-r on outgoing messages (useful for CCs) - chmrr
- * Identify ourselves as barnowl more consistently - chmrr
- * Report subscription errors more accurately. - chmrr
-
-BarnOwl r751 (2007-08-01)
- * Refactored message processing: All new messages, incoming or outgoing, get
-   added to the owl_global_messagequeue by protocol code, and then passed to
-   owl_proces_message, which serves as a single central code path for adding
-   messages to the message list. - nelhage
- * Properly pass the usage when defining the jabberlogin command - nelhage
- * Outgoing messages now log as much information as incoming messages - chmrr
- * Fix a pointer corruption issue if we redefine the current style. - nelhage
- * Adding 3 variables for the Jabber module: jabber:show_offline_buddies,
-   jabber:auto_away_timeout, jabber:auto_xa_timeout - asedeno
- * Don't include self when replying to CC'd messages - chmrr
- * Outgoing CC'd messages get logged to all recipients - chmrr
- * Incoming CC'd zephyrs logged to all people they were sent to - chmrr
- * Change the width at which we hard-wrap outgoing zephyrs by default so
-   that zephyrs will fit on screen with the default style. (suggested by
-   andersk) - nelhage
- * Added a -s switch to change the location of the config dir (~/.owl) -
-   nelhage
- * Don't allow you to go off the end of an empty message list. [trac
-   #9] - nelhage
- * Allow you to send to -c message -i personal * - nelhage
- * Make zephyr smartnarrow use the `personal' and `private' distinction
-   properly [trac #2] - nelhage
- * Change the default personal filter to <message,personal,*> for
-   zephyr. - nelhage
- * Display opcodes with the default style - nelhage
-
-BarnOwl r720 (2007-05-29)
- * Correctly define a ``private'' zephyr as one that is sent to a
-    recipient that is neither empty nor starts with ``@'' - nelhage
- * Fix builds under make -j - nelhage
- * Fix sending of zcrypted zephyrs - nelhage
- * Rewrite perl internals to factor out module loading. - nelhage
- * Fix display of zephyrs with empty instances - nelhage
- * Implemented a Module::Install plugin for building barnowl plugins - nelhage
- * Modified the makefile to build and install perl modules - nelhage
- * Fix the bug in which rejoining a MUC you're already in (nick change)
-   results in the MUC appearing multiple times when you show presence info for
-   all MUCs. - asedeno
- * Implemented loading of both PAR and unpacked modules, and module
-   reloading. - nelhage
- * Make the Makefile build and install perl modules on a clean install.
-   - nelhage
- * Implemented an LRU cache of the message list fmtexts. This reduces
-   memory usage by roughly 1MB/kilo-zephyrs in steady state. - nelhage
- * Escape $ in regexes (e.g. smartnarrowed instances)
-  - nelhage
- * Adding 256-color support. This requires a version of ncurses that supports
-   ABI-6. Colors beyond the first eight are refered to by number. - asedeno
- * Correctly escape {} and () in regular expressions - nelhage
- * When generating filters, change single quotes and double quotes into
-   dots, so they line parser doesn't choke on them. This fixes problems
-   smart-narrowing to instances such as "this'll break it". - asedeno
- * Improving the private/personal distinction:
- * ``private'' means to/or from an individual, not a chat/class/etc.
- * ``personal'' means ``matches the personal filter'' - nelhage
- * Beep on personal messages, not private, by default.
-  - nelhage
- * Some small doc fixes (thanks to jwalden for pointing them out). - nelhage
- * Added the ability to define new variables from perl. - nelhage
- * Documented said ability via BarnOwl::new_variable_* - nelhage
- * Add a "setsearch" command which sets the search highlight string without
-   moving the cursor. - glasser
-
-BarnOwl r657 (2007-03-06)
- * Fix libfaim to make it compile - nelhage
- * Apply some memory leak patches by alexmv and yoz - nelhage
- * Make smartnarrow un- and .d-aware - chmrr
- * Add a `getstyle' command - asedeno
- * Make Test failures print file/line numbers - nelhage
- * Fixed regression tests for booleans variables. - asedeno
- * Add a perl perl hook into owl's main loop. - asedeno
- * Added the ability to install real commands from perl code - nelhage
- * Fix a hang in owl_editwin_move_to_previousword - nelhage
- * Updated the version number and startup message - nelhage
- * Added initial support for creating and injecting messages into the display
-   from perl. - nelhage
- * Added the ability for perl code to hang arbitrary reply commands off of
-   messages. - nelhage
- * Expose the edit window hooks to perl - nelhage
- * Removed references to -ldes - kchen
- * Exposed owl_function_error and owl_function_makemsg as commands - nelhage
- * Implemented initial Jabber support. - asedeno
- * Implemented initial Jabber groupchat support. - asedeno
- * Added a perl hook to the buddy list display - nelhage
- * Added a get_data_dir function to the perl interface - hartmans
- * Don't include the default typemap in xsubpp compile line - hartmans
- * Cause perl to always be loaded, even if no owlconf is present. - hartmans
- * Implemented an extensible perl module system - hartmans
- * Exposed owl_fuction_popless_text() and owl_fuction_popless_ztext() to
-   perl - asedeno
- * Support multiple simaltaneous Jabber connections - asedeno
- * Fixed a segfault on subbing without a .zephyr.subs file - nelhage
- * Implemented Jabber Roster support - asedeno
- * Don't quit if we can't contact the hostmaster. - nelhage
- * Support filters based on arbitrary message attributes - nelhage
- * Rewrote and massively cleaned up the filter system internals. - nelhage
- * Fixed the ``personal'' filter to work better with all protocols - nelhage
- * Made `smartnarrow' more generic, and implemented it for jabber. - nelhage
- * Changed executable name to "barnowl" - nelhage
- * Renamed the `owl::' package to BarnOwl:: - nelhage
- * Dynamically link perl libraries - nelhage
- * Added background color support - asedeno
- * Added idle-time tracking, and updated jabber to automatically set away
-   status - asedeno
- * Implemented shortnames for jabber rosters and jwriting. - nelhage
- * Fixed a crash when smartnarrowing to instances with lots of periods or
-   other regular expression metacharacters. - nelhage
- * Support comments in ~/.owl/startup - asedeno
- * Dispal tweaks for MIT's -c discuss messages. - asedeno
- * Don't override perl's idea of the switches we need to do embedding. -
-   shadow
- * Make the default style perl, rather than C. - nelhage
- * Refactor the default style to be protocol generic - nelhage
- * Prefer ~/.barnowlconf to .owlconf, if it exists. - nelhage
- * Intern hostnames and message attribute keys for a slight memory
-   saving. - nelhage
- * Use libncursesw when available - asedeno
-
-2.1.12pre
-        Don't crash when sending/logging outgoing 
-	   AIM message and not logged in [BZ 90]
-	Don't crash when senging to someone not on AIM buddy list [BZ 94]
-	   (patch from Alex Vandiver)
-	
-2.1.11
-	Don't crash doing zlocate with bad tickets. [BZ 12]
-	Metion the path for the owlconf in intro.txt [BZ 54]
-	Print better error message if startup fails due to unreadable
-	   .owlconf [BZ 57]
-	In load-subs: Print an error message if the file is unreadable or
-	  doesn't exist, UNLESS load-subs is called with no arguments.  In
-	  that case only print an error if the file exists but isn't
-	  readable.  Still prints an error either way if zephyr reports a
-	  failure. [BZ 19]
-	Fixed some small memory leaks in logging if files unwriteable
-	If the variable logfilter is set it names a filter.  Any messages
-	  matching this filter are logged.  This is an independent
-	  mechanism from the other logging variables.  If you want to
-	  control all logging with logfilter the other variables must be
-	  set to their default (off) settings. [BZ 37]
-	Relatively substantial changes made under the hood to support
-	  filter logging.  Now have more consistent interfaces to
-	  creating messages etc.  Still needs more work though.
-	Deal gracefully with being resized as small as 1x1 [BZ 3]
-
-2.1.10
-	Fix a new problem finding libdes425
-	Don't crash on very long hostnames [BZ 52]
-	In 'sub' command, create .zephyr.subs if it doesn't exist [BZ 15]
-	A fix for certain resize crashes (partly from alexmv) [BZ 55]
-	Turn off ISTRIP (gildea)
-	
-2.1.9
-	Include /usr/include/kerberosIV if it's found
-	
-2.1.8
-	Do OLC formatting for anything coming from olc.matisse
-	Improvements to popup size algorithm (from gildea)
-	Improved 'show colors' with non-colored labels
-	
-2.1.7
-	The colorclass command is added, to make colorization easy
-	Handle MIT Athena OLC zephyrs correctly
-	Updated ktools website / bug address
-	Do ntohs() when printing zephyr port in zephyr info
-	Updated man page
-	
-2.1.6
-        Fixed three bugs found by Valgrind.
-        Fixed a case where doing "aim addbuddy" instead of "addbuddy aim"
-	  would cause a segfault.
-	pexec will now incrimentally display data as it is output
-	  by the child process.  Additionally, commands running under
-	  pexec may now be killed by quitting out of the popless window.
-	Added muxevents select loop dispatcher.  File descriptors may
-	  be registered with muxevents and handlers will be dispatched
-	  to when data is available for non-blocking read/write/except.
-	Switched the stderr_redir stuff to use muxevents.
-	Print C-\ correctly (from gildea)
-	Dropped first brace in muxevents functions for consistency
-	Catch SIGHUP and SIGTERM and do a proper logout
-	
-2.1.5
-	Added a licence
-	The 'personalbell' variable can now be set to 'on' 'off' or
-	  the name of a filter to match against
-	The 'loglogins' variable now controls whether login/logout
-	  messages are logged.  It is off by default.  For now this
-	  affects only AIM messages, later zephyr login/logout messages
-	  will also be logged if this is set to 'on'
-	Added 'show license'
-	
-2.1.4
-	Normalize and downcase AIM names for logging
-	Fixed a bug where sending a null zsig could cause a crash
-	Better 'away' toggling if only one protocol is away.
-
-2.1.3
-	Added perl filter elements.  Similar to having "filter <subfilter>"
-	  in a filter, you may also have "perl <functionname>"
-	  where <functionname> is passed an owl::Message object and
-	  returns 0 or 1 depending on whether the message matches
-	  that element of the filter.
-	Don't print an error about loading subs if there is no
-	  .zephyr.subs
-	Do the initial zephyr_buddy_check when pseduologin set to true.
-	Updated man page
-	
-2.1.2
-	removed unused filter_depth variable
-	Fixed memory bug on receiving pings
-	
-2.1.1
-	Filters of filters now work.
-	Removed the "possibly not readable" part of the config parsing
-  	  error
-	In the sepbar, reverse video the view name when it's not set to
-	  view_home (as opposed to the static 'all').
-	The '!' key (bound to 'view -r') now creates a negative version of
-	  the current view and switches to it.  i.e. "show me all the
-	  messages that are not these"
-	Added the 'ignorelogins' variable
-	Log when outgoing personal message fails
-	Removed file descriptor from sigpipe catcher printer just for now,
-	  since the field does not exist on OSX
-	Added an ifndef for socklen_t in libfaim/ft.c
-	Added the 'aim search' command.  The popup on callback may be
-	  dangerous, should switch to an admin msg for results, or add a
-	  new event queue
-	First pass at AIM away messages.  It is a little different from
-	  what most clients seem to do, in that an away reply is sent for
-	  each message received.  Most clients only reply to the first one
-	  per away-session.
-	Now have a set of 'aaway' commands and variables just like the
-	  'zaway' ones (except that changing the 'aaway' variable talks to
-	  the server)
-	The new 'away' command does everything for both AIM *and* zephyr.
-	  There is a known funkiness here, where if you turn one away on,
-	  and then use 'away' (or 'A') to toggle, you will turn on off and
-	  the other on.  Just leaving it for now.  Should do better in the
-	  next patch.
-	The 'A' key is bound to 'away'
-	Status bar can now read AWAY, Z-AWAY or A-AWAY.
-	Changed C-n to scroll down just a line in popless
-	If the config exists but is not readable, print an error before
-	  exiting
-	Only print forced AIM logout message once.
-	Don't bind F1 to help in edit context
-	Fix bug in 'getsubs' with no tickets
-	New code for getting users from .anyfile
-	Added the 'pseudologins' variable, and code to do it
-	new attributes 'pseudo' 'logintty' and 'loginhost'
-	Don't print extra new lines in popless_file
-	New zephyr_get_field function
-	
-2.0.14
-	Fixed missing word in startup message
-	Better 'status' command
-	Use '+' for popwin corners when 'fancylines' is off
-	Allow TERMINFO to be overridden in the envrionment
-	Command line arg -D turns on debugging and deletes previous
-	  debugging file
-	Do ~ expansion in 'dump' command.
-	Current directory added to 'status' command
-	Massive changes to libfaim and aim
-	
-2.0.13
-	Changed startup message for new mailing list
-	blist now prints AIM info even if .anyone is unreadable
-	Catch SIGPIPE and print an error rather than crashing.
-	        [It's possible that this may have some portability 
-		issues under Solaris and we may need to add some 
-		configure stuff around SA_SIGINFO...]
-	Handle the case in aim_bstream_send where aim_send returns -1,
-	        although there is likely an underlying problem here
-		that would lead to this case.
-	Print the username on aim login failure, not something random like
-	        the password.  ;)
-	Un-word-wrap text when sending AIM messages.
-	Replace the main loop continue in the keyboard handler with an else.
-	
-2.0.12
-	Command history now doesn't allow the last entry
-	   to be repeated
-	If format_msg returns "" print "<unformatted message>"
-	Better align oneline admin and loopback messages
-	Print an admin message indicating when subscriptions can
-	   not be loaded on startup
-	Set aim_ignorelogin_timer to 15 by default
-	Admin message on login/logout of AIM
-	Fixed double quoting in smartzpunt
-	Added timestamp to login/logout messages
-	Fixed replies to loopback messages
-	Fixed smartnarrow on classes/instances with spaces
-	Added the 'loggingdirection' variable
-	All loopback messages log to 'loopback' now
-	Print an error message if trying an invalid color for a filter
-	Fixed bug causing > not to go to end of editwin every time
-	
-2.0.11
-	Updated basic help
-	Display CC: in outgoing CC messages
-	More AIM logout detection
-	Don't proclaim "interfaces changed" on first build.
-	Added the 'loopback' message type
-	Added the 'loopwrite' command
-	Added a timestamp to the default style
-	Zpunt now works with weird regex characters
-	Smart filters now work with weird regex characters
-	
-2.0.10
-	Allow 'hostname' in filters.
-	Fixed bug in reporting when no one is subbed to a class
-	Added an extral newline in logging incoming zephyrs
-	An admin message is displayed when you are logged out of AIM
-	Print an error message and admin message if an AIM send fails
-	
-2.0.9
-	Added the 'fancylines' variable.
-	Added the 'show startup' command.
-	Added feature for capturing stderr messages
-	   from commands and displaying them in the errors buffer.
-	Create an admin message explaning that a zephyr couldn't
-	   be sent
-	Better reporting of perl errors (both into the errqueue
-	        and also clearing the error after displaying it).
-	Allow default_style to be specified in config.
-	Added errqueue
-	Added command "show errors"
-	Fixed bug removing newlines in backup files
-	
-2.0.8
-	Increased size of screen name field in buddy listing
-	Fixed bug with idle times causing broken pipes.
-	New libfaim
-	Added the 'source' command.
-        Make sure that a newline is always at the end of messages
-	        returned by perl style formatting functions.
-	Add owl::login and owl::auth to legacy variables populated for format_msg.
-	Additions to intro.txt and advanced.txt documents.  (Still in progress.)
-	Add base methods for login_host and login_tty 
-	        and others that return undef.
-	New API for perl message formatting functions.  
-		Legacy variables are still supported for owl::format_msg
-	        and owl::receive_msg, but these functions are now also 
-	        passed an owl::Message object which contains methods
-	        for accessing the contents of the message.  See perlwrap.pm 
-		(and docs TBD) for the available methods.
-		*** WARNING:  The exact API for owl::Message has
-		*** not yet stabilized.
-	Added "style" command for creating new styles.
-	        Usage:  style <name> perl <function_name>
-	Added support for "show styles".  Changed global style table
-	        from list to dictionary.
-	Changed AIM password prompt from "Password:" to "AIM Password:".
-	Messages are reformatted after a window resize to allow styles
-	        to take into account the width of the window.
-	When perl throws an error, the message is put in the msgwin
-	        if possible.
-	Added perl functions for:	
-	        owl::getcurmsg() -- returns an owl::Message object for
-		                    the active message
-		                    in the current view.
-	        owl::getnumcols() -- returns the column width of the window
-		owl::zephyr_getrealm() -- returns the zephyr realm
-	        owl::zephyr_getsender() -- returns the zephyr sender
-	Made owl::COMMAND("foo"); be syntactic sugar for 
-	        owl::command("COMMAND foo");
-	Added perlwrap.pm to contain perl code to be compiled into 
-	        the binary.  This is transformed into perlwrap.c by
-		encapsulate.pl.
-	Renamed readconfig.c to perlconfig.c and changed variables accordingly.
-	Minor bugfixes in cmd.c and commands.c
-	Improved intro doc
-
-2.0.7
-	Idletimes now appear in the buddylisting
-	Failed AIM logins are now correctly reported
-	Owl will build now without zephyr, enabling it to act as a
-	  standalone AIM client.
-	There is now a zcrypt command
-	Replies to zcrypted messages now work
-	Don't allow zwrite if zephyr isn't present
-	Cleaned up some warnings from linux gcc.
-	Fixed bug that can cause response stuff to crash
-	Improved status command
-	Fixed bug in buddy stuff
-	
-2.0.6
-	aimlogin will now accept the screenname without a password and ask
-	   for the password such that it is not echo'd to the terminal
-	'addbuddy aim' and 'delbuddy aim' now work
-	Bug fix to make zwrite -m work with -c/-i
-	Fixed documentation bug in aimwrite
-	Initialze $owl::auth
-	Fix in autoconf for des425
-	Reformatted editwin.c and added capability of doing password-style
-	   echoing
-	
-2.0.5
-	Fix in finding des for building zcrypt
-	Fixed description for alert_action variable
-	More detailed usage from -h
-	Special cased replies for webzephyr users on classes and
-	  login notifications for webzephyr users
-	Fixed bug that caused a crash on zpunt with '*' for an instance
-	AIM logout and then login now works.
-	Fixed bug causing view -d not to work.
-	Added hostname and tty name to LOGIN/LOGOUT zephyrs on oneline
-	  style
-	
-2.0.4
-	Made command line option -n actually work
-	Implemented styles, including the 'default' 'basic' and 'oneline'
-	  styles.  A 'perl' style is available if a format_msg() function
-	  is found in .owlconf
-	Added the 'default_style' variable
-	Added the 'toggle-oneline' command
-	The 'o' key is bound to 'toggle-oneline'
-	Internally, the one view now has a name, 'main', and message
-	  recalcuations are done in place when its filter is changed.
-	Added filter field 'login' which can take the values 'login'
-	   'logout' or 'none'
-	Added the perl variable $owl::login, just as above
-	Updated the 'login' and 'trash' filters appropriately
-	Fix for checking for DES in build system
-	Bug fix in using makemsg when no curses window is present
-	The variable $owl::auth now exists in perl
-	Use new internal function to delete zephyr subs from file
-	New 'sepbar_disable' variable can turn off sepbar info display
-	Updated contributor info
-	Added the 'show view' command
-	Bug fix in owl_regex
-	Fixed personal aim messages logging to class directory
-	Log "LOGIN" or "LOGOUT" for AIM buddy messages
-	zwrite -m now correctly displays an outgoing message and logs
-	zwrite -s now works
-	Strip spaces in AIM usernames on aimwrite send
-	Removed libfaim/config.log from CVS
-	Fixed some easy fixed-length buffers
-	Wordwrap incoming AIM messages
-	Fixed bug causing buddies not to be added to buddy list during
-	  ingorelogin timer
-	Translate &lt; &gt; &amp; &quot; &nbsp; &ensp, &emsp, &endash and
-	   &emdash
-	
-2.0.3
-	Don't ring the terminal bell on mail messages.
-	Nuke <FONT>
-	Make the build work a little better on OSX
-	Fixed a bug in fmtext
-	Expanded the size of the hostname buffer
-	
-2.0.2
-	Fixed bug in 'startup' command.
-
-2.0.1
-	Moved newmsgproc stuff to a function procedure
-	Added the 'newlinestrip' variable, on by default, that strips
-	  leading and trailing newlines from incoming messages.
-	Fixed a case sensitivity probelm in owl_message_is_personal and
-	   owl_message_is_private
-	The message object now uses a list of attributes internally, in
-  	  prep. for supporting new messaging protocols
-	owl_function_info now uses fmtext instead of one staticly sized
-	  buffer
-	in owl_message_get_cc() require that the colon be present after
-	  cc.
-	Added some defenses against resize crashes, and put in debug
-	  messages if they're encountered
-	In filters 'true' and 'false' are now valid tokens.
-	The 'all' filter has been redefinied to be 'true' and there is a
-	  'none' filter defined as 'false'
-	Fixed bug in 'unsub' command that could cause file corruption
-	In the zlist function, give a more detailed error message if
-	  the file cannot be opened.
-	Renamed old instances of zsig_exec in the code to zsigproc
-	Don't print the stderr from zsigproc
-	Added a 'loadloginsubs' command to load login subscriptions from a
-	  file
-	Added a 'loadsubs' command to eventually phase out the 'load-subs'
-	  command
-	Made M-n work on classes and instances with spaces in them
-	Zaway now obeys the smart strip variable
-	Hacked the build system to not have the -E link problem on Athena
-	Added ZResetAuthentication in a number of places to fix problems
-	  with stale tickets
-	Added some hooks for malloc debugging
-	M-p is bound to 'view personal' by default
-	loadsubs and loadloginsubs only print messages if in interactive
-	  mode
-	added the 'alert_filter' variable, defaults to 'none'.
-	added the 'alert_action' variable, which is an owl command that
-	  will be executed when new messages arive that match the
-	  alert_filter
-	added the 'term' command which takes the 'raise' and 'deiconify'
-	  options.  It assumes xterm for now.
-	only 'make distclean' will nuke core and ~ files now
-	fixes to owl_function_do_newmsgproc from Stephen
-	converted functions.c to new code style, which I'm giving a shot
-	Makefile.in: define DATADIR, for default owlconf.
-	Makefile.in: provide "all" and "install" rules.
-	configure.in: try also libdes and libkrb4, for people using heimdal
-	configure.in: see if des_ecb_encrypt is already prototyped.
-	configure.in: minor changes to work with new autoconf without needing acconfig.h.
-        configure.in: find the install program.
-	configure.in: test for use_default_colors since some versions of
-	  solaris don't have it, so we can at least compile something
-	  vaguely working there.
-	keypress.c: ifdefs for keys not defined on at least some solarises.
-	owl.c: don't call use_default_colors if we don't have it
-	readconfig.c: added *commented out* code to try to find a
-	  system-default owlconf if the user doesn't have one.  Have to
-	  ponder if I want this
-	zcrypt.c: don't prototype des_ecb_encrypt if there is a prototype in
-	  des.h.
-	zcrypt.c: include owl.h so we get the configure-generated config.h
-	Change to codelist.pl to deal with new code style
-	Remove some ancient stuff from zcrypt.c
-	General cleanup to Makefile.in
-	CTRL and META are now OWL_CTRL and OWL_META.  OWL_CTRL moved to
-	  keypress.c
-	do_encrypt declaired static
-	if we don't have des functions, do not try to build in zcrypt
-	kill the newmsgproc function on exit
-	Added libfaim
-	Added basic AIM support, including the "aimlogin", "aimwrite" and
-	   "aimlogout" commands
-	New built-in filters 'aim' and 'zephyr'.
-	Do ZResetAuthentication() before zlog_in and zlog_out as well.
-	Print AIM login / logout notifications
-	The 'alist' command prints a list of aim buddies logged in
-	The 'blist' command prints users from all protocols
-	The 'l' key is now bound to 'blist' instead of 'zlist'
-	Started work on 'addbuddy' and 'delbuddy' command but they DO NOT
-	  WORK yet
-	Removed a bit of faim code that allowed commands to be executed.
-	The 'B' key is now bound to 'alist'
-	Added the 'startup' and 'unstartup' commands
-	The $HOME/.owl directory is created on startup if it does not exist
-	Added the 'aim_ingorelogin_timer' variable
-	'addbuddy zephyr <user>' and 'delbuddy zephyr <user>' now work.
-	'isloginout' and 'isprivate' are now message attributes
-	improved 'info' function lists seperate info for zephyr, aim and
-	   also prints all message attributes
-	AIM logging (both in and out) now works
-	Disabled 'addbuddy' and 'delbuddy' for aim since it doesn't work yet
-	Hacked the Perl build stuff not to link with iconv
-	
-1.2.8
-	Class pings are displayed differently now
-	Updated owlconf.simple example to format outgoing messages.
-	
-1.2.7
-	Outgoing messages now go through the config for formatting
-	Zaway now makes an outgoing message, instead of an admin message
-	The 'zlocate' command can now handle multiple users
-	The simple user format for "To:" is in effect again
-	Prettyed up the zwrite line for using 'reply' on a zaway
-	Added a workaround for a libzephyr bug that caused zwrites to fail
-  	  if zephyrs were sent just before and just after renewing tickets
-	Fixed a memory bug in getsubs
-	Added receive support for zcrypt messages
-	Added the 'zcrypt' variable which controls whether or not zcrypt
-  	  messages are decrypted
-	'reply' is disabled for zcrypt until sending zcrypt works
-	Started implementing zcrypt command
-	More updates to the intro doc
-	
-1.2.6
-	Started adding code for newmsgproc.  It doesn't fully work yet!
-	  Don't use it.
-	Added search, '/' and '?' to basic help.
-	Will attempt to keep the current message as close as possible
-	     to the previous current message after an expunge.
-	"set <variable>" and "unset <variable>" now work for boolean variables.
-	Fixed a bug in owl_function_calculate_topmsg_normal that caused a
-	  segfault
-	Fixed some typos in the intro doc
-	Removed old zlog functions from zephyr.c
-	Implemented the dump command
-	New startup message
-	
-1.2.5
-	Patch to fix memory bug in replying to CC messages
-	If we're on Athena and have static krb (or other) libraries, use
-	  them
-	Added "athstatic" program to the release, which handles the above
-	Cast to an int for isspace, to make gcc -Wall quiet
-	Added 'zlist' and 'l' to basic help.
-	
-1.2.4
-	'zlog in' will now take an optional thrid argument to set the
-	     'tty' variable before setting the zlocation
-	There is now a 'zlist' command that acts like 'znol -l'
-	'l' is bound to 'zlist'
-	Fixed memory leak uninitialzed memory read in fmtext
-	viewwin will now say "End" instead of "More" when at the end
-	Added a debugging message indicating the result of topmsg
-	  calculations
-	You can now use %me% in filters
-	The built-in personal filter is updated to do so
-	Fixed a bug in moving the pointer after an expunge
-	Fixed up the normal scrolling code.  Now it should always
-	  land on a message, but it's still not optimal.
-	Added the variable 'smartstrip' which will strip kerberos
-	  instances out for the 'reply' command.
-	Added -R/usr/athena/lib to the build for Athena
-	Started updating the intro document
-	Small changes to help / about
-	The 'subscribe' and 'unsubscribe' commands (and their aliases) now
-	  update .zephyr.subs by default.  If either is given the '-t'
-	  (for "temporary") option the .zephyr.subs will not be updated
-	Turned off beeping for hitting the top or bottom of the list of
-	  messages
-	Made daemon.webzephyr a special case for smartstrip
-	Added 'out' as a default filter for outgoing messages
-	
-1.2.3
-	Added filters "ping", "auto" and "login" by default.
-	Added "body" as a valid field to match on in a filter.
-	Temporary fix to bug where C-SPACE would cause the key handler to
-	     lock up.
-	Messages now have a direciton (in, out or none).  Filters can
-	     match on this direction
-	Outbound messages are no longer type 'admin' but are of the
-	     appropriate message type (i.e. 'zephyr') and are direction
-	     'out'.
-	Smartnarrow now works on outgoing messages
-	'info' updated to show more information for admin and outgoing
-	     messages
-	Renamed pretty_sender to short_zuser and renamed long_sender to
-             long_zuser
-	Moved zsig generation to the zwrite object
-	Print the zsig used for outgoing messages
-	The tty variable now controls the zephyr location tty name
-	
-1.2.2
-	Added the 'search' command.
-	'/' is a keybinding for 'search'
-	'?' is a keybinding for 'search -r'
-	Fixed stristr, which was completely broken
-	renamed owl_fmtext_ztext_stylestrip to owl_function_ztext_styletsrip
-	     and put it in functions.c
-	Attempts to stay near the current message when switching views.
-	     When switching from an empty view to one we've previously
-	     been in, the new current message position will attempt
-	     to be close to the current position from the last 
-	     time we visited that view.
-	Fixed bug in readconfig.c that prevented building under perl 5.005.
-	Switched "C-x C-x" to only "startcommand quit"
-	'getsubs' prints closer to the order you sub in.
-	Modified the behavior of last so that "> >" will clear the screen.
-	The new behavior of last is:
-	      Moves the pointer to the last message in the view.
-	      If we are already at the last message in the view,
-	      blanks the screen and moves just past the end of the view
-	      so that new messages will appear starting at the top
-	      of the screen.
-	Fixed a typo in the help for smartzpunt.
-	Fixed functions to handle curmsg being past the end of the view.
-
-1.2.1
-        New framework for command handling.
-        New framework for keymap handling.
-        Added commands for everything that is bound 
-             to a key (do 'show commands' to get the full list).
-        Added 'multi' and '(' commands to allow multiple commands
-             to be specified on a line.              
-        Added user keybindings with bindkey command.
-        Added command aliases (eg, "alias foo bar").
-        Added undelete command that parallels the delete command.
-        Added additional options to delete command.
-        The reply command now takes arguments.
-        Added 'edit:insert-text' command.
-        Added 'show zpunts' to show active punt filters.
-        Added 'show variable <name>' and 'show variables'.
-        Added 'show command <name>' and 'show commands'.
-        Added 'show keymap <name>' and 'show keymaps'.
-        Added 'M-u' to undelete all messages in current view.
-        Fixed dotsend so that the zephyr will still send if there
-             is whitespace after the dot but not on the same line.
-             This should resolve an issue where dotsend wouldn't work
-             if you'd gone up and edited a zephyr.
-	Bug in page down fixed
-	C-t will transpose characters
-        Fix the scrolling bug where we would sometimes fail to scroll
-             the screen down, leaving the current message off 
-             the bottom of the screen.
-        Refixed 'login or login' typo in help
-        Fixed M-u description
-        Removed 'first' and 'last' from basic command help
-        Added M-N to basic key help
-        Added M-D, M-u to basic key help
-        Fixed a quoting problem in configure.in
-        Changed top of help to use 'show' instead of M-x
-        Fixed a bug in the summary field for user-created aliases
-        Added "reply zaway" which sends a zaway response to the current msg.
-        Added "edit:delete-prev-word" command and bound M-BACKSPACE to it.
-	Some buffer overruns fixed
-        Variables now have a summary and a long description.
-                Only the summary is shown with help.
-                The long description is shown with "show variable foo".
-        Added a 'scrollmode' variable which determines how the screen
-             will scroll as the cursor moves.  The default behaves
-             identically to previous versions of owl.
-             The following modes are supported:
-             normal      - This is the owl default.  Scrolling happens
-                           when it needs to, and an attempt is made to
-                           keep the current message roughly near
-                           the middle of the screen.  (default)
-             top         - The current message will always be the
-                           the top message displayed.
-             neartop     - The current message will be one down
-                           from the top message displayed,
-                           where possible.
-             center      - An attempt is made to keep the current
-                           message near the center of the screen.
-             paged       - The top message displayed only changes
-                           when user moves the cursor to the top
-                           or bottom of the screen.  When it moves,
-                           the screen will be paged up or down and
-                           the cursor will be near the top or
-                           the bottom.
-             pagedcenter - The top message displayed only changes
-                           when user moves the cursor to the top
-                           or bottom of the screen.  When it moves,
-                           the screen will be paged up or down and
-                           the cursor will be near the center.
-        Added owl_sprintf which returns the formatted string, or NULL.
-                The caller must free this string.
-                This will allocate enough memory and thus 
-                avoid potential some buffer overrun situations.
-        Simple implementation of 'zwrite -m' (doesn't yet log an outgoing
-                message as having been sent.)
-        The "Not logged in or subscribing to messages" error 
-                now includes the name of the recipient.
-        The "disable-ctrl-d" variable may also be set to "middle"
-                which will result in ctrl-d only sending at the 
-                end of the message.  This is now the default.
-                This also added a command "editmulti:done-or-delete".
-        Fixed a bug in the "reply -e" command.
-        Always clear the command buffer before executing the command.
-                (So that interactive commands can sanely do start-command.)
-        Fixed preservation of e->dotsend across owl_editwin_clear().
-        Added history for multiline edit windows (eg, for zephyr composition).
-                The M-n and M-p keys will cycle through the history ring.
-                In particular, it is now possible to edit the command line
-                of a zephyr being composed:  C-c it and restart it 
-                and then M-p to get the aborted composition back.
-        Added owl::send_zwrite(command, message) to the perl glue
-                to allow for the direct sending of multi-line messages.
-                For example:  owl::send_zwrite("-c foo -i bar", "hello"); 
-        Changed owl_fmtext_print_plain to return an alloc'd string to 
-                avoid buffer overrun risks.
-        Added owl::ztext_stylestrip("...") function to perlglue 
-                 which returns the ztext with formatting stripped out.
-        Added colorztext variable which can be used to disable @color()
-                 strings arriving in messages after it is set.
-                 (Currently, changing its value won't reformat messages).
-        Outgoing zephyr logging now obeys the logpath variable.
-        The '~' character in logpath and classlogpath now gets
-                 replaced with the user's home directory.
-        Added simple implementation of smartnarrow-to-admin that
-                 creates a "type-admin" autofilter.
-                 This was done mostly so that M-C-n and M-C-p do something
-                 sane on admin messages.
-        Added opera to the allowed options to the webbrowser variable.
-        Fixed some buffer overruns in the "reply" command.
-        When repying to "all" on a message that begins with "CC:" (eg, sent 
-                 with "zwrite -C", the reply line will be constructed
-                 from the sender and the usernames on the CC: line
-                 of the message being replied to.
-        There is no such thing as C-R, so left C-r as it is but added:
-                 M-r --- edit reply to all
-                 M-R --- edit reply to sender
-        Added RCS Id strings to all files.
-        'show keymaps' shows details of all keymaps after summary list.
-        Added --no-move option to delete command.
-                In particular, delete-and-always-move-down may now
-                be implemented with 
-                '( delete --no-move ; next --skip-deleted )'.
-        Folded the nextmsg and prevmsg commands and functions together into 
-                one command which takes arguments.
-                Added '--filter <name>' option (eg, for next_personal),
-                '--skip-deleted' option, and
-                '--last-if-none'/'--first-if-none' options.
-                Help updated accordingly.  
-                In particular, the 'personal' filter is now used 
-                for 'next personal'.  
-	        Added --smart-filter and --smart-filter-instance options 
-                to the next and prev commands.
-        Updated examples/owlconf.erik with the above.
-        Made owl_function_fast*filt return a string and not do the 
-                narrowing, to make it more general.
-        Added a smartfilter command that creates a filter
-                based on the current message and returns the name
-                of the filter.
-        Added M-C-n and M-C-p keybindings to "move to next message 
-                matching current" and "move to previous message 
-                matching current"
-        Added variables edit:maxfillcols and edit:maxwrapcols which 
-                will limit how wide editing paragraphs may get before
-                they get wrapped.  This is a max and may be narrower
-                depending on the current size of the window.
-                If 0, the max is unlimited.  Default is 70 columns for
-                edit:maxfillcols and unlimited for edit:maxwrapcols.
-        Added smartzpunt command with key binding of "C-x k".
-                This starts a zpunt command filled in with 
-                the proposed zpunt.
-        Fixed a memory reference bug in delete and undelete commands.
-        Added support for perl to call directly back into owl.
-        Changed the implementation of owl::command("...") to immediately
-                call back into owl.  This allows perl to get the return
-                value of strings returned by owl commands.
-        Added the getview command which returns the name of the current 
-                view's filter.  
-        Added the getvar command which returns the value of a variable.
-        Added an example to examples/owlconf.erik which uses TAB to 
-                narrow and restore the view.  
-        Added an example to examples/owlconf.erik which uses M-c to 
-                color messages matching the current one green.
-        Integrated change to fix problem with popup blinking on new zephyrs.
-        C-l and resizes will now refresh an open viewwin (eg, help).
-        Updated doc/code.txt to include info about filters, commands,
-                contexts, and keybindings.
-        Exec commands cleaned up to not have buffer-size limitations
-                and to not mess up spaces.  exec also returns a string
-                of the output now.
-        Integrated changes from 1.1.3, and added docs for "zlocate -d"
-                and new show commands.
-        Show with arguments produces help on show.
-        Fix a bug in readconfig caught by efence (where we'd try to read before 
-                the beginning of a string if it was empty).
-        The perl command doesn't do makemsg directly, but instead
-             returns the string and it will get printed if it 
-             was run interactively.
-	
-1.1.3
-	'show subs' and 'show subscriptions' are now the same as 'getsubs'
-	zlocate now takes an optional -d argument
-	'show terminal' / 'show term'
-	'>' / last doesn't set the last message at the top of the screen now
-	implemented _followlast as an unsupported feature
-	include 'default' in the 'show colors' list
-	added help for 'zpunt' and 'zunpunt'
-	changed the bug address in the startup message
-	can now do 'show status'
-	can now do 'show version'
-	'status' / 'show status' includes the owl version number now
-	'show terminal' includes whether the terminal can change colors
-	fixed off by one bugs in paging / scrolling viewwin
-	don't downcase the sender when getting the log name for personals
-	support @owl::fields as well as @fields
-	downcase class/inst filter names in auto filters
-
-1.1.2
-	Fixed memory mishandling bug
-	Fixed bug in redfining the filter attached to the current view
-	M-n will narrow to message, instance on non-personal, class
-	     MESSAGE messages
-	M-N behavies like M-n except that on class messages it narrows
-	    to class and instance
-	line wrap earlier, to account for tabbing
-	fixed typo in help
-	'status' command now displays info on terminal color support
-	zephyr @ formatting is now case independant
-	added support for color terminals
-	zephyr @color(foo) now works
-	'D' for deleted messages is now not bold, unless it's the current
-  	  message
-	F1 displays the help screen
-	added filter colors
-	added the 'colorview' command
-	added the 'show colors' command
-	users who don't have a .zephyr.subs get a simpler format for
-  	  incoming messages
-        If colors are available 'show filters' will show a filter in the
-	  color associated with it.
-	Added the zpunt and zunpunt commands
-	Lines in the subs file starting with '-' are zpunted
-	Include login/logout messages in auto user filters
-	'V' changes to the home view ('all' by default)
-	
-1.1.1
-	Fixed perl, aperl, and pperl commands to deal with quoting 
-	      and spaces in a saner manner.
-	Removed all owl_get_* methods for booleans and switched
-	      cases where they were used to owl_is_* 
-	Changes to owlconf.erik to use some new features.
-	Increased the size of the help buffer (as it 
-	      was overflowing and truncating the help message).
-	Variables prefixed with a _ are not shown in help
-	      or by printallvars (and prefixed Not Yet Implemented 
-	      variables with this).
-	Fix typo in help
-	include stdio.h in functions.c
-	remove stale "q to quit" from bottom of info message
-	fix downward scrolling more than a page
-	use authentication for zlocate, by default
-	fixed buffer over run in info command on long messages
-	call 'perl <file>' from Makefile to avoid hardcoding perl paths
-	in Makefile don't build owl_prototypes.h unless necessary
-	store the time for admin messages
-	display admin message time in 'info' command
-	fixed an editwin M-> last character bug
-		
-1.1
-	reply is a normal function now
-	'R' does reply to sender
-	'T' tells you how many messages were marked for deletion
-	local realm removed from login / logout messages
-	added command history
-	better runtime / starttime reporting in 'status' command
-	leave the pointer near the current message after expunge
-	C-l recenters editwin
-	implemented zlocate
-	@italic works the same as @i
-	on reply only quote class / instance when necessary
-	C-r allows you to edit the reply line
-	don't use unecessary options in reply line
-	display 'info' errors in msgwin, not popup
-	impelemnted aexec, pexec commands
-	the zsig now goes through ztext formatting
-	messages have id numbers now
-	'info' prints the msgid
-	added the 'filter' command
-	added the 'view' command
-	added the 'show filter' command
-	added the 'viewclass' (and 'vc') commands
-	added the 'viewuser' (and 'vu') commands
-	M-n will filter to the current class or user
-	'v' starts a view command
-	M-D will delete all messages in current view
-	added the 'delete' (and 'del') command
-	load-subs with no argument loads the default subs file
-	'<truncated>' is now when the *current* message is truncated
-	the reply-lockout filter (with default) specifices messages that
-           cannot be replied to.
-	in the configfile owl::receive_msg is run whenever a message is
-	  received
-	added the beep command
-	added the contributors file
-	declare ZGetSubscriptions and ZGetLocations since the includes
-          don't seem to
-	fixed bug in displaying last line in popwin if no final '\n'
-	'T' uses the 'trash' filter now
-	zaway_msg, zaway_msg_default and zaway are all user variables now.
-	zsig variable overrides zsigproc
-	If there's no appendtosepbar don't interfear with the sepbar
-	Changed: owl_message_get_numlines will return 0 of m is NULL
-	Added login messages to messages marked by owl_function_delete_automsgs
-	Added owl_function_delete_by_id(id) which acts independent of view
-	Added "-id <id>" option to delete command
-	Fixed an arg checking bug in delete command
-	Added owl::id to perl namespace with message id
-	Fixed a memory corruption bug in readconfig.c (where right 
-	      after the strdup to "out", we'd strcat a \n onto the end.
-	      This would be triggered whenever owl::format_msg returned
-	      a string not ending in a newline
-	Added 'X' keybinding which expunges and then switches to 
-	      a view defined by the variable "view_home" which defaults 
-	      to "all"
-	Consolidated readconfig.c somewhat to remove duplication.
-	      owl_config_execute now returns a string.
-	Added an example config file that does vt-style formatting.
-	      (examples/owlconf.vtformat)
-	Added the 'perl', 'aperl', and 'pperl' commands which will
-	      evaluate perl expressions.
-        Fixed bug where pclose zsigproc would cause zombies
-	Can set zsigproc or zsig to "" to disable
-	Added support for multiple browsers (galeon and none were added).
-	      Configure with the "webbrowser" variable.
-	Changing typewinsize height triggers resize event.
-	Added zsig variable which will be used if no zsigproc and non-empty.
-	Added "make test" rule to Makefile which will run regression tests,
-	      and added regression testing framework to tester
-	Fixed codelist.pl to ignore static declarations.
-	Added dict.c which contains string->ptr dictionary routines
-	      and the owl_dict type.
-	      These include regression tests.
-	Overhaul/rewrite of variable handling.  Variables are now managed
-	      in an owl_vardict (in g.vars) which contains a dictionary
-	      of owl_variable's.  Each owl_variable has dispatch functions
-	      for validating values, setting it and getting it,
-	      and for setting it to and from string values.
-	      The variable.c file contains the list of variables.
-	      Stubs for the owl_global_<varname>_get functions and friends
-	      are generated from variable.c by stubgen.pl.
-	      The help.c messages for variables now calls into variable.c
-	      so all information about most variables is in one place.   
-	Cleaned out code from global.c and command.c that was made obselete
-	      by variable overhaul.
-	The set command now takes a -q option to not log a message.
-	Fixed a bug where set and print with no arguments would
-	      print "Undefined variable" in addition 
-	      to running owl_function_printallvars.
-	debug is now a variable that can be turned on and off.
-	Fixed mail,inbox message parsing in examples/owlconf.erik
-	Made zaway_msg and zaway_msg_default into variables 
-	Changed owl_function_makemsg and owl_function_debugmsg 
-	       to use varargs (ie, so they can now take a format
-	       string with args).
-	Don't allow " and \ characters in URLs with the "w" command.
-	Removed lots of build warnings.
-	Popwins are wider by default so help messages fit better.
-	Added an atokenize_free function.
-        Fixes to work with an older version of libzephyr.
-	Added dependencies on header files to Makefile.in
-	Added pageup and pagedown key bindings to message list
-	Added pageup and pagedown to viewwin
-	Added configfile section to doc/intro.txt (from example config file)
-	Added appendtosepbar variable which may contain text which will
-	      be appended to the sepbar.  This allows the configfile
-	      to put information about pings and logins into
-	      the sepbar.  (It may be worth also providing a variable
-	      which enables this by default, but for now this allows
-	      for experimenting with what works well.)
-	Added doc/code.txt which gives a brief overview of the code.
-	Added tags makefile rule and added TAGS to distclean rule.
-	
-1.0.1
-	fix frees in loadsubs and loadloginsubs
-	don't return in owl_free
-	
-1.0
-	'print' and 'set' with no arguments prints all variables
-	Added the 'unsubscribe' and 'unsub' command
-	Renamed the 'unsub' command to 'unsuball'
-	Added the 'getsubs' command which is like zctl ret
-	Fixed bug in logging messages sent to more than one recipient
-	Support '-C', '-O', and '-n' options to zwrite
-	Fixed bug in owl_editwin_delete_char when there are no later chars
-	  after the cursor
-	Make "more" and "truncated" work in the status bar
-	enable printing of zsigproc and loginsubs variables
-	only allow message scrolling if the message is actually off the
-	  screen
-	'T' will mark all automated message for deletion
-	'P' will go to the next personal message
-	'M-P' will go to the previous personal message
-	replying to a login message goes to the user now
-	added a status command
-	added the intro doc to the release
-	fixed off by one bug in viewwin
-	added complete online help
-	pass $owl::realm in configfile
-	fixed editwin wordwrapping on the last line
-	fixed editwin problem with key_right past the last char
-	print an error and quit if the configfile can't be parsed
-	got rid of owl_mainwin_calculate_topmsg
-	fixed off by one error in calculating topmsg upwards
-	you can now reply to an admin message
-	don't display an error about keypress on window resize
-	
-0.11
-	fixed bug in viewing messages longer than the screen
-	indicate in the sepbar if there is a non zero vert offset
-	send on '.' on a line by itself
-	added disable-ctrl-d variable
-	fixed bug where C-k did not delete the last \n in the buffer
-	make non-character meta keys work
-	use ZSendNotice instead of ZSendList
-	implemented <, >, M-< and M-> in viewwin
-	removed the spaces at the bottom of viewwin
-	added 'about' command
-	fixed bug using 'M' with no current message
-	changed message object to use char *'s to save on memory
-	change malloc, realloc, strdup and free to use owl hooks so that
-	   debugging can be added
-		
-0.10.1
-	fixed a trailing space bug in the parser
-	impelemented the "burning ears" feature
-	have admin messages do ztext parsing
-	fixed bug in reporting which M- key was pressed
-	C-g will now cancel commands like C-c
-	
-0.10
-	implemented owl_function_full_redisplay().
-	C-l uses owl_function_full_redisplay().
-	when a popwin exists to a full redisplay.  (fixes bug)
-	improved the owl_editwin_process_char logic
-	removed all unnecessary wrefresh's and replaced with wnoutrefesh
-	owl_editwin_redisplay now takes an argument to optionally doupdate()
-	improved the cut-and-paste speed by not doing a usleep the first
-	  time through the loop after getting a keypress.
-	nuked typwin.c and associated stuff.  It's useless now.
-	added viewwin code for paging windows
-	curly braces work for zephyr formatting
-	@i in zephyr formatting will be displayed as underlined text
-	turned off idlok
-	implemented viewwin
-	implemented viewwi in popwin for pageable popwins
-	help, info now use pageable popwins
-	bound 'M' to bring the current message up in a popwin
-	return, space bar, 'b' and backspace now scroll within a message
-	turned off resize message
-	C-v and M-v page the main window
-	implemented owl_message_is_mail
-	some build cleanup
-
-	
-0.9
-	added owl_message_is_personal and have things use it
-	added owl_message_is_private
-	fixed 'print personalbell' and have 'set personalbell'
-	   print a message
-	bold only on message_is_personal
-	display the realm if not local
-	implemented M-f, M-b, M-d, M-<, M-> in editwin
-	implemnted word wrapping in editwin
-	implemented M-q (paragraph-fill) in editwin
-	fixed bug that caused owl to segfault logging a 'weird' class
-	M-x is a keysym for ':'
-	added smart bolding and userclue
-	fixed a bug causing pings to beep even if rxping is off
-	
-0.8.1
-	fixed bug in logging code
-	
-0.8
-	implemented personal logging
-	implemented class logging
-	implemented resize of typewin
-	fixed the backspace problem
-	-v command line option prints the version number
-	
-0.7
-	load-subs will report error opening file
-	skip comment lines in loadsubs and loadloginsubs
-	changed internal references to rxping and txping
-	fix replying to a blank instance
-	added subscribe command
-	subscribe to login messages from .anyone by default
-	'loginsubs' variarble controlls automated login messages
-	redisplay the editwin after a resize
-	leave the cursor in the editwin if active
-	fix problems in the build system
-	added displayoutgoing variable
-	temporarily removed error printing for zlog in / out
-	
-0.61
-	fixed bug in "message sent to <foo>" for zwrite
-	
-0.6
-	help updated
-	zaway key set to caps A
-	support zephyring other realms
-	rxping variable for receiving pings
-	txping variable for sending pings
-	function in place to resize typwin
-	C-l to refresh
-	personal bell variable
-	beta message now an admin message
-	
-0.5
-	Added the debug command and flag
-	Fixed bug in printing fields in info command
-	Added owl_fmtext_append_ztext and use it
-	Better formating for pings and login zephyrs
-	make tester depends on proto
Index: kefile.in
===================================================================
--- Makefile.in	(revision d4b6b23362b3a9b7e5b8ca836bfceba4383c11f7)
+++ 	(revision )
@@ -1,145 +1,0 @@
-# $Id$
-
-srcdir = @srcdir@
-VPATH = @srcdir@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-datarootdir = @datarootdir@
-datadir = @datadir@/barnowl
-bindir = @bindir@
-mandir = @mandir@
-
-CC=@CC@
-LIBS=@LIBS@ -L./libfaim -lfaim
-CFLAGS=@CFLAGS@ -I./libfaim -DDATADIR=\"${datadir}\"
-LDFLAGS=@LDFLAGS@
-XSUBPPDIR=@XSUBPPDIR@
-XSUBPPFLAGS=@XSUBPPFLAGS@
-INSTALL=@INSTALL@
-INSTALL_PROGRAM=@INSTALL_PROGRAM@
-INSTALL_DATA=@INSTALL_DATA@
-ATHSTATIC=@ATHSTATIC@
-
-BASE_SRCS=list.c message.c mainwin.c popwin.c zephyr.c messagelist.c \
-     commands.c global.c text.c fmtext.c editwin.c util.c logging.c \
-     perlconfig.c keys.c functions.c zwrite.c viewwin.c help.c filter.c \
-     regex.c history.c view.c dict.c variable.c filterelement.c pair.c \
-     keypress.c keymap.c keybinding.c cmd.c context.c zcrypt.c \
-     aim.c buddy.c buddylist.c timer.c style.c errqueue.c \
-     zbuddylist.c muxevents.c popexec.c obarray.c select.c wcwidth.c \
-     glib_compat.c
-OWL_SRC = owl.c
-TESTER_SRC = tester.c
-
-EXE = barnowl
-PERL_MODULES = Jabber IRC
-MODULE_DIRS = $(PERL_MODULES:%=perl/modules/%)
-
-BASE_OBJS = $(BASE_SRCS:.c=.o)
-
-GEN_C = varstubs.c perlglue.c perlwrap.c
-GEN_H = owl_prototypes.h 
-GEN_O = $(GEN_C:.c=.o)
-
-OBJS = $(BASE_OBJS) $(GEN_O)
-
-AUTOGEN=$(GEN_C) $(GEN_H)
-#AUTOGEN=$(GEN_C)
-
-HEADERS=$(GEN_H) owl.h config.h test.h
-
-all: $(EXE) $(MODULE_DIRS)
-
-$(EXE): $(AUTOGEN) $(OBJS) owl.o libfaim
-	$(ATHSTATIC) $(CC) -o $(EXE) owl.o $(OBJS) $(LDFLAGS) $(LIBS)
-
-tester: $(AUTOGEN) $(OBJS) tester.o libfaim
-	$(ATHSTATIC) $(CC) -o tester tester.o $(OBJS) $(LDFLAGS) $(LIBS)
-
-%.o: %.c $(HEADERS)
-	$(CC) -c $(CFLAGS) $< -o $@
-
-# zcrypt is old crufty DES code I don't want to touch
-# Disable all warnings when compiling it
-zcrypt.o: zcrypt.c $(HEADERS)
-	$(CC) -c $(CFLAGS) $< -w -o $@
-
-test: tester
-	./tester reg
-
-clean: libfaimclean modules_clean
-	$(RM) $(EXE) tester *.o $(AUTOGEN) owl_prototypes.h.new
-
-distclean: clean libfaimdistclean
-	$(RM) config.cache config.log config.status  Makefile config.h TAGS *~ core
-
-.PHONY: $(MODULE_DIRS)
-
-modules: $(MODULE_DIRS)
-modules_clean:
-	for i in $(MODULE_DIRS); do \
-		cd $$i; test ! -f Makefile || make clean; \
-	done
-
-$(MODULE_DIRS): %: %/Makefile
-	( cd $@ && make $(notdir $@).par )
-
-$(MODULE_DIRS:=/Makefile): %/Makefile: %/Makefile.PL
-	( cd $(dir $@) && perl -I../../lib Makefile.PL )
-
-proto: owl_prototypes.h
-
-perlglue.c: perlglue.xs Makefile 
-	perl $(XSUBPPDIR)/xsubpp $(XSUBPPFLAGS) -prototypes perlglue.xs > perlglue.c
-
-varstubs.c: variable.c stubgen.pl
-	perl stubgen.pl > varstubs.c
-
-perlwrap.c: perlwrap.pm encapsulate.pl
-	perl encapsulate.pl perlwrap.pm owl_perlwrap_codebuff > perlwrap.c
-
-# Only move owl_prototypes.h into place if the new one is different
-owl_prototypes.h: codelist.pl varstubs.c $(BASE_SRCS)
-	perl codelist.pl > owl_prototypes.h.new
-	@cmp -s owl_prototypes.h.new $@ || { \
-	 test -f $@ && echo 'Interfaces changed!'; \
-	 echo mv -f owl_prototypes.h.new $@; \
-	      mv -f owl_prototypes.h.new $@; }
-#owl_prototypes.h:
-
-.PHONY: tags clean distclean proto test check-syntax
-
-tags: TAGS
-
-TAGS: $(BASE_SRCS) $(OWL_SRC) $(TESTER_SRC) $(GEN_C) owl.h $(GEN_H)
-	etags $(BASE_SRCS) $(OWL_SRC) $(TESTER_SRC) $(GEN_C) owl.h $(GEN_H)
-
-$(BASE_OBJS) varstubs.h: owl.h config.h owl_prototypes.h
-
-libfaim: libfaim/libfaim.a
-
-libfaim/libfaim.a:
-	(cd libfaim; $(MAKE))
-
-libfaimclean:
-	(cd libfaim; $(MAKE) clean)
-
-libfaimdistclean:
-	(cd libfaim; $(MAKE) distclean)
-
-install: all installdirs
-	${INSTALL_PROGRAM} $(EXE) ${DESTDIR}${bindir}/$(EXE)
-	${INSTALL_DATA} doc/barnowl.1 ${DESTDIR}${mandir}/man1/barnowl.1
-	${INSTALL} -d ${DESTDIR}${datadir}/lib
-	${INSTALL} -d ${DESTDIR}${datadir}/modules
-	tar -C perl/lib --exclude .svn -cf - . | tar -C ${DESTDIR}${datadir}/lib -xf -
-	for i in $(PERL_MODULES); do \
-		${INSTALL_DATA} perl/modules/$$i/$$i.par ${DESTDIR}${datadir}/modules/$$i.par; \
-	done
-
-installdirs: mkinstalldirs
-	${srcdir}/mkinstalldirs ${DESTDIR}${bindir} ${DESTDIR}${mandir}/man1 ${DESTDIR}${datadir}
-
-# For emacs flymake-mode
-check-syntax: proto
-	$(CC) $(CFLAGS) -Wall -Wextra -pedantic -fsyntax-only $(CHK_SOURCES)
Index: WS
===================================================================
--- NEWS	(revision 1aee7d914de75510e7cf09c452bad63b2dad2166)
+++ 	(revision )
@@ -1,281 +1,0 @@
-
-$Id$
-
-What's new in owl version 1.1
------------------------------
-* Generic filtering now exists
-
-* The filter command creates a filter
-
-* The view command narrows the view to a filter
-
-* The viewclass / vc command automatically narrows the view
-  to a particular class
-
-* The viewuser / vu command automatically narrows the view
-  to a particular user
-
-* M-n automatically narrows the view to whatever is appropriate for
-  the current message
-
-* v will start a view command
-
-* X will expunge and change the view to the view_home variable value
-
-* R will reply to sender
-
-* C-r and C-R will let the user edit the reply line
-
-* T now uses the 'trash' filter
-
-* T tells you how many messages were marked for deletion
-
-* The local realm has been removed from login/logout messages
-
-* Command history works
-
-* Prettier status command
-
-* Leave the pointer near the current message after an expunge
-
-* C-l recenters the typing window
-
-* zlocate is implemented
-
-* @italic works like @i
-
-* Unecessary quoting and options in reply lines have been removed
-
-* Errors in the 'info' command don't show up in a popup now
-
-* Implemented the aexec, pexec commands
-
-* The zsig now gets zephyr formatting
-
-* Messages now have message id's. They are displayed in 'info' and are
-  passed to the config as $owl::id.
-
-* The 'show' command is implemented to display info about filters.
-
-* M-D marks for deletion all messages in the current view
-
-* added the delete command
-
-* load-subs with no argument loads the default subscription file
-
-* "Truncated" is now displayed when the *current* message is truncated
-  not when the last displayed message is truncated.
-
-* The reply-lockout filter locks out replies to some classes
-
-* In the configfile owl::receive_msg is run when a message is
-  received.
-
-* Added the beep command
-
-* Added the contributors file
-
-* zaway, zaway_msg and zaway_msg_default are all user variables now
-
-* There is a zsig variable that overrides other zsig mechanisims
-
-* The appendtosepbar variable exists to allow the config to display
-  things in the sepbar
-
-* login messages are included as 'trash' messages by default now
-
-* Fixed a memory corruption bug in readconfig.c
-
-* There are example configs in the distribution now
-
-* Implemented the perl, aperl and pperl commands
-
-* FIxed bug with zsigproc zombies
-
-* Can disable zsigproc after setting it now
-
-* There is support for multiple browsers with the 'webbrowser'
-  variable.
-
-* Set now takes a -q option to not echo
-
-* debug is now a variable that can be turned on and off
-
-* Don't allow " and \ characters in URLs passed to a webbrowser
-
-* Build system cleaned up some
-
-* Pop up windows are wider by default
-
-* Fix to work with older versions of libzephyr
-
-* PageUp and PageDown work in the main window and in popups
-
-* Added doc/code.txt describing the code layout
-
-
-What's new in owl version 1.0
------------------------------
-* 'print' and 'set' with no arguments prints all variables
-
-* The 'unsub' command renamed to 'unsuball'
-
-* 'unsubscribe' (and 'unsub') command
-
-* 'getsubs' command to print subscriptions
-
-* Bug fixed in logging messages to more than one recipient
-
-* Support for zwrite options -C, -O and -n
-
-* Fixed owl_editwin_delete_char bug when there are no chars after the
-  cursor
-
-* Display 'more' and 'truncated' in the status bar
-
-* Enable printing of the 'zsigproc' and 'loginsubs' variables
-
-* Only allow message scrolling if the message is longer than the
-  screen
-
-* 'P' (capitolized) will advance the pointer to the next personal
-  message.  'M-P' will move the pointer to the previous personal
-  message.
-
-* 'T' will mark certain "trash" messages for deletion.  This includes:
-  mail notifications, pings and admin messages.
-
-* Replying to a login/logout message sends as a personal message to
-  the user
-
-* Replying to an admin message that's an outgoing message copy sends
-  as a personal message to the user
-
-* 'status' command
-
-* intro document added to the release
-
-* The local realm is trimmed everywhere, including in logging
-
-* Fixed off by one bug in scrolling popups
-
-* Complete on line help added
-
-* Pass the realm to the config file in $owl::realm
-
-* Word wrap and scroll at the bottom right corner of the editing
-  window
-
-* Fixed a bug in editwing window key_right past the last character
-
-* Print an error and don't start owl if the configfile can't be
-  parsed
-
-* Fix bug where the only message displayed might not be the current
-  message
-
-* Don't display the M-^Z key error on resize
-
-What's new in owl version 0.11
-------------------------------
-* Bug fixed in viewing messages longer than a screen
-
-* Indicate in the sepbar if there is a vertical offset present
-
-* '.' on a line by itself will send a zephyr
-
-* disable-ctrl-d variable will disable sending on C-d
-
-* bug fixed that kept C-k from deleting a final newline
-
-* make non-character meta keys work
-
-* fixed phatom zephyr problem
-
-* <, >, M-< and M-> work in popups now
-
-* removed extra spaces at bottom of a popup
-
-* Added "about" command
-
-* Fixed bug using 'M' with no current message
-
-* Log personal messages to 'all' as well as the personal file
-
-* Messages take up less memory
-
-What's new in owl version 0.10
-------------------------------
-* Scrollable / pageable popup windows.  They act like the 'less' or
-  'more' programs.
-
-* Scrolling within a message, to facilitate reading messages longer
-  than the screen size.
-
-* The command parser deals with quoting.  i.e. zwrite -c "foo class"
-  now works.
-
-* The slow cut and paste bug is fixed.
-
-* C-v and M-v will page down and up in the main window, respectively.
-
-* A bug in redrawing the popup windows is fixed.
-
-* An error is displayed when non-functional keys are pressed.
-
-* @i() formatting is displayed as underlined in curses.
-
-* Curly braces work for zephyr formatting.
-
-* The popup window size is relatively larger on small terminals
-
-* A bug in having meta keys work on eight bit input xterms is fixed.
-
-* The cursor location is more consistent.
-
-
-What's new in owl version 0.9
------------------------------
-* Many emacs meta keys work
-
-  M-q, M-f, M-b, M-d, M-< and M-> now work in the typing window
-  M-< and M-> also work in the main window
-  M-x in the main window now enters command mode, just like ':'
-
-* The typing window will automatically word-wrap when hitting the
-  end of the line
-
-* SmaatBolding (TM)
-
-  Users without a .zephyr.subs won't have personal messages
-  displayed in all bold
-
-* Realm displayed for interrealm zephyrs
-
-* 'personalbell' variable printing fixed
-
-* bug with ringing terminal bell on pings fixed
-
-
-What's new in owl version 0.8
------------------------------
-* personal logging
-  
-  "set logging on" will turn on personal logging.  By default messages
-  will go to ~/zlog/people.  This path can be changed by setting the
-  "logpath" variable.
-
-* class logging
-
-  "set classlogging on" will turn on class logging.  By default
-  messages will go to ~/zlog/class.  This path can be changed by
-  setting the "classlogpath" variable.
-
-* variable for resizeing the typing window
-
-  "set typewinsize <n>" will change the number of lines in the typing
-  window to n.
-
-* fixed bugs with backspace
-
-* -v command line option prints the version number
Index: ADME
===================================================================
--- README	(revision 6824a761650618e2ebf99d9beab3f0e2ac156a8f)
+++ 	(revision )
@@ -1,34 +1,0 @@
-BarnOwl - owl, with more ponies
-
-Based on owl 2.1.11, by James Kretchmar (http://www.ktools.org)
-
-This project is a work in progress.
-We guarantee no stability of form or function.
-
-Notes:
------
-This project's perl/lib/ contains the lib directories from the
-following CPAN modules:
-
-Net::Jabber
-Net::XMPP
-XML::Stream
-
-They have been modified slightly for the needs of this project.
-
-BarnOwl currently requires the following perl modules off of CPAN:
-
-PAR
-Net::DNS
-Authen::SASL::Perl
-IO::Socket::SSL
-Digest::SHA1
-
-(Note that these are all available as Debian packages)
-We plan to soon add targets to the Makefile to check for and install
-these for you.
-
-The IRC module requires:
-
-Net::IRC
-Class::Accessor
Index: DO
===================================================================
--- TODO	(revision 94cbc453465ef3fa82dedb364c14077d2d40db73)
+++ 	(revision )
@@ -1,14 +1,0 @@
-barnowl TODO list
-------------------
-
-1) Basic Jabber functionality
- * MUST   think about priority & status
- * SHOULD Store list of muc rooms to join
-   > .owl/startup is insufficient, since ideally you should autojoin
-     them any time you :jabberlogin, not just at start.
- * MAY  More extensive room configuration
-* Check for memory leaks
- * perl eval()s from owl seem problematic
-* Add sane default keybindings
-* Add jabber capabilities to one-line mode
-* We should work well even when zephyr is not available
Index: m.c
===================================================================
--- aim.c	(revision 554a2b836ba40cb8a9fbbc1b1b8aeb195a334e78)
+++ 	(revision )
@@ -1,2773 +1,0 @@
-#include <stdio.h>
-#include <stdio.h>
-#include <sys/stat.h>
-#include "owl.h"
-
-/**********************************************************************/
-
-struct owlfaim_priv {
-  char *aimbinarypath;
-  char *screenname;
-  char *password;
-  char *server;
-  char *proxy;
-  char *proxyusername;
-  char *proxypass;
-  char *ohcaptainmycaptain;
-  int connected;
-
-  FILE *listingfile;
-  char *listingpath;
-
-  fu8_t *buddyicon;
-  int buddyiconlen;
-  time_t buddyiconstamp;
-  fu16_t buddyiconsum;
-};
-
-static char *msgerrreasons[] = {
-	"Invalid error",
-	"Invalid SNAC",
-	"Rate to host",
-	"Rate to client",
-	"Not logged on",
-	"Service unavailable",
-	"Service not defined",
-	"Obsolete SNAC",
-	"Not supported by host",
-	"Not supported by client",
-	"Refused by client",
-	"Reply too big",
-	"Responses lost",
-	"Request denied",
-	"Busted SNAC payload",
-	"Insufficient rights",
-	"In local permit/deny",
-	"Too evil (sender)",
-	"Too evil (receiver)",
-	"User temporarily unavailable",
-	"No match",
-	"List overflow",
-	"Request ambiguous",
-	"Queue full",
-	"Not while on AOL",
-};
-static int msgerrreasonslen = 25;
-
-static void faimtest_debugcb(aim_session_t *sess, int level, const char *format, va_list va);
-static int faimtest_parse_login(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_parse_authresp(aim_session_t *sess, aim_frame_t *fr, ...);
-int faimtest_flapversion(aim_session_t *sess, aim_frame_t *fr, ...);
-int faimtest_conncomplete(aim_session_t *sess, aim_frame_t *fr, ...);
-void addcb_bos(aim_session_t *sess, aim_conn_t *bosconn);
-static int conninitdone_bos(aim_session_t *sess, aim_frame_t *fr, ...);
-static int conninitdone_admin(aim_session_t *sess, aim_frame_t *fr, ...);
-static int conninitdone_chatnav  (aim_session_t *, aim_frame_t *, ...);
-static int conninitdone_chat     (aim_session_t *, aim_frame_t *, ...);
-int logout(aim_session_t *sess);
-
-static int faimtest_parse_connerr(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_accountconfirm(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_infochange(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_handleredirect(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_icbmparaminfo(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_parse_buddyrights(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_bosrights(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_locrights(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_reportinterval(aim_session_t *sess, aim_frame_t *fr, ...);
-/* static int reportinterval(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs); */
-static int faimtest_parse_motd(aim_session_t *sess, aim_frame_t *fr, ...);
-static int getaimdata(aim_session_t *sess, unsigned char **bufret, int *buflenret, unsigned long offset, unsigned long len, const char *modname);
-static int faimtest_memrequest(aim_session_t *sess, aim_frame_t *fr, ...);
-/* static void printuserflags(fu16_t flags); */
-static int faimtest_parse_userinfo(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_handlecmd(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, const char *tmpstr);
-static int faimtest_parse_incoming_im_chan1(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch1_args *args);
-static int faimtest_parse_incoming_im_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args);
-static int faimtest_parse_incoming_im(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_parse_oncoming(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_parse_offgoing(aim_session_t *sess, aim_frame_t *fr, ...);
-int faimtest_parse_genericerr(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_parse_msgerr(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_parse_locerr(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_parse_misses(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_parse_msgack(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_parse_ratechange(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_parse_evilnotify(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_parse_searchreply(aim_session_t *sess, aim_frame_t *fr, ...);
-static int faimtest_parse_searcherror(aim_session_t *sess, aim_frame_t *fr, ...);
-static int handlepopup(aim_session_t *sess, aim_frame_t *fr, ...);
-static int serverpause(aim_session_t *sess, aim_frame_t *fr, ...);
-static int migrate(aim_session_t *sess, aim_frame_t *fr, ...);
-static int ssirights(aim_session_t *sess, aim_frame_t *fr, ...);
-static int ssidata(aim_session_t *sess, aim_frame_t *fr, ...);
-static int ssidatanochange(aim_session_t *sess, aim_frame_t *fr, ...);
-static int offlinemsg(aim_session_t *sess, aim_frame_t *fr, ...);
-static int offlinemsgdone(aim_session_t *sess, aim_frame_t *fr, ...);
-/*
-static int faimtest_ssi_parseerr     (aim_session_t *, aim_frame_t *, ...);
-static int faimtest_ssi_parserights  (aim_session_t *, aim_frame_t *, ...);
-static int faimtest_ssi_parselist    (aim_session_t *, aim_frame_t *, ...);
-static int faimtest_ssi_parseack     (aim_session_t *, aim_frame_t *, ...);
-static int faimtest_ssi_authgiven    (aim_session_t *, aim_frame_t *, ...);
-static int faimtest_ssi_authrequest  (aim_session_t *, aim_frame_t *, ...);
-static int faimtest_ssi_authreply    (aim_session_t *, aim_frame_t *, ...);
-static int faimtest_ssi_gotadded     (aim_session_t *, aim_frame_t *, ...);
-*/
-
-void chatnav_redirect(aim_session_t *sess, struct aim_redirect_data *redir);
-void chat_redirect(aim_session_t *sess, struct aim_redirect_data *redir);
-
-/*****************************************************************/
-
-void owl_aim_init(void)
-{
-  /* this has all been moved to owl_aim_login, but we'll leave the
-   * function here, in case there's stuff we want to init in the
-   * future.  It's still called by Owl.
-   */
-     
-}
-
-
-int owl_aim_login(char *screenname, char *password)
-{
-  struct owlfaim_priv *priv;
-  aim_conn_t *conn;
-  aim_session_t *sess;
-
-  sess=owl_global_get_aimsess(&g);
-
-  aim_session_init(sess, TRUE, 0);
-  aim_setdebuggingcb(sess, faimtest_debugcb);
-  aim_tx_setenqueue(sess, AIM_TX_IMMEDIATE, NULL);
-  
-  /* this will leak, I know and just don't care right now */
-  priv=owl_malloc(sizeof(struct owlfaim_priv));
-  memset(priv, 0, sizeof(struct owlfaim_priv));
-
-  priv->screenname = owl_strdup(screenname);
-  priv->password = owl_strdup(password);
-  priv->server = owl_strdup(FAIM_LOGIN_SERVER);
-  sess->aux_data = priv;
-
-  conn=aim_newconn(sess, AIM_CONN_TYPE_AUTH, priv->server ? priv->server : FAIM_LOGIN_SERVER);
-  /*  conn=aim_newconn(sess, AIM_CONN_TYPE_AUTH, NULL); */
-  if (!conn) {
-    owl_function_error("owl_aim_login: connection error during AIM login\n");
-    owl_global_set_aimnologgedin(&g);
-    owl_global_set_no_doaimevents(&g);
-    return (-1);
-  }
-
-  /*
-  else if (conn->fd == -1) {
-    if (conn->status & AIM_CONN_STATUS_RESOLVERR) {
-      owl_function_error("owl_aim_login: could not resolve authorize name");
-    } else if (conn->status & AIM_CONN_STATUS_CONNERR) {
-      owl_function_error("owl_aim_login: could not connect to authorizer");
-    } else {
-      owl_function_error("owl_aim_login: unknown connection error");
-    }
-    owl_global_set_aimnologgedin(&g);
-    owl_global_set_no_doaimevents(&g);
-    aim_conn_kill(sess, &conn);
-    return(-1);
-  }
-  */
-
-    
-  aim_conn_addhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
-  aim_conn_addhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
-
-  aim_conn_addhandler(sess, conn, AIM_CB_FAM_ATH, AIM_CB_ATH_AUTHRESPONSE, faimtest_parse_login, 0);
-  aim_conn_addhandler(sess, conn, AIM_CB_FAM_ATH, AIM_CB_ATH_LOGINRESPONSE, faimtest_parse_authresp, 0);
-  /* aim_conn_addhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0); */
-  /* aim_conn_addhandler(sess, conn, 0x0017, 0x0007, gaim_parse_login, 0); */
-  /* aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0); */
-    
-  /* start processing AIM events */
-  owl_global_set_doaimevents(&g);
-  /* conn->status |= AIM_CONN_STATUS_INPROGRESS; */
-  owl_function_debugmsg("owl_aim_login: sending login request for %s", screenname);
-  aim_request_login(sess, conn, screenname);
-  owl_function_debugmsg("owl_aim_login: connecting");
-
-  return(0);
-}
-
-/* stuff to run once login has been successful */
-void owl_aim_successful_login(char *screenname)
-{
-  char *buff;
-  owl_function_debugmsg("doing owl_aim_successful_login");
-  owl_global_set_aimloggedin(&g, screenname);
-  owl_global_set_doaimevents(&g); /* this should already be on */
-  owl_function_makemsg("%s logged in", screenname);
-  buff=owl_sprintf("Logged in to AIM as %s", screenname);
-  owl_function_adminmsg("", buff);
-  owl_free(buff);
-
-  owl_function_debugmsg("Successful AIM login for %s", screenname);
-
-  /* start the ingorelogin timer */
-  owl_timer_reset_newstart(owl_global_get_aim_login_timer(&g),
-			   owl_global_get_aim_ignorelogin_timer(&g));
-
-  
-  /* aim_ssi_setpresence(owl_global_get_aimsess(&g), 0x00000400); */
-  /* aim_bos_setidle(owl_global_get_aimsess(&g), owl_global_get_bosconn(&g), 5000); */
-}
-
-void owl_aim_logout(void)
-{
-  /* need to check if it's connected first, I think */
-  logout(owl_global_get_aimsess(&g));
-
-  if (owl_global_is_aimloggedin(&g)) owl_function_adminmsg("", "Logged out of AIM");
-  owl_global_set_aimnologgedin(&g);
-  owl_global_set_no_doaimevents(&g);
-}
-
-void owl_aim_logged_out()
-{
-  if (owl_global_is_aimloggedin(&g)) owl_function_adminmsg("", "Logged out of AIM");
-  owl_aim_logout();
-}
-
-void owl_aim_login_error(char *message)
-{
-  if (message) {
-    owl_function_error("%s", message);
-  } else {
-    owl_function_error("Authentication error on login");
-  }
-  owl_function_beep();
-  owl_global_set_aimnologgedin(&g);
-  owl_global_set_no_doaimevents(&g);
-}
-
-int owl_aim_send_im(char *to, char *msg)
-{
-  int ret;
-
-  ret=aim_im_sendch1(owl_global_get_aimsess(&g), to, 0, msg);
-    
-  /* I don't know how to check for an error yet */
-  return(ret);
-}
-
-int owl_aim_send_awaymsg(char *to, char *msg)
-{
-  int ret;
-
-  ret=aim_im_sendch1(owl_global_get_aimsess(&g), to, AIM_IMFLAGS_AWAY, msg);
-
-  /* I don't know how to check for an error yet */
-  return(ret);
-}
-
-void owl_aim_addbuddy(char *name)
-{
-
-  aim_ssi_addbuddy(owl_global_get_aimsess(&g), name, "Buddies", NULL, NULL, NULL, 0);
-
-  /*
-  aim_ssi_addbuddy(owl_global_get_aimsess(&g),
-		   name,
-		   "Buddies",
-		   NULL, NULL, NULL,
-		   aim_ssi_waitingforauth(owl_global_get_aimsess(&g)->ssi.local, "Buddies", name));
-  */
-}
-
-void owl_aim_delbuddy(char *name)
-{
-  aim_ssi_delbuddy(owl_global_get_aimsess(&g), name, "Buddies");
-  owl_buddylist_offgoing(owl_global_get_buddylist(&g), name);
-}
-
-void owl_aim_search(char *email)
-{
-  int ret;
-
-  owl_function_debugmsg("owl_aim_search: doing search for %s", email);
-  ret=aim_search_address(owl_global_get_aimsess(&g), 
-			 aim_getconn_type(owl_global_get_aimsess(&g), AIM_CONN_TYPE_BOS),
-			 email);
-
-  if (ret) owl_function_error("owl_aim_search: aim_search_address returned %i", ret);
-}
-
-
-int owl_aim_set_awaymsg(char *msg)
-{
-  int len;
-  char *foo;
-  /* there is a max away message lentgh we should check against */
-
-  foo=owl_strdup(msg);
-  len=strlen(foo);
-  if (len>500) {
-    foo[500]='\0';
-    len=499;
-  }
-    
-  aim_locate_setprofile(owl_global_get_aimsess(&g),
-			NULL, NULL, 0,
-			"us-ascii", foo, len);
-  owl_free(foo);
-
-  /*
-  aim_bos_setprofile(owl_global_get_aimsess(&g),
-		     owl_global_get_bosconn(&g),
-		     NULL, NULL, 0, "us-ascii", msg, 
-		     strlen(msg), 0);
-  */
-  return(0);
-}
-
-void owl_aim_chat_join(char *name, int exchange)
-{
-  int ret;
-  aim_conn_t *cur;
-  /*
-  OscarData *od = (OscarData *)g->proto_data;
-  char *name, *exchange;
-  */
-
-  owl_function_debugmsg("Attempting to join chatroom %s exchange %i", name, exchange);
-
-  /*
-  name = g_hash_table_lookup(data, "room");
-  exchange = g_hash_table_lookup(data, "exchange");
-  */
-  if ((cur = aim_getconn_type(owl_global_get_aimsess(&g), AIM_CONN_TYPE_CHATNAV))) {
-    owl_function_debugmsg("owl_aim_chat_join: chatnav exists, creating room");
-    aim_chatnav_createroom(owl_global_get_aimsess(&g), cur, name, exchange);
-  } else {
-    /*    struct create_room *cr = g_new0(struct create_room, 1); */
-    owl_function_debugmsg("owl_aim_chat_join: chatnav does not exist, opening chatnav");
-    /*
-    cr->exchange = atoi(exchange);
-    cr->name = g_strdup(name);
-    od->create_rooms = g_slist_append(od->create_rooms, cr);
-    */
-    aim_reqservice(owl_global_get_aimsess(&g),
-		   aim_getconn_type(owl_global_get_aimsess(&g), AIM_CONN_TYPE_CHATNAV),
-		   AIM_CONN_TYPE_CHATNAV);
-    aim_reqservice(owl_global_get_aimsess(&g), NULL, AIM_CONN_TYPE_CHATNAV);
-    aim_chatnav_createroom(owl_global_get_aimsess(&g), cur, name, exchange);
-    ret=aim_chat_join(owl_global_get_aimsess(&g), owl_global_get_bosconn(&g), exchange, name, 0x0000);
-
-  }
-  return;
-  /******/
-
-
-  /* ret=aim_chat_join(owl_global_get_aimsess(&g), owl_global_get_bosconn(&g), exchange, chatroom, 0x0000); */
-  /*
-  ret=aim_chat_join(owl_global_get_aimsess(&g),
-		    aim_getconn_type(owl_global_get_aimsess(&g), AIM_CONN_TYPE_CHATNAV), exchange, chatroom, 0x0000);
-  */
-
-  aim_reqservice(owl_global_get_aimsess(&g), owl_global_get_bosconn(&g), AIM_CONN_TYPE_CHATNAV);
-  ret = aim_chatnav_createroom(owl_global_get_aimsess(&g),
-			       aim_getconn_type(owl_global_get_aimsess(&g), AIM_CONN_TYPE_CHATNAV), name, exchange);
-   ret=aim_chat_join(owl_global_get_aimsess(&g), owl_global_get_bosconn(&g), exchange, name, 0x0000);
-  
-}
-
-void owl_aim_chat_leave(char *chatroom)
-{
-}
-
-int owl_aim_chat_sendmsg(char *chatroom, char *msg)
-{
-  return(0);
-}
-
-/* caller must free the return */
-char *owl_aim_normalize_screenname(char *in)
-{
-  char *out;
-  int i, j, k;
-
-  j=strlen(in);
-  out=owl_malloc(j+30);
-  k=0;
-  for (i=0; i<j; i++) {
-    if (in[i]!=' ') {
-      out[k]=in[i];
-      k++;
-    }
-  }
-  out[k]='\0';
-  return(out);
-}
-
-int owl_aim_process_events()
-{
-  aim_session_t *aimsess;
-  aim_conn_t *waitingconn = NULL;
-  struct timeval tv;
-  int selstat = 0;
-  struct owlfaim_priv *priv;
-
-  aimsess=owl_global_get_aimsess(&g);
-  priv = (struct owlfaim_priv *) &(aimsess->aux_data);
-
-  /* do a select without blocking */
-  tv.tv_sec = 0;
-  tv.tv_usec = 0;
-  waitingconn = aim_select(aimsess, &tv, &selstat);
-
-  if (owl_global_is_aimnop_time(&g)) {
-    aim_flap_nop(aimsess, aim_getconn_type(aimsess, AIM_CONN_TYPE_BOS));
-    owl_global_aimnop_sent(&g);
-  }
-
-  if (selstat == -1) {
-    owl_aim_logged_out();
-  } else if (selstat == 0) { 
-    /* no events pending */
-  } else if (selstat == 1) { /* outgoing data pending */
-    aim_tx_flushqueue(aimsess);
-  } else if (selstat == 2) { /* incoming data pending */
-    /* printf("selstat == 2\n"); */
-    
-    if (aim_get_command(aimsess, waitingconn) >= 0) {
-      aim_rxdispatch(aimsess);
-    } else {
-      /* printf("connection error (type 0x%04x:0x%04x)\n", waitingconn->type, waitingconn->subtype); */
-      /* we should have callbacks for all these, else the library will do the conn_kill for us. */
-      if (waitingconn->type == AIM_CONN_TYPE_RENDEZVOUS) {
-	if (waitingconn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) {
-	  /* printf("disconnected from %s\n", aim_directim_getsn(waitingconn)); */
-	  aim_conn_kill(aimsess, &waitingconn);
-	  owl_aim_logged_out();
-	}
-      } else {
-	aim_conn_kill(aimsess, &waitingconn);
-	owl_aim_logged_out();
-      }
-      if (!aim_getconn_type(aimsess, AIM_CONN_TYPE_BOS)) {
-	/* printf("major connection error\n"); */
-	owl_aim_logged_out();
-	/* break; */
-      }
-    }
-  }
-  /* free(priv->buddyicon); */
-  /* exit(0); */
-  return(0);
-}
-
-static void faimtest_debugcb(aim_session_t *sess, int level, const char *format, va_list va)
-{
-  return;
-}
-
-static int faimtest_parse_login(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  struct owlfaim_priv *priv = (struct owlfaim_priv *)sess->aux_data;
-  struct client_info_s info = CLIENTINFO_AIM_KNOWNGOOD;
-    
-  char *key;
-  va_list ap;
-
-  va_start(ap, fr);
-  key = va_arg(ap, char *);
-  va_end(ap);
-
-  owl_function_debugmsg("faimtest_parse_login: %s %s %s", priv->screenname, priv->password, key);
-
-  aim_send_login(sess, fr->conn, priv->screenname, priv->password, &info, key);
-  
-  return(1);
-}
-
-
-static int faimtest_parse_authresp(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  struct aim_authresp_info *info;
-  aim_conn_t *bosconn;
-
-  va_start(ap, fr);
-  info = va_arg(ap, struct aim_authresp_info *);
-  va_end(ap);
-
-  /* printf("Screen name: %s\n", info->sn); */
-  owl_function_debugmsg("doing faimtest_parse_authresp");
-  owl_function_debugmsg("faimtest_parse_authresp: %s", info->sn);
-
-  /*
-   * Check for error.
-   */
-  if (info->errorcode || !info->bosip || !info->cookie) {
-    /*
-    printf("Login Error Code 0x%04x\n", info->errorcode);
-    printf("Error URL: %s\n", info->errorurl);
-    */
-    if (info->errorcode==0x05) {
-      owl_aim_login_error("Incorrect nickname or password.");
-    } else if (info->errorcode==0x11) {
-      owl_aim_login_error("Your account is currently suspended.");
-    } else if (info->errorcode==0x14) {
-      owl_aim_login_error("The AOL Instant Messenger service is temporarily unavailable.");
-    } else if (info->errorcode==0x18) {
-      owl_aim_login_error("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer.");
-    } else if (info->errorcode==0x1c) {
-      owl_aim_login_error("The client version you are using is too old.");
-    } else {
-      owl_aim_login_error(NULL);
-    }
-    aim_conn_kill(sess, &fr->conn);
-    return(1);
-  }
-
-  /*
-  printf("Reg status: %d\n", info->regstatus);
-  printf("Email: %s\n", info->email);
-  printf("BOS IP: %s\n", info->bosip);
-  */
-
-  /* printf("Closing auth connection...\n"); */
-  aim_conn_kill(sess, &fr->conn);
-  if (!(bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, info->bosip))) {
-    /* printf("could not connect to BOS: internal error\n"); */
-    return(1);
-  } else if (bosconn->status & AIM_CONN_STATUS_CONNERR) {
-    /* printf("could not connect to BOS\n"); */
-    aim_conn_kill(sess, &bosconn);
-    return(1);
-  }
-  owl_global_set_bossconn(&g, bosconn);
-  owl_aim_successful_login(info->sn);
-  addcb_bos(sess, bosconn);
-  aim_sendcookie(sess, bosconn, info->cookielen, info->cookie);
-  return(1);
-}
-
-int faimtest_flapversion(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  owl_function_debugmsg("doing faimtest_flapversion");
-
-#if 0
-  /* XXX fix libfaim to support this */
-  printf("using FLAP version 0x%08x\n", /* aimutil_get32(fr->data)*/ 0xffffffff);
-
-  /*
-   * This is an alternate location for starting the login process.
-   */
-  /* XXX should do more checking to make sure its really the right AUTH conn */
-  if (fr->conn->type == AIM_CONN_TYPE_AUTH) {
-    /* do NOT send a flapversion, request_login will send it if needed */
-    aim_request_login(sess, fr->conn, priv->screenname);
-    /* printf("faimtest: login request sent\n"); */
-  }
-#endif
-
-  return 1;
-}
-
-
-int faimtest_conncomplete(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  owl_function_debugmsg("doing faimtest_conncomplete");
-  /* owl_aim_successful_login(info->sn); */
-  return 1;
-}
-
-void addcb_bos(aim_session_t *sess, aim_conn_t *bosconn)
-{
-  owl_function_debugmsg("doing addcb_bos");
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_bos, 0);
-
-  aim_conn_addhandler(sess, bosconn, 0x0013,         0x0003,                        ssirights, 0);
-  aim_conn_addhandler(sess, bosconn, 0x0013,         0x0006,                        ssidata, 0);
-  aim_conn_addhandler(sess, bosconn, 0x0013,         0x000f,                        ssidatanochange, 0);
-  aim_conn_addhandler(sess, bosconn, 0x0008,         0x0002,                        handlepopup, 0);
-  aim_conn_addhandler(sess, bosconn, 0x0009,         0x0003,                        faimtest_bosrights, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_REDIRECT,           faimtest_handleredirect, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_STS, AIM_CB_STS_SETREPORTINTERVAL,  faimtest_reportinterval, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_RIGHTSINFO,         faimtest_parse_buddyrights, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD,               faimtest_parse_motd, 0);
-  aim_conn_addhandler(sess, bosconn, 0x0004,         0x0005,                        faimtest_icbmparaminfo, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR,    faimtest_parse_connerr, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_RIGHTSINFO,         faimtest_locrights, 0);
-  aim_conn_addhandler(sess, bosconn, 0x0001,         0x001f,                        faimtest_memrequest, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING,           faimtest_parse_oncoming, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING,           faimtest_parse_offgoing, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING,           faimtest_parse_incoming_im, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR,              faimtest_parse_locerr, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL,         faimtest_parse_misses, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE,         faimtest_parse_ratechange, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL,               faimtest_parse_evilnotify, 0);
-
-  aim_conn_addhandler(sess, bosconn, 0x000a,         0x0001,                        faimtest_parse_searcherror, 0);
-  aim_conn_addhandler(sess, bosconn, 0x000a,         0x0003,                        faimtest_parse_searchreply, 0);
-
-  /*
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, AIM_CB_LOK_ERROR, faimtest_parse_searcherror, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, 0x0003, faimtest_parse_searchreply, 0);
-  */
-  
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR,              faimtest_parse_msgerr, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO,           faimtest_parse_userinfo, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK,                faimtest_parse_msgack, 0);
-
-  aim_conn_addhandler(sess, bosconn, 0x0001,         0x0001,                        faimtest_parse_genericerr, 0);
-  aim_conn_addhandler(sess, bosconn, 0x0003,         0x0001,                        faimtest_parse_genericerr, 0);
-  aim_conn_addhandler(sess, bosconn, 0x0009,         0x0001,                        faimtest_parse_genericerr, 0);
-  aim_conn_addhandler(sess, bosconn, 0x0001,         0x000b,                        serverpause, 0);
-  aim_conn_addhandler(sess, bosconn, 0x0001,         0x0012,                        migrate, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG,         offlinemsg, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSGCOMPLETE, offlinemsgdone, 0);
-
-  /*
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR,     gaim_connerr, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_chatnav, 0);
-  */
-
-  /*
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_ERROR,              faimtest_ssi_parseerr, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RIGHTSINFO,         faimtest_ssi_parserights, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_LIST,               faimtest_ssi_parselist, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_NOLIST,             faimtest_ssi_parselist, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_SRVACK,             faimtest_ssi_parseack, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTH,           faimtest_ssi_authgiven, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREQ,        faimtest_ssi_authrequest, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREP,        faimtest_ssi_authreply, 0);
-  aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_ADDED,              faimtest_ssi_gotadded, 0);
-  */
-
-  return;
-}
-
-static int conninitdone_bos(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  owl_function_debugmsg("doing coninitdone_bos");
-
-
-  aim_reqpersonalinfo(sess, fr->conn);
-  aim_ssi_reqrights(sess);
-  aim_ssi_reqdata(sess);
-  aim_locate_reqrights(sess);
-  aim_buddylist_reqrights(sess, fr->conn);
-
-  aim_im_reqparams(sess);
-  /* aim_bos_reqrights(sess, fr->conn); */ /* XXX - Don't call this with ssi */
-
-  owl_function_debugmsg("conninitdone_bos: requesting rights");
-  aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi */
-  aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS);
-  aim_bos_setprivacyflags(sess, fr->conn, AIM_PRIVFLAGS_ALLOWIDLE | AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
-
-  return(1);
-}
-
-static int conninitdone_admin(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  aim_clientready(sess, fr->conn);
-  owl_function_debugmsg("conninitdone_admin: initializtion done for admin connection");
-  return(1);
-}
-
-int logout(aim_session_t *sess)
-{
-  aim_session_kill(sess);
-  owl_aim_init();
-
-  owl_function_debugmsg("libfaim logout called");
-  /*
-  if (faimtest_init() == -1)
-    printf("faimtest_init failed\n");
-  */
-
-  return(0);
-}
-
-/**************************************************************************************************/
-
-static int faimtest_parse_connerr(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  struct owlfaim_priv *priv = (struct owlfaim_priv *)sess->aux_data;
-  va_list ap;
-  fu16_t code;
-  char *msg;
-  
-  va_start(ap, fr);
-  code = va_arg(ap, int);
-  msg = va_arg(ap, char *);
-  va_end(ap);
-  
-  owl_function_error("faimtest_parse_connerr: Code 0x%04x: %s\n", code, msg);
-  aim_conn_kill(sess, &fr->conn); /* this will break the main loop */
-  
-  priv->connected = 0;
-  
-  return 1;
-}
-
-static int faimtest_accountconfirm(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  int status;
-  va_list ap;
-  
-  va_start(ap, fr);
-  status = va_arg(ap, int); /* status code of confirmation request */
-  va_end(ap);
-
-  /* owl_function_debugmsg("faimtest_accountconfirm: Code 0x%04x: %s\n", code, msg); */
-  owl_function_debugmsg("faimtest_accountconfirm: account confirmation returned status 0x%04x (%s)\n", status, (status==0x0000)?"email sent":"unknown");
-  
-  return 1;
-}
-
-static int faimtest_infochange(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  fu16_t change = 0, perms, type;
-  int length, str;
-  char *val;
-  va_list ap;
-  
-  va_start(ap, fr);
-  change = va_arg(ap, int);
-  perms = (fu16_t)va_arg(ap, unsigned int);
-  type = (fu16_t)va_arg(ap, unsigned int);
-  length = va_arg(ap, int);
-  val = va_arg(ap, char *);
-  str = va_arg(ap, int);
-  va_end(ap);
-  
-  owl_function_debugmsg("faimtest_infochange: info%s: perms = %d, type = %x, length = %d, val = %s", change?" change":"", perms, type, length, str?val:"(not string)");
-  
-  return(1);
-}
-
-
-static int faimtest_handleredirect(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  struct aim_redirect_data *redir;
-
-  owl_function_debugmsg("faimtest_handledirect:");
-  
-  va_start(ap, fr);
-  redir = va_arg(ap, struct aim_redirect_data *);
-  
-  if (redir->group == 0x0005) {  /* Adverts */
-    
-  } else if (redir->group == 0x0007) {  /* Authorizer */
-    aim_conn_t *tstconn;
-
-    owl_function_debugmsg("faimtest_handledirect: autorizer");
-    
-    tstconn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, redir->ip);
-    if (!tstconn || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
-      owl_function_error("faimtest_handleredirect: unable to reconnect with authorizer");
-    } else {
-      aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, faimtest_flapversion, 0);
-      aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
-      aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_admin, 0);
-      aim_conn_addhandler(sess, tstconn, 0x0007, 0x0007, faimtest_accountconfirm, 0);
-      aim_conn_addhandler(sess, tstconn, 0x0007, 0x0003, faimtest_infochange, 0);
-      aim_conn_addhandler(sess, tstconn, 0x0007, 0x0005, faimtest_infochange, 0);
-      /* Send the cookie to the Auth */
-      aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie);
-      owl_function_debugmsg("faimtest_handleredirect: sent cookie to authorizer host");
-    }
-  } else if (redir->group == 0x000d) {  /* ChatNav */
-    owl_function_debugmsg("faimtest_handledirect: chatnav");
-    chatnav_redirect(sess, redir);
-  } else if (redir->group == 0x000e) { /* Chat */
-    owl_function_debugmsg("faimtest_handledirect: chat");
-    chat_redirect(sess, redir);
-  } else {
-    owl_function_debugmsg("faimtest_handleredirect: uh oh... got redirect for unknown service 0x%04x!!", redir->group);
-  }
-  va_end(ap);
-  return 1;
-}
-
-static int faimtest_icbmparaminfo(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  struct aim_icbmparameters *params;
-  va_list ap;
-  
-  va_start(ap, fr);
-  params = va_arg(ap, struct aim_icbmparameters *);
-  va_end(ap);
-  
-  owl_function_debugmsg("faimtest_icbmparaminfo: ICBM Parameters: maxchannel = %d, default flags = 0x%08lx, max msg len = %d, max sender evil = %f, max reciever evil = %f, min msg interval = %ld",
-		       params->maxchan, params->flags, params->maxmsglen, ((float)params->maxsenderwarn)/10.0, ((float)params->maxrecverwarn)/10.0, params->minmsginterval);
-     
-  /*
-  * Set these to your taste, or client medium.  Setting minmsginterval
-  * higher is good for keeping yourself from getting flooded (esp
-  * if you're on a slow connection or something where that would be
-  * useful).
-  */
-  params->maxmsglen = 8000;
-  params->minmsginterval = 0; /* in milliseconds */
-  /* aim_seticbmparam(sess, params); */
-  aim_im_setparams(sess, params);
-  
-  return 1;
-}
-
-static int faimtest_parse_buddyrights(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  fu16_t maxbuddies, maxwatchers;
-  
-  va_start(ap, fr);
-  maxbuddies = va_arg(ap, int);
-  maxwatchers = va_arg(ap, int);
-  va_end(ap);
-  
-  owl_function_debugmsg("faimtest_parse_buddyrights: Max buddies = %d / Max watchers = %d\n", maxbuddies, maxwatchers);
-  
-  /* aim_ssi_reqrights(sess, fr->conn); */
-  aim_ssi_reqrights(sess);
-  
-  return 1;
-}
-
-static int faimtest_bosrights(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  fu16_t maxpermits, maxdenies;
-  
-  va_start(ap, fr);
-  maxpermits = va_arg(ap, int);
-  maxdenies = va_arg(ap, int);
-  va_end(ap);
-  
-  owl_function_debugmsg("faimtest_bosrights: Max permit = %d / Max deny = %d\n", maxpermits, maxdenies);
-  aim_clientready(sess, fr->conn);
-  owl_function_debugmsg("officially connected to BOS.");
-  aim_icq_reqofflinemsgs(sess);
-  return 1;
-}
-
-static int faimtest_locrights(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  fu16_t maxsiglen;
-  
-  va_start(ap, fr);
-  maxsiglen = va_arg(ap, int);
-  va_end(ap);
-
-  owl_function_debugmsg("faimtest_locrights: rights: max signature length = %d\n", maxsiglen);
-  
-  return(1);
-}
-
-static int faimtest_reportinterval(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  struct owlfaim_priv *priv = (struct owlfaim_priv *)sess->aux_data;
-  va_list ap;
-  fu16_t interval;
-
-  va_start(ap, fr);
-  interval = va_arg(ap, int);
-  va_end(ap);
-
-  owl_function_debugmsg("faimtest_reportinterval: %d (seconds?)\n", interval);
-
-  if (!priv->connected) {
-    priv->connected++;
-  }
-  /* aim_reqicbmparams(sess); */
-  aim_im_reqparams(sess);
-  /* kretch */
-  return 1;
-}
-
-static int faimtest_parse_motd(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  char *msg;
-  fu16_t id;
-  va_list ap;
-  static int codeslen = 5;
-  static char *codes[] = {
-    "Unknown",
-    "Mandatory upgrade",
-    "Advisory upgrade",
-    "System bulletin",
-    "Top o' the world!"
-  };
-
-  va_start(ap, fr);
-  id = va_arg(ap, int);
-  msg = va_arg(ap, char *);
-  va_end(ap);
-
-  owl_function_debugmsg("faimtest_parse_motd: %s (%d / %s)\n", msg?msg:"nomsg", id, (id < codeslen)?codes[id]:"unknown");
-  
-  return 1;
-}
-
-/*
- * This is a little more complicated than it looks.  The module
- * name (proto, boscore, etc) may or may not be given.  If it is
- * not given, then use aim.exe.  If it is given, put ".ocm" on the
- * end of it.
- *
- * Now, if the offset or length requested would cause a read past
- * the end of the file, then the request is considered invalid.  Invalid
- * requests are processed specially.  The value hashed is the
- * the request, put into little-endian (eight bytes: offset followed
- * by length).  
- *
- * Additionally, if the request is valid, the length is mod 4096.  It is
- * important that the length is checked for validity first before doing
- * the mod.
- *
- * Note to Bosco's Brigade: if you'd like to break this, put the 
- * module name on an invalid request.
- *
- */
-static int getaimdata(aim_session_t *sess, unsigned char **bufret, int *buflenret, unsigned long offset, unsigned long len, const char *modname)
-{
-  struct owlfaim_priv *priv = (struct owlfaim_priv *)sess->aux_data;
-  FILE *f;
-  static const char defaultmod[] = "aim.exe";
-  char *filename = NULL;
-  struct stat st;
-  unsigned char *buf;
-  int invalid = 0;
-  
-  if (!bufret || !buflenret)
-    return -1;
-  
-  if (modname) {
-    if (!(filename = owl_malloc(strlen(priv->aimbinarypath)+1+strlen(modname)+4+1))) {
-      /* perror("memrequest: malloc"); */
-      return -1;
-    }
-    sprintf(filename, "%s/%s.ocm", priv->aimbinarypath, modname);
-  } else {
-    if (!(filename = owl_malloc(strlen(priv->aimbinarypath)+1+strlen(defaultmod)+1))) {
-      /* perror("memrequest: malloc"); */
-      return -1;
-    }
-    sprintf(filename, "%s/%s", priv->aimbinarypath, defaultmod);
-  }
-  
-  if (stat(filename, &st) == -1) {
-    if (!modname) {
-      /* perror("memrequest: stat"); */
-      owl_free(filename);
-      return -1;
-    }
-    invalid = 1;
-  }
-  
-  if (!invalid) {
-    if ((offset > st.st_size) || (len > st.st_size))
-      invalid = 1;
-    else if ((st.st_size - offset) < len)
-      len = st.st_size - offset;
-    else if ((st.st_size - len) < len)
-      len = st.st_size - len;
-  }
-  
-  if (!invalid && len) {
-    len %= 4096;
-  }
-  
-  if (invalid) {
-    int i;
-    
-    owl_free(filename); /* not needed */
-    owl_function_error("getaimdata memrequest: recieved invalid request for 0x%08lx bytes at 0x%08lx (file %s)\n", len, offset, modname);
-    i = 8;
-    if (modname) {
-      i+=strlen(modname);
-    }
-    
-    if (!(buf = owl_malloc(i))) {
-      return -1;
-    }
-    
-    i=0;
-    
-    if (modname) {
-      memcpy(buf, modname, strlen(modname));
-      i+=strlen(modname);
-    }
-    
-    /* Damn endianness. This must be little (LSB first) endian. */
-    buf[i++] = offset & 0xff;
-    buf[i++] = (offset >> 8) & 0xff;
-    buf[i++] = (offset >> 16) & 0xff;
-    buf[i++] = (offset >> 24) & 0xff;
-    buf[i++] = len & 0xff;
-    buf[i++] = (len >> 8) & 0xff;
-    buf[i++] = (len >> 16) & 0xff;
-    buf[i++] = (len >> 24) & 0xff;
-    
-    *bufret = buf;
-    *buflenret = i;
-  } else {
-    if (!(buf = owl_malloc(len))) {
-      owl_free(filename);
-      return -1;
-    }
-    /* printf("memrequest: loading %ld bytes from 0x%08lx in \"%s\"...\n", len, offset, filename); */
-    if (!(f = fopen(filename, "r"))) {
-      /* perror("memrequest: fopen"); */
-      owl_free(filename);
-      owl_free(buf);
-      return -1;
-    }
-    
-    owl_free(filename);
-    
-    if (fseek(f, offset, SEEK_SET) == -1) {
-      /* perror("memrequest: fseek"); */
-      fclose(f);
-      owl_free(buf);
-      return -1;
-    }
-    
-    if (fread(buf, len, 1, f) != 1) {
-      /* perror("memrequest: fread"); */
-      fclose(f);
-      owl_free(buf);
-      return -1;
-    }
-    
-    fclose(f);
-    *bufret = buf;
-    *buflenret = len;
-  }
-  return 0; /* success! */
-}
-
-/*
- * This will get an offset and a length.  The client should read this
- * data out of whatever AIM.EXE binary the user has provided (hopefully
- * it matches the client information thats sent at login) and pass a
- * buffer back to libfaim so it can hash the data and send it to AOL for
- * inspection by the client police.
- */
-static int faimtest_memrequest(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  struct owlfaim_priv *priv = (struct owlfaim_priv *)sess->aux_data;
-  va_list ap;
-  fu32_t offset, len;
-  char *modname;
-  unsigned char *buf;
-  int buflen;
-  
-  va_start(ap, fr);
-  offset = va_arg(ap, fu32_t);
-  len = va_arg(ap, fu32_t);
-  modname = va_arg(ap, char *);
-  va_end(ap);
-  
-  if (priv->aimbinarypath && (getaimdata(sess, &buf, &buflen, offset, len, modname) == 0)) {
-    aim_sendmemblock(sess, fr->conn, offset, buflen, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
-    owl_free(buf);
-  } else {
-    owl_function_debugmsg("faimtest_memrequest: unable to use AIM binary (\"%s/%s\"), sending defaults...\n", priv->aimbinarypath, modname);
-    aim_sendmemblock(sess, fr->conn, offset, len, NULL, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
-  }
-  return 1;
-}
-
-/*
-static void printuserflags(fu16_t flags)
-{
-  if (flags & AIM_FLAG_UNCONFIRMED) printf("UNCONFIRMED ");
-  if (flags & AIM_FLAG_ADMINISTRATOR) printf("ADMINISTRATOR ");
-  if (flags & AIM_FLAG_AOL) printf("AOL ");
-  if (flags & AIM_FLAG_OSCAR_PAY) printf("OSCAR_PAY ");
-  if (flags & AIM_FLAG_FREE) printf("FREE ");
-  if (flags & AIM_FLAG_AWAY) printf("AWAY ");
-  if (flags & AIM_FLAG_ICQ) printf("ICQ ");
-  if (flags & AIM_FLAG_WIRELESS) printf("WIRELESS ");
-  if (flags & AIM_FLAG_ACTIVEBUDDY) printf("ACTIVEBUDDY ");
-  
-  return;
-}
-*/
-
-static int faimtest_parse_userinfo(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  aim_userinfo_t *userinfo;
-  char *prof_encoding = NULL;
-  char *prof = NULL;
-  fu16_t inforeq = 0;
-  owl_buddy *b;
-  va_list ap;
-  va_start(ap, fr);
-  userinfo = va_arg(ap, aim_userinfo_t *);
-  inforeq = (fu16_t)va_arg(ap, unsigned int);
-  prof_encoding = va_arg(ap, char *);
-  prof = va_arg(ap, char *);
-  va_end(ap);
-
-  /* right now the only reason we call this is for idle times */
-  owl_function_debugmsg("parse_userinfo sn: %s idle: %i", userinfo->sn, userinfo->idletime);
-  b=owl_buddylist_get_aim_buddy(owl_global_get_buddylist(&g),
-				userinfo->sn);
-  if (!b) return(1);
-  owl_buddy_set_idle_since(b, userinfo->idletime);
-  return(1);
-
-  /*
-  printf("userinfo: sn: %s\n", userinfo->sn);
-  printf("userinfo: warnlevel: %f\n", aim_userinfo_warnlevel(userinfo));
-  printf("userinfo: flags: 0x%04x = ", userinfo->flags);
-  printuserflags(userinfo->flags);
-  printf("\n");
-  */
-
-  /*
-  printf("userinfo: membersince: %lu\n", userinfo->membersince);
-  printf("userinfo: onlinesince: %lu\n", userinfo->onlinesince);
-  printf("userinfo: idletime: 0x%04x\n", userinfo->idletime);
-  printf("userinfo: capabilities = %s = 0x%08lx\n", (userinfo->present & AIM_USERINFO_PRESENT_CAPABILITIES) ? "present" : "not present", userinfo->capabilities);
-  */
-
-  /*
-  if (inforeq == AIM_GETINFO_GENERALINFO) {
-    owl_function_debugmsg("userinfo: profile_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
-    owl_function_debugmsg("userinfo: prof: %s\n", prof ? prof : "[none]");
-  } else if (inforeq == AIM_GETINFO_AWAYMESSAGE) {
-    owl_function_debugmsg("userinfo: awaymsg_encoding: %s\n", prof_encoding ? prof_encoding : "[none]");
-    owl_function_debugmsg("userinfo: awaymsg: %s\n", prof ? prof : "[none]");
-  } else if (inforeq == AIM_GETINFO_CAPABILITIES) {
-    owl_function_debugmsg("userinfo: capabilities: see above\n");
-  } else {
-    owl_function_debugmsg("userinfo: unknown info request\n");
-  }
-  */
-  return(1);
-}
-
-#if 0
-static int faimtest_handlecmd(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, const char *tmpstr)
-{
-  struct owlfaim_priv *priv = (struct owlfaim_priv *)sess->aux_data;
-  
-  if (!strncmp(tmpstr, "disconnect", 10)) {
-    logout(sess);
-  } else if (strstr(tmpstr, "goodday")) {
-    /* aim_send_im(sess, userinfo->sn, AIM_IMFLAGS_ACK, "Good day to you too."); */
-  } else if (strstr(tmpstr, "haveicon") && priv->buddyicon) {
-    struct aim_sendimext_args args;
-    /* static const char iconmsg[] = {"I have an icon"}; */
-    static const char iconmsg[] = {""};
-    
-    args.destsn = userinfo->sn;
-    args.flags = AIM_IMFLAGS_HASICON;
-    args.msg = iconmsg;
-    args.msglen = strlen(iconmsg);
-    args.iconlen = priv->buddyiconlen;
-    args.iconstamp = priv->buddyiconstamp;
-    args.iconsum = priv->buddyiconsum;
-    
-    /* aim_send_im_ext(sess, &args); */
-    
-  } else if (strstr(tmpstr, "sendbin")) {
-    struct aim_sendimext_args args;
-    static const unsigned char data[] = {
-      0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-      0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-      0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-      0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-      0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
-    };
-    
-    /*
-     * I put this here as a demonstration of how to send 
-     * arbitrary binary data via OSCAR ICBM's without the need
-     * for escape or baseN encoding of any sort.  
-     *
-     * Apparently if you set the charset to something WinAIM
-     * doesn't recognize, it will completly ignore the message.
-     * That is, it will not display anything in the conversation
-     * window for the user that recieved it.
-     *
-     * HOWEVER, if they do not have a conversation window open
-     * for you, a new one will be created, but it will not have
-     * any messages in it.  Therefore sending these things could
-     * be a great way to seemingly subliminally convince people
-     * to talk to you...
-     *
-     */
-    args.destsn = userinfo->sn;
-    /* args.flags = AIM_IMFLAGS_CUSTOMCHARSET; */
-    args.charset = args.charsubset = 0x4242;
-    args.msg = data;
-    args.msglen = sizeof(data);
-    /* aim_send_im_ext(sess, &args); */
-   } else if (strstr(tmpstr, "sendmulti")) {
-    struct aim_sendimext_args args;
-    aim_mpmsg_t mpm;
-    static const fu16_t unidata[] = { /* "UNICODE." */
-      0x0055, 0x004e, 0x0049, 0x0043,
-      0x004f, 0x0044, 0x0045, 0x002e,
-    };
-    static const int unidatalen = 8;
-    
-    /*
-     * This is how multipart messages should be sent.
-     *
-     * This should render as:
-     *        "Part 1, ASCII.  UNICODE.Part 3, ASCII.  "
-     */
-    
-    aim_mpmsg_init(sess, &mpm);
-    aim_mpmsg_addascii(sess, &mpm, "Part 1, ASCII.  ");
-    aim_mpmsg_addunicode(sess, &mpm, unidata, unidatalen);
-    aim_mpmsg_addascii(sess, &mpm, "Part 3, ASCII.  ");
-    
-    args.destsn = userinfo->sn;
-    args.flags = AIM_IMFLAGS_MULTIPART;
-    args.mpmsg = &mpm;
-    
-    /* aim_send_im_ext(sess, &args); */
-    
-    aim_mpmsg_free(sess, &mpm);
-    
-  } else if (strstr(tmpstr, "sendprebin")) {
-    static const unsigned char data[] = {
-      0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-      0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
-      0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-      0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
-      0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-      0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
-    };
-    struct aim_sendimext_args args;
-    aim_mpmsg_t mpm;
-    
-    /*
-     * This demonstrates sending a human-readable preamble,
-     * and then arbitrary binary data.
-     *
-     * This means that you can very inconspicuously send binary
-     * attachments to other users.  In WinAIM, this appears as
-     * though it only had the ASCII portion.
-     *
-     */
-    
-    aim_mpmsg_init(sess, &mpm);
-    aim_mpmsg_addascii(sess, &mpm, "This message has binary data.");
-    aim_mpmsg_addraw(sess, &mpm, 0x4242, 0x4242, data, sizeof(data));
-    
-    args.destsn = userinfo->sn;
-    args.flags = AIM_IMFLAGS_MULTIPART;
-    args.mpmsg = &mpm;
-    
-    /* aim_send_im_ext(sess, &args); */
-    aim_mpmsg_free(sess, &mpm);
-    
-  } else if (strstr(tmpstr, "havefeat")) {
-    struct aim_sendimext_args args;
-    static const char featmsg[] = {"I have nifty features."};
-    fu8_t features[] = {0x01, 0x01, 0x01, 0x02, 0x42, 0x43, 0x44, 0x45};
-    
-    args.destsn = userinfo->sn;
-    args.flags = AIM_IMFLAGS_CUSTOMFEATURES;
-    args.msg = featmsg;
-    args.msglen = strlen(featmsg);
-    args.features = features;
-    args.featureslen = sizeof(features);
-    
-    /* aim_send_im_ext(sess, &args); */
-  } else if (strstr(tmpstr, "sendicon") && priv->buddyicon) {
-    /* aim_send_icon(sess, userinfo->sn, priv->buddyicon, priv->buddyiconlen, priv->buddyiconstamp, priv->buddyiconsum); */
-  } else if (strstr(tmpstr, "warnme")) {
-    /* printf("icbm: sending non-anon warning\n"); */
-    /* aim_send_warning(sess, conn, userinfo->sn, 0); */
-  } else if (strstr(tmpstr, "anonwarn")) {
-    /* printf("icbm: sending anon warning\n"); */
-    /* aim_send_warning(sess, conn, userinfo->sn, AIM_WARN_ANON); */
-  } else if (strstr(tmpstr, "setdirectoryinfo")) {
-    /* printf("icbm: sending backwards profile data\n"); */
-    aim_setdirectoryinfo(sess, conn, "tsrif", "elddim", "tsal", "nediam", "emankcin", "teerts", "ytic", "etats", "piz", 0, 1);
-  } else if (strstr(tmpstr, "setinterests")) {
-    /* printf("icbm: setting fun interests\n"); */
-    aim_setuserinterests(sess, conn, "interest1", "interest2", "interest3", "interest4", "interest5", 1);
-  } else if (!strncmp(tmpstr, "open chatnav", 12)) {
-    aim_reqservice(sess, conn, AIM_CONN_TYPE_CHATNAV);
-  } else if (!strncmp(tmpstr, "create", 6)) {
-    aim_chatnav_createroom(sess,aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV), (strlen(tmpstr) < 7)?"WorldDomination":tmpstr+7, 0x0004);
-  } else if (!strncmp(tmpstr, "close chatnav", 13)) {
-    aim_conn_t *chatnavconn;
-    if ((chatnavconn = aim_getconn_type(sess, AIM_CONN_TYPE_CHATNAV)))
-      aim_conn_kill(sess, &chatnavconn);
-  } else if (!strncmp(tmpstr, "join", 4)) {
-    aim_chat_join(sess, conn, 0x0004, "worlddomination", 0x0000);
-  } else if (!strncmp(tmpstr, "leave", 5)) {
-    aim_chat_leaveroom(sess, "worlddomination");
-  } else if (!strncmp(tmpstr, "getinfo", 7)) {
-    aim_getinfo(sess, conn, "midendian", AIM_GETINFO_GENERALINFO);
-    aim_getinfo(sess, conn, "midendian", AIM_GETINFO_AWAYMESSAGE);
-    aim_getinfo(sess, conn, "midendian", AIM_GETINFO_CAPABILITIES);
-  } else if(strstr(tmpstr, "lookup")) {
-    /* aim_usersearch_address(sess, conn, "mid@auk.cx"); */
-  } else if (!strncmp(tmpstr, "reqsendmsg", 10)) {
-    /* aim_send_im(sess, priv->ohcaptainmycaptain, 0, "sendmsg 7900"); */
-  } else if (!strncmp(tmpstr, "reqadmin", 8)) {
-    aim_reqservice(sess, conn, AIM_CONN_TYPE_AUTH);
-  } else if (!strncmp(tmpstr, "changenick", 10)) {
-    aim_admin_setnick(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), "diputs8  1");
-  } else if (!strncmp(tmpstr, "reqconfirm", 10)) {
-    aim_admin_reqconfirm(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH));
-  } else if (!strncmp(tmpstr, "reqemail", 8)) {
-    aim_admin_getinfo(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), 0x0011);
-  } else if (!strncmp(tmpstr, "changepass", 8)) {
-    aim_admin_changepasswd(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), "NEWPASSWORD", "OLDPASSWORD");
-  } else if (!strncmp(tmpstr, "setemail", 8)) {
-    aim_admin_setemail(sess, aim_getconn_type(sess, AIM_CONN_TYPE_AUTH), "NEWEMAILADDRESS");
-  } else if (!strncmp(tmpstr, "sendmsg", 7)) {
-    int i;
-    
-    i = atoi(tmpstr+8);
-    if (i < 10000) {
-      char *newbuf;
-      int z;
-      
-      newbuf = owl_malloc(i+1);
-      for (z = 0; z < i; z++)
-	newbuf[z] = (z % 10)+0x30;
-      newbuf[i] = '\0';
-      /* aim_send_im(sess, userinfo->sn, AIM_IMFLAGS_ACK | AIM_IMFLAGS_AWAY, newbuf); */
-      owl_free(newbuf);
-    }
-  } else if (strstr(tmpstr, "seticqstatus")) {
-    aim_setextstatus(sess, AIM_ICQ_STATE_DND);
-  } else if (strstr(tmpstr, "rtfmsg")) {
-    static const char rtfmsg[] = {"{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fswiss\\fcharset0 Arial;}{\\f1\\froman\\fprq2\\fcharset0 Georgia;}{\\f2\\fmodern\\fprq1\\fcharset0 MS Mincho;}{\\f3\\froman\\fprq2\\fcharset2 Symbol;}}\\viewkind4\\uc1\\pard\\f0\\fs20 Test\\f1 test\\f2\fs44 test\\f3\\fs20 test\\f0\\par}"};
-    struct aim_sendrtfmsg_args rtfargs;
-    
-    memset(&rtfargs, 0, sizeof(rtfargs));
-    rtfargs.destsn = userinfo->sn;
-    rtfargs.fgcolor = 0xffffffff;
-    rtfargs.bgcolor = 0x00000000;
-    rtfargs.rtfmsg = rtfmsg;
-    /* aim_send_rtfmsg(sess, &rtfargs); */
-  } else {
-    /* printf("unknown command.\n"); */
-    aim_add_buddy(sess, conn, userinfo->sn);
-  }  
-  
-  return 0;
-}
-#endif
-
-/*
- * Channel 1: Standard Message
- */
-static int faimtest_parse_incoming_im_chan1(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch1_args *args)
-{
-  struct owlfaim_priv *priv = (struct owlfaim_priv *)sess->aux_data;
-  owl_message *m;
-  char *stripmsg, *nz_screenname, *wrapmsg;
-  char realmsg[8192+1] = {""};
-  /* int clienttype = AIM_CLIENTTYPE_UNKNOWN; */
-
-  /* clienttype = aim_fingerprintclient(args->features, args->featureslen); */
-
-  /*
-  printf("icbm: sn = \"%s\"\n", userinfo->sn);
-  printf("icbm: probable client type: %d\n", clienttype);
-  printf("icbm: warnlevel = %f\n", aim_userinfo_warnlevel(userinfo));
-  printf("icbm: flags = 0x%04x = ", userinfo->flags);
-  printuserflags(userinfo->flags);
-  printf("\n");
-  */
-
-  /*
-  printf("icbm: membersince = %lu\n", userinfo->membersince);
-  printf("icbm: onlinesince = %lu\n", userinfo->onlinesince);
-  printf("icbm: idletime = 0x%04x\n", userinfo->idletime);
-  printf("icbm: capabilities = %s = 0x%08lx\n", (userinfo->present & AIM_USERINFO_PRESENT_CAPABILITIES) ? "present" : "not present", userinfo->capabilities);
-  */
-
-  /*
-  printf("icbm: icbmflags = ");
-  if (args->icbmflags & AIM_IMFLAGS_AWAY) printf("away ");
-  if (args->icbmflags & AIM_IMFLAGS_ACK) printf("ackrequest ");
-  if (args->icbmflags & AIM_IMFLAGS_OFFLINE) printf("offline ");
-  if (args->icbmflags & AIM_IMFLAGS_BUDDYREQ) printf("buddyreq ");
-  if (args->icbmflags & AIM_IMFLAGS_HASICON) printf("hasicon ");
-  printf("\n");
-  */
-
-  /*
-  if (args->icbmflags & AIM_IMFLAGS_CUSTOMCHARSET) {
-  printf("icbm: encoding flags = {%04x, %04x}\n", args->charset, args->charsubset);
-  }
-  */
-  
-  /*
-   * Quickly convert it to eight bit format, replacing non-ASCII UNICODE 
-   * characters with their equivelent HTML entity.
-   */
-  if (args->icbmflags & AIM_IMFLAGS_UNICODE) {
-    int i;
-    
-    for (i=0; i<args->msglen; i+=2) {
-      fu16_t uni;
-
-      uni = ((args->msg[i] & 0xff) << 8) | (args->msg[i+1] & 0xff);
-      if ((uni < 128) || ((uni >= 160) && (uni <= 255))) { /* ISO 8859-1 */
-	snprintf(realmsg+strlen(realmsg), sizeof(realmsg)-strlen(realmsg), "%c", uni);
-      } else { /* something else, do UNICODE entity */
-	snprintf(realmsg+strlen(realmsg), sizeof(realmsg)-strlen(realmsg), "&#%04x;", uni);
-      }
-    }
-  } else {
-    /*
-     * For non-UNICODE encodings (ASCII and ISO 8859-1), there is 
-     * no need to do anything special here.  Most 
-     * terminals/whatever will be able to display such characters 
-     * unmodified.
-     *
-     * Beware that PC-ASCII 128 through 159 are _not_ actually 
-     * defined in ASCII or ISO 8859-1, and you should send them as 
-     * UNICODE.  WinAIM will send these characters in a UNICODE 
-     * message, so you need to do so as well.
-     *
-     * You may not think it necessary to handle UNICODE messages.  
-     * You're probably wrong.  For one thing, Microsoft "Smart
-     * Quotes" will be sent by WinAIM as UNICODE (not HTML UNICODE,
-     * but real UNICODE). If you don't parse UNICODE at all, your 
-     * users will get a blank message instead of the message 
-     * containing Smart Quotes.
-     *
-     */
-    if (args->msg && args->msglen)
-      strncpy(realmsg, args->msg, sizeof(realmsg));
-  }
-
-  owl_function_debugmsg("faimtest_parse_incoming_im_chan1: message from: %s", userinfo->sn?userinfo->sn:"");
-  /* create a message, and put it on the message queue */
-  stripmsg=owl_text_htmlstrip(realmsg);
-  wrapmsg=owl_text_wordwrap(stripmsg, 70);
-  nz_screenname=owl_aim_normalize_screenname(userinfo->sn);
-  m=owl_malloc(sizeof(owl_message));
-  owl_message_create_aim(m,
-			 nz_screenname,
-			 owl_global_get_aim_screenname(&g),
-			 wrapmsg,
-			 OWL_MESSAGE_DIRECTION_IN,
-			 0);
-  if (args->icbmflags & AIM_IMFLAGS_AWAY) owl_message_set_attribute(m, "isauto", "");
-  owl_global_messagequeue_addmsg(&g, m);
-  owl_free(stripmsg);
-  owl_free(wrapmsg);
-  owl_free(nz_screenname);
-
-  return(1);
-
-  owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: message: %s\n", realmsg);
-  
-  if (args->icbmflags & AIM_IMFLAGS_MULTIPART) {
-    aim_mpmsg_section_t *sec;
-    int z;
-
-    owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: multipart: this message has %d parts\n", args->mpmsg.numparts);
-    
-    for (sec = args->mpmsg.parts, z = 0; sec; sec = sec->next, z++) {
-      if ((sec->charset == 0x0000) || (sec->charset == 0x0003) || (sec->charset == 0xffff)) {
-	owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: multipart:   part %d: charset 0x%04x, subset 0x%04x, msg = %s\n", z, sec->charset, sec->charsubset, sec->data);
-      } else {
-	owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: multipart:   part %d: charset 0x%04x, subset 0x%04x, binary or UNICODE data\n", z, sec->charset, sec->charsubset);
-      }
-    }
-  }
-  
-  if (args->icbmflags & AIM_IMFLAGS_HASICON) {
-    /* aim_send_im(sess, userinfo->sn, AIM_IMFLAGS_BUDDYREQ, "You have an icon"); */
-    owl_function_debugmsg("faimtest_parse_incoming_im_chan1: icbm: their icon: iconstamp = %ld, iconlen = 0x%08lx, iconsum = 0x%04x\n", args->iconstamp, args->iconlen, args->iconsum);
-  }
-
-  /*
-  if (realmsg) {
-    int i = 0;
-    while (realmsg[i] == '<') {
-      if (realmsg[i] == '<') {
-	while (realmsg[i] != '>')
-	  i++;
-	i++;
-      }
-    }
-    tmpstr = realmsg+i;
-    faimtest_handlecmd(sess, conn, userinfo, tmpstr);
-  }
-  */
-  
-  if (priv->buddyicon && (args->icbmflags & AIM_IMFLAGS_BUDDYREQ)) {
-    /* aim_send_icon(sess, userinfo->sn, priv->buddyicon, priv->buddyiconlen, priv->buddyiconstamp, priv->buddyiconsum); */
-  }
-  
-  return(1);
-}
-
-/*
- * Channel 2: Rendevous Request
- */
-static int faimtest_parse_incoming_im_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args)
-{
-  /* 
-  printf("rendezvous: source sn = %s\n", userinfo->sn);
-  printf("rendezvous: \twarnlevel = %f\n", aim_userinfo_warnlevel(userinfo));
-  printf("rendezvous: \tclass = 0x%04x = ", userinfo->flags);
-  printuserflags(userinfo->flags);
-  printf("\n");
-  
-  printf("rendezvous: \tonlinesince = %lu\n", userinfo->onlinesince);
-  printf("rendezvous: \tidletime = 0x%04x\n", userinfo->idletime);
-  
-  printf("rendezvous: message/description = %s\n", args->msg);
-  printf("rendezvous: encoding = %s\n", args->encoding);
-  printf("rendezvous: language = %s\n", args->language);
-  */
-  
-  if (args->reqclass == AIM_CAPS_SENDFILE) {
-    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: send file!");
-  } else if (args->reqclass == AIM_CAPS_CHAT) {
-    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: chat invite: %s, %i, %i", args->info.chat.roominfo.name, args->info.chat.roominfo.exchange, args->info.chat.roominfo.instance);
-    /*
-    printf("chat invitation: room name = %s\n", args->info.chat.roominfo.name);
-    printf("chat invitation: exchange = 0x%04x\n", args->info.chat.roominfo.exchange);
-    printf("chat invitation: instance = 0x%04x\n", args->info.chat.roominfo.instance);
-    */
-    /* Automatically join room... */
-    /* printf("chat invitiation: autojoining %s...\n", args->info.chat.roominfo.name); */
-
-    /* aim_chat_join(sess, conn, args->info.chat.roominfo.exchange, args->info.chat.roominfo.name, args->info.chat.roominfo.instance); */
-  } else if (args->reqclass == AIM_CAPS_BUDDYICON) {
-    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: Buddy Icon from %s, length = %lu\n",
-			  userinfo->sn, args->info.icon.length);
-  } else if (args->reqclass == AIM_CAPS_ICQRTF) {
-    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: RTF message from %s: (fgcolor = 0x%08lx, bgcolor = 0x%08lx) %s\n",
-			  userinfo->sn, args->info.rtfmsg.fgcolor, args->info.rtfmsg.bgcolor, args->info.rtfmsg.rtfmsg);
-  } else {
-    owl_function_debugmsg("faimtest_parse_incoming_im_chan2: icbm: unknown reqclass (%d)\n", args->reqclass);
-  }
-  return 1;
-}
-
-static int faimtest_parse_incoming_im(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  fu16_t channel;
-  aim_userinfo_t *userinfo;
-  va_list ap;
-  int ret = 0;
-  
-  va_start(ap, fr);
-  channel = (fu16_t)va_arg(ap, unsigned int);
-  userinfo = va_arg(ap, aim_userinfo_t *);
-  
-  if (channel == 1) {
-    struct aim_incomingim_ch1_args *args;
-    args = va_arg(ap, struct aim_incomingim_ch1_args *);
-    ret = faimtest_parse_incoming_im_chan1(sess, fr->conn, userinfo, args);
-  } else if (channel == 2) {
-    struct aim_incomingim_ch2_args *args;
-    args = va_arg(ap, struct aim_incomingim_ch2_args *);
-    ret = faimtest_parse_incoming_im_chan2(sess, fr->conn, userinfo, args);
-  } else {
-    owl_function_debugmsg("faimtest_parse_incoming_im: unsupported channel 0x%04x\n", channel);
-  }
-  va_end(ap);
-  owl_function_debugmsg("faimtest_parse_incoming_im: done with ICBM handling (ret = %d)\n", ret);
-  return 1;
-}
-
-static int faimtest_parse_oncoming(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  aim_userinfo_t *userinfo;
-  char *nz_screenname;
-  owl_buddy *b;
-  owl_buddylist *bl;
-  va_list ap;
-  va_start(ap, fr);
-  userinfo = va_arg(ap, aim_userinfo_t *);
-  va_end(ap);
-
-  nz_screenname=owl_aim_normalize_screenname(userinfo->sn);
-  bl=owl_global_get_buddylist(&g);
-  
-  owl_buddylist_oncoming(owl_global_get_buddylist(&g), nz_screenname);
-
-  if (userinfo->present & AIM_USERINFO_PRESENT_IDLE) {
-    owl_function_debugmsg("faimtest_parseoncoming: in empty part of userinfo present and present idle");
-  }
-
-  b=owl_buddylist_get_aim_buddy(owl_global_get_buddylist(&g), nz_screenname);
-  if (!b) {
-    owl_function_debugmsg("Error: parse_oncoming setting idle time with no buddy present.");
-    return(1);
-  }
-  if (userinfo->idletime==0) {
-    owl_buddy_set_unidle(b);
-  } else {
-    owl_buddy_set_idle(b);
-    owl_buddy_set_idle_since(b, userinfo->idletime);
-  }
-
-  if (userinfo->flags & AIM_FLAG_AWAY) {
-    owl_function_debugmsg("parse_oncoming sn: %s away flag!", userinfo->sn);
-  }
-  
-  owl_function_debugmsg("parse_oncoming sn: %s idle: %i", userinfo->sn, userinfo->idletime);
-    
-  owl_free(nz_screenname);
-  
-  /*
-    printf("%ld  %s is now online (flags: %04x = %s%s%s%s%s%s%s%s) (caps = %s = 0x%08lx)\n",
-    time(NULL),
-    userinfo->sn, userinfo->flags,
-    (userinfo->flags&AIM_FLAG_UNCONFIRMED)?" UNCONFIRMED":"",
-    (userinfo->flags&AIM_FLAG_ADMINISTRATOR)?" ADMINISTRATOR":"",
-    (userinfo->flags&AIM_FLAG_AOL)?" AOL":"",
-    (userinfo->flags&AIM_FLAG_OSCAR_PAY)?" OSCAR_PAY":"",
-    (userinfo->flags&AIM_FLAG_FREE)?" FREE":"",
-    (userinfo->flags&AIM_FLAG_AWAY)?" AWAY":"",
-    (userinfo->flags&AIM_FLAG_ICQ)?" ICQ":"",
-    (userinfo->flags&AIM_FLAG_WIRELESS)?" WIRELESS":"",
-    (userinfo->present & AIM_USERINFO_PRESENT_CAPABILITIES) ? "present" : "not present",
-    userinfo->capabilities);
-  */
-  return(1);
-}
-
-static int faimtest_parse_offgoing(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  aim_userinfo_t *userinfo;
-  char *nz_screenname;
-  va_list ap;
-  
-  va_start(ap, fr);
-  userinfo = va_arg(ap, aim_userinfo_t *);
-  va_end(ap);
-
-  nz_screenname=owl_aim_normalize_screenname(userinfo->sn);
-  owl_buddylist_offgoing(owl_global_get_buddylist(&g), nz_screenname);
-  owl_free(nz_screenname);
-
-  if (userinfo->present & AIM_USERINFO_PRESENT_IDLE) {
-    owl_function_debugmsg("parse_offgoing sn: %s idle time %i", userinfo->sn, userinfo->idletime);
-  }
-
-  /*
-  printf("%ld  %s is now offline (flags: %04x = %s%s%s%s%s%s%s%s) (caps = %s = 0x%08lx)\n",
-	 time(NULL),
-	 userinfo->sn, userinfo->flags,
-	 (userinfo->flags&AIM_FLAG_UNCONFIRMED)?" UNCONFIRMED":"",
-	 (userinfo->flags&AIM_FLAG_ADMINISTRATOR)?" ADMINISTRATOR":"",
-	 (userinfo->flags&AIM_FLAG_AOL)?" AOL":"",
-	 (userinfo->flags&AIM_FLAG_OSCAR_PAY)?" OSCAR_PAY":"",
-	 (userinfo->flags&AIM_FLAG_FREE)?" FREE":"",
-	 (userinfo->flags&AIM_FLAG_AWAY)?" AWAY":"",
-	 (userinfo->flags&AIM_FLAG_ICQ)?" ICQ":"",
-	 (userinfo->flags&AIM_FLAG_WIRELESS)?" WIRELESS":"",
-	 (userinfo->present & AIM_USERINFO_PRESENT_CAPABILITIES) ? "present" : "not present",
-	 userinfo->capabilities);
-  */
-  
-  return 1;
-}
-
-/* Used by chat as well. */
-int faimtest_parse_genericerr(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  fu16_t reason;
-  
-  va_start(ap, fr);
-  reason = (fu16_t)va_arg(ap, unsigned int);
-  va_end(ap);
-  
-  /* printf("snac threw error (reason 0x%04x: %s)\n", reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown"); */
-  if (reason<msgerrreasonslen) owl_function_error("%s", msgerrreasons[reason]);
-  
-  return 1;
-}
-
-static int faimtest_parse_msgerr(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  char *destsn;
-  fu16_t reason;
-  
-  va_start(ap, fr);
-  reason = (fu16_t)va_arg(ap, unsigned int);
-  destsn = va_arg(ap, char *);
-  va_end(ap);
-  
-  /* printf("message to %s bounced (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown"); */
-  if (reason<msgerrreasonslen) owl_function_error("%s", msgerrreasons[reason]);
-
-  if (reason==4) {
-    owl_function_adminmsg("", "Could not send AIM message, user not logged on");
-  }
-  
-  return 1;
-}
-
-static int faimtest_parse_locerr(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  char *destsn;
-  fu16_t reason;
-  
-  va_start(ap, fr);
-  reason = (fu16_t)va_arg(ap, unsigned int);
-  destsn = va_arg(ap, char *);
-  va_end(ap);
-  
-  /* printf("user information for %s unavailable (reason 0x%04x: %s)\n", destsn, reason, (reason<msgerrreasonslen)?msgerrreasons[reason]:"unknown"); */
-  if (reason<msgerrreasonslen) owl_function_error("%s", msgerrreasons[reason]);
-  
-  return 1;
-}
-
-static int faimtest_parse_misses(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  static char *missedreasons[] = {
-    "Invalid (0)",
-    "Message too large",
-    "Rate exceeded",
-    "Evil Sender",
-    "Evil Receiver"
-  };
-  static int missedreasonslen = 5;
-  
-  va_list ap;
-  fu16_t chan, nummissed, reason;
-  aim_userinfo_t *userinfo;
-  
-  va_start(ap, fr);
-  chan = (fu16_t)va_arg(ap, unsigned int);
-  userinfo = va_arg(ap, aim_userinfo_t *);
-  nummissed = (fu16_t)va_arg(ap, unsigned int);
-  reason = (fu16_t)va_arg(ap, unsigned int);
-  va_end(ap);
-  
-  owl_function_debugmsg("faimtest_parse_misses: missed %d messages from %s on channel %d (reason %d: %s)\n", nummissed, userinfo->sn, chan, reason, (reason<missedreasonslen)?missedreasons[reason]:"unknown");
-  
-  return 1;
-}
-
-/*
- * Received in response to an IM sent with the AIM_IMFLAGS_ACK option.
- */
-static int faimtest_parse_msgack(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  fu16_t type;
-  char *sn = NULL;
-  
-  va_start(ap, fr);
-  type = (fu16_t)va_arg(ap, unsigned int);
-  sn = va_arg(ap, char *);
-  va_end(ap);
-  
-  owl_function_debugmsg("faimtest_parse_msgack: 0x%04x / %s\n", type, sn);
-  
-  return 1;
-}
-
-static int faimtest_parse_ratechange(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  static char *codes[5] = {
-    "invalid",
-    "change",
-    "warning",
-    "limit",
-    "limit cleared"
-  };
-  va_list ap;
-  fu16_t code, rateclass;
-  fu32_t windowsize, clear, alert, limit, disconnect;
-  fu32_t currentavg, maxavg;
-  
-  va_start(ap, fr); 
-  
-  /* See code explanations below */
-  code = (fu16_t)va_arg(ap, unsigned int);
-  
-  /*
-   * See comments above aim_parse_ratechange_middle() in aim_rxhandlers.c.
-   */
-  rateclass = (fu16_t)va_arg(ap, unsigned int);
-  
-  /*
-   * Not sure what this is exactly.  I think its the temporal 
-   * relation factor (ie, how to make the rest of the numbers
-   * make sense in the real world). 
-   */
-  windowsize = va_arg(ap, fu32_t);
-  
-  /* Explained below */
-  clear = va_arg(ap, fu32_t);
-  alert = va_arg(ap, fu32_t);
-  limit = va_arg(ap, fu32_t);
-  disconnect = va_arg(ap, fu32_t);
-  currentavg = va_arg(ap, fu32_t);
-  maxavg = va_arg(ap, fu32_t);
-  
-  va_end(ap);
-  
-  owl_function_debugmsg("faimtest_parse_ratechange: rate %s (rate class 0x%04x): curavg = %ld, maxavg = %ld, alert at %ld, clear warning at %ld, limit at %ld, disconnect at %ld (window size = %ld)",
-			(code < 5)?codes[code]:"invalid",
-			rateclass,
-			currentavg, maxavg,
-			alert, clear,
-			limit, disconnect,
-			windowsize);
-  return 1;
-}
-
-static int faimtest_parse_evilnotify(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  fu16_t newevil;
-  aim_userinfo_t *userinfo;
-  
-  va_start(ap, fr);
-  newevil = (fu16_t)va_arg(ap, unsigned int);
-  userinfo = va_arg(ap, aim_userinfo_t *);
-  va_end(ap);
-  
-  /*
-   * Evil Notifications that are lacking userinfo->sn are anon-warns
-   * if they are an evil increases, but are not warnings at all if its
-   * a decrease (its the natural backoff happening).
-   *
-   * newevil is passed as an int representing the new evil value times
-   * ten.
-   */
-  owl_function_debugmsg("faimtest_parse_evilnotify: new value = %2.1f%% (caused by %s)\n", ((float)newevil)/10, (userinfo && strlen(userinfo->sn))?userinfo->sn:"anonymous");
-  
-  return 1;
-}
-
-static int faimtest_parse_searchreply(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  char *address, *SNs;
-  int num, i;
-  owl_list list;
-  
-  va_start(ap, fr);
-  address = va_arg(ap, char *);
-  num = va_arg(ap, int);
-  SNs = va_arg(ap, char *);
-  va_end(ap);
-
-  owl_list_create(&list);
-  
-  owl_function_debugmsg("faimtest_parse_searchreply: E-Mail Search Results for %s: ", address);
-  for (i=0; i<num; i++) {
-    owl_function_debugmsg("  %s", &SNs[i*(MAXSNLEN+1)]);
-    owl_list_append_element(&list, &SNs[i*(MAXSNLEN+1)]);
-  }
-  owl_function_aimsearch_results(address, &list);
-  owl_list_free_simple(&list);
-  return(1);
-}
-
-static int faimtest_parse_searcherror(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  char *address;
-  
-  va_start(ap, fr);
-  address = va_arg(ap, char *);
-  va_end(ap);
-
-  owl_function_error("No results searching for %s", address);
-  owl_function_debugmsg("faimtest_parse_searcherror: E-Mail Search Results for %s: No Results or Invalid Email\n", address);
-  
-  return(1);
-}
-
-static int handlepopup(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  char *msg, *url;
-  fu16_t width, height, delay;
-  
-  va_start(ap, fr);
-  msg = va_arg(ap, char *);
-  url = va_arg(ap, char *);
-  width = va_arg(ap, unsigned int);
-  height = va_arg(ap, unsigned int);
-  delay = va_arg(ap, unsigned int);
-  va_end(ap);
-  
-  owl_function_debugmsg("handlepopup: (%dx%x:%d) %s (%s)\n", width, height, delay, msg, url);
-  
-  return 1;
-}
-
-static int serverpause(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  aim_sendpauseack(sess, fr->conn);
-  return 1;
-}
-
-static int migrate(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  aim_conn_t *bosconn;
-  char *bosip;
-  fu8_t *cookie;
-  
-  va_start(ap, fr);
-  bosip = va_arg(ap, char *);
-  cookie = va_arg(ap, fu8_t *);
-  va_end(ap);
-  
-  owl_function_debugmsg("migrate: migration in progress -- new BOS is %s -- disconnecting", bosip);
-  aim_conn_kill(sess, &fr->conn);
-  
-  if (!(bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, bosip))) {
-    owl_function_debugmsg("migrate: could not connect to BOS: internal error");
-    return 1;
-  } else if (bosconn->status & AIM_CONN_STATUS_CONNERR) {	
-    owl_function_debugmsg("migrate: could not connect to BOS");
-    aim_conn_kill(sess, &bosconn);
-    return 1;
-  }
-  
-  /* Login will happen all over again. */
-  addcb_bos(sess, bosconn);
-  /* aim_sendcookie(sess, bosconn, cookie); */ /********/
-  return 1;
-}
-
-static int ssirights(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  owl_function_debugmsg("ssirights: got SSI rights, requesting data\n");
-  /* aim_ssi_reqdata(sess, fr->conn, 0, 0x0000); */
-  aim_ssi_reqdata(sess);
-  
-  return(1);
-}
-
-static int ssidata(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  fu8_t fmtver;
-  fu16_t itemcount;
-  fu32_t stamp;
-  struct aim_ssi_item *list;
-  /*
-  struct aim_ssi_item *curitem;
-  struct aim_ssi_item *l;
-  */
-  
-  va_start(ap, fr);
-  fmtver = va_arg(ap, unsigned int);
-  itemcount = va_arg(ap, unsigned int);
-  stamp = va_arg(ap, fu32_t);
-  list = va_arg(ap, struct aim_ssi_item *);
-  va_end(ap);
-  
-  owl_function_debugmsg("ssiddata: got SSI data (0x%02x, %d items, %ld)", fmtver, itemcount, stamp);
-  /*
-  for (curitem=sess->ssi.local; curitem; curitem=curitem->next) {
-    for (l = list; l; l = l->next) {
-      owl_function_debugmsg("\t0x%04x (%s) - 0x%04x/0x%04x", l->type, l->name, l->gid, l->bid);
-    }
-  }
-  */
-  aim_ssi_enable(sess);
-  
-  return 1;
-}
-
-static int ssidatanochange(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  owl_function_debugmsg("ssidatanochange: server says we have the latest SSI data already");
-  /* aim_ssi_enable(sess, fr->conn); */
-  aim_ssi_enable(sess);
-  return 1;
-}
-
-static int offlinemsg(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  struct aim_icq_offlinemsg *msg;
-  
-  va_start(ap, fr);
-  msg = va_arg(ap, struct aim_icq_offlinemsg *);
-  va_end(ap);
-  
-  if (msg->type == 0x0001) {
-    owl_function_debugmsg("offlinemsg: from %ld at %d/%d/%d %02d:%02d : %s", msg->sender, msg->year, msg->month, msg->day, msg->hour, msg->minute, msg->msg);
-  } else {
-    owl_function_debugmsg("unknown offline message type 0x%04x", msg->type);
-  }
-  return 1;
-}
-
-static int offlinemsgdone(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  /* Tell the server to delete them. */
-  owl_function_debugmsg("offlinemsg done: ");
-  aim_icq_ackofflinemsgs(sess);
-  return 1;
-}
-
-
-/******************** chat.c **************************/
-
-static int faimtest_chat_join(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  aim_userinfo_t *userinfo;
-  int count;
-  /* int i; */
-  
-  va_start(ap, fr);
-  count = va_arg(ap, int);
-  userinfo = va_arg(ap, aim_userinfo_t *);
-  va_end(ap);
-
-  owl_function_debugmsg("In faimtest_chat_join");
-  /*
-  printf("chat: %s:  New occupants have joined:\n", aim_chat_getname(fr->conn));
-  for (i = 0; i < count; i++)
-    printf("chat: %s: \t%s\n", aim_chat_getname(fr->conn), userinfo[i].sn);
-  */
-  return 1;
-}
-
-static int faimtest_chat_leave(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  aim_userinfo_t *userinfo;
-  va_list ap;
-  int count;
-  /* int i; */
-
-  
-  va_start(ap, fr);
-  count = va_arg(ap, int);
-  userinfo = va_arg(ap, aim_userinfo_t *);
-  va_end(ap);
-  
-  /*
-    printf("chat: %s:  Some occupants have left:\n", aim_chat_getname(fr->conn));
-    
-    for (i = 0; i < count; i++)
-    printf("chat: %s: \t%s\n", aim_chat_getname(fr->conn), userinfo[i].sn);
-  */
-  return 1;
-}
-
-static int faimtest_chat_infoupdate(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  aim_userinfo_t *userinfo;
-  struct aim_chat_roominfo *roominfo;
-  char *roomname;
-  int usercount;
-  char *roomdesc;
-  fu16_t flags, unknown_d2, unknown_d5, maxmsglen, maxvisiblemsglen;
-  fu32_t creationtime;
-  const char *croomname;
-  /* int i; */
-  
-  croomname = aim_chat_getname(fr->conn);
-  
-  va_start(ap, fr);
-  roominfo = va_arg(ap, struct aim_chat_roominfo *);
-  roomname = va_arg(ap, char *);
-  usercount = va_arg(ap, int);
-  userinfo = va_arg(ap, aim_userinfo_t *);
-  roomdesc = va_arg(ap, char *);
-  flags = (fu16_t)va_arg(ap, unsigned int);
-  creationtime = va_arg(ap, fu32_t);
-  maxmsglen = (fu16_t)va_arg(ap, unsigned int);
-  unknown_d2 = (fu16_t)va_arg(ap, unsigned int);
-  unknown_d5 = (fu16_t)va_arg(ap, unsigned int);
-  maxvisiblemsglen = (fu16_t)va_arg(ap, unsigned int);
-  va_end(ap);
-
-  owl_function_debugmsg("In faimtest_chat_infoupdate");
-  /*
-  printf("chat: %s:  info update:\n", croomname);
-  printf("chat: %s:  \tRoominfo: {%04x, %s, %04x}\n", croomname, roominfo->exchange, roominfo->name, roominfo->instance);
-  printf("chat: %s:  \tRoomname: %s\n", croomname, roomname);
-  printf("chat: %s:  \tRoomdesc: %s\n", croomname, roomdesc);
-  printf("chat: %s:  \tOccupants: (%d)\n", croomname, usercount);
-
-  for (i = 0; i < usercount; i++)
-    printf("chat: %s:  \t\t%s\n", croomname, userinfo[i].sn);
-  
-  owl_function_debugmsg("chat: %s:  \tRoom flags: 0x%04x (%s%s%s%s)\n", 
-	 croomname, flags,
-	 (flags & AIM_CHATROOM_FLAG_EVILABLE) ? "Evilable, " : "",
-	 (flags & AIM_CHATROOM_FLAG_NAV_ONLY) ? "Nav Only, " : "",
-	 (flags & AIM_CHATROOM_FLAG_INSTANCING_ALLOWED) ? "Instancing allowed, " : "",
-	 (flags & AIM_CHATROOM_FLAG_OCCUPANT_PEEK_ALLOWED) ? "Occupant peek allowed, " : "");
-  printf("chat: %s:  \tCreation time: %lu (time_t)\n", croomname, creationtime);
-  printf("chat: %s:  \tUnknown_d2: 0x%04x\n", croomname, unknown_d2);
-  printf("chat: %s:  \tUnknown_d5: 0x%02x\n", croomname, unknown_d5);
-  printf("chat: %s:  \tMax message length: %d bytes\n", croomname, maxmsglen);
-  printf("chat: %s:  \tMax visible message length: %d bytes\n", croomname, maxvisiblemsglen);
-  */
-  
-  return(1);
-}
-
-static int faimtest_chat_incomingmsg(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  va_list ap;
-  aim_userinfo_t *userinfo;
-  char *msg;
-  char tmpbuf[1152];
-  
-  va_start(ap, fr);
-  userinfo = va_arg(ap, aim_userinfo_t *);	
-  msg = va_arg(ap, char *);
-  va_end(ap);
-
-  owl_function_debugmsg("in faimtest_chat_incomingmsg");
-
-  /*
-  printf("chat: %s: incoming msg from %s: %s\n", aim_chat_getname(fr->conn), userinfo->sn, msg);
-  */
-  
-  /*
-   * Do an echo for testing purposes.  But not for ourselves ("oops!")
-   */
-  if (strcmp(userinfo->sn, sess->sn) != 0) {
-    /* sprintf(tmpbuf, "(%s said \"%s\")", userinfo->sn, msg); */
-    aim_chat_send_im(sess, fr->conn, 0, tmpbuf, strlen(tmpbuf));
-  }
-  
-  return 1;
-}
-
-static int faimtest_chatnav_info(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  fu16_t type;
-  va_list ap;
-  
-  va_start(ap, fr);
-  type = (fu16_t)va_arg(ap, unsigned int);
-
-  owl_function_debugmsg("in faimtest_chatnav_info");
-  
-  if (type == 0x0002) {
-    int maxrooms;
-    struct aim_chat_exchangeinfo *exchanges;
-    int exchangecount;
-    /* int i; */
-    
-    maxrooms = va_arg(ap, int);
-    exchangecount = va_arg(ap, int);
-    exchanges = va_arg(ap, struct aim_chat_exchangeinfo *);
-    va_end(ap);
-
-    /*
-    printf("chat info: Chat Rights:\n");
-    printf("chat info: \tMax Concurrent Rooms: %d\n", maxrooms);
-    printf("chat info: \tExchange List: (%d total)\n", exchangecount);
-    for (i = 0; i < exchangecount; i++) {
-      printf("chat info: \t\t%x: %s (%s/%s) (0x%04x = %s%s%s%s)\n", 
-	     exchanges[i].number,
-	     exchanges[i].name,
-	     exchanges[i].charset1,
-	     exchanges[i].lang1,
-	     exchanges[i].flags,
-	     (exchanges[i].flags & AIM_CHATROOM_FLAG_EVILABLE) ? "Evilable, " : "",
-	     (exchanges[i].flags & AIM_CHATROOM_FLAG_NAV_ONLY) ? "Nav Only, " : "",
-	     (exchanges[i].flags & AIM_CHATROOM_FLAG_INSTANCING_ALLOWED) ? "Instancing allowed, " : "",
-	     (exchanges[i].flags & AIM_CHATROOM_FLAG_OCCUPANT_PEEK_ALLOWED) ? "Occupant peek allowed, " : "");
-    }
-    */
-  } else if (type == 0x0008) {
-    char *fqcn, *name, *ck;
-    fu16_t instance, flags, maxmsglen, maxoccupancy, unknown, exchange;
-    fu8_t createperms;
-    fu32_t createtime;
-    
-    fqcn = va_arg(ap, char *);
-    instance = (fu16_t)va_arg(ap, unsigned int);
-    exchange = (fu16_t)va_arg(ap, unsigned int);
-    flags = (fu16_t)va_arg(ap, unsigned int);
-    createtime = va_arg(ap, fu32_t);
-    maxmsglen = (fu16_t)va_arg(ap, unsigned int);
-    maxoccupancy = (fu16_t)va_arg(ap, unsigned int);
-    createperms = (fu8_t)va_arg(ap, unsigned int);
-    unknown = (fu16_t)va_arg(ap, unsigned int);
-    name = va_arg(ap, char *);
-    ck = va_arg(ap, char *);
-    va_end(ap);
-    
-    /* printf("received room create reply for %s/0x%04x\n", fqcn, exchange); */
-    
-  } else {
-    va_end(ap);
-    /* printf("chatnav info: unknown type (%04x)\n", type); */
-  }
-  
-  return 1;
-}
-
-static int conninitdone_chat(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  owl_function_debugmsg("faimtest_conninitdone_chat:");
-
-  aim_conn_addhandler(sess, fr->conn, 0x000e, 0x0001, faimtest_parse_genericerr, 0);
-  aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERJOIN, faimtest_chat_join, 0);
-  aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERLEAVE, faimtest_chat_leave, 0);
-  aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_ROOMINFOUPDATE, faimtest_chat_infoupdate, 0);
-  aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_INCOMINGMSG, faimtest_chat_incomingmsg, 0);
-  
-  aim_clientready(sess, fr->conn);
-  
-  owl_function_debugmsg("Chat ready");
-
-  /*
-    chatcon = find_oscar_chat_by_conn(gc, fr->conn);
-    chatcon->id = id;
-    chatcon->cnv = serv_got_joined_chat(gc, id++, chatcon->show);
-  */
-  return(1);
-}
-
-static int conninitdone_chatnav(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  owl_function_debugmsg("faimtest_conninitdone_chatnav:");
-
-  /* aim_conn_addhandler(sess, fr->conn, 0x000d, 0x0001, gaim_parse_genericerr, 0); */
-  /* aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CTN, AIM_CB_CTN_INFO, gaim_chatnav_info, 0); */
-
-  aim_clientready(sess, fr->conn);
-
-  aim_chatnav_reqrights(sess, fr->conn);
-
-  return(1);
-}
-
-void chatnav_redirect(aim_session_t *sess, struct aim_redirect_data *redir)
-{
-  aim_conn_t *tstconn;
-
-  owl_function_debugmsg("in faimtest_chatnav_redirect");
-  
-  tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, redir->ip);
-  if (!tstconn || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
-    /* printf("unable to connect to chat(nav) server\n"); */
-    if (tstconn)
-      aim_conn_kill(sess, &tstconn);
-    return;
-  }
-  
-  aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
-  aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_chat, 0);
-  aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie);
-  /* printf("chatnav: connected\n"); */
-  return;
-}
-
-/* XXX this needs instance too */
-void chat_redirect(aim_session_t *sess, struct aim_redirect_data *redir)
-{
-  aim_conn_t *tstconn;
-
-  owl_function_debugmsg("in chat_redirect");
-  
-  tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHAT, redir->ip);
-  if (!tstconn || (tstconn->status & AIM_CONN_STATUS_RESOLVERR)) {
-    /* printf("unable to connect to chat server\n"); */
-    if (tstconn) aim_conn_kill(sess, &tstconn);
-    return; 
-  }		
-  /* printf("chat: connected to %s instance %d on exchange %d\n", redir->chat.room, redir->chat.instance, redir->chat.exchange); */
-  
-  /*
-   * We must do this to attach the stored name to the connection!
-   */
-  aim_chat_attachname(tstconn, redir->chat.exchange, redir->chat.room, redir->chat.instance);
-  aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE, faimtest_conncomplete, 0);
-  aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_chat, 0);
-  aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie);
-  return;	
-}
-
-void owl_process_aim()
-{
-  if (owl_global_is_doaimevents(&g)) {
-    owl_aim_process_events();
-
-    if (owl_global_is_aimloggedin(&g)) {
-      if (owl_timer_is_expired(owl_global_get_aim_buddyinfo_timer(&g))) {
-        /* owl_buddylist_request_idletimes(owl_global_get_buddylist(&g)); */
-        owl_timer_reset(owl_global_get_aim_buddyinfo_timer(&g));
-      }
-    }
-  }
-}
-
-
-/**********************************************************************************/
-
-#if 0
-static int faimtest_ssi_rerequestdata(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  aim_ssi_reqdata(sess);
-  return(0);
-}
-
-static int faimtest_ssi_parseerr(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  /* GaimConnection *gc = sess->aux_data; */
-  /*	OscarData *od = gc->proto_data; */
-  va_list ap;
-  fu16_t reason;
-
-  va_start(ap, fr);
-  reason = (fu16_t)va_arg(ap, unsigned int);
-  va_end(ap);
-
-  owl_function_debugmsg("faimtest_ssi_parseerr: ssi: SNAC error %hu", reason);
-
-  if (reason == 0x0005) {
-    owl_function_error("faimtest_ssi_parseerr: unable to retrieve buddy list");
-  }
-
-  /* Activate SSI */
-  /* Sending the enable causes other people to be able to see you, and you to see them */
-  /* Make sure your privacy setting/invisibility is set how you want it before this! */
-  owl_function_debugmsg("faimtest_ssi_parseerr: ssi: activating server-stored buddy list");
-  aim_ssi_enable(sess);
-  
-  return(1);
-}
-
-static int faimtest_ssi_parserights(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  /* GaimConnection *gc = sess->aux_data; */
-  /* OscarData *od = (OscarData *)gc->proto_data; */
-  int numtypes, i;
-  fu16_t *maxitems;
-  va_list ap;
-
-  va_start(ap, fr);
-  numtypes = va_arg(ap, int);
-  maxitems = va_arg(ap, fu16_t *);
-  va_end(ap);
-
-  owl_function_debugmsg("faimtest_ssi_parserights: ");
-  for (i=0; i<numtypes; i++) {
-    owl_function_debugmsg(" max type 0x%04x=%hd,", i, maxitems[i]);
-  }
-
-  /*
-  if (numtypes >= 0) od->rights.maxbuddies = maxitems[0];
-  if (numtypes >= 1) od->rights.maxgroups = maxitems[1];
-  if (numtypes >= 2) od->rights.maxpermits = maxitems[2];
-  if (numtypes >= 3) od->rights.maxdenies = maxitems[3];
-  */
-  
-  return(1);
-}
-
-static int faimtest_ssi_parselist(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  /* GaimConnection *gc = sess->aux_data; */
-  /* GaimAccount *account = gaim_connection_get_account(gc); */
-  /* OscarData *od = (OscarData *)gc->proto_data; */
-  struct aim_ssi_item *curitem;
-  int tmp;
-  int export = FALSE;
-  /* XXX - use these?
-     va_list ap;
-     
-     va_start(ap, fr);
-     fmtver = (fu16_t)va_arg(ap, int);
-     numitems = (fu16_t)va_arg(ap, int);
-     items = va_arg(ap, struct aim_ssi_item);
-     timestamp = va_arg(ap, fu32_t);
-     va_end(ap); */
-  
-  owl_function_debugmsg("faimtest_ssi_parselist: syncing local list and server list");
-
-  /* Clean the buddy list */
-  aim_ssi_cleanlist(sess);
-
-  /* Add from server list to local list */
-  for (curitem=sess->ssi.local; curitem; curitem=curitem->next) {
-    if ((curitem->name == NULL) || (g_utf8_validate(curitem->name, -1, NULL)))
-      switch (curitem->type) {
-      case 0x0000: { /* Buddy */
-	if (curitem->name) {
-	  char *gname = aim_ssi_itemlist_findparentname(sess->ssi.local, curitem->name);
-	  char *gname_utf8 = gname ? gaim_utf8_try_convert(gname) : NULL;
-	  char *alias = aim_ssi_getalias(sess->ssi.local, gname, curitem->name);
-	  char *alias_utf8 = alias ? gaim_utf8_try_convert(alias) : NULL;
-	  GaimBuddy *buddy = gaim_find_buddy(gc->account, curitem->name);
-	  /* Should gname be freed here? -- elb */
-	  /* Not with the current code, but that might be cleaner -- med */
-	  free(alias);
-	  if (buddy) {
-	    /* Get server stored alias */
-	    if (alias_utf8) {
-	      g_free(buddy->alias);
-	      buddy->alias = g_strdup(alias_utf8);
-	    }
-	  } else {
-	    GaimGroup *g;
-	    buddy = gaim_buddy_new(gc->account, curitem->name, alias_utf8);
-	    
-	    if (!(g = gaim_find_group(gname_utf8 ? gname_utf8 : _("Orphans")))) {
-	      g = gaim_group_new(gname_utf8 ? gname_utf8 : _("Orphans"));
-	      gaim_blist_add_group(g, NULL);
-	    }
-	    
-	    gaim_debug(GAIM_DEBUG_INFO, "oscar",
-		       "ssi: adding buddy %s to group %s to local list\n", curitem->name, gname_utf8 ? gname_utf8 : _("Orphans"));
-	    gaim_blist_add_buddy(buddy, NULL, g, NULL);
-	    export = TRUE;
-	  }
-	  g_free(gname_utf8);
-	  g_free(alias_utf8);
-	}
-      } break;
-      
-      case 0x0001: { /* Group */
-	/* Shouldn't add empty groups */
-      } break;
-      
-      case 0x0002: { /* Permit buddy */
-	if (curitem->name) {
-	  /* if (!find_permdeny_by_name(gc->permit, curitem->name)) { AAA */
-	  GSList *list;
-	  for (list=account->permit; (list && aim_sncmp(curitem->name, list->data)); list=list->next);
-	  if (!list) {
-	    gaim_debug(GAIM_DEBUG_INFO, "oscar",
-		       "ssi: adding permit buddy %s to local list\n", curitem->name);
-	    gaim_privacy_permit_add(account, curitem->name, TRUE);
-	    export = TRUE;
-	  }
-	}
-      } break;
-      
-      case 0x0003: { /* Deny buddy */
-	if (curitem->name) {
-	  GSList *list;
-	  for (list=account->deny; (list && aim_sncmp(curitem->name, list->data)); list=list->next);
-	  if (!list) {
-	    gaim_debug(GAIM_DEBUG_INFO, "oscar",
-		       "ssi: adding deny buddy %s to local list\n", curitem->name);
-	    gaim_privacy_deny_add(account, curitem->name, TRUE);
-	    export = TRUE;
-	  }
-	}
-      } break;
-      
-      case 0x0004: { /* Permit/deny setting */
-	if (curitem->data) {
-	  fu8_t permdeny;
-	  if ((permdeny = aim_ssi_getpermdeny(sess->ssi.local)) && (permdeny != account->perm_deny)) {
-	    gaim_debug(GAIM_DEBUG_INFO, "oscar",
-		       "ssi: changing permdeny from %d to %hhu\n", account->perm_deny, permdeny);
-	    account->perm_deny = permdeny;
-	    if (od->icq && account->perm_deny == 0x03) {
-	      serv_set_away(gc, "Invisible", "");
-	    }
-	    export = TRUE;
-	  }
-	}
-      } break;
-      
-      case 0x0005: { /* Presence setting */
-	/* We don't want to change Gaim's setting because it applies to all accounts */
-      } break;
-      } /* End of switch on curitem->type */
-  } /* End of for loop */
-  
-  /* If changes were made, then flush buddy list to file */
-  if (export)
-    gaim_blist_save();
-  
-  { /* Add from local list to server list */
-    GaimBlistNode *gnode, *cnode, *bnode;
-    GaimGroup *group;
-    GaimBuddy *buddy;
-    GaimBuddyList *blist;
-    GSList *cur;
-    
-    /* Buddies */
-    if ((blist = gaim_get_blist()))
-      for (gnode = blist->root; gnode; gnode = gnode->next) {
-	if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
-	  continue;
-	group = (GaimGroup *)gnode;
-	for (cnode = gnode->child; cnode; cnode = cnode->next) {
-	  if(!GAIM_BLIST_NODE_IS_CONTACT(cnode))
-	    continue;
-	  for (bnode = cnode->child; bnode; bnode = bnode->next) {
-	    if(!GAIM_BLIST_NODE_IS_BUDDY(bnode))
-	      continue;
-	    buddy = (GaimBuddy *)bnode;
-	    if (buddy->account == gc->account) {
-	      const char *servernick = gaim_buddy_get_setting(buddy, "servernick");
-	      if (servernick)
-		serv_got_alias(gc, buddy->name, servernick);
-	      
-	      if (aim_ssi_itemlist_exists(sess->ssi.local, buddy->name)) {
-		/* Store local alias on server */
-		char *alias = aim_ssi_getalias(sess->ssi.local, group->name, buddy->name);
-		if (!alias && buddy->alias && strlen(buddy->alias))
-		  aim_ssi_aliasbuddy(sess, group->name, buddy->name, buddy->alias);
-		free(alias);
-	      } else {
-		gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "ssi: adding buddy %s from local list to server list\n", buddy->name);
-		aim_ssi_addbuddy(sess, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0);
-	      }
-	    }
-	  }
-	}
-      }
-    
-    /* Permit list */
-    if (gc->account->permit) {
-      for (cur=gc->account->permit; cur; cur=cur->next)
-	if (!aim_ssi_itemlist_finditem(sess->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) {
-	  gaim_debug(GAIM_DEBUG_INFO, "oscar",
-		     "ssi: adding permit %s from local list to server list\n", (char *)cur->data);
-	  aim_ssi_addpermit(sess, cur->data);
-	}
-    }
-    
-    /* Deny list */
-    if (gc->account->deny) {
-      for (cur=gc->account->deny; cur; cur=cur->next)
-	if (!aim_ssi_itemlist_finditem(sess->ssi.local, NULL, cur->data, AIM_SSI_TYPE_DENY)) {
-	  gaim_debug(GAIM_DEBUG_INFO, "oscar",
-		     "ssi: adding deny %s from local list to server list\n", (char *)cur->data);
-	  aim_ssi_adddeny(sess, cur->data);
-	}
-    }
-    /* Presence settings (idle time visibility) */
-    if ((tmp = aim_ssi_getpresence(sess->ssi.local)) != 0xFFFFFFFF)
-      if (!(tmp & 0x400))
-	aim_ssi_setpresence(sess, tmp | 0x400);
-  } /* end adding buddies from local list to server list */
-  
-  /* Set our ICQ status */
-  if  (od->icq && !gc->away) {
-    aim_setextstatus(sess, AIM_ICQ_STATE_NORMAL);
-  }
-  
-  /* Activate SSI */
-  /* Sending the enable causes other people to be able to see you, and you to see them */
-  /* Make sure your privacy setting/invisibility is set how you want it before this! */
-  gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: activating server-stored buddy list\n");
-  aim_ssi_enable(sess);
-  
-  return 1;
-}
-
-static int gaim_ssi_parseack(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  GaimConnection *gc = sess->aux_data;
-  va_list ap;
-  struct aim_ssi_tmp *retval;
-  
-  va_start(ap, fr);
-  retval = va_arg(ap, struct aim_ssi_tmp *);
-  va_end(ap);
-  
-  while (retval) {
-    gaim_debug(GAIM_DEBUG_MISC, "oscar",
-	       "ssi: status is 0x%04hx for a 0x%04hx action with name %s\n", retval->ack,  retval->action, retval->item ? (retval->item->name ? retval->item->name : "no name") : "no item");
-    
-    if (retval->ack != 0xffff)
-      switch (retval->ack) {
-      case 0x0000: { /* added successfully */
-      } break;
-      
-      case 0x000c: { /* you are over the limit, the cheat is to the limit, come on fhqwhgads */
-	gchar *buf;
-	buf = g_strdup_printf(_("Could not add the buddy %s because you have too many buddies in your buddy list.  Please remove one and try again."), (retval->name ? retval->name : _("(no name)")));
-	gaim_notify_error(gc, NULL, _("Unable To Add"), buf);
-	g_free(buf);
-      }
-	
-      case 0x000e: { /* buddy requires authorization */
-	if ((retval->action == AIM_CB_SSI_ADD) && (retval->name))
-	  gaim_auth_sendrequest(gc, retval->name);
-      } break;
-      
-      default: { /* La la la */
-	gchar *buf;
-	gaim_debug(GAIM_DEBUG_ERROR, "oscar", "ssi: Action 0x%04hx was unsuccessful with error 0x%04hx\n", retval->action, retval->ack);
-	buf = g_strdup_printf(_("Could not add the buddy %s for an unknown reason.  The most common reason for this is that you have the maximum number of allowed buddies in your buddy list."), (retval->name ? retval->name : _("(no name)")));
-	gaim_notify_error(gc, NULL, _("Unable To Add"), buf);
-	g_free(buf);
-	/* XXX - Should remove buddy from local list */
-      } break;
-      }
-    
-    retval = retval->next;
-  }
-  
-  return 1;
-}
-
-static int gaim_ssi_authgiven(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  GaimConnection *gc = sess->aux_data;
-  va_list ap;
-  char *sn, *msg;
-  gchar *dialog_msg, *nombre;
-  struct name_data *data;
-  GaimBuddy *buddy;
-  
-  va_start(ap, fr);
-  sn = va_arg(ap, char *);
-  msg = va_arg(ap, char *);
-  va_end(ap);
-  
-  gaim_debug(GAIM_DEBUG_INFO, "oscar",
-	     "ssi: %s has given you permission to add him to your buddy list\n", sn);
-  
-  buddy = gaim_find_buddy(gc->account, sn);
-  if (buddy && (gaim_get_buddy_alias_only(buddy)))
-    nombre = g_strdup_printf("%s (%s)", sn, gaim_get_buddy_alias_only(buddy));
-  else
-    nombre = g_strdup(sn);
-  
-  dialog_msg = g_strdup_printf(_("The user %s has given you permission to add you to their buddy list.  Do you want to add them?"), nombre);
-  data = g_new(struct name_data, 1);
-  data->gc = gc;
-  data->name = g_strdup(sn);
-  data->nick = NULL;
-  
-  gaim_request_yes_no(gc, NULL, _("Authorization Given"), dialog_msg,
-		      0, data,
-		      G_CALLBACK(gaim_icq_buddyadd),
-		      G_CALLBACK(oscar_free_name_data));
-  
-  g_free(dialog_msg);
-  g_free(nombre);
-  
-  return 1;
-}
-
-static int gaim_ssi_authrequest(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  GaimConnection *gc = sess->aux_data;
-  va_list ap;
-  char *sn, *msg;
-  gchar *dialog_msg, *nombre;
-  struct name_data *data;
-  GaimBuddy *buddy;
-  
-  va_start(ap, fr);
-  sn = va_arg(ap, char *);
-  msg = va_arg(ap, char *);
-  va_end(ap);
-  
-  gaim_debug(GAIM_DEBUG_INFO, "oscar",
-	     "ssi: received authorization request from %s\n", sn);
-  
-  buddy = gaim_find_buddy(gc->account, sn);
-  if (buddy && (gaim_get_buddy_alias_only(buddy)))
-    nombre = g_strdup_printf("%s (%s)", sn, gaim_get_buddy_alias_only(buddy));
-  else
-    nombre = g_strdup(sn);
-  
-  dialog_msg = g_strdup_printf(_("The user %s wants to add you to their buddy list for the following reason:\n%s"), nombre, msg ? msg : _("No reason given."));
-  data = g_new(struct name_data, 1);
-  data->gc = gc;
-  data->name = g_strdup(sn);
-  data->nick = NULL;
-  
-  gaim_request_action(gc, NULL, _("Authorization Request"), dialog_msg,
-		      0, data, 2,
-		      _("Authorize"), G_CALLBACK(gaim_auth_grant),
-		      _("Deny"), G_CALLBACK(gaim_auth_dontgrant_msgprompt));
-  
-  g_free(dialog_msg);
-  g_free(nombre);
-  
-  return 1;
-}
-
-static int gaim_ssi_authreply(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  GaimConnection *gc = sess->aux_data;
-  va_list ap;
-  char *sn, *msg;
-  gchar *dialog_msg, *nombre;
-  fu8_t reply;
-  GaimBuddy *buddy;
-  
-  va_start(ap, fr);
-  sn = va_arg(ap, char *);
-  reply = (fu8_t)va_arg(ap, int);
-  msg = va_arg(ap, char *);
-  va_end(ap);
-  
-  gaim_debug(GAIM_DEBUG_INFO, "oscar",
-	     "ssi: received authorization reply from %s.  Reply is 0x%04hhx\n", sn, reply);
-  
-  buddy = gaim_find_buddy(gc->account, sn);
-  if (buddy && (gaim_get_buddy_alias_only(buddy)))
-    nombre = g_strdup_printf("%s (%s)", sn, gaim_get_buddy_alias_only(buddy));
-  else
-    nombre = g_strdup(sn);
-  
-  if (reply) {
-    /* Granted */
-    dialog_msg = g_strdup_printf(_("The user %s has granted your request to add them to your buddy list."), nombre);
-    gaim_notify_info(gc, NULL, _("Authorization Granted"), dialog_msg);
-  } else {
-    /* Denied */
-    dialog_msg = g_strdup_printf(_("The user %s has denied your request to add them to your buddy list for the following reason:\n%s"), nombre, msg ? msg : _("No reason given."));
-    gaim_notify_info(gc, NULL, _("Authorization Denied"), dialog_msg);
-  }
-  g_free(dialog_msg);
-  g_free(nombre);
-  
-  return 1;
-}
-
-static int gaim_ssi_gotadded(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-  GaimConnection *gc = sess->aux_data;
-  va_list ap;
-  char *sn;
-  GaimBuddy *buddy;
-  
-  va_start(ap, fr);
-  sn = va_arg(ap, char *);
-  va_end(ap);
-  
-  buddy = gaim_find_buddy(gc->account, sn);
-  gaim_debug(GAIM_DEBUG_INFO, "oscar",
-	     "ssi: %s added you to their buddy list\n", sn);
-  gaim_account_notify_added(gc->account, NULL, sn, (buddy ? gaim_get_buddy_alias_only(buddy) : NULL), NULL);
-  
-  return 1;
-}
-#endif
Index: hstatic
===================================================================
--- athstatic	(revision 855dc8d060c78460217b895ed0ae73eee2c9c4dc)
+++ 	(revision )
@@ -1,32 +1,0 @@
-#!/bin/sh
-# $Id$
-
-# Usage: athstatic progname options ...
-
-# Replaces -lfoo options with /usr/athena/lib/libfoo.a if it exists,
-# thus preferring static libraries to shared libraries for stuff in
-# /usr/athena/lib.
-
-progname=$1
-shift
-
-options=
-for arg do
-  case $arg in
-  -l*)
-    # Chop off the first two characters to get the library name.
-    lib=`expr "$arg" : '..\(.*\)$'`
-    if [ -f /usr/athena/lib/lib${lib}.a -a "$lib" != "perl" ]; then
-      options="$options /usr/athena/lib/lib${lib}.a"
-    else
-      options="$options $arg"
-    fi
-    ;;
-  *)
-    options="$options $arg"
-    ;;
-  esac
-done
-
-echo "$progname" $options
-exec "$progname" $options
Index: barnowl_1.0.0.orig.tar.gz.id
===================================================================
--- barnowl_1.0.0.orig.tar.gz.id	(revision b321e671ca87b9023d2c334a62cc4bf284367855)
+++ barnowl_1.0.0.orig.tar.gz.id	(revision b321e671ca87b9023d2c334a62cc4bf284367855)
@@ -0,0 +1,1 @@
+c471a071d89e324eab4b41f7420bab6a11e73962
Index: ddy.c
===================================================================
--- buddy.c	(revision f4d0975bed0618ba963347663b4b5de5825c0a22)
+++ 	(revision )
@@ -1,71 +1,0 @@
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-void owl_buddy_create(owl_buddy *b, int proto, char *name)
-{
-  b->proto=proto;
-  b->name=owl_strdup(name);
-  b->idlesince=0;
-}
-
-char *owl_buddy_get_name(owl_buddy *b)
-{
-  if (b->name) return(b->name);
-  return("");
-}
-
-int owl_buddy_is_idle(owl_buddy *b)
-{
-  if (b->isidle) return(1);
-  return(0);
-}
-
-void owl_buddy_set_idle(owl_buddy *b)
-{
-  b->isidle=1;
-}
-
-void owl_buddy_set_unidle(owl_buddy *b)
-{
-  b->isidle=0;
-}
-
-int owl_buddy_get_proto(owl_buddy *b)
-{
-  return(b->proto);
-}
-
-int owl_buddy_is_proto_aim(owl_buddy *b)
-{
-  if (b->proto==OWL_PROTOCOL_AIM) return(1);
-  return(0);
-}
-
-/* Set the buddy to have been idle since 'diff' minutes ago
- */
-void owl_buddy_set_idle_since(owl_buddy *b, int diff)
-{
-  time_t now;
-
-  now=time(NULL);
-  b->idlesince=now-(diff*60);
-}
-
-/* return the number of minutes the buddy has been idle
- */
-int owl_buddy_get_idle_time(owl_buddy *b)
-{
-  time_t now;
-
-  if (b->isidle) {
-    now=time(NULL);
-    return((now - b->idlesince)/60);
-  }
-  return(0);
-}
-
-void owl_buddy_free(owl_buddy *b)
-{
-  if (b->name) owl_free(b->name);
-}
Index: ddylist.c
===================================================================
--- buddylist.c	(revision 257a22f9949fe230526eb336a3d6c236f702da66)
+++ 	(revision )
@@ -1,142 +1,0 @@
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-void owl_buddylist_init(owl_buddylist *bl)
-{
-  owl_list_create(&(bl->buddies));
-}
-
-/* add a (logged-in) AIM buddy to the buddy list
- */
-void owl_buddylist_add_aim_buddy(owl_buddylist *bl, char *screenname)
-{
-  owl_buddy *b;
-  b=owl_malloc(sizeof(owl_buddy));
-  
-  owl_buddy_create(b, OWL_PROTOCOL_AIM, screenname);
-  owl_list_append_element(&(bl->buddies), b);
-}
-
-/* remove an AIM buddy from the buddy list
- */
-int owl_buddylist_remove_aim_buddy(owl_buddylist *bl, char *name)
-{
-  int i, j;
-  owl_buddy *b;
-
-  j=owl_list_get_size(&(bl->buddies));
-  for (i=0; i<j; i++) {
-    b=owl_list_get_element(&(bl->buddies), i);
-    if (!strcasecmp(name, owl_buddy_get_name(b)) && owl_buddy_is_proto_aim(b)) {
-      owl_list_remove_element(&(bl->buddies), i);
-      owl_buddy_free(b);
-      return(0);
-    }
-  }
-  return(1);
-}
-
-/* Deal with an "oncoming" message.  This means recognizing the user
- * has logged in, and displaying a message if they were not already
- * logged in.
- */
-void owl_buddylist_oncoming(owl_buddylist *bl, char *screenname)
-{
-  owl_message *m;
-
-  if (!owl_buddylist_is_aim_buddy_loggedin(bl, screenname)) {
-
-    owl_buddylist_add_aim_buddy(bl, screenname);
-
-    /* are we ingoring login messages for a while? */
-    if (!owl_timer_is_expired(owl_global_get_aim_login_timer(&g))) return;
-
-    /* if not, create the login message */
-    m=owl_malloc(sizeof(owl_message));
-    owl_message_create_aim(m,
-			   screenname,
-			   owl_global_get_aim_screenname(&g),
-			   "",
-			   OWL_MESSAGE_DIRECTION_IN,
-			   1);
-    owl_global_messagequeue_addmsg(&g, m);
-  }
-}
-
-/* Deal with an "offgoing" message.  This means recognizing the user
- * has logged out, and sending a message if they were logged in.
- */
-void owl_buddylist_offgoing(owl_buddylist *bl, char *screenname)
-{
-  owl_message *m;
-
-  if (owl_buddylist_is_aim_buddy_loggedin(bl, screenname)) {
-    m=owl_malloc(sizeof(owl_message));
-    owl_message_create_aim(m,
-			   screenname,
-			   owl_global_get_aim_screenname(&g),
-			   "",
-			   OWL_MESSAGE_DIRECTION_IN,
-			   -1);
-    owl_global_messagequeue_addmsg(&g, m);
-  }
-
-  owl_buddylist_remove_aim_buddy(bl, screenname);
-}
-
-/* return the number of logged in buddies */
-int owl_buddylist_get_size(owl_buddylist *bl)
-{
-  return(owl_list_get_size(&(bl->buddies)));
-}
-
-/* return the buddy with index N.  If out of range, return NULL
- */
-owl_buddy *owl_buddylist_get_buddy_n(owl_buddylist *bl, int index)
-{
-  if (index<0) return(NULL);
-  if (index>(owl_buddylist_get_size(bl)-1)) return(NULL);
-
-  return(owl_list_get_element(&(bl->buddies), index));
-}
-
-/* return the AIM buddy with screenname 'name'.  If
- * no such buddy is logged in, return NULL.
- */
-owl_buddy *owl_buddylist_get_aim_buddy(owl_buddylist *bl, char *name)
-{
-  int i, j;
-  owl_buddy *b;
-
-  j=owl_list_get_size(&(bl->buddies));
-  for (i=0; i<j; i++) {
-    b=owl_list_get_element(&(bl->buddies), i);
-    if (!strcasecmp(name, owl_buddy_get_name(b))) return(b);
-  }
-  return(NULL);
-}
-
-/* return 1 if the buddy 'screenname' is logged in,
- * otherwise return 0
- */
-int owl_buddylist_is_aim_buddy_loggedin(owl_buddylist *bl, char *screenname)
-{
-  owl_buddy *b;
-
-  b=owl_buddylist_get_aim_buddy(bl, screenname);
-  if (b==NULL) return(0);
-  return(1);
-}
-
-/* remove all buddies from the list */
-void owl_buddylist_clear(owl_buddylist *bl)
-{
-  owl_list_free_all(&(bl->buddies), (void(*)(void*))owl_buddy_free);
-  owl_list_create(&(bl->buddies));
-}
-
-void owl_buddylist_free(owl_buddylist *bl)
-{
-  owl_list_free_all(&(bl->buddies), (void(*)(void*))owl_buddy_free);
-}
Index: d.c
===================================================================
--- cmd.c	(revision c4ba74dbb881fe02a8e19d2936144c033c7bb68f)
+++ 	(revision )
@@ -1,305 +1,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-extern owl_cmd commands_to_init[];
-
-/**************************************************************************/
-/***************************** COMMAND DICT *******************************/
-/**************************************************************************/
-
-int owl_cmddict_setup(owl_cmddict *cd) {
-  if (0 != owl_cmddict_init(cd)) return(-1);
-  if (0 != owl_cmddict_add_from_list(cd, commands_to_init)) return(-1);
-  return(0);
-}
-
-int owl_cmddict_init(owl_cmddict *cd) {
-  if (owl_dict_create(cd)) return(-1);
-  return(0);
-}
-
-/* for bulk initialization at startup */
-int owl_cmddict_add_from_list(owl_cmddict *cd, owl_cmd *cmds) {
-  owl_cmd *cur, *cmd;
-  for (cur = cmds; cur->name != NULL; cur++) {  
-    cmd = owl_malloc(sizeof(owl_cmd));
-    owl_cmd_create_from_template(cmd, cur);
-    owl_dict_insert_element(cd, cmd->name, (void*)cmd, NULL);
-  }
-  return 0;
-}
-
-/* free the list with owl_cmddict_namelist_free */
-void owl_cmddict_get_names(owl_cmddict *d, owl_list *l) {
-  owl_dict_get_keys(d, l);
-}
-
-owl_cmd *owl_cmddict_find(owl_cmddict *d, char *name) {
-  return (owl_cmd*)owl_dict_find_element(d, name);
-}
-
-void owl_cmddict_namelist_free(owl_list *l) {
-  owl_list_free_all(l, owl_free);
-}
-
-/* creates a new command alias */
-int owl_cmddict_add_alias(owl_cmddict *cd, char *alias_from, char *alias_to) {
-  owl_cmd *cmd;
-  cmd = owl_malloc(sizeof(owl_cmd));
-  owl_cmd_create_alias(cmd, alias_from, alias_to);
-  owl_dict_insert_element(cd, cmd->name, (void*)cmd, (void(*)(void*))owl_cmd_free);    
-  return(0);
-}
-
-int owl_cmddict_add_cmd(owl_cmddict *cd, owl_cmd * cmd) {
-  owl_cmd * newcmd = owl_malloc(sizeof(owl_cmd));
-  if(owl_cmd_create_from_template(newcmd, cmd) < 0) {
-    owl_free(newcmd);
-    return -1;
-  }
-  owl_function_debugmsg("Add cmd %s", cmd->name);
-  return owl_dict_insert_element(cd, newcmd->name, (void*)newcmd, (void(*)(void*))owl_cmd_free);
-}
-
-char *_owl_cmddict_execute(owl_cmddict *cd, owl_context *ctx, char **argv, int argc, char *buff) {
-  char *retval = NULL;
-  owl_cmd *cmd;
-
-  if (!strcmp(argv[0], "")) {
-  } else if (NULL != (cmd = (owl_cmd*)owl_dict_find_element(cd, argv[0]))) {
-    retval = owl_cmd_execute(cmd, cd, ctx, argc, argv, buff);
-  } else {
-    owl_function_makemsg("Unknown command '%s'.", buff);
-  }
-  return retval;
-}
-
-char *owl_cmddict_execute(owl_cmddict *cd, owl_context *ctx, char *cmdbuff) {
-  char **argv;
-  int argc;
-  char *tmpbuff;
-  char *retval = NULL;
-
-  tmpbuff=owl_strdup(cmdbuff);
-  argv=owl_parseline(tmpbuff, &argc);
-  if (argc < 0) {
-    owl_free(tmpbuff);
-    sepbar(NULL);
-    owl_function_makemsg("Unbalanced quotes");
-    return NULL;
-  } 
-  
-  if (argc < 1) return(NULL);
-
-  retval = _owl_cmddict_execute(cd, ctx, argv, argc, cmdbuff);
-
-  owl_parsefree(argv, argc);
-  owl_free(tmpbuff);
-  sepbar(NULL);
-  return retval;
-}
-
-char *owl_cmddict_execute_argv(owl_cmddict *cd, owl_context *ctx, char **argv, int argc) {
-  char *buff, *ptr;
-  int len = 0, i;
-  char *retval = NULL;
-
-  for(i = 0; i < argc; i++) {
-    len += strlen(argv[i]) + 1;
-  }
-
-  ptr = buff = owl_malloc(len);
-
-  for(i = 0; i < argc; i++) {
-    strcpy(ptr, argv[i]);
-    ptr += strlen(argv[i]);
-    *(ptr++) = ' ';
-  }
-  *(ptr - 1) = 0;
-
-  retval = _owl_cmddict_execute(cd, ctx, argv, argc, buff);
-
-  owl_free(buff);
-  return retval;
-}
-
-/*********************************************************************/
-/***************************** COMMAND *******************************/
-/*********************************************************************/
-
-/* sets up a new command based on a template, copying strings */
-int owl_cmd_create_from_template(owl_cmd *cmd, owl_cmd *templ) {
-  *cmd = *templ;
-  if (!templ->name) return(-1);
-  cmd->name = owl_strdup(templ->name);
-  if (templ->summary)     cmd->summary     = owl_strdup(templ->summary);
-  if (templ->usage)       cmd->usage       = owl_strdup(templ->usage);
-  if (templ->description) cmd->description = owl_strdup(templ->description);
-  if (templ->cmd_aliased_to) cmd->cmd_aliased_to = owl_strdup(templ->cmd_aliased_to);
-  return(0);
-}
-
-int owl_cmd_create_alias(owl_cmd *cmd, char *name, char *aliased_to) {
-  memset(cmd, 0, sizeof(owl_cmd));
-  cmd->name = owl_strdup(name);
-  cmd->cmd_aliased_to = owl_strdup(aliased_to);
-  cmd->summary = owl_malloc(strlen(aliased_to)+strlen(OWL_CMD_ALIAS_SUMMARY_PREFIX)+2);
-  strcpy(cmd->summary, OWL_CMD_ALIAS_SUMMARY_PREFIX);
-  strcat(cmd->summary, aliased_to);
-  return(0);
-}
-
-void owl_cmd_free(owl_cmd *cmd) {
-  if (cmd->name) owl_free(cmd->name);
-  if (cmd->summary) owl_free(cmd->summary);
-  if (cmd->usage) owl_free(cmd->usage);
-  if (cmd->description) owl_free(cmd->description);
-  if (cmd->cmd_aliased_to) owl_free(cmd->cmd_aliased_to);
-  if (cmd->cmd_perl) owl_perlconfig_cmd_free(cmd);
-}
-
-int owl_cmd_is_context_valid(owl_cmd *cmd, owl_context *ctx) { 
-  if (owl_context_matches(ctx, cmd->validctx)) return 1;
-  else return 0;
-}
-
-char *owl_cmd_execute(owl_cmd *cmd, owl_cmddict *cd, owl_context *ctx, int argc, char **argv, char *cmdbuff) {
-  static int alias_recurse_depth = 0;
-  int ival=0;
-  char *cmdbuffargs, *newcmd, *rv=NULL;
-
-  if (argc < 1) return(NULL);
-
-  /* Recurse if this is an alias */
-  if (cmd->cmd_aliased_to) {
-    if (alias_recurse_depth++ > 50) {
-      owl_function_makemsg("Alias loop detected for '%s'.", cmdbuff);
-    } else {
-      cmdbuffargs = skiptokens(cmdbuff, 1);
-      newcmd = owl_malloc(strlen(cmd->cmd_aliased_to)+strlen(cmdbuffargs)+2);
-      strcpy(newcmd, cmd->cmd_aliased_to);
-      strcat(newcmd, " ");
-      strcat(newcmd, cmdbuffargs);
-      rv = owl_function_command(newcmd);
-      owl_free(newcmd);
-    } 
-    alias_recurse_depth--;
-    return rv;
-  }
-
-  /* Do validation and conversions */
-  if (cmd->cmd_ctxargs_fn || cmd->cmd_ctxv_fn || cmd->cmd_ctxi_fn) {
-    if (!owl_cmd_is_context_valid(cmd, ctx)) {
-      owl_function_makemsg("Invalid context for command '%s'.", cmdbuff);
-      return NULL;
-    }
-  }
-
-  if ((argc != 1) && (cmd->cmd_v_fn || cmd->cmd_ctxv_fn)) {
-    owl_function_makemsg("Wrong number of arguments for %s command.", argv[0]);
-    return NULL;
-  }
-
-  if (cmd->cmd_i_fn || cmd->cmd_ctxi_fn) {
-      char *ep = "x";
-      if (argc != 2) {
-	owl_function_makemsg("Wrong number of arguments for %s command.", argv[0]);
-	return NULL;
-      }
-      ival = strtol(argv[1], &ep, 10);
-      if (*ep || ep==argv[1]) {
-	owl_function_makemsg("Invalid argument '%s' for %s command.", argv[1], argv[0]);
-	return(NULL);
-      }
-  }
-
-  if (cmd->cmd_args_fn) {
-    return cmd->cmd_args_fn(argc, argv, cmdbuff);
-  } else if (cmd->cmd_v_fn) {    
-    cmd->cmd_v_fn();
-  } else if (cmd->cmd_i_fn) {
-    cmd->cmd_i_fn(ival);
-  } else if (cmd->cmd_ctxargs_fn) {
-    return cmd->cmd_ctxargs_fn(owl_context_get_data(ctx), argc, argv, cmdbuff);
-  } else if (cmd->cmd_ctxv_fn) {    
-    cmd->cmd_ctxv_fn(owl_context_get_data(ctx));
-  } else if (cmd->cmd_ctxi_fn) {
-    cmd->cmd_ctxi_fn(owl_context_get_data(ctx), ival);
-  } else if (cmd->cmd_perl) {
-    return owl_perlconfig_perlcmd(cmd, argc, argv);
-  }
-
-  return NULL;
-}
-
-/* returns a reference */
-char *owl_cmd_get_summary(owl_cmd *cmd) {
-  return cmd->summary;
-}
-
-/* returns a summary line describing this keymap.  the caller must free. */
-char *owl_cmd_describe(owl_cmd *cmd) {
-  char *s;
-  int slen;
-  if (!cmd || !cmd->name || !cmd->summary) return NULL;
-  slen = strlen(cmd->name)+strlen(cmd->summary)+30;
-  s = owl_malloc(slen);
-  snprintf(s, slen-1, "%-25s - %s", cmd->name, cmd->summary);
-  return s;
-}
-
-
-
-void owl_cmd_get_help(owl_cmddict *d, char *name, owl_fmtext *fm) {
-  char *indent, *s;
-  owl_cmd *cmd;
-
-  if (!name || (cmd = owl_dict_find_element(d, name)) == NULL) {
-    owl_fmtext_append_bold(fm, "OWL HELP\n\n");
-    owl_fmtext_append_normal(fm, "No such command...\n");
-    return;
-  }
-
-  owl_fmtext_append_bold(fm, "OWL HELP\n\n");
-  owl_fmtext_append_bold(fm, "NAME\n\n");
-  owl_fmtext_append_normal(fm, OWL_TABSTR);
-  owl_fmtext_append_normal(fm, cmd->name);
-
-  if (cmd->summary && *cmd->summary) {
-    owl_fmtext_append_normal(fm, " - ");
-    owl_fmtext_append_normal(fm, cmd->summary);
-  }
-  owl_fmtext_append_normal(fm, "\n");
-
-  if (cmd->usage && *cmd->usage) {
-    s = cmd->usage;
-    indent = owl_malloc(strlen(s)+(owl_text_num_lines(s)+3)*OWL_TAB+1);
-    owl_text_indent(indent, s, OWL_TAB);
-    owl_fmtext_append_bold(fm, "\nSYNOPSIS\n");
-    owl_fmtext_append_normal(fm, indent);
-    owl_fmtext_append_normal(fm, "\n");
-    owl_free(indent);
-  } else {
-    owl_fmtext_append_bold(fm, "\nSYNOPSIS\n");
-    owl_fmtext_append_normal(fm, OWL_TABSTR);
-    owl_fmtext_append_normal(fm, cmd->name);
-    owl_fmtext_append_normal(fm, "\n");
-  }
-
-  if (cmd->description && *cmd->description) {
-    s = cmd->description;
-    indent = owl_malloc(strlen(s)+(owl_text_num_lines(s)+3)*OWL_TAB+1);
-    owl_text_indent(indent, s, OWL_TAB);
-    owl_fmtext_append_bold(fm, "\nDESCRIPTION\n");
-    owl_fmtext_append_normal(fm, indent);
-    owl_fmtext_append_normal(fm, "\n");
-    owl_free(indent);
-  }
-
-  owl_fmtext_append_normal(fm, "\n\n");  
-}
Index: delist.pl
===================================================================
--- codelist.pl	(revision 09489b896891e6c4e2b0a2a7d622c25749410cf1)
+++ 	(revision )
@@ -1,40 +1,0 @@
-#! /usr/bin/perl
-# $Id$
-
-if ($#ARGV eq -1) {
-    @ARGV=`ls *.c`;
-    chop(@ARGV);
-}
-
-foreach $file (@ARGV) {
-    open(FILE, $file);
-
-    print "/* -------------------------------- $file -------------------------------- */\n";
-    while (<FILE>) {
-	if (/^\S/
-	    && (/\{\s*$/ || /\)\s*$/)
-	    && !/\}/
-	    && !/^\{/
-	    && !/^#/
-	    && !/^static/
-	    && !/^system/
-	    && !/^XS/
-	    && !/\/\*/
-	    && !/ZWRITEOPTIONS/
-	    && !/owlfaim_priv/)
-	{
-
-	    s/\s+\{/\;/;
-	    s/\)[ \t]*$/\)\;/;
-	    print "extern ";
-	    print;
-	} elsif (/^#if/ || /^#else/ || /^#endif/) {
-	    print;
-	}
-	    
-    }
-    close(FILE);
-    print "\n";
-}
-
-
Index: mmands.c
===================================================================
--- commands.c	(revision 9b70dd4730dcdc958150fe126007d358cec3c713)
+++ 	(revision )
@@ -1,2787 +1,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-/* fn is "char *foo(int argc, char **argv, char *buff)" */
-#define OWLCMD_ARGS(name, fn, ctx, summary, usage, description) \
-        { name, summary, usage, description, ctx, \
-          NULL, fn, NULL, NULL, NULL, NULL, NULL }
-
-/* fn is "void foo(void)" */
-#define OWLCMD_VOID(name, fn, ctx, summary, usage, description) \
-        { name, summary, usage, description, ctx, \
-          NULL, NULL, fn, NULL, NULL, NULL, NULL }
-
-/* fn is "void foo(int)" */
-#define OWLCMD_INT(name, fn, ctx, summary, usage, description) \
-        { name, summary, usage, description, ctx, \
-          NULL, NULL, NULL, fn, NULL, NULL, NULL }
-
-#define OWLCMD_ALIAS(name, actualname) \
-        { name, OWL_CMD_ALIAS_SUMMARY_PREFIX actualname, "", "", OWL_CTX_ANY, \
-          actualname, NULL, NULL, NULL, NULL, NULL, NULL }
-
-/* fn is "char *foo(void *ctx, int argc, char **argv, char *buff)" */
-#define OWLCMD_ARGS_CTX(name, fn, ctx, summary, usage, description) \
-        { name, summary, usage, description, ctx, \
-          NULL, NULL, NULL, NULL, ((char*(*)(void*,int,char**,char*))fn), NULL, NULL }
-
-/* fn is "void foo(void)" */
-#define OWLCMD_VOID_CTX(name, fn, ctx, summary, usage, description) \
-        { name, summary, usage, description, ctx, \
-          NULL, NULL, NULL, NULL, NULL, ((void(*)(void*))(fn)), NULL }
-
-/* fn is "void foo(int)" */
-#define OWLCMD_INT_CTX(name, fn, ctx, summary, usage, description) \
-        { name, summary, usage, description, ctx, \
-          NULL, NULL, NULL, NULL, NULL, NULL, ((void(*)(void*,int))fn) }
-
-
-owl_cmd commands_to_init[]
-  = {
-  OWLCMD_ARGS("zlog", owl_command_zlog, OWL_CTX_ANY,
-	      "send a login or logout notification",
-	      "zlog in [tty]\nzlog out",
-	      "zlog in will send a login notification, zlog out will send a\n"
-	      "logout notification.  By default a login notification is sent\n"
-	      "when owl is started and a logout notification is sent when owl\n"
-	      "is exited.  This behavior can be changed with the 'startuplogin'\n"
-	      "and 'shutdownlogout' variables.  If a tty is specified for zlog in\n"
-	      "then the owl variable 'tty' will be set to that string, causing\n"
-	      "it to be used as the zephyr location tty.\n"),
-
-  OWLCMD_VOID("quit", owl_command_quit, OWL_CTX_ANY,
-	      "exit owl",
-	      "",
-	      "Exit owl and run any shutdown activities."),
-  OWLCMD_ALIAS("exit", "quit"),
-  OWLCMD_ALIAS("q",    "quit"),
-
-  OWLCMD_ARGS("term", owl_command_term, OWL_CTX_ANY,
-	      "control the terminal",
-	      "term raise\n"
-	      "term deiconify\n",
-	      ""),
-
-  OWLCMD_VOID("nop", owl_command_nop, OWL_CTX_ANY,
-	      "do nothing",
-	      "",
-	      ""),
-  
-  OWLCMD_ARGS("start-command", owl_command_start_command, OWL_CTX_INTERACTIVE,
-	      "prompts the user to enter a command",
-	      "start-command [initial-value]",
-	      "Initializes the command field to initial-value."),
-
-  OWLCMD_ARGS("start-question", owl_command_start_question, OWL_CTX_INTERACTIVE,
-	      "prompts the user to enter a response to some question",
-	      "start-command <question>",
-	      ""),
-
-  OWLCMD_ARGS("start-password", owl_command_start_password, OWL_CTX_INTERACTIVE,
-	      "prompts the user to enter a password",
-	      "start-password <question>",
-	      ""),
-
-  OWLCMD_ARGS("alias", owl_command_alias, OWL_CTX_ANY,
-	      "creates a command alias",
-	      "alias <new_command> <old_command>",
-	      "Creates a command alias from new_command to old_command.\n"
-	      "Any arguments passed to <new_command> will be appended to\n"
-	      "<old_command> before it is executed.\n"),
-
-  OWLCMD_ARGS("bindkey", owl_command_bindkey, OWL_CTX_ANY,
-	      "creates a binding in a keymap",
-	      "bindkey <keymap> <keyseq> command <command>",
-	      "Binds a key sequence to a command within a keymap.\n"
-	      "Use 'show keymaps' to see the existing keymaps.\n"
-	      "Key sequences may be things like M-C-t or NPAGE.\n"),
-
-  OWLCMD_ARGS("zwrite", owl_command_zwrite, OWL_CTX_INTERACTIVE,
-	      "send a zephyr",
-	      "zwrite [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcde] [<user> ...] [-m <message...>]",
-	      "Zwrite send a zephyr to the one or more users specified.\n\n"
-	      "The following options are available:\n\n"
-	      "-m    Specifies a message to send without prompting.\n"
-	      "      Note that this does not yet log an outgoing message.\n"
-	      "      This must be the last argument.\n\n"
-	      "-n    Do not send a ping message.\n\n"
-	      "-C    If the message is sent to more than one user include a\n"
-	      "      \"cc:\" line in the text\n\n"
-	      "-c class\n"
-	      "      Send to the specified zephyr class\n\n"
-	      "-i instance\n"
-	      "      Send to the specified zephyr instance\n\n"
-	      "-r realm\n"
-	      "      Send to a foreign realm\n"
-	      "-O opcode\n"
-	      "      Send to the specified opcode\n"),
-
-  OWLCMD_ARGS("aimwrite", owl_command_aimwrite, OWL_CTX_INTERACTIVE,
-	      "send an AIM message",
-	      "aimwrite <user> [-m <message...>]",
-	      "Send an aim message to a user.\n\n" 
-              "The following options are available:\n\n"
-              "-m    Specifies a message to send without prompting.\n"),
-
-  OWLCMD_ARGS("loopwrite", owl_command_loopwrite, OWL_CTX_INTERACTIVE,
-	      "send a loopback message",
-	      "loopwrite",
-	      "Send a local message.\n"),
-
-  OWLCMD_ARGS("zcrypt", owl_command_zcrypt, OWL_CTX_INTERACTIVE,
-	      "send an encrypted zephyr",
-	      "zcrypt [-n] [-C] [-c class] [-i instance] [-r realm] [-O opcde] [-m <message...>]\n",
-	      "Behaves like zwrite but uses encryption.  Not for use with\n"
-	      "personal messages\n"),
-  
-  OWLCMD_ARGS("reply", owl_command_reply,  OWL_CTX_INTERACTIVE,
-	      "reply to the current message",
-	      "reply [-e] [ sender | all | zaway ]",
-	      "If -e is specified, the zwrite command line is presented to\n"
-	      "allow editing.\n\n"
-	      "If 'sender' is specified, reply to the sender.\n\n"
-	      "If 'all' or no args are specified, reply publically to the\n"
-	      "same class/instance for non-personal messages and to the\n"
-	      "sender for personal messages.\n\n"
-	      "If 'zaway' is specified, replies with a zaway message.\n\n"),
-
-  OWLCMD_ARGS("set", owl_command_set, OWL_CTX_ANY,
-	      "set a variable value",
-	      "set [-q] [<variable>] [<value>]\n"
-	      "set",
-	      "Set the named variable to the specified value.  If no\n"
-	      "arguments are given, print the value of all variables.\n"
-	      "If the value is unspecified and the variable is a boolean, it will be\n"
-	      "set to 'on'.  If -q is used, set is silent and does not print a\n"
-	      "message.\n"),
-
-  OWLCMD_ARGS("unset", owl_command_unset, OWL_CTX_ANY,
-	      "unset a boolean variable value",
-	      "set [-q] <variable>\n"
-	      "set",
-	      "Set the named boolean variable to off.\n"
-	      "If -q is specified, is silent and doesn't print a message.\n"),
-
-  OWLCMD_ARGS("print", owl_command_print, OWL_CTX_ANY,
-	      "print a variable value",
-	      "print <variable>\n"
-	      "print",
-	      "Print the value of the named variable.  If no arguments\n"
-	      "are used print the value of all variables.\n"),
-
-  OWLCMD_ARGS("startup", owl_command_startup, OWL_CTX_ANY,
-	      "run a command and set it to be run at every Owl startup",
-	      "startup <commands> ...",
-	      "Everything on the command line after the startup command\n"
-	      "is executed as a normal owl command and is also placed in\n"
-	      "a file so that the command is executed every time owl\n"
-	      "is started"),
-
-  OWLCMD_ARGS("unstartup", owl_command_unstartup, OWL_CTX_ANY,
-	      "remove a command from the list of those to be run at Owl startup",
-	      "unstartup <commands> ...",
-	      ""),
-
-  OWLCMD_VOID("version", owl_command_version, OWL_CTX_ANY,
-	      "print the version of the running owl", "", ""),
-
-  OWLCMD_ARGS("subscribe", owl_command_subscribe, OWL_CTX_ANY,
-	      "subscribe to a zephyr class, instance, recipient",
-	      "subscribe [-t] <class> [instance [recipient]]",
-	      "Subscribe to the specified class and instance.  If the\n"
-	      "instance or recipient is not listed on the command\n"
-	      "line they default to * (the wildcard recipient).\n"
-	      "If the -t option is present the subscription will\n"
-	      "only be temporary, i.e., it will not be written to\n"
-	      "the subscription file and will therefore not be\n"
-	      "present the next time owl is started.\n"),
-  OWLCMD_ALIAS("sub", "subscribe"),
-
-  OWLCMD_ARGS("unsubscribe", owl_command_unsubscribe, OWL_CTX_ANY,
-	      "unsubscribe from a zephyr class, instance, recipient",
-	      "unsubscribe [-t] <class> [instance [recipient]]",
-	      "Unsubscribe from the specified class and instance.  If the\n"
-	      "instance or recipient is not listed on the command\n"
-	      "line they default to * (the wildcard recipient).\n"
-	      "If the -t option is present the unsubscription will\n"
-	      "only be temporary, i.e., it will not be updated in\n"
-	      "the subscription file and will therefore not be\n"
-	      "in effect the next time owl is started.\n"),
-  OWLCMD_ALIAS("unsub", "unsubscribe"),
-
-  OWLCMD_VOID("unsuball", owl_command_unsuball, OWL_CTX_ANY,
-	      "unsubscribe from all zephyrs", "", ""),
-  
-  OWLCMD_VOID("getsubs", owl_command_getsubs, OWL_CTX_ANY,
-	      "print all current subscriptions",
-	      "getsubs",
-	      "getsubs retrieves the current subscriptions from the server\n"
-	      "and displays them.\n"),
-
-  OWLCMD_ARGS("dump", owl_command_dump, OWL_CTX_ANY,
-	      "dump messages to a file",
-	      "dump <filename>",
-	      "Dump messages in current view to the named file."),
-
-  OWLCMD_ARGS("source", owl_command_source, OWL_CTX_ANY,
-	      "execute owl commands from a file",
-	      "source <filename>",
-	      "Execute the owl commands in <filename>.\n"),
-
-  OWLCMD_ARGS("aim", owl_command_aim, OWL_CTX_INTERACTIVE,
-	      "AIM specific commands",
-	      "aim search <email>",
-	      ""),
-
-  OWLCMD_ARGS("addbuddy", owl_command_addbuddy, OWL_CTX_INTERACTIVE,
-	      "add a buddy to a buddylist",
-	      "addbuddy <protocol> <screenname>",
-	      "Add the named buddy to your buddylist.  <protocol> can be aim or zephyr\n"),
-
-  OWLCMD_ARGS("delbuddy", owl_command_delbuddy, OWL_CTX_INTERACTIVE,
-	      "delete a buddy from a buddylist",
-	      "delbuddy <protocol> <screenname>",
-	      "Delete the named buddy from your buddylist.  <protocol> can be aim or zephyr\n"),
-
-  OWLCMD_ARGS("join", owl_command_join, OWL_CTX_INTERACTIVE,
-	      "join a chat group",
-	      "join aim <groupname> [exchange]",
-	      "Join the AIM chatroom with 'groupname'.\n"),
-
-  OWLCMD_ARGS("smartzpunt", owl_command_smartzpunt, OWL_CTX_INTERACTIVE,
-	      "creates a zpunt based on the current message",
-	      "smartzpunt [-i | --instance]",
-	      "Starts a zpunt command based on the current message's class\n"
-	      "(and instance if -i is specified).\n"),
-
-  OWLCMD_ARGS("zpunt", owl_command_zpunt, OWL_CTX_ANY,
-	      "suppress a given zephyr triplet",
-	      "zpunt <class> <instance> [recipient]\n"
-	      "zpunt <instance>",
-	      "The zpunt command will supress message to the specified\n"
-	      "zephyr triplet.  In the second usage messages are suppressed\n"
-	      "for class MESSAGE and the named instance.\n\n"
-	      "SEE ALSO:  zunpunt, show zpunts\n"),
-
-  OWLCMD_ARGS("zunpunt", owl_command_zunpunt, OWL_CTX_ANY,
-	      "undo a previous zpunt",
-	      "zunpunt <class> <instance> [recipient]\n"
-	      "zunpunt <instance>",
-	      "The zunpunt command will allow messages that were previously\n"
-	      "suppressed to be received again.\n\n"
-	      "SEE ALSO:  zpunt, show zpunts\n"),
-
-  OWLCMD_ARGS("punt", owl_command_punt, OWL_CTX_ANY,
-	      "suppress an arbitrary filter",
-	      "punt <filter-name>",
-	      "punt <filter-text (multiple words)>\n"
-	      "The punt command will supress message to the specified\n"
-	      "filter\n\n"
-	      "SEE ALSO:  unpunt, zpunt, show zpunts\n"),
-
-  OWLCMD_ARGS("unpunt", owl_command_unpunt, OWL_CTX_ANY,
-	      "remove an entry from the punt list",
-	      "zpunt <filter-name>\n"
-	      "zpunt <filter-text>\n"
-	      "zpunt <number>\n",
-	      "The unpunt command will remove an entry from the puntlist.\n"
-	      "The first two forms correspond to the first two forms of the :punt\n"
-	      "command. The latter allows you to remove a specific entry from the\n"
-	      "the list (see :show zpunts)\n\n"
-	      "SEE ALSO:  punt, zpunt, zunpunt, show zpunts\n"),
-
-  OWLCMD_VOID("info", owl_command_info, OWL_CTX_INTERACTIVE,
-	      "display detailed information about the current message",
-	      "", ""),
-  
-  OWLCMD_ARGS("help", owl_command_help, OWL_CTX_INTERACTIVE,
-	      "display help on using owl",
-	      "help [command]", ""),
-
-  OWLCMD_ARGS("zlist", owl_command_zlist, OWL_CTX_INTERACTIVE,
-	      "List users logged in",
-	      "znol [-f file]",
-	      "Print a znol-style listing of users logged in"),
-
-  OWLCMD_ARGS("alist", owl_command_alist, OWL_CTX_INTERACTIVE,
-	      "List AIM users logged in",
-	      "alist",
-	      "Print a listing of AIM users logged in"),
-
-  OWLCMD_ARGS("blist", owl_command_blist, OWL_CTX_INTERACTIVE,
-	      "List all buddies logged in",
-	      "blist",
-	      "Print a listing of buddies logged in, regardless of protocol."),
-
-  OWLCMD_ARGS("toggle-oneline", owl_command_toggleoneline, OWL_CTX_INTERACTIVE,
-	      "Toggle the style between oneline and the default style",
-	      "toggle-oneline",
-	      ""),
-
-  OWLCMD_VOID("recv:shiftleft", owl_command_shift_left, OWL_CTX_INTERACTIVE,
-	      "scrolls receive window to the left", "", ""),
-
-  OWLCMD_VOID("recv:shiftright", owl_command_shift_right, OWL_CTX_INTERACTIVE,
-	      "scrolls receive window to the left", "", ""),
-
-  OWLCMD_VOID("recv:pagedown", owl_function_mainwin_pagedown, 
-	      OWL_CTX_INTERACTIVE,
-	      "scrolls down by a page", "", ""),
-
-  OWLCMD_VOID("recv:pageup", owl_function_mainwin_pageup, OWL_CTX_INTERACTIVE,
-	      "scrolls up by a page", "", ""),
-
-  OWLCMD_INT ("recv:scroll", owl_function_page_curmsg, OWL_CTX_INTERACTIVE,
-	      "scrolls current message up or down", 
-	      "recv:scroll <numlines>", 
-	      "Scrolls the current message up or down by <numlines>.\n"
-	      "Scrolls up if <numlines> is negative, else scrolls down.\n"),
-
-  OWLCMD_ARGS("next", owl_command_next, OWL_CTX_INTERACTIVE,
-	      "move the pointer to the next message",
-	      "recv:next [ --filter <name> ] [ --skip-deleted ] [ --last-if-none ]\n"
-	      "          [ --smart-filter | --smart-filter-instance ]",
-	      "Moves the pointer to the next message in the current view.\n"
-	      "If --filter is specified, will only consider messages in\n"
-	      "the filter <name>.\n"
-	      "If --smart-filter or --smart-filter-instance is specified,\n"
-	      "goes to the next message that is similar to the current message.\n"
-	      "If --skip-deleted is specified, deleted messages will\n"
-	      "be skipped.\n"
-	      "If --last-if-none is specified, will stop at last message\n"
-	      "in the view if no other suitable messages are found.\n"),
-  OWLCMD_ALIAS("recv:next", "next"),
-
-  OWLCMD_ARGS("prev", owl_command_prev, OWL_CTX_INTERACTIVE,
-	      "move the pointer to the previous message",
-	      "recv:prev [ --filter <name> ] [ --skip-deleted ] [ --first-if-none ]\n"
-	      "          [ --smart-filter | --smart-filter-instance ]",
-	      "Moves the pointer to the next message in the current view.\n"
-	      "If --filter is specified, will only consider messages in\n"
-	      "the filter <name>.\n"
-	      "If --smart-filter or --smart-filter-instance is specified,\n"
-	      "goes to the previous message that is similar to the current message.\n"
-	      "If --skip-deleted is specified, deleted messages will\n"
-	      "be skipped.\n"
-	      "If --first-if-none is specified, will stop at first message\n"
-	      "in the view if no other suitable messages are found.\n"),
-  OWLCMD_ALIAS("recv:prev", "prev"),
-
-  OWLCMD_ALIAS("recv:next-notdel", "recv:next --skip-deleted --last-if-none"),
-  OWLCMD_ALIAS("next-notdel",      "recv:next --skip-deleted --last-if-none"),
-
-  OWLCMD_ALIAS("recv:prev-notdel", "recv:prev --skip-deleted --first-if-none"),
-  OWLCMD_ALIAS("prev-notdel",      "recv:prev --skip-deleted --first-if-none"),
-
-  OWLCMD_ALIAS("recv:next-personal", "recv:next --filter personal"),
-
-  OWLCMD_ALIAS("recv:prev-personal", "recv:prev --filter personal"),
-
-  OWLCMD_VOID("first", owl_command_first, OWL_CTX_INTERACTIVE,
-	      "move the pointer to the first message", "", ""),
-  OWLCMD_ALIAS("recv:first", "first"),
-
-  OWLCMD_VOID("last", owl_command_last, OWL_CTX_INTERACTIVE,
-	      "move the pointer to the last message", "", 
-	      "Moves the pointer to the last message in the view.\n"
-	      "If we are already at the last message in the view,\n"
-	      "blanks the screen and moves just past the end of the view\n"
-	      "so that new messages will appear starting at the top\n"
-	      "of the screen.\n"),
-  OWLCMD_ALIAS("recv:last", "last"),
-
-  OWLCMD_VOID("expunge", owl_command_expunge, OWL_CTX_INTERACTIVE,
-	      "remove all messages marked for deletion", "", ""),
-
-  OWLCMD_VOID("resize", owl_command_resize, OWL_CTX_ANY,
-	      "resize the window to the current screen size", "", ""),
-
-  OWLCMD_VOID("redisplay", owl_command_redisplay, OWL_CTX_ANY,
-	      "redraw the entire window", "", ""),
-
-  OWLCMD_VOID("suspend", owl_command_suspend, OWL_CTX_ANY,
-	      "suspend owl", "", ""),
-
-  OWLCMD_ARGS("echo", owl_command_echo, OWL_CTX_ANY,
-	      "pops up a message in popup window",
-	      "echo [args .. ]\n\n", ""),
-
-  OWLCMD_ARGS("exec", owl_command_exec, OWL_CTX_ANY,
-	      "run a command from the shell",
-	      "exec [args .. ]", ""),
-
-  OWLCMD_ARGS("aexec", owl_command_aexec, OWL_CTX_INTERACTIVE,
-	      "run a command from the shell and display in an admin message",
-	      "aexec [args .. ]", ""),
-
-  OWLCMD_ARGS("pexec", owl_command_pexec, OWL_CTX_INTERACTIVE,
-	      "run a command from the shell and display in a popup window",
-	      "pexec [args .. ]", ""),
-
-  OWLCMD_ARGS("perl", owl_command_perl, OWL_CTX_ANY,
-	      "run a perl expression",
-	      "perl [args .. ]", ""),
-
-  OWLCMD_ARGS("aperl", owl_command_aperl, OWL_CTX_INTERACTIVE,
-	      "run a perl expression and display in an admin message",
-	      "aperl [args .. ]", ""),
-
-  OWLCMD_ARGS("pperl", owl_command_pperl, OWL_CTX_INTERACTIVE,
-	      "run a perl expression and display in a popup window",
-	      "pperl [args .. ]", ""),
-
-  OWLCMD_ARGS("multi", owl_command_multi, OWL_CTX_ANY,
-	      "runs multiple ;-separated commands",
-	      "multi <command1> ( ; <command2> )*\n",
-	      "Runs multiple semicolon-separated commands in order.\n"
-	      "Note quoting isn't supported here yet.\n"
-	      "If you want to do something fancy, use perl.\n"),
-
-  OWLCMD_ARGS("(", owl_command_multi, OWL_CTX_ANY,
-	      "runs multiple ;-separated commands",
-	      "'(' <command1> ( ; <command2> )* ')'\n",
-	      "Runs multiple semicolon-separated commands in order.\n"
-	      "You must have a space before the final ')'\n"
-	      "Note quoting isn't supported here yet.\n"
-	      "If you want to do something fancy, use perl.\n"),
-
-  OWLCMD_VOID("pop-message", owl_command_pop_message, OWL_CTX_RECWIN,
-	      "pops up a message in a window", "", ""),
-
-  OWLCMD_ARGS("zaway", owl_command_zaway, OWL_CTX_INTERACTIVE,
-	      "Set, enable or disable zephyr away message",
-	      "zaway [ on | off | toggle ]\n"
-	      "zaway <message>",
-	      "Turn on or off a zaway message.  If 'message' is\n"
-	      "specified turn on zaway with that message, otherwise\n"
-	      "use the default.\n"),
-
-  OWLCMD_ARGS("aaway", owl_command_aaway, OWL_CTX_INTERACTIVE,
-	      "Set, enable or disable AIM away message",
-	      "aaway [ on | off | toggle ]\n"
-	      "aaway <message>",
-	      "Turn on or off the AIM away message.  If 'message' is\n"
-	      "specified turn on aaway with that message, otherwise\n"
-	      "use the default.\n"),
-
-  OWLCMD_ARGS("away", owl_command_away, OWL_CTX_INTERACTIVE,
-	      "Set, enable or disable both AIM and zephyr away messages",
-	      "away [ on | off | toggle ]\n"
-	      "away <message>",
-	      "Turn on or off the AIM and zephyr away message.  If\n"
-	      "'message' is specified turn them on with that message,\n"
-	      "otherwise use the default.\n"
-	      "\n"
-	      "This command really just runs the 'aaway' and 'zaway'\n"
-	      "commands together\n"
-	      "\n"
-	      "SEE ALSO: aaway, zaway"),
-
-  OWLCMD_ARGS("load-subs", owl_command_loadsubs, OWL_CTX_ANY,
-	      "load subscriptions from a file",
-	      "load-subs <file>\n", ""),
-
-  OWLCMD_ARGS("loadsubs", owl_command_loadsubs, OWL_CTX_ANY,
-	      "load subscriptions from a file",
-	      "loadsubs <file>\n", ""),
-
-  OWLCMD_ARGS("loadloginsubs", owl_command_loadloginsubs, OWL_CTX_ANY,
-	      "load login subscriptions from a file",
-	      "loadloginsubs <file>\n",
-	      "The file should contain a list of usernames, one per line."),
-
-  OWLCMD_VOID("about", owl_command_about, OWL_CTX_INTERACTIVE,
-	      "print information about owl", "", ""),
-
-  OWLCMD_VOID("status", owl_command_status, OWL_CTX_ANY,
-	      "print status information about the running owl", "", ""),
-  
-  OWLCMD_ARGS("zlocate", owl_command_zlocate, OWL_CTX_INTERACTIVE,
-	      "locate a user",
-	      "zlocate [-d] <user> ...", 
-	      "Performs a zlocate on one ore more users and puts the result\n"
-	      "int a popwin.  If -d is specified, does not authenticate\n"
-	      "the lookup request.\n"),
-  
-  OWLCMD_ARGS("filter", owl_command_filter, OWL_CTX_ANY,
-	      "create a message filter",
-	      "filter <name> [ -c fgcolor ] [ -b bgcolor ] [ <expression> ... ]",
-	      "The filter command creates a filter with the specified name,\n"
-	      "or if one already exists it is replaced.  Example filter\n"
-	      "syntax would be:\n\n"
-	      "     filter myfilter -c red ( class ^foobar$ ) or ( class ^quux$ and instance ^bar$ )\n\n"
-	      "Valid matching fields are:\n"
-	      "    sender     -  sender\n"
-	      "    recipient  -  recipient\n"
-	      "    class      -  zephyr class name\n"
-	      "    instance   -  zephyr instance name\n"
-	      "    opcode     -  zephyr opcode\n"
-	      "    realm      -  zephyr realm\n"
-	      "    body       -  message body\n"
-	      "    hostname   -  hostname of sending host\n"
-	      "    type       -  message type (zephyr, aim, admin)\n"
-	      "    direction  -  either 'in' 'out' or 'none'\n"
-	      "    login      -  either 'login' 'logout' or 'none'\n"
-	      "Also you may match on the validity of another filter:\n"
-	      "    filter <filtername>\n"
-	      "Also you may pass the message to a perl function returning 0 or 1,\n"
-	      "where 1 indicates that the function matches the filter:\n"
-	      "    perl <subname>\n"
-	      "Valid operators are:\n"
-	      "    and\n"
-	      "    or\n"
-              "    not\n"
-              "And additionally you may use the static values:\n"
-	      "    true\n"
-	      "    false\n"
-	      "Spaces must be present before and after parentheses.  If the\n"
-	      "optional color arguments are used they specifies the colors that\n"
-	      "messages matching this filter should be displayed in.\n\n"
-	      "SEE ALSO: view, viewclass, viewuser\n"),
-
-  OWLCMD_ARGS("colorview", owl_command_colorview, OWL_CTX_INTERACTIVE,
-	      "change the colors on the current filter",
-	      "colorview <fgcolor> [<bgcolor>]",
-	      "The colors of messages in the current filter will be changed\n"
-	      "to <fgcolor>,<bgcolor>.  Use the 'show colors' command for a list\n"
-	      "of valid colors.\n\n"
-	      "SEE ALSO: 'show colors'\n"),
-
-  OWLCMD_ARGS("colorclass", owl_command_colorclass, OWL_CTX_INTERACTIVE,
-	      "create a filter to color messages of the given class name",
-	      "colorclass <class> <fgcolor> [<bgcolor>]",
-	      "A filter will be created to color messages in <class>"
-	      "in <fgcolor>,<bgcolor>.  Use the 'show colors' command for a list\n"
-	      "of valid colors.\n\n"
-	      "SEE ALSO: 'show colors'\n"),
-
-  OWLCMD_ARGS("view", owl_command_view, OWL_CTX_INTERACTIVE,
-	      "view messages matching a filter",
-	      "view [<viewname>] [-f <filter> | --home | -r ] [-s <style>]\n"
-	      "view <filter>\n"
-	      "view -d <expression>\n"
-	      "view --home",
-	      "The view command sets information associated with a particular view,\n"
-	      "such as view's filter or style.  In the first general usage listed\n"
-	      "above <viewname> is the name of the view to be changed.  If not\n"
-	      "specified the default view 'main' will be used.  A filter can be set\n"
-	      "for the view by listing a named filter after the -f argument.  If\n"
-	      "the --home argument is used the filter will be set to the filter named\n"
-	      "by the\n 'view_home' variable.  The style can be set by listing the\n"
-              "name style after the -s argument.\n"
-	      "\n"
-	      "The other usages listed above are abbreivated forms that simply set\n"
-	      "the filter of the current view. The -d option allows you to write a\n"
-              "filter expression that will be dynamically created by owl and then\n"
-              "applied as the view's filter\n"
-	      "SEE ALSO: filter, viewclass, viewuser\n"),
-
-  OWLCMD_ARGS("smartnarrow", owl_command_smartnarrow, OWL_CTX_INTERACTIVE,
-	      "view only messages similar to the current message",
-	      "smartnarrow [-i | --instance]",
-	      "If the curmsg is a personal message narrow\n"
-	      "   to the conversation with that user.\n"
-	      "If the curmsg is a <MESSAGE, foo, *>\n"
-	      "   message, narrow to the instance.\n"
-	      "If the curmsg is a class message, narrow\n"
-	      "    to the class.\n"
-	      "If the curmsg is a class message and '-i' is specified\n"
-	      "    then narrow to the class and instance.\n"),
-
-  OWLCMD_ARGS("smartfilter", owl_command_smartfilter, OWL_CTX_INTERACTIVE,
-	      "returns the name of a filter based on the current message",
-	      "smartfilter [-i | --instance]",
-	      "If the curmsg is a personal message, the filter is\n"
-	      "   the conversation with that user.\n"
-	      "If the curmsg is a <MESSAGE, foo, *>\n"
-	      "   message, the filter is to that instance.\n"
-	      "If the curmsg is a class message, the filter is that class.\n"
-	      "If the curmsg is a class message and '-i' is specied\n"
-	      "    the filter is to that class and instance.\n"),
-
-  OWLCMD_ARGS("viewclass", owl_command_viewclass, OWL_CTX_INTERACTIVE,
-	      "view messages matching a particular class",
-	      "viewclass <class>",
-	      "The viewclass command will automatically create a filter\n"
-	      "matching the specified class and switch the current view\n"
-	      "to it.\n\n"
-	      "SEE ALSO: filter, view, viewuser\n"),
-  OWLCMD_ALIAS("vc", "viewclass"),
-
-  OWLCMD_ARGS("viewuser", owl_command_viewuser, OWL_CTX_INTERACTIVE,
-	      "view messages matching a particular user",
-	      "viewuser <user>",
-	      "The viewuser command will automatically create a filter\n"
-	      "matching the specified user and switch the current\n"
-	      "view to it.\n\n"
-	      "SEE ALSO: filter, view, viewclass\n"),
-  OWLCMD_ALIAS("vu", "viewuser"),
-
-  OWLCMD_ARGS("show", owl_command_show, OWL_CTX_INTERACTIVE,
-	      "show information",
-	      "show colors\n"
-	      "show commands\n"
-	      "show command <command>\n"
-	      "show errors\n"
-	      "show filters\n"
-	      "show filter <filter>\n"
-	      "show keymaps\n"
-	      "show keymap <keymap>\n"
-	      "show license\n"
-	      "show quickstart\n"
-	      "show startup\n"
-	      "show status\n"
-	      "show styles\n"
-	      "show subscriptions / show subs\n"
-	      "show terminal\n"
-	      "show variables\n"
-	      "show variable <variable>\n"
-	      "show version\n"
-	      "show view [<view>]\n"
-	      "show zpunts\n",
-
-	      "Show colors will display a list of valid colors for the\n"
-	      "     terminal."
-	      "Show filters will list the names of all filters.\n"
-	      "Show filter <filter> will show the definition of a particular\n"
-	      "     filter.\n\n"
-	      "Show startup will display the custom startup config\n\n"
-	      "Show zpunts will show the active zpunt filters.\n\n"
-	      "Show keymaps will list the names of all keymaps.\n"
-	      "Show keymap <keymap> will show the key bindings in a keymap.\n\n"
-	      "Show commands will list the names of all keymaps.\n"
-	      "Show command <command> will provide information about a command.\n\n"
-	      "Show styles will list the names of all styles available\n"
-	      "for formatting messages.\n\n"
-	      "Show variables will list the names of all variables.\n\n"
-	      "Show errors will show a list of errors ecountered by Owl.\n\n"
-	      "SEE ALSO: filter, view, alias, bindkey, help\n"),
-  
-  OWLCMD_ARGS("delete", owl_command_delete, OWL_CTX_INTERACTIVE,
-	      "mark a message for deletion",
-	      "delete [ -id msgid ] [ --no-move ]\n"
-	      "delete view\n"
-	      "delete trash",
-	      "If no message id is specified the current message is marked\n"
-	      "for deletion.  Otherwise the message with the given message\n"
-	      "id is marked for deletion.\n"
-	      "If '--no-move' is specified, don't move after deletion.\n"
-	      "If 'trash' is specified, deletes all trash/auto messages\n"
-	      "in the current view.\n"
-	      "If 'view' is specified, deletes all messages in the\n"
-	      "current view.\n"),
-  OWLCMD_ALIAS("del", "delete"),
-
-  OWLCMD_ARGS("undelete", owl_command_undelete, OWL_CTX_INTERACTIVE,
-	      "unmark a message for deletion",
-	      "undelete [ -id msgid ] [ --no-move ]\n"
-	      "undelete view",
-	      "If no message id is specified the current message is\n"
-	      "unmarked for deletion.  Otherwise the message with the\n"
-	      "given message id is unmarked for deletion.\n"
-	      "If '--no-move' is specified, don't move after deletion.\n"
-	      "If 'view' is specified, undeletes all messages\n"
-	      "in the current view.\n"),
-  OWLCMD_ALIAS("undel", "undelete"),
-
-  OWLCMD_VOID("beep", owl_command_beep, OWL_CTX_ANY,
-	      "ring the terminal bell",
-	      "beep",
-	      "Beep will ring the terminal bell.\n"
-	      "If the variable 'bell' has been\n"
-	      "set to 'off' this command does nothing.\n"),
-
-  OWLCMD_ARGS("debug", owl_command_debug, OWL_CTX_ANY,
-	      "prints a message into the debug log",
-	      "debug <message>", ""),
-
-  OWLCMD_ARGS("getview", owl_command_getview, OWL_CTX_INTERACTIVE,
-	      "returns the name of the filter for the current view",
-	      "", ""),
-
-  OWLCMD_ARGS("getvar", owl_command_getvar, OWL_CTX_INTERACTIVE,
-	      "returns the value of a variable",
-	      "getvar <varname>", ""),
-
-  OWLCMD_ARGS("getfilter", owl_command_getfilter, OWL_CTX_INTERACTIVE,
-	      "returns the definition of a filter",
-	      "getfilter <filtername>", ""),
-
-  OWLCMD_ARGS("getstyle", owl_command_getstyle, OWL_CTX_INTERACTIVE,
-	      "returns the name of the style for the current view",
-	      "", ""),
-
-  OWLCMD_ARGS("search", owl_command_search, OWL_CTX_INTERACTIVE,
-	      "search messages for a particular string",
-	      "search [-r] [<string>]",
-	      "The search command will find messages that contain the\n"
-	      "specified string and move the cursor there.  If no string\n"
-	      "argument is supplied then the previous one is used.  By\n"
-	      "default searches are done forwards; if -r is used the search\n"
-	      "is performed backwards"),
-
-  OWLCMD_ARGS("setsearch", owl_command_setsearch, OWL_CTX_INTERACTIVE,
-	      "set the search highlight string without searching",
-	      "setsearch <string>",
-	      "The setsearch command highlights all occurences of its\n"
-          "argument and makes it the default argument for future\n"
-          "search commands, but does not move the cursor.  With\n"
-          "no argument, it makes search highlighting inactive."),
-
-  OWLCMD_ARGS("aimlogin", owl_command_aimlogin, OWL_CTX_ANY,
-	      "login to an AIM account",
-	      "aimlogin <screenname> [<password>]\n",
-	      ""),
-
-  OWLCMD_ARGS("aimlogout", owl_command_aimlogout, OWL_CTX_ANY,
-	      "logout from AIM",
-	      "aimlogout\n",
-	      ""),
-
-  OWLCMD_ARGS("error", owl_command_error, OWL_CTX_ANY,
-              "Display an error message",
-              "error <message>",
-              ""),
-
-  OWLCMD_ARGS("message", owl_command_message, OWL_CTX_ANY,
-              "Display an informative message",
-              "message <message>",
-              ""),
-
-  OWLCMD_VOID("yes", owl_command_yes, OWL_CTX_RECV,
-              "Answer yes to a question",
-              "yes",
-              ""),
-
-  OWLCMD_VOID("no", owl_command_no, OWL_CTX_RECV,
-              "Answer no to a question",
-              "no",
-              ""),
-
-  /****************************************************************/
-  /************************* EDIT-SPECIFIC ************************/
-  /****************************************************************/
-
-  OWLCMD_VOID_CTX("edit:move-next-word", owl_editwin_move_to_nextword, 
-		  OWL_CTX_EDIT,
-		  "moves cursor forward a word",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:move-prev-word", owl_editwin_move_to_previousword, 
-		  OWL_CTX_EDIT,
-		  "moves cursor backwards a word",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:move-to-buffer-start", owl_editwin_move_to_top,
-		  OWL_CTX_EDIT,
-		  "moves cursor to the top left (start) of the buffer",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:move-to-buffer-end", owl_editwin_move_to_end, 
-		  OWL_CTX_EDIT,
-		  "moves cursor to the bottom right (end) of the buffer",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:move-to-line-end", owl_editwin_move_to_line_end, 
-		  OWL_CTX_EDIT,
-		  "moves cursor to the end of the line",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:move-to-line-start", owl_editwin_move_to_line_start, 
-		  OWL_CTX_EDIT,
-		  "moves cursor to the beginning of the line",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:move-left", owl_editwin_key_left, 
-		  OWL_CTX_EDIT,
-		  "moves the cursor left by a character",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:move-right", owl_editwin_key_right,
-		  OWL_CTX_EDIT,
-		  "moves the cursor right by a character",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:delete-next-word", owl_editwin_delete_nextword,
-		  OWL_CTX_EDIT,
-		  "deletes the word to the right of the cursor",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:delete-prev-word", owl_editwin_delete_previousword,
-		  OWL_CTX_EDIT,
-		  "deletes the word to the left of the cursor",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:delete-prev-char", owl_editwin_backspace,
-		  OWL_CTX_EDIT,
-		  "deletes the character to the left of the cursor",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:delete-next-char", owl_editwin_delete_char, 
-		  OWL_CTX_EDIT,
-		  "deletes the character to the right of the cursor",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:delete-to-line-end", owl_editwin_delete_to_endofline,
-		  OWL_CTX_EDIT,
-		  "deletes from the cursor to the end of the line",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:delete-all", owl_editwin_clear, 
-		  OWL_CTX_EDIT,
-		  "deletes all of the contents of the buffer",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:transpose-chars", owl_editwin_transpose_chars,
-		  OWL_CTX_EDIT,
-		  "Interchange characters around point, moving forward one character.",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:fill-paragraph", owl_editwin_fill_paragraph, 
-		  OWL_CTX_EDIT,
-		  "fills the current paragraph to line-wrap well",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:recenter", owl_editwin_recenter, 
-		  OWL_CTX_EDIT,
-		  "recenters the buffer",
-		  "", ""),
-
-  OWLCMD_ARGS_CTX("edit:insert-text", owl_command_edit_insert_text, 
-		  OWL_CTX_EDIT,
-		  "inserts text into the buffer",
-		  "edit:insert-text <text>", ""),
-
-  OWLCMD_VOID_CTX("edit:cancel", owl_command_edit_cancel, 
-		  OWL_CTX_EDIT,
-		  "cancels the current command",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:history-next", owl_command_edit_history_next, 
-		  OWL_CTX_EDIT,
-		  "replaces the text with the previous history",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("edit:history-prev", owl_command_edit_history_prev, 
-		  OWL_CTX_EDIT,
-		  "replaces the text with the previous history",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("editline:done", owl_command_editline_done, 
-		  OWL_CTX_EDITLINE,
-		  "completes the command (eg, executes command being composed)",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("editresponse:done", owl_command_editresponse_done, 
-		  OWL_CTX_EDITRESPONSE,
-		  "completes the response to a question",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("editmulti:move-up-line", owl_editwin_key_up, 
-		  OWL_CTX_EDITMULTI,
-		  "moves the cursor up one line",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("editmulti:move-down-line", owl_editwin_key_down, 
-		  OWL_CTX_EDITMULTI,
-		  "moves the cursor down one line",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("editmulti:done", owl_command_editmulti_done, 
-		  OWL_CTX_EDITMULTI,
-		  "completes the command (eg, sends message being composed)",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("editmulti:done-or-delete", owl_command_editmulti_done_or_delete, 
-		  OWL_CTX_EDITMULTI,
-		  "completes the command, but only if at end of message",
-		  "", 
-		  "If only whitespace is to the right of the cursor,\n"
-		  "runs 'editmulti:done'.\n"\
-		  "Otherwise runs 'edit:delete-next-char'\n"),
-
-  /****************************************************************/
-  /********************** POPLESS-SPECIFIC ************************/
-  /****************************************************************/
-
-  OWLCMD_VOID_CTX("popless:scroll-down-page", owl_viewwin_pagedown, 
-		  OWL_CTX_POPLESS,
-		  "scrolls down one page",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("popless:scroll-down-line", owl_viewwin_linedown, 
-		  OWL_CTX_POPLESS,
-		  "scrolls down one line",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("popless:scroll-up-page", owl_viewwin_pageup, 
-		  OWL_CTX_POPLESS,
-		  "scrolls up one page",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("popless:scroll-up-line", owl_viewwin_lineup, 
-		  OWL_CTX_POPLESS,
-		  "scrolls up one line",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("popless:scroll-to-top", owl_viewwin_top, 
-		  OWL_CTX_POPLESS,
-		  "scrolls to the top of the buffer",
-		  "", ""),
-
-  OWLCMD_VOID_CTX("popless:scroll-to-bottom", owl_viewwin_bottom, 
-		  OWL_CTX_POPLESS,
-		  "scrolls to the bottom of the buffer",
-		  "", ""),
-
-  OWLCMD_INT_CTX ("popless:scroll-right", owl_viewwin_right, 
-		  OWL_CTX_POPLESS,
-		  "scrolls right in the buffer",
-		  "popless:scroll-right <num-chars>", ""),
-
-  OWLCMD_INT_CTX ("popless:scroll-left", owl_viewwin_left, 
-		  OWL_CTX_POPLESS,
-		  "scrolls left in the buffer",
-		  "popless:scroll-left <num-chars>", ""),
-
-  OWLCMD_VOID_CTX("popless:quit", owl_command_popless_quit, 
-		  OWL_CTX_POPLESS,
-		  "exits the popless window",
-		  "", ""),
-
-  OWLCMD_ALIAS("webzephyr", "zwrite daemon.webzephyr -c webzephyr -i"),
-
-  /* This line MUST be last! */
-  { NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
-
-};
-
-void owl_command_info()
-{
-  owl_function_info();
-}
-
-void owl_command_nop()
-{
-}
-
-char *owl_command_help(int argc, char **argv, char *buff)
-{
-  if (argc!=2) {
-    owl_help();
-    return NULL;
-  }
-  
-  owl_function_help_for_command(argv[1]);
-  return NULL;
-}
-
-char *owl_command_zlist(int argc, char **argv, char *buff)
-{
-  int elapsed=0, timesort=0;
-  char *file=NULL;
-
-  argc--;
-  argv++;
-  while (argc) {
-    if (!strcmp(argv[0], "-e")) {
-      elapsed=1;
-      argc--;
-      argv++;
-    } else if (!strcmp(argv[0], "-t")) {
-      timesort=1;
-      argc--;
-      argv++;
-    } else if (!strcmp(argv[0], "-f")) {
-      if (argc==1) {
-	owl_function_makemsg("zlist: -f needs an argument");
-	return(NULL);
-      }
-      file=argv[1];
-      argc-=2;
-      argv+=2;
-    } else {
-      owl_function_makemsg("zlist: unknown argument");
-      return(NULL);
-    }
-  }
-  owl_function_buddylist(0, 1, file);
-  return(NULL);
-}
-
-char *owl_command_alist()
-{
-  owl_function_buddylist(1, 0, NULL);
-  return(NULL);
-}
-
-char *owl_command_blist()
-{
-  owl_function_buddylist(1, 1, NULL);
-  return(NULL);
-}
-
-char *owl_command_toggleoneline()
-{
-  owl_function_toggleoneline();
-  return(NULL);
-}
-
-void owl_command_about()
-{
-  owl_function_about();
-}
-
-void owl_command_version()
-{
-  owl_function_makemsg("BarnOwl version %s", OWL_VERSION_STRING);
-}
-
-char *owl_command_aim(int argc, char **argv, char *buff)
-{
-  if (argc<2) {
-    owl_function_makemsg("not enough arguments to aim command");
-    return(NULL);
-  }
-
-  if (!strcmp(argv[1], "search")) {
-    if (argc!=3) {
-      owl_function_makemsg("not enough arguments to aim search command");
-      return(NULL);
-    }
-    owl_aim_search(argv[2]);
-  } else {
-    owl_function_makemsg("unknown subcommand '%s' for aim command", argv[1]);
-    return(NULL);
-  }
-  return(NULL);
-}
-
-char *owl_command_addbuddy(int argc, char **argv, char *buff)
-{
-  if (argc!=3) {
-    owl_function_makemsg("usage: addbuddy <protocol> <buddyname>");
-    return(NULL);
-  }
-
-  if (!strcasecmp(argv[1], "aim")) {
-    if (!owl_global_is_aimloggedin(&g)) {
-      owl_function_makemsg("addbuddy: You must be logged into aim to use this command.");
-      return(NULL);
-    }
-    /*
-    owl_function_makemsg("This function is not yet operational.  Stay tuned.");
-    return(NULL);
-    */
-    owl_aim_addbuddy(argv[2]);
-    owl_function_makemsg("%s added as AIM buddy for %s", argv[2], owl_global_get_aim_screenname(&g));
-  } else if (!strcasecmp(argv[1], "zephyr")) {
-    owl_zephyr_addbuddy(argv[2]);
-    owl_function_makemsg("%s added as zephyr buddy", argv[2]);
-  } else {
-    owl_function_makemsg("addbuddy: currently the only supported protocols are 'zephyr' and 'aim'");
-  }
-
-  return(NULL);
-}
-
-char *owl_command_delbuddy(int argc, char **argv, char *buff)
-{
-  if (argc!=3) {
-    owl_function_makemsg("usage: delbuddy <protocol> <buddyname>");
-    return(NULL);
-  }
-
-  if (!strcasecmp(argv[1], "aim")) {
-    if (!owl_global_is_aimloggedin(&g)) {
-      owl_function_makemsg("delbuddy: You must be logged into aim to use this command.");
-      return(NULL);
-    }
-    owl_aim_delbuddy(argv[2]);
-    owl_function_makemsg("%s deleted as AIM buddy for %s", argv[2], owl_global_get_aim_screenname(&g));
-  } else if (!strcasecmp(argv[1], "zephyr")) {
-    owl_zephyr_delbuddy(argv[2]);
-    owl_function_makemsg("%s deleted as zephyr buddy", argv[2]);
-  } else {
-    owl_function_makemsg("delbuddy: currently the only supported protocols are 'zephyr' and 'aim'");
-  }
-
-  return(NULL);
-}
-
-char *owl_command_join(int argc, char **argv, char *buff)
-{
-  if (argc!=3 && argc!=4) {
-    owl_function_makemsg("usage: join <protocol> <buddyname> [exchange]");
-    return(NULL);
-  }
-
-  if (!strcasecmp(argv[1], "aim")) {
-    if (!owl_global_is_aimloggedin(&g)) {
-      owl_function_makemsg("join aim: You must be logged into aim to use this command.");
-      return(NULL);
-    }
-    if (argc==3) {
-      owl_aim_chat_join(argv[2], 4);
-    } else {
-      owl_aim_chat_join(argv[2], atoi(argv[3]));
-    }
-    /* owl_function_makemsg("%s deleted as AIM buddy for %s", argv[2], owl_global_get_aim_screenname(&g)); */
-  } else {
-    owl_function_makemsg("join: currently the only supported protocol is 'aim'");
-  }
-  return(NULL);
-}
-
-char *owl_command_startup(int argc, char **argv, char *buff)
-{
-  char *ptr;
-
-  if (argc<2) {
-    owl_function_makemsg("usage: %s <commands> ...", argv[0]);
-    return(NULL);
-  }
-
-  ptr=strchr(buff, ' ');
-  if (!ptr) {
-    owl_function_makemsg("Parse error finding command for startup");
-    return(NULL);
-  }
-
-  owl_function_command(ptr+1);
-  owl_function_addstartup(ptr+1);
-
-  return(NULL);
-}
-
-char *owl_command_unstartup(int argc, char **argv, char *buff)
-{
-  char *ptr;
-
-  if (argc<2) {
-    owl_function_makemsg("usage: %s <commands> ...", argv[0]);
-    return(NULL);
-  }
-
-  ptr=strchr(buff, ' ');
-  if (!ptr) {
-    owl_function_makemsg("Parse error finding command for unstartup");
-    return(NULL);
-  }
-
-  owl_function_delstartup(ptr+1);
-
-  return(NULL);
-}
-
-char *owl_command_dump(int argc, char **argv, char *buff)
-{
-  char *filename;
-  
-  if (argc!=2) {
-    owl_function_makemsg("usage: dump <filename>");
-    return(NULL);
-  }
-  filename=owl_util_makepath(argv[1]);
-  owl_function_dump(filename);
-  owl_free(filename);
-  return(NULL);
-}
-
-char *owl_command_source(int argc, char **argv, char *buff)
-{
-  if (argc!=2) {
-    owl_function_makemsg("usage: source <filename>");
-    return(NULL);
-  }
-
-  owl_function_source(argv[1]);
-  return(NULL);
-}
-
-char *owl_command_next(int argc, char **argv, char *buff)
-{
-  char *filter=NULL;
-  int skip_deleted=0, last_if_none=0;
-  while (argc>1) {
-    if (argc>=1 && !strcmp(argv[1], "--skip-deleted")) {
-      skip_deleted=1;
-      argc-=1; argv+=1; 
-    } else if (argc>=1 && !strcmp(argv[1], "--last-if-none")) {
-      last_if_none=1;
-      argc-=1; argv+=1; 
-    } else if (argc>=2 && !strcmp(argv[1], "--filter")) {
-      filter = owl_strdup(argv[2]);
-      argc-=2; argv+=2; 
-    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter")) {
-      filter = owl_function_smartfilter(0);
-      argc-=2; argv+=2; 
-    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter-instance")) {
-      filter = owl_function_smartfilter(1);
-      argc-=2; argv+=2; 
-    } else {
-      owl_function_makemsg("Invalid arguments to command 'next'.");
-      return(NULL);
-    }
-  }
-  owl_function_nextmsg_full(filter, skip_deleted, last_if_none);
-  if (filter) owl_free(filter);
-  return(NULL);
-}
-
-char *owl_command_prev(int argc, char **argv, char *buff)
-{
-  char *filter=NULL;
-  int skip_deleted=0, first_if_none=0;
-  while (argc>1) {
-    if (argc>=1 && !strcmp(argv[1], "--skip-deleted")) {
-      skip_deleted=1;
-      argc-=1; argv+=1; 
-    } else if (argc>=1 && !strcmp(argv[1], "--first-if-none")) {
-      first_if_none=1;
-      argc-=1; argv+=1; 
-    } else if (argc>=2 && !strcmp(argv[1], "--filter")) {
-      filter = owl_strdup(argv[2]);
-      argc-=2; argv+=2; 
-    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter")) {
-      filter = owl_function_smartfilter(0);
-      argc-=2; argv+=2; 
-    } else if (argc>=2 && !strcmp(argv[1], "--smart-filter-instance")) {
-      filter = owl_function_smartfilter(1);
-      argc-=2; argv+=2;  
-   } else {
-      owl_function_makemsg("Invalid arguments to command 'prev'.");
-      return(NULL);
-    }
-  }
-  owl_function_prevmsg_full(filter, skip_deleted, first_if_none);
-  if (filter) owl_free(filter);
-  return(NULL);
-}
-
-char *owl_command_smartnarrow(int argc, char **argv, char *buff)
-{
-  char *filtname = NULL;
-
-  if (argc == 1) {
-    filtname = owl_function_smartfilter(0);
-  } else if (argc == 2 && (!strcmp(argv[1], "-i") || !strcmp(argv[1], "--instance"))) {
-    filtname = owl_function_smartfilter(1);
-  } else {
-    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);    
-  }
-  if (filtname) {
-    owl_function_change_currentview_filter(filtname);
-    owl_free(filtname);
-  }
-  return NULL;
-}
-
-char *owl_command_smartfilter(int argc, char **argv, char *buff)
-{
-  char *filtname = NULL;
-
-  if (argc == 1) {
-    filtname = owl_function_smartfilter(0);
-  } else if (argc == 2 && (!strcmp(argv[1], "-i") || !strcmp(argv[1], "--instance"))) {
-    filtname = owl_function_smartfilter(1);
-  } else {
-    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);    
-  }
-  return filtname;
-}
-
-void owl_command_expunge()
-{
-  owl_function_expunge();
-}
-
-void owl_command_first()
-{
-  owl_global_set_rightshift(&g, 0);
-  owl_function_firstmsg();
-}
-
-void owl_command_last()
-{
-  owl_function_lastmsg();
-}
-
-void owl_command_resize()
-{
-  owl_function_resize();
-}
-
-void owl_command_redisplay()
-{
-  owl_function_full_redisplay();
-  owl_global_set_needrefresh(&g);
-}
-
-void owl_command_shift_right()
-{
-  owl_function_shift_right();
-}
-
-void owl_command_shift_left()
-{
-  owl_function_shift_left();
-}
-
-void owl_command_unsuball()
-{
-  owl_function_unsuball();
-}
-
-char *owl_command_loadsubs(int argc, char **argv, char *buff)
-{
-  if (argc == 2) {
-    owl_function_loadsubs(argv[1]);
-  } else if (argc == 1) {
-    owl_function_loadsubs(NULL);
-  } else {
-    owl_function_makemsg("Wrong number of arguments for load-subs.");
-    return(NULL);
-  }
-  return(NULL);
-}
-
-
-char *owl_command_loadloginsubs(int argc, char **argv, char *buff)
-{
-  if (argc == 2) {
-    owl_function_loadloginsubs(argv[1]);
-  } else if (argc == 1) {
-    owl_function_loadloginsubs(NULL);
-  } else {
-    owl_function_makemsg("Wrong number of arguments for load-subs.");
-    return(NULL);
-  }
-  return(NULL);
-}
-
-void owl_command_suspend()
-{
-  owl_function_suspend();
-}
-
-char *owl_command_start_command(int argc, char **argv, char *buff)
-{
-  buff = skiptokens(buff, 1);
-  owl_function_start_command(buff);
-  return(NULL);
-}
-
-char *owl_command_start_question(int argc, char **argv, char *buff)
-{
-  buff = skiptokens(buff, 1);
-  owl_function_start_question(buff);
-  return(NULL);
-}
-
-char *owl_command_start_password(int argc, char **argv, char *buff)
-{
-  buff = skiptokens(buff, 1);
-  owl_function_start_password(buff);
-  return(NULL);
-}
-
-char *owl_command_zaway(int argc, char **argv, char *buff)
-{
-  if ((argc==1) ||
-      ((argc==2) && !strcmp(argv[1], "on"))) {
-    owl_global_set_zaway_msg(&g, owl_global_get_zaway_msg_default(&g));
-    owl_function_zaway_on();
-    return NULL;
-  }
-
-  if (argc==2 && !strcmp(argv[1], "off")) {
-    owl_function_zaway_off();
-    return NULL;
-  }
-
-  if (argc==2 && !strcmp(argv[1], "toggle")) {
-    owl_function_zaway_toggle();
-    return NULL;
-  }
-
-  buff = skiptokens(buff, 1);
-  owl_global_set_zaway_msg(&g, buff);
-  owl_function_zaway_on();
-  return NULL;
-}
-
-
-char *owl_command_aaway(int argc, char **argv, char *buff)
-{
-  if ((argc==1) ||
-      ((argc==2) && !strcmp(argv[1], "on"))) {
-    owl_global_set_aaway_msg(&g, owl_global_get_aaway_msg_default(&g));
-    owl_function_aaway_on();
-    return NULL;
-  }
-
-  if (argc==2 && !strcmp(argv[1], "off")) {
-    owl_function_aaway_off();
-    return NULL;
-  }
-
-  if (argc==2 && !strcmp(argv[1], "toggle")) {
-    owl_function_aaway_toggle();
-    return NULL;
-  }
-
-  buff = skiptokens(buff, 1);
-  owl_global_set_aaway_msg(&g, buff);
-  owl_function_aaway_on();
-  return NULL;
-}
-
-
-char *owl_command_away(int argc, char **argv, char *buff)
-{
-  if ((argc==1) ||
-      ((argc==2) && !strcmp(argv[1], "on"))) {
-    owl_global_set_aaway_msg(&g, owl_global_get_aaway_msg_default(&g));
-    owl_global_set_zaway_msg(&g, owl_global_get_zaway_msg_default(&g));
-    owl_function_aaway_on();
-    owl_function_zaway_on();
-    owl_function_makemsg("Away messages set.");
-    return NULL;
-  }
-
-  if (argc==2 && !strcmp(argv[1], "off")) {
-    owl_function_aaway_off();
-    owl_function_zaway_off();
-    return NULL;
-  }
-
-  if (argc==2 && !strcmp(argv[1], "toggle")) {
-    /* if either one is on, turn it off, otherwise toggle both (turn
-     *  them both on)
-     */
-    if (!owl_global_is_zaway(&g) && !owl_global_is_aaway(&g)) {
-      owl_function_aaway_toggle();
-      owl_function_zaway_toggle();
-      owl_function_makemsg("Away messages set.");
-    } else {
-      if (owl_global_is_zaway(&g)) owl_function_zaway_toggle();
-      if (owl_global_is_aaway(&g)) owl_function_aaway_toggle();
-      owl_function_makemsg("Away messages off.");
-    }
-    return NULL;
-  }
-
-  buff = skiptokens(buff, 1);
-  owl_global_set_aaway_msg(&g, buff);
-  owl_global_set_zaway_msg(&g, buff);
-  owl_function_aaway_on();
-  owl_function_zaway_on();
-  owl_function_makemsg("Away messages set.");
-  return NULL;
-}
-
-char *owl_command_set(int argc, char **argv, char *buff)
-{
-  char *var, *val;
-  int  silent=0;
-  int requirebool=0;
-
-  if (argc == 1) {
-    owl_function_printallvars();
-    return NULL;
-  } 
-
-  if (argc > 1 && !strcmp("-q",argv[1])) {
-    silent = 1;
-    argc--; argv++;
-  }
-
-  if (argc == 2) {
-    var=argv[1];
-    val="on";
-    requirebool=1;
-  } else if (argc == 3) {
-    var=argv[1];
-    val=argv[2];
-  } else {
-    owl_function_makemsg("Wrong number of arguments for set command");
-    return NULL;
-  }
-  owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent, requirebool);
-  return NULL;
-}
-
-char *owl_command_unset(int argc, char **argv, char *buff)
-{
-  char *var, *val;
-  int  silent=0;
-
-  if (argc > 1 && !strcmp("-q",argv[1])) {
-    silent = 1;
-    argc--; argv++;
-  }
-  if (argc == 2) {
-    var=argv[1];
-    val="off";
-  } else {
-    owl_function_makemsg("Wrong number of arguments for unset command");
-    return NULL;
-  }
-  owl_variable_set_fromstring(owl_global_get_vardict(&g), var, val, !silent, 1);
-  return NULL;
-}
-
-char *owl_command_print(int argc, char **argv, char *buff)
-{
-  char *var;
-  char valbuff[1024];
-
-  if (argc==1) {
-    owl_function_printallvars();
-    return NULL;
-  } else if (argc!=2) {
-    owl_function_makemsg("Wrong number of arguments for print command");
-    return NULL;
-  }
-
-  var=argv[1];
-    
-  if (0 == owl_variable_get_tostring(owl_global_get_vardict(&g), 
-				     var, valbuff, 1024)) {
-    owl_function_makemsg("%s = '%s'", var, valbuff);
-  } else {
-    owl_function_makemsg("Unknown variable '%s'.", var);
-  }
-  return NULL;
-}
-
-
-char *owl_command_exec(int argc, char **argv, char *buff)
-{
-  return owl_function_exec(argc, argv, buff, 0);
-}
-
-char *owl_command_pexec(int argc, char **argv, char *buff)
-{
-  return owl_function_exec(argc, argv, buff, 1);
-}
-
-char *owl_command_aexec(int argc, char **argv, char *buff)
-{
-  return owl_function_exec(argc, argv, buff, 2);
-}
-
-char *owl_command_perl(int argc, char **argv, char *buff)
-{
-  return owl_function_perl(argc, argv, buff, 0);
-}
-
-char *owl_command_pperl(int argc, char **argv, char *buff)
-{
-  return owl_function_perl(argc, argv, buff, 1);
-}
-
-char *owl_command_aperl(int argc, char **argv, char *buff)
-{
-  return owl_function_perl(argc, argv, buff, 2);
-}
-
-char *owl_command_multi(int argc, char **argv, char *buff)
-{
-  char *lastrv = NULL, *dupbuff, *newbuff;
-  char **commands;
-  int  ncommands, i;
-  if (argc < 2) {
-    owl_function_makemsg("Invalid arguments to 'multi' command.");    
-    return NULL;
-  }
-  dupbuff = owl_strdup(buff);
-  newbuff = skiptokens(dupbuff, 1);
-  if (!strcmp(argv[0], "(")) {
-    for (i=strlen(newbuff)-1; i>=0; i--) {
-      if (newbuff[i] == ')') {
-	newbuff[i] = '\0';
-	break;
-      } else if (newbuff[i] != ' ') {
-	owl_function_makemsg("Invalid arguments to 'multi' command.");    
-	owl_free(newbuff);
-	return NULL;
-      }
-    }
-  }
-  commands = atokenize(newbuff, ";", &ncommands);
-  for (i=0; i<ncommands; i++) {
-    if (lastrv) {
-      owl_free(lastrv);
-    }
-    lastrv = owl_function_command(commands[i]);
-  }
-  owl_free(dupbuff);
-  atokenize_free(commands, ncommands);
-  return lastrv;
-}
-
-
-char *owl_command_alias(int argc, char **argv, char *buff)
-{
-  if (argc < 3) {
-    owl_function_makemsg("Invalid arguments to 'alias' command.");
-    return NULL;
-  }
-  buff = skiptokens(buff, 2);
-  owl_function_command_alias(argv[1], buff);
-  return (NULL);
-}
-
-
-char *owl_command_bindkey(int argc, char **argv, char *buff)
-{
-  owl_keymap *km;
-  int ret;
-
-  if (argc < 5 || strcmp(argv[3], "command")) {
-    owl_function_makemsg("Usage: bindkey <keymap> <binding> command <cmd>");
-    return NULL;
-  }
-  km = owl_keyhandler_get_keymap(owl_global_get_keyhandler(&g), argv[1]);
-  if (!km) {
-    owl_function_makemsg("No such keymap '%s'", argv[1]);
-    return NULL;
-  }
-  buff = skiptokens(buff, 4);
-  ret = owl_keymap_create_binding(km, argv[2], buff, NULL, "*user*");
-  if (ret!=0) {
-    owl_function_makemsg("Unable to bind '%s' in keymap '%s' to '%s'.",
-			 argv[2], argv[1], buff);
-    return NULL;
-  }
-  return NULL;
-}
-
-void owl_command_quit()
-{
-  owl_function_quit();
-}
-
-char *owl_command_debug(int argc, char **argv, char *buff)
-{
-  if (argc<2) {
-    owl_function_makemsg("Need at least one argument to debug command");
-    return(NULL);
-  }
-
-  if (!owl_global_is_debug_fast(&g)) {
-    owl_function_makemsg("Debugging is not turned on");
-    return(NULL);
-  }
-
-  owl_function_debugmsg("%s", argv[1]);
-  return(NULL);
-}
-
-char *owl_command_term(int argc, char **argv, char *buff)
-{
-  if (argc<2) {
-    owl_function_makemsg("Need at least one argument to the term command");
-    return(NULL);
-  }
-
-  if (!strcmp(argv[1], "raise")) {
-    owl_function_xterm_raise();
-  } else if (!strcmp(argv[1], "deiconify")) {
-    owl_function_xterm_deiconify();
-  } else {
-    owl_function_makemsg("Unknown terminal subcommand");
-  }
-  return(NULL);
-}
-
-char *owl_command_zlog(int argc, char **argv, char *buff)
-{
-  if ((argc<2) || (argc>3)) {
-    owl_function_makemsg("Wrong number of arguments for zlog command");
-    return(NULL);
-  }
-
-  if (!strcmp(argv[1], "in")) {
-    if (argc>2) {
-      owl_global_set_tty(&g, argv[2]);
-    }
-    owl_zephyr_zlog_in();
-  } else if (!strcmp(argv[1], "out")) {
-    if (argc!=2) {
-      owl_function_makemsg("Wrong number of arguments for zlog command");
-      return(NULL);
-    }
-    owl_zephyr_zlog_out();
-  } else {
-    owl_function_makemsg("Invalid subcommand for zlog");
-  }
-  return(NULL);
-}
-
-
-void owl_command_zlog_out(void)
-{
-  owl_zephyr_zlog_out();
-}
-
-
-char *owl_command_subscribe(int argc, char **argv, char *buff)
-{
-  char *class, *instance, *recip="";
-  int temp=0;
-  int ret=0;
-
-  if (argc < 2) {
-    owl_function_makemsg("Not enough arguments to the subscribe command");
-    return(NULL);
-  }
-  argc--;
-  argv++;
-
-  if (!strcmp(argv[0], "-t")) {
-    temp=1;
-    argc--;
-    argv++;
-  }
-  if (argc < 1) {
-    owl_function_makemsg("Not enough arguments to the subscribe command");
-    return(NULL);
-  }
-
-  if (argc > 3) {
-    owl_function_makemsg("Too many arguments to the subscribe command");
-    return(NULL);
-  }
-
-  class = argv[0];
-
-  if (argc == 1) {
-    instance = "*";
-  } else {
-    instance = argv[1];
-  }
-
-  if (argc <= 2) {
-    recip="";
-  } else if (argc==3) {
-    recip=argv[2];
-  }
-
-  ret = owl_function_subscribe(class, instance, recip);
-  if (!temp && !ret) {
-    owl_zephyr_addsub(NULL, class, instance, recip);
-  }
-  return(NULL);
-}
-
-
-char *owl_command_unsubscribe(int argc, char **argv, char *buff)
-{
-  char *class, *instance, *recip="";
-  int temp=0;
-
-  if (argc < 2) {
-    owl_function_makemsg("Not enough arguments to the unsubscribe command");
-    return(NULL);
-  }
-  argc--;
-  argv++;
-
-  if (!strcmp(argv[0], "-t")) {
-    temp=1;
-    argc--;
-    argv++;
-  }
-  if (argc < 1) {
-    owl_function_makemsg("Not enough arguments to the unsubscribe command");
-    return(NULL);
-  }
-
-  if (argc > 3) {
-    owl_function_makemsg("Too many arguments to the unsubscribe command");
-    return(NULL);
-  }
-
-  class = argv[0];
-
-  if (argc == 1) {
-    instance = "*";
-  } else {
-    instance = argv[1];
-  }
-
-  if (argc <= 2) {
-    recip="";
-  } else if (argc==3) {
-    recip=argv[2];
-  }
-
-  owl_function_unsubscribe(class, instance, recip);
-  if (!temp) {
-    owl_zephyr_delsub(NULL, class, instance, recip);
-  }
-  return(NULL);
-}
-
-char *owl_command_echo(int argc, char **argv, char *buff)
-{
-  buff = skiptokens(buff, 1);
-  owl_function_popless_text(buff);
-  return NULL;
-}
-
-void owl_command_getsubs(void)
-{
-  owl_function_getsubs();
-}
-
-void owl_command_status(void)
-{
-  owl_function_status();
-}
-
-char *owl_command_zwrite(int argc, char **argv, char *buff)
-{
-  owl_zwrite z;
-
-  if (!owl_global_is_havezephyr(&g)) {
-    owl_function_makemsg("Zephyr is not available");
-    return(NULL);
-  }
-  /* check for a zwrite -m */
-  owl_zwrite_create_from_line(&z, buff);
-  if (owl_zwrite_is_message_set(&z)) {
-    owl_function_zwrite(buff, NULL);
-    owl_zwrite_free(&z);
-    return (NULL);
-  }
-
-  if (argc < 2) {
-    owl_function_makemsg("Not enough arguments to the zwrite command.");
-  } else {
-    owl_function_zwrite_setup(buff);
-  }
-  return(NULL);
-}
-
-char *owl_command_aimwrite(int argc, char **argv, char *buff)
-{
-  char *newbuff, *recip, **myargv;
-  int i, j, myargc;
-  owl_message *m;
-  
-  if (!owl_global_is_aimloggedin(&g)) {
-    owl_function_makemsg("You are not logged in to AIM.");
-    return(NULL);
-  }
-
-  if (argc < 2) {
-    owl_function_makemsg("Not enough arguments to the aimwrite command.");
-    return(NULL);
-  }
-
-  myargv=argv;
-  if (argc<0) {
-    owl_function_error("Unbalanced quotes in aimwrite");
-    return(NULL);
-  }
-  myargc=argc;
-  if (myargc && *(myargv[0])!='-') {
-    myargc--;
-    myargv++;
-  }
-  while (myargc) {
-    if (!strcmp(myargv[0], "-m")) {
-      if (myargc<2) {
-	break;
-      }
-
-      /* Once we have -m, gobble up everything else on the line */
-      myargv++;
-      myargc--;
-      newbuff=owl_malloc(1);
-      newbuff=owl_strdup("");
-      while (myargc) {
-	newbuff=realloc(newbuff, strlen(newbuff)+strlen(myargv[0])+5);
-	strcat(newbuff, myargv[0]);
-	strcat(newbuff, " ");
-	myargc--;
-	myargv++;
-      }
-      newbuff[strlen(newbuff)-1]='\0'; /* remove last space */
-
-      recip=owl_malloc(strlen(argv[0])+5);
-      sprintf(recip, "%s ", argv[1]);
-      owl_aim_send_im(recip, newbuff);
-      m=owl_function_make_outgoing_aim(newbuff, recip);
-      if (m) { 
-          owl_global_messagequeue_addmsg(&g, m);
-      } else {
-          owl_function_error("Could not create outgoing AIM message");
-      }
-
-      owl_free(recip);
-      owl_free(newbuff);
-      return(NULL);
-    } else {
-      /* we don't care */
-      myargv++;
-      myargc--;
-    }
-  }
-
-  /* squish arguments together to make one screenname w/o spaces for now */
-  newbuff=owl_malloc(strlen(buff)+5);
-  sprintf(newbuff, "%s ", argv[0]);
-  j=argc-1;
-  for (i=0; i<j; i++) {
-    strcat(newbuff, argv[i+1]);
-  }
-    
-  owl_function_aimwrite_setup(newbuff);
-  owl_free(newbuff);
-  return(NULL);
-}
-
-char *owl_command_loopwrite(int argc, char **argv, char *buff)
-{
-  owl_function_loopwrite_setup();
-  return(NULL);
-}
-
-char *owl_command_zcrypt(int argc, char **argv, char *buff)
-{
-#ifdef OWL_ENABLE_ZCRYPT
-  owl_zwrite z;
-
-  if (!owl_global_is_havezephyr(&g)) {
-    owl_function_makemsg("Zephyr is not available");
-    return(NULL);
-  }
-  /* check for a zcrypt -m */
-  owl_zwrite_create_from_line(&z, buff);
-  if (owl_zwrite_is_message_set(&z)) {
-    owl_function_zcrypt(buff, NULL);
-    owl_zwrite_free(&z);
-    return (NULL);
-  }
-
-  if (argc < 2) {
-    owl_function_makemsg("Not enough arguments to the zcrypt command.");
-  } else {
-    owl_function_zwrite_setup(buff);
-  }
-  return(NULL);
-#else
-  owl_function_makemsg("This Owl does not support zcrypt");
-#endif
-}
-
-char *owl_command_reply(int argc, char **argv, char *buff)
-{
-  int edit=0;
-  
-  if (argc>=2 && !strcmp("-e", argv[1])) {
-    edit=1;
-    argv++;
-    argc--;
-  }
-
-  if ((argc==1) || (argc==2 && !strcmp(argv[1], "all"))) {    
-    owl_function_reply(0, !edit);
-  } else if (argc==2 && !strcmp(argv[1], "sender")) {
-    owl_function_reply(1, !edit);
-  } else if (argc==2 && !strcmp(argv[1], "zaway")) {
-    owl_message *m;
-    owl_view    *v;
-    v = owl_global_get_current_view(&g);    
-    m = owl_view_get_element(v, owl_global_get_curmsg(&g));
-    if (m) owl_zephyr_zaway(m);
-  } else {
-    owl_function_makemsg("Invalid arguments to the reply command.");
-  }
-  return NULL;
-}
-
-char *owl_command_filter(int argc, char **argv, char *buff)
-{
-  owl_function_create_filter(argc, argv);
-  return NULL;
-}
-
-char *owl_command_zlocate(int argc, char **argv, char *buff)
-{
-  int auth;
-  
-  if (argc<2) {
-    owl_function_makemsg("Too few arguments for zlocate command");
-    return NULL;
-  }
-
-  auth=1;
-  if (!strcmp(argv[1], "-d")) {
-    if (argc>2) {
-      auth=0;
-      argc--;
-      argv++;
-    } else {
-      owl_function_makemsg("Missing arguments for zlocate command");
-      return NULL;
-    }
-  }
-
-  argc--;
-  argv++;
-  owl_function_zlocate(argc, argv, auth);
-  return NULL;
-}
-
-
-/* Backwards compatability has made this kind of complicated:
- * view [<viewname>] [-f <filter> | -d <expression> | --home | -r ] [-s <style>]
- * view <filter>
- * view -d <expression>
- * view --home
- */
-char *owl_command_view(int argc, char **argv, char *buff)
-{
-  /* First take the 'view --home' and 'view -r' cases */
-  if (argc == 2) {
-    if (!strcmp(argv[1], "--home")) {
-      owl_function_change_currentview_filter(owl_global_get_view_home(&g));
-      return(NULL);
-    } else if (!strcmp(argv[1], "-r")) {
-      char *foo;
-      foo=owl_function_create_negative_filter(owl_view_get_filtname(owl_global_get_current_view(&g)));
-      owl_function_change_currentview_filter(foo);
-      owl_free(foo);
-      return(NULL);
-    }
-  }
-
-  /* Now look for 'view <filter>' */
-  if (argc==2) {
-    owl_function_change_currentview_filter(argv[1]);
-    return(NULL);
-  }
-
-  /* Now get 'view -d <expression>' */
-  if (argc>=3 && !strcmp(argv[1], "-d")) {
-    char **myargv;
-    int i;
-
-    myargv=owl_malloc((argc*sizeof(char *))+50);
-    myargv[0]="";
-    myargv[1]="owl-dynamic";
-    for (i=2; i<argc; i++) {
-      myargv[i]=argv[i];
-    }
-    owl_function_create_filter(argc, myargv);
-    owl_function_change_currentview_filter("owl-dynamic");
-    owl_free(myargv);
-    return NULL;
-  }
-
-  /* Finally handle the general case */
-  if (argc<3) {
-    owl_function_makemsg("Too few arguments to the view command.");
-    return(NULL);
-  }
-  argc--;
-  argv++;
-  if (strcmp(argv[0], "-f") &&
-      strcmp(argv[0], "-d") &&
-      strcmp(argv[0], "--home") &&
-      strcmp(argv[0], "-s") &&
-      strcmp(argv[0], "-r")) {
-    if (strcmp(argv[0], "main")) {
-      owl_function_makemsg("No view named '%s'", argv[0]);
-      return(NULL);
-    }
-    argc--;
-    argv++;
-  }
-  while (argc) {
-    if (!strcmp(argv[0], "-f")) {
-      if (argc<2) {
-	owl_function_makemsg("Too few argments to the view command");
-	return(NULL);
-      }
-      owl_function_change_currentview_filter(argv[1]);
-      argc-=2;
-      argv+=2;
-    } else if (!strcmp(argv[0], "--home")) {
-      owl_function_change_currentview_filter(owl_global_get_view_home(&g));
-      argc--;
-      argv++;
-    } else if (!strcmp(argv[0], "-r")) {
-      char *foo;
-      foo=owl_function_create_negative_filter(owl_view_get_filtname(owl_global_get_current_view(&g)));
-      owl_function_change_currentview_filter(foo);
-    } else if (!strcmp(argv[0], "-s")) {
-      if (argc<2) {
-	owl_function_makemsg("Too few argments to the view command");
-	return(NULL);
-      }
-      owl_function_change_style(owl_global_get_current_view(&g), argv[1]);
-      argc-=2;
-      argv+=2;
-    } else {
-      owl_function_makemsg("Too few argments to the view command");
-      return(NULL);
-    }
-    
-  }
-  return(NULL);
-}
-
-char *owl_command_show(int argc, char **argv, char *buff)
-{
-  if (argc<2) {
-    owl_function_help_for_command("show");
-    return NULL;
-  }
-
-  if (!strcmp(argv[1], "filter") || !strcmp(argv[1], "filters")) {
-    if (argc==2) {
-      owl_function_show_filters();
-    } else {
-      owl_function_show_filter(argv[2]);
-    }
-  } else if (argc==2 
-	     && (!strcmp(argv[1], "zpunts") || !strcmp(argv[1], "zpunted"))) {
-    owl_function_show_zpunts();
-  } else if (!strcmp(argv[1], "command") || !strcmp(argv[1], "commands")) {
-    if (argc==2) {
-      owl_function_show_commands();
-    } else {
-      owl_function_show_command(argv[2]);
-    }
-  } else if (!strcmp(argv[1], "variable") || !strcmp(argv[1], "variables")) {
-    if (argc==2) {
-      owl_function_show_variables();
-    } else {
-      owl_function_show_variable(argv[2]);
-    }
-  } else if (!strcmp(argv[1], "keymap") || !strcmp(argv[1], "keymaps")) {
-    if (argc==2) {
-      owl_function_show_keymaps();
-    } else {
-      owl_function_show_keymap(argv[2]);
-    }
-  } else if (!strcmp(argv[1], "view")) {
-    if (argc==3) {
-      owl_function_show_view(argv[2]);
-    } else {
-      owl_function_show_view(NULL);
-    }
-  } else if (!strcmp(argv[1], "colors")) {
-    owl_function_show_colors();
-  } else if (!strcmp(argv[1], "styles")) {
-    owl_function_show_styles();
-  } else if (!strcmp(argv[1], "subs") || !strcmp(argv[1], "subscriptions")) {
-    owl_function_getsubs();
-  } else if (!strcmp(argv[1], "terminal") || !strcmp(argv[1], "term")) {
-    owl_function_show_term();
-  } else if (!strcmp(argv[1], "version")) {
-    owl_function_about();
-  } else if (!strcmp(argv[1], "status")) {
-    owl_function_status();
-  } else if (!strcmp(argv[1], "license")) {
-    owl_function_show_license();
-  } else if (!strcmp(argv[1], "quickstart")) {
-    owl_function_show_quickstart();
-  } else if (!strcmp(argv[1], "startup")) {
-    char *filename;
-    
-    filename=owl_global_get_startupfile(&g);
-    owl_function_popless_file(filename);
-  } else if (!strcmp(argv[1], "errors")) {
-    owl_function_showerrs();
-  } else {
-    owl_function_makemsg("Unknown subcommand for 'show' command (see 'help show' for allowed args)");
-    return NULL;
-  }
-  return NULL;
-}
-
-char *owl_command_viewclass(int argc, char **argv, char *buff)
-{
-  char *filtname;
-  if (argc!=2) {
-    owl_function_makemsg("Wrong number of arguments to viewclass command");
-    return NULL;
-  }
-  filtname = owl_function_classinstfilt(argv[1], NULL);
-  owl_function_change_currentview_filter(filtname);
-  owl_free(filtname);
-  return NULL;
-}
-
-char *owl_command_viewuser(int argc, char **argv, char *buff)
-{
-  char *filtname;
-  if (argc!=2) {
-    owl_function_makemsg("Wrong number of arguments to viewuser command");
-    return NULL;
-  }
-  filtname=owl_function_zuserfilt(argv[1]);
-  owl_function_change_currentview_filter(filtname);
-  owl_free(filtname);
-  return NULL;
-}
-
-
-void owl_command_pop_message(void)
-{
-  owl_function_curmsg_to_popwin();
-}
-
-char *owl_command_delete(int argc, char **argv, char *buff)
-{
-  int move_after = 1;
-
-  if (argc>1 && !strcmp(argv[1], "--no-move")) {
-    move_after = 0;
-    argc--; 
-    argv++;
-  }
-
-  if (argc==1) {
-    owl_function_deletecur(move_after);
-    return NULL;
-  }
-
-  if (argc==2 && !strcmp(argv[1], "view")) {
-    owl_function_delete_curview_msgs(1);
-    return NULL;
-  }
-
-  if (argc==2 && !strcmp(argv[1], "trash")) {
-    owl_function_delete_automsgs();
-    return NULL;
-  }
-
-  if (argc==3 && (!strcmp(argv[1], "-id") || !strcmp(argv[1], "--id"))) {
-    owl_function_delete_by_id(atoi(argv[2]), 1);
-    return NULL;
-  }
-
-  owl_function_makemsg("Unknown arguments to delete command");
-  return NULL;
-}
-
-char *owl_command_undelete(int argc, char **argv, char *buff)
-{
-  int move_after = 1;
-
-  if (argc>1 && !strcmp(argv[1], "--no-move")) {
-    move_after = 0;
-    argc--; 
-    argv++;
-  }
-
-  if (argc==1) {
-    owl_function_undeletecur(move_after);
-    return NULL;
-  }
-
-  if (argc==2 && !strcmp(argv[1], "view")) {
-    owl_function_delete_curview_msgs(0);
-    return NULL;
-  }
-
-  if (argc==3 && (!strcmp(argv[1], "-id") || !strcmp(argv[1], "--id"))) {
-    owl_function_delete_by_id(atoi(argv[2]), 0);
-    return NULL;
-  }
-
-  owl_function_makemsg("Unknown arguments to delete command");
-  return NULL;
-}
-
-void owl_command_beep()
-{
-  owl_function_beep();
-}
-
-char *owl_command_colorview(int argc, char **argv, char *buff)
-{
-  if (argc < 2 || argc > 3) {
-    owl_function_makemsg("Wrong number of arguments to colorview command");
-    return NULL;
-  }
-  owl_function_color_current_filter(argv[1], (argc == 3 ? argv[2] : NULL));
-  return NULL;
-}
-
-char *owl_command_colorclass(int argc, char **argv, char *buff)
-{
-  char *filtname;
-  
-  if (argc < 3 || argc > 4) {
-    owl_function_makemsg("Wrong number of arguments to colorclass command");
-    return NULL;
-  }
-
-  filtname=owl_function_classinstfilt(argv[1], NULL);
-  (void) owl_function_color_filter(filtname, argv[2], (argc == 4 ? argv[3] : NULL));
-  return NULL;
-}
-
-char *owl_command_zpunt(int argc, char **argv, char *buff)
-{
-  owl_command_zpunt_and_zunpunt(argc, argv, 0);
-  return NULL;
-}
-
-char *owl_command_zunpunt(int argc, char **argv, char *buff)
-{
-  owl_command_zpunt_and_zunpunt(argc, argv, 1);
-  return NULL;
-}
-
-void owl_command_zpunt_and_zunpunt(int argc, char **argv, int type)
-{
-  /* if type==0 then zpunt
-   * if type==1 then zunpunt
-   */
-  char *class, *inst, *recip;
-
-  class="message";
-  inst="";
-  recip="*";
-
-  if (argc==1) {
-    /* show current punt filters */
-    owl_function_show_zpunts();
-    return;
-  } else if (argc==2) {
-    inst=argv[1];
-  } else if (argc==3) {
-    class=argv[1];
-    inst=argv[2];
-  } else if (argc==4) {
-    class=argv[1];
-    inst=argv[2];
-    recip=argv[3];
-  } else {
-    owl_function_makemsg("Wrong number of arguments to the zpunt command");
-    return;
-  }
-
-  owl_function_zpunt(class, inst, recip, type);
-  if (type==0) {
-    owl_function_makemsg("<%s, %s, %s> added to punt list.", class, inst, recip);
-  } else if (type==1) {
-    owl_function_makemsg("<%s, %s, %s> removed from punt list.", class, inst, recip);
-  }
-}
-
-char *owl_command_smartzpunt(int argc, char **argv, char *buff)
-{
-  if (argc == 1) {
-    owl_function_smartzpunt(0);
-  } else if (argc == 2 && (!strcmp(argv[1], "-i") || !strcmp(argv[1], "--instance"))) {
-    owl_function_smartzpunt(1);
-  } else {
-    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);    
-  }
-  return NULL;
-}
-
-char *owl_command_punt(int argc, char **argv, char *buff)
-{
-  owl_command_punt_unpunt(argc, argv, buff, 0);
-  return NULL;
-}
-
-char *owl_command_unpunt(int argc, char **argv, char *buff)
-{
-  owl_command_punt_unpunt(argc, argv, buff, 1);
-  return NULL;
-}
-
-void owl_command_punt_unpunt(int argc, char ** argv, char *buff, int unpunt)
-{
-  owl_list * fl;
-  owl_filter * f;
-  char * text;
-  int i;
-
-  fl = owl_global_get_puntlist(&g);
-  if(argc == 1) {
-    owl_function_show_zpunts();
-  }
-
-  if(argc == 2) {
-    /* Handle :unpunt <number> */
-    if(unpunt && (i=atoi(argv[1])) !=0) {
-      i--;      /* Accept 1-based indexing */
-      if(i < owl_list_get_size(fl)) {
-        f = (owl_filter*)owl_list_get_element(fl, i);
-        owl_list_remove_element(fl, i);
-        owl_filter_free(f);
-        return;
-      } else {
-        owl_function_error("No such filter number: %d", i+1);
-      }
-    }
-    text = owl_sprintf("filter %s", argv[1]);
-  } else {
-    text = skiptokens(buff, 1);
-  }
-
-  owl_function_punt(text, unpunt);
-}
-
-
-char *owl_command_getview(int argc, char **argv, char *buff)
-{
-  char *filtname;
-  if (argc != 1) {
-    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);
-    return NULL;
-  }
-  filtname = owl_view_get_filtname(owl_global_get_current_view(&g));
-  if (filtname) filtname = owl_strdup(filtname);
-  return filtname;
-}
-
-char *owl_command_getvar(int argc, char **argv, char *buff)
-{
-  char tmpbuff[1024];
-  if (argc != 2) {
-    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);
-    return NULL;
-  }
-  if (owl_variable_get_tostring(owl_global_get_vardict(&g), 
-				argv[1], tmpbuff, 1024)) {
-    return NULL;
-  }
-  return owl_strdup(tmpbuff); 
-}
-
-char *owl_command_getfilter(int argc, char **argv, char *buf)
-{
-  owl_filter *f;
-  if (argc != 2) {
-    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);
-    return NULL;
-  }
-  f = owl_global_get_filter(&g, argv[1]);
-  if (!f) {
-    return NULL;
-  }
-  return owl_filter_print(f);
-}
-
-char *owl_command_search(int argc, char **argv, char *buff)
-{
-  int direction;
-  char *buffstart;
-
-  direction=OWL_DIRECTION_DOWNWARDS;
-  buffstart=skiptokens(buff, 1);
-  if (argc>1 && !strcmp(argv[1], "-r")) {
-    direction=OWL_DIRECTION_UPWARDS;
-    buffstart=skiptokens(buff, 2);
-  }
-    
-  if (argc==1 || (argc==2 && !strcmp(argv[1], "-r"))) {
-    owl_function_search_continue(direction);
-  } else {
-    owl_function_search_start(buffstart, direction);
-  }
-  
-  return(NULL);
-}
-
-char *owl_command_setsearch(int argc, char **argv, char *buff)
-{
-  char *buffstart;
-
-  buffstart=skiptokens(buff, 1);
-
-  owl_global_set_search_active(&g, buffstart);
-
-  if (!*buffstart) {
-    owl_global_set_search_inactive(&g);
-  }
-
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  
-  return(NULL);
-}
-
-char *owl_command_aimlogin(int argc, char **argv, char *buff)
-{
-  if ((argc<2) || (argc>3)) {
-    owl_function_makemsg("Wrong number of arguments to aimlogin command");
-    return(NULL);
-  }
-
-  /* if we get two arguments, ask for the password */
-  if (argc==2) {
-    owl_global_set_buffercommand(&g, argv[1]);
-    owl_global_set_buffercallback(&g, &owl_callback_aimlogin);
-    owl_function_start_password("AIM Password: ");
-    return(NULL);
-  } else {
-    owl_function_aimlogin(argv[1], argv[2]);
-  }
-
-  /* this is a test */
-  return(NULL);
-}
-
-char *owl_command_aimlogout(int argc, char **argv, char *buff)
-{
-  /* clear the buddylist */
-  owl_buddylist_clear(owl_global_get_buddylist(&g));
-
-  owl_aim_logout();
-  return(NULL);
-}
-
-char *owl_command_getstyle(int argc, char **argv, char *buff)
-{
-  char *stylename;
-  if (argc != 1) {
-    owl_function_makemsg("Wrong number of arguments for %s", argv[0]);
-    return NULL;
-  }
-  stylename = owl_view_get_style_name(owl_global_get_current_view(&g));
-  if (stylename) stylename = owl_strdup(stylename);
-  return stylename;
-}
-
-char *owl_command_error(int argc, char **argv, char *buff)
-{
-    buff = skiptokens(buff, 1);
-    owl_function_error("%s", buff);
-    return NULL;
-}
-
-char *owl_command_message(int argc, char **argv, char *buff)
-{
-    buff = skiptokens(buff, 1);
-    owl_function_makemsg("%s", buff);
-    return NULL;
-}
-
-void owl_command_yes(void)
-{
-  owl_message *m;
-  owl_view *v;
-  char *cmd;
-
-  v = owl_global_get_current_view(&g);
-
-  /* bail if there's no current message */
-  if (owl_view_get_size(v) < 1) {
-    owl_function_error("No current message.");
-    return;
-  }
-
-  m = owl_view_get_element(v, owl_global_get_curmsg(&g));
-  if(!owl_message_is_question(m)) {
-    owl_function_error("That message isn't a question.");
-    return;
-  }
-  if(owl_message_is_answered(m)) {
-    owl_function_error("You already answered that question.");
-    return;
-  }
-  cmd = owl_message_get_attribute_value(m, "yescommand");
-  if(!cmd) {
-    owl_function_error("No 'yes' command!");
-    return;
-  }
-
-  owl_function_command_norv(cmd);
-  owl_message_set_isanswered(m);
-  return;
-}
-
-void owl_command_no(void)
-{
-  owl_message *m;
-  owl_view *v;
-  char *cmd;
-
-  v = owl_global_get_current_view(&g);
-
-  /* bail if there's no current message */
-  if (owl_view_get_size(v) < 1) {
-    owl_function_error("No current message.");
-    return;
-  }
-
-  m = owl_view_get_element(v, owl_global_get_curmsg(&g));
-  if(!owl_message_is_question(m)) {
-    owl_function_error("That message isn't a question.");
-    return;
-  }
-  if(owl_message_is_answered(m)) {
-    owl_function_error("You already answered that question.");
-    return;
-  }
-  cmd = owl_message_get_attribute_value(m, "nocommand");
-  if(!cmd) {
-    owl_function_error("No 'no' command!");
-    return;
-  }
-
-  owl_function_command_norv(cmd);
-  owl_message_set_isanswered(m);
-  return;
-}
-
-/*********************************************************************/
-/************************** EDIT SPECIFIC ****************************/
-/*********************************************************************/
-
-void owl_command_edit_cancel(owl_editwin *e)
-{
-  owl_history *hist;
-
-  owl_function_makemsg("Command cancelled.");
-
-  hist=owl_editwin_get_history(e);
-  owl_history_store(hist, owl_editwin_get_text(e));
-  owl_history_reset(hist);
-
-  owl_editwin_fullclear(e);
-  owl_global_set_needrefresh(&g);
-  wnoutrefresh(owl_editwin_get_curswin(e));
-  owl_global_set_typwin_inactive(&g);
-  owl_editwin_new_style(e, OWL_EDITWIN_STYLE_ONELINE, NULL);
-
-  owl_function_activate_keymap("recv");
-}
-
-void owl_command_edit_history_prev(owl_editwin *e)
-{
-  owl_history *hist;
-  char *ptr;
-
-  hist=owl_editwin_get_history(e);
-  if (!owl_history_is_touched(hist)) {
-    owl_history_store(hist, owl_editwin_get_text(e));
-    owl_history_set_partial(hist);
-  }
-  ptr=owl_history_get_prev(hist);
-  if (ptr) {
-    owl_editwin_clear(e);
-    owl_editwin_insert_string(e, ptr);
-    owl_editwin_redisplay(e, 0);
-    owl_global_set_needrefresh(&g);
-  } else {
-    owl_function_beep();
-  }
-}
-
-void owl_command_edit_history_next(owl_editwin *e)
-{
-  owl_history *hist;
-  char *ptr;
-
-  hist=owl_editwin_get_history(e);
-  ptr=owl_history_get_next(hist);
-  if (ptr) {
-    owl_editwin_clear(e);
-    owl_editwin_insert_string(e, ptr);
-    owl_editwin_redisplay(e, 0);
-    owl_global_set_needrefresh(&g);
-  } else {
-    owl_function_beep();
-  }
-}
-
-char *owl_command_edit_insert_text(owl_editwin *e, int argc, char **argv, char *buff)
-{
-  buff = skiptokens(buff, 1);
-  owl_editwin_insert_string(e, buff);
-  owl_editwin_redisplay(e, 0);
-  owl_global_set_needrefresh(&g);  
-  return NULL;
-}
-
-void owl_command_editline_done(owl_editwin *e)
-{
-  owl_history *hist=owl_editwin_get_history(e);
-  char *rv, *cmd;
-
-  owl_history_store(hist, owl_editwin_get_text(e));
-  owl_history_reset(hist);
-  owl_global_set_typwin_inactive(&g);
-  cmd = owl_strdup(owl_editwin_get_text(e));
-  owl_editwin_fullclear(e);
-  rv = owl_function_command(cmd);
-  owl_free(cmd);
-
-  wnoutrefresh(owl_editwin_get_curswin(e));
-  owl_global_set_needrefresh(&g);
-
-  if (rv) {
-    owl_function_makemsg("%s", rv);
-    owl_free(rv);
-  }
-}
-
-
-void owl_command_editresponse_done(owl_editwin *e)
-{
-  owl_function_run_buffercommand();
-
-  owl_global_set_typwin_inactive(&g);
-  owl_editwin_fullclear(e);
-  wnoutrefresh(owl_editwin_get_curswin(e));
-  owl_global_set_needrefresh(&g);
-}
-
-
-void owl_command_editmulti_done(owl_editwin *e)
-{
-  owl_history *hist=owl_editwin_get_history(e);
-
-  owl_history_store(hist, owl_editwin_get_text(e));
-  owl_history_reset(hist);
-
-  owl_function_run_buffercommand();
-  owl_editwin_new_style(e, OWL_EDITWIN_STYLE_ONELINE, NULL);
-  owl_editwin_fullclear(e);
-  owl_global_set_typwin_inactive(&g);
-  owl_global_set_needrefresh(&g);
-  wnoutrefresh(owl_editwin_get_curswin(e));
-}
-
-void owl_command_editmulti_done_or_delete(owl_editwin *e)
-{
-  if (owl_editwin_is_at_end(e)) {
-    owl_command_editmulti_done(e);
-  } else {
-    owl_editwin_delete_char(e);
-  }
-}
-
-
-/*********************************************************************/
-/*********************** POPLESS SPECIFIC ****************************/
-/*********************************************************************/
-
-void owl_command_popless_quit(owl_viewwin *vw)
-{
-  owl_popwin_close(owl_global_get_popwin(&g));
-  owl_viewwin_free(vw);
-  owl_global_set_needrefresh(&g);
-}
Index: nfig.h.in
===================================================================
--- config.h.in	(revision e23eb2b7a8b842ee6ac86fc356ffe7831757dd87)
+++ 	(revision )
@@ -1,115 +1,0 @@
-/* config.h.in.  Generated from configure.in by autoheader.  */
-
-/* Define to 1 if you have the <com_err.h> header file. */
-#undef HAVE_COM_ERR_H
-
-/* Define to 1 if you have the `des_ecb_encrypt' function. */
-#undef HAVE_DES_ECB_ENCRYPT
-
-/* have proto for des_ecb_encrypt */
-#undef HAVE_DES_ECB_ENCRYPT_PROTO
-
-/* Define to 1 if you have the `des_key_sched' function. */
-#undef HAVE_DES_KEY_SCHED
-
-/* Define to 1 if you have the `des_string_to_key' function. */
-#undef HAVE_DES_STRING_TO_KEY
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the `com_err' library (-lcom_err). */
-#undef HAVE_LIBCOM_ERR
-
-/* Define to 1 if you have the `des425' library (-ldes425). */
-#undef HAVE_LIBDES425
-
-/* Define to 1 if you have the `k5crypto' library (-lk5crypto). */
-#undef HAVE_LIBK5CRYPTO
-
-/* Define to 1 if you have the `krb' library (-lkrb). */
-#undef HAVE_LIBKRB
-
-/* Define to 1 if you have the `krb4' library (-lkrb4). */
-#undef HAVE_LIBKRB4
-
-/* Define to 1 if you have the `krb5' library (-lkrb5). */
-#undef HAVE_LIBKRB5
-
-/* Define to 1 if you have the `ncursesw' library (-lncursesw). */
-#undef HAVE_LIBNCURSESW
-
-/* Define to 1 if you have the `nsl' library (-lnsl). */
-#undef HAVE_LIBNSL
-
-/* Define to 1 if you have the `resolv' library (-lresolv). */
-#undef HAVE_LIBRESOLV
-
-/* Define to 1 if you have the `socket' library (-lsocket). */
-#undef HAVE_LIBSOCKET
-
-/* Define to 1 if you have the `zephyr' library (-lzephyr). */
-#undef HAVE_LIBZEPHYR
-
-/* Have ZInitLocationInfo */
-#undef HAVE_LIBZEPHYR_ZINITLOCATIONINFO
-
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the `resizeterm' function. */
-#undef HAVE_RESIZETERM
-
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
-
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the <sys/filio.h> header file. */
-#undef HAVE_SYS_FILIO_H
-
-/* Define to 1 if you have the <sys/ioctl.h> header file. */
-#undef HAVE_SYS_IOCTL_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
-#undef HAVE_SYS_WAIT_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to 1 if you have the `use_default_colors' function. */
-#undef HAVE_USE_DEFAULT_COLORS
-
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Have terminfo */
-#undef TERMINFO
Index: nfigure.ac
===================================================================
--- configure.ac	(revision d9337637b38624a9f8d064c1a45062f7762f7b72)
+++ 	(revision )
@@ -1,130 +1,0 @@
-dnl $Id$
-dnl Process this file with autoconf to produce a configure script.
-AC_INIT(owl.c)
-
-AC_CONFIG_HEADER(config.h)
-
-AC_PROG_CC
-
-dnl If we're using GCC, enable all warnings
-if test "$GCC" = yes; then
-     CFLAGS="$CFLAGS -Wall -g";
-fi
-
-m4_include(/usr/share/aclocal/pkg.m4)
-dnl m4_include(pkg.m4)
-
-dnl Check for Athena
-AC_MSG_CHECKING(for /usr/athena/include)
-if test -d /usr/athena/include; then
-	CFLAGS=${CFLAGS}\ -I/usr/athena/include
-	CPPFLAGS=${CPPFLAGS}\ -I/usr/athena/include
-	AC_MSG_RESULT(yes)
-else
-	AC_MSG_RESULT(no)
-fi
-AC_MSG_CHECKING(for /usr/athena/lib)
-if test -d /usr/athena/lib; then
-	LDFLAGS=${LDFLAGS}\ -L/usr/athena/lib
-	AC_MSG_RESULT(yes)
-else
-	AC_MSG_RESULT(no)
-fi
-
-dnl Check for kerberosIV include
-AC_MSG_CHECKING(for kerberosIV)
-if test -d /usr/include/kerberosIV; then
-        CFLAGS=${CFLAGS}\ -I/usr/include/kerberosIV
-        CPPFLAGS=${CPPFLAGS}\ -I/usr/include/kerberosIV
-        AC_MSG_RESULT(yes)
-elif test -d /usr/local/include/kerberosIV; then
-        CFLAGS=${CFLAGS}\ -I/usr/local/include/kerberosIV
-        CPPFLAGS=${CPPFLAGS}\ -I/usr/local/include/kerberosIV
-        AC_MSG_RESULT(yes)
-else
-        AC_MSG_RESULT(no)
-fi
-
-AC_CHECK_LIB(ncursesw, initscr,, AC_MSG_ERROR(No curses library found.))
-AC_CHECK_LIB(com_err, com_err)
-AC_CHECK_LIB(nsl, gethostbyname)
-AC_CHECK_LIB(socket, socket)
-AC_CHECK_LIB(k5crypto, krb5_derive_key)
-dnl AC_CHECK_LIB(des425, req_act_vno)
-AC_CHECK_LIB(des425, des_cbc_encrypt)
-AC_CHECK_LIB(resolv, res_search)
-AC_CHECK_LIB(krb5, krb5_get_credentials)
-AC_CHECK_LIB(krb4, krb_sendauth,,
-   AC_CHECK_LIB(krb, krb_sendauth))
-dnl AC_CHECK_LIB(zephyr, ZGetSender,, AC_MSG_ERROR(No zephyr library found.))
-AC_CHECK_LIB(zephyr, ZGetSender)
-AC_CHECK_LIB(zephyr, ZInitLocationInfo, AC_DEFINE([HAVE_LIBZEPHYR_ZINITLOCATIONINFO], [], [Have ZInitLocationInfo]),)
-
-AC_ARG_ENABLE([athstatic], AS_HELP_STRING([--enable-athstatic],
-                                          [Statically link libraries in /usr/athena/lib]),
-                                          [ATHSTATIC=./athstatic],
-                                          [ATHSTATIC=])
-
-AC_CHECK_FUNCS(use_default_colors resizeterm des_string_to_key des_key_sched des_ecb_encrypt)
-
-AC_MSG_CHECKING(for des_ecb_encrypt prototype)
-AC_TRY_COMPILE([#include <des.h>
-int des_ecb_encrypt(char foo[], char bar[], des_key_schedule baz, int qux);],
-[int foo = des_ecb_encrypt(0,0,0,0);],
-ac_cv_des_ecb_encrypt_proto=no,
-ac_cv_des_ecb_encrypt_proto=yes)
-AC_MSG_RESULT($ac_cv_des_ecb_encrypt_proto)
-if test "$ac_cv_des_ecb_encrypt_proto" = yes; then
-	AC_DEFINE([HAVE_DES_ECB_ENCRYPT_PROTO], [], [have proto for des_ecb_encrypt])
-fi
-
-dnl Checks for header files.
-AC_HEADER_STDC
-AC_HEADER_SYS_WAIT
-AC_CHECK_HEADERS(strings.h sys/ioctl.h sys/filio.h unistd.h com_err.h)
-
-dnl Add CFLAGS for embeded perl
-FOO=`perl -MExtUtils::Embed -e ccopts`
-echo Adding perl CFLAGS ${FOO}
-CFLAGS=${CFLAGS}\ ${FOO}
-
-dnl Find the location of perl XSUBPP
-AC_MSG_CHECKING(for the perl xsubpp precompiler)
-XSUBPPDIR="`(perl -MExtUtils::MakeMaker -e 'print ExtUtils::MakeMaker->new({NAME => qw(owl)})->tool_xsubpp;') | grep \^XSUBPPDIR | sed -e 's/XSUBPPDIR = //g;'`"
-if test -n "${XSUBPPDIR}"; then
-   AC_MSG_RESULT(${XSUBPPDIR})
-else
-   AC_MSG_ERROR(not found)
-fi
-
-if test -f "${XSUBPPDIR}/typemap"; then
-   XSUBPPFLAGS="-typemap ${XSUBPPDIR}/typemap"
-else
-   XSUBPPFLAGS=""
-fi
-
-dnl Add LDFLAGS for embedded perl
-FOO=`perl -MExtUtils::Embed -e ldopts`
-echo Adding perl LDFLAGS ${FOO}
-LDFLAGS=${LDFLAGS}\ ${FOO}
-
-dnl Add CFLAGS and LDFLAGS for glib-2.0
-PKG_CHECK_MODULES(GLIB,glib-2.0)
-
-echo Adding glib-2.0 CFLAGS ${GLIB_CFLAGS}
-CFLAGS="${GLIB_CFLAGS} ${CFLAGS}"
-echo Adding glib-2.0 LDFLAGS ${GLIB_LIBS}
-LDFLAGS="${GLIB_LIBS} ${LDFLAGS}"
-
-
-dnl Checks for typedefs, structures, and compiler characteristics.
-
-AC_SUBST(XSUBPPDIR)
-AC_SUBST(XSUBPPFLAGS)
-AC_SUBST(ATHSTATIC)
-
-AC_PROG_INSTALL
-
-AC_CONFIG_SUBDIRS(libfaim)
-
-AC_OUTPUT(Makefile)
Index: ntext.c
===================================================================
--- context.c	(revision cf83b7a15ef998b48ca0aa69dae69a963b365dc1)
+++ 	(revision )
@@ -1,100 +1,0 @@
-#include <string.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-#define SET_ACTIVE(ctx, new) ctx->mode = ((ctx->mode)&~OWL_CTX_ACTIVE_BITS)|new
-#define SET_MODE(ctx, new) ctx->mode = ((ctx->mode)&~OWL_CTX_MODE_BITS)|new
-
-int owl_context_init(owl_context *ctx)
-{
-  ctx->mode = OWL_CTX_STARTUP;
-  ctx->data = NULL;
-  return 0;
-}
-
-
-/* returns whether test matches the current context */
-int owl_context_matches(owl_context *ctx, int test)
-{
-  /*owl_function_debugmsg(", current: 0x%04x test: 0x%04x\n", ctx->mode, test);*/
-  if ((((ctx->mode&OWL_CTX_MODE_BITS) & test)
-       || !(test&OWL_CTX_MODE_BITS))
-      && 
-      (((ctx->mode&OWL_CTX_ACTIVE_BITS) & test) 
-       || !(test&OWL_CTX_ACTIVE_BITS))) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-void *owl_context_get_data(owl_context *ctx)
-{
-  return ctx->data;
-}
-
-int owl_context_get_mode(owl_context *ctx)
-{
-  return ctx->mode & OWL_CTX_MODE_BITS;
-}
-
-int owl_context_get_active(owl_context *ctx)
-{
-  return ctx->mode & OWL_CTX_ACTIVE_BITS;
-}
-
-int owl_context_is_startup(owl_context *ctx)
-{
-  return (ctx->mode & OWL_CTX_STARTUP)?1:0;
-}
-
-int owl_context_is_interactive(owl_context *ctx)
-{
-  return(ctx->mode & OWL_CTX_INTERACTIVE)?1:0;
-}
-
-void owl_context_set_startup(owl_context *ctx)
-{
-  SET_MODE(ctx, OWL_CTX_STARTUP);
-}
-
-void owl_context_set_readconfig(owl_context *ctx)
-{
-  SET_MODE(ctx, OWL_CTX_READCONFIG);
-}
-
-void owl_context_set_interactive(owl_context *ctx)
-{
-  SET_MODE(ctx, OWL_CTX_INTERACTIVE);
-}
-
-void owl_context_set_popless(owl_context *ctx, owl_viewwin *vw)
-{
-  ctx->data = (void*)vw;
-  SET_ACTIVE(ctx, OWL_CTX_POPLESS);
-}
-
-void owl_context_set_recv(owl_context *ctx)
-{
-  SET_ACTIVE(ctx, OWL_CTX_RECV);
-}
-
-void owl_context_set_editmulti(owl_context *ctx, owl_editwin *ew)
-{
-  ctx->data = (void*)ew;
-  SET_ACTIVE(ctx, OWL_CTX_EDITMULTI);
-}
-
-void owl_context_set_editline(owl_context *ctx, owl_editwin *ew)
-{
-  ctx->data = (void*)ew;
-  SET_ACTIVE(ctx, OWL_CTX_EDITLINE);
-}
-
-void owl_context_set_editresponse(owl_context *ctx, owl_editwin *ew)
-{
-  ctx->data = (void*)ew;
-  SET_ACTIVE(ctx, OWL_CTX_EDITRESPONSE);
-}
-
Index: bian/README.Debian
===================================================================
--- debian/README.Debian	(revision 1b3023e70800b46584987bd943109fdde1a54075)
+++ 	(revision )
@@ -1,9 +1,0 @@
-barnowl for Debian
---------------
-
-owl is one of the simpler (while still being extensible) non-graphical
-zephyr clients, which may make it simpler to get started as a user.
-
-Barnowl is a fork of owl with Jabber support.
-
- -- Sam Hartman <hartmans@debian.org>, Sat,  3 Mar 2007 14:49:31 -0500
Index: bian/barnowl-irc.install
===================================================================
--- debian/barnowl-irc.install	(revision 1b3023e70800b46584987bd943109fdde1a54075)
+++ 	(revision )
@@ -1,1 +1,0 @@
-usr/share/barnowl/modules/IRC.par
Index: bian/barnowl.dirs
===================================================================
--- debian/barnowl.dirs	(revision 1b3023e70800b46584987bd943109fdde1a54075)
+++ 	(revision )
@@ -1,1 +1,0 @@
-usr/bin
Index: bian/barnowl.docs
===================================================================
--- debian/barnowl.docs	(revision cacc65bf3a2801a2a019d987c5c70cf29f6c93fd)
+++ 	(revision )
@@ -1,2 +1,0 @@
-doc/*.txt
-AUTHORS
Index: bian/barnowl.install
===================================================================
--- debian/barnowl.install	(revision 43ff04b88cdedcc081481f13ffe6a4fcfa3e8be8)
+++ 	(revision )
@@ -1,4 +1,0 @@
-usr/bin/barnowl
-usr/share/barnowl/lib/*
-usr/share/man/man1/barnowl.1
-usr/share/barnowl/modules/Jabber.par
Index: bian/changelog
===================================================================
--- debian/changelog	(revision 92f8fc29ff739c9286655b8c717473a4d2d3fa81)
+++ 	(revision )
@@ -1,197 +1,0 @@
-barnowl (1.0.4.1-0debathena1) unstable; urgency=low
-
-  * New upstream release
-
- -- Evan Broder <broder@mit.edu>  Sat, 24 Jan 2009 20:54:46 -0500
-
-barnowl (1.0.3-1) unstable; urgency=low
-  
-  * New upstream release
-  * Call perl_sys_init3; Closes: #495056
-
- -- Sam Hartman <hartmans@debian.org>  Sat, 13 Dec 2008 18:40:42 -0500
-
-barnowl (1.0.3-0debathena1) unstable; urgency=low
-
-  * New upstream version
-
- -- Evan Broder <broder@mit.edu>  Sun, 02 Nov 2008 15:07:28 -0500
-
-barnowl (1.0.1-2) unstable; urgency=low
-
-  * Don't include LGPL in debian/copyright
-  * Fix description line
-
- -- Sam Hartman <hartmans@debian.org>  Sat, 31 May 2008 10:55:08 -0400
-
-barnowl (1.0.1-1) unstable; urgency=low
-
-  * New Upstream version
-  * Upload to Debian, Closes: #483382
-      - The IRC module is split into its own package at the request of
-    upstream.  They believe it is less stable than the rest of the
-    project.  
-
- -- Sam Hartman <hartmans@debian.org>  Fri, 30 May 2008 19:38:19 -0400
-
-barnowl (1.0.0-1) unstable; urgency=low
-
-  * First upstream release
-
- -- Sam Hartman <hartmans@debian.org>  Wed, 28 May 2008 10:40:54 -0400
-
-barnowl (1.0-0debathena1) unstable; urgency=low
-
-  * New upstream version - 1.0 release
-
- -- Evan Broder <broder@mit.edu>  Tue, 27 May 2008 14:22:05 -0400
-
-barnowl (0.0.r1048-0debathena1) unstable; urgency=low
-
-  * Add the IRC module as a separate package
-
- -- Evan Broder <broder@mit.edu>  Fri, 23 May 2008 16:16:40 -0400
-
-barnowl (0.0.r1046-0debathena1) unstable; urgency=low
-
-  * New upstream version
-
- -- Evan Broder <broder@mit.edu>  Fri, 16 May 2008 15:27:17 -0400
-
-barnowl (0.0.r1017-0debathena1) unstable; urgency=low
-
-  * new build
-  * use cdbs
-
- -- Gregory Nathan Price <price@mit.edu>  Sun,  6 Apr 2008 17:24:37 -0400
-
-barnowl (0.0.r650-1) unstable; urgency=low
-
-  * new build
-
- -- Sam Hartman <hartmans@debian.org>  Thu,  5 Apr 2007 10:35:13 -0400
-
-barnowl (0.0.r643-1) unstable; urgency=low
-
-  * Fork of owl.
-
- -- Sam Hartman <hartmans@debian.org>  Thu,  5 Apr 2007 10:34:47 -0400
-
-owl (2.1.8-2.1) unstable; urgency=low
-
-  * Non-maintainer upload.
-  * Include a patch from Andreas Jochens to fix compilation with gcc-4.0.
-    Closes: #287891
-  * Add some prototypes to perlglue.xs to avoid the implicit conversion of
-    return pointers from owl_zephyr_get_realm() & owl_zephyr_get_sender().
-    Closes: #326106
-
- -- dann frazier <dannf@debian.org>  Tue, 11 Oct 2005 20:47:51 -0600
-
-owl (2.1.8-2) unstable; urgency=low
-
-  * zcrypt.c: use kerberosIV/des.h, not the openafs one. Closes: #189108.
-  * configure.in: change it in the test, too.
-
- -- Mark W. Eichin <eichin@thok.org>  Sun, 29 Aug 2004 16:25:03 -0400
-
-owl (2.1.8-1) unstable; urgency=low
-
-  * New upstream release.  Kept debian/*, dropped all old patches
-    (everything that mattered was already upstream.)
-  * debian/copyright: new upstream location and mailing lists
-  * configure.in: don't look for libdes, it breaks kerberized zephyr.
-  * zephyr.c: actually record error_message in owl_function_error calls.     
-
- -- Mark W. Eichin <eichin@thok.org>  Sun, 29 Aug 2004 13:21:53 -0400
-
-owl (1.2.9-1.1) unstable; urgency=low
-
-  * NMU
-  * Fix compile error, patch in BTS.  Closes: #189108
-
- -- LaMont Jones <lamont@debian.org>  Sun,  3 Aug 2003 18:54:07 -0600
-
-owl (1.2.9-1) unstable; urgency=low
-
-  * New upstream release
-  * update fixes resize problem (Closes: #182897)
-  * upstream also took changes for perl multithreading, thanks Bas
-    Zoetekouw and Lamont Jones for the NMU (Closes: #159123)
-	
- -- Mark W. Eichin <eichin@thok.org>  Sun, 13 Apr 2003 21:04:52 -0400
-
-owl (1.1.3-1.1) unstable; urgency=low
-
-  * NMU
-  * Fix perl 5.8 build problem.  Closes: #159123
-
- -- LaMont Jones <lamont@debian.org>  Tue,  8 Oct 2002 18:21:44 -0600
-
-owl (1.1.3-1) unstable; urgency=low
-
-  * New upstream release
-
- -- Mark W. Eichin <eichin@thok.org>  Fri,  5 Jul 2002 14:33:23 -0400
-
-owl (1.0.1-4) unstable; urgency=low
-
-  * debian/control: build-depend on a version of libzephyr late enough to
-    have #110486 fixed.  (Closes: #148404)
-
- -- Mark W. Eichin <eichin@thok.org>  Thu, 30 May 2002 14:19:18 -0400
-
-owl (1.0.1-3) unstable; urgency=low
-
-  * debian/shlibs.local: override libzephyr3-krb's shlibs file until
-    #148175 is fixed.  (Closes: #148107)
-
- -- Mark W. Eichin <eichin@thok.org>  Sat, 25 May 2002 18:35:09 -0400
-
-owl (1.0.1-2) unstable; urgency=low
-
-  * update README.debian from pre-release.
-  * configure.in: ditch the explicit krb tests, so we can get the right
-    libs. Crudely done, improvements sought.
-
- -- Mark W. Eichin <eichin@thok.org>  Sat, 25 May 2002 02:19:47 -0400
-
-owl (1.0.1-1) unstable; urgency=low
-
-  * New upstream release.  Includes the 1.0.1 fixes below.
-  * debian/watch: new file, lets us use uscan and be very lazy :-)
-
- -- Mark W. Eichin <eichin@thok.org>  Fri, 24 May 2002 17:42:44 -0400
-
-owl (1.0-1) unstable; urgency=low
-
-  * New upstream release (first public deb.) (Closes: #147980)
-  * zephyr.c (loadloginsubs, loadsubs): use free correctly.  (pre-1.0.1 fix)
-  * util.c (owl_free): void, don't return.  (pre-1.0.1 fix)
-
- -- Mark W. Eichin <eichin@thok.org>  Fri, 24 May 2002 01:27:28 -0400
-
-owl (0.10-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Mark W. Eichin <eichin@thok.org>  Tue,  7 May 2002 17:25:28 -0400
-
-owl (0.9-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Mark W. Eichin <eichin@thok.org>  Sun, 28 Apr 2002 22:29:02 -0400
-
-owl (0.8.1-1) unstable; urgency=low
-
-  * New upstream release.
-
- -- Mark W. Eichin <eichin@thok.org>  Wed, 24 Apr 2002 19:19:29 -0400
-
-owl (0.7-1) unstable; urgency=low
-
-  * Initial Release.
-
- -- Mark W. Eichin <eichin@thok.org>  Tue, 23 Apr 2002 01:58:14 -0400
-
Index: bian/compat
===================================================================
--- debian/compat	(revision 1b3023e70800b46584987bd943109fdde1a54075)
+++ 	(revision )
@@ -1,1 +1,0 @@
-4
Index: bian/control
===================================================================
--- debian/control	(revision d85cf01ac25794fedc6c5e32e62448cf3f132c7a)
+++ 	(revision )
@@ -1,31 +1,0 @@
-Source: barnowl
-Section: net
-Priority: optional
-Maintainer: Sam Hartman <hartmans@debian.org>
-Build-Depends: cdbs (>= 0.4.23-1.1), debhelper (>= 4.2.0), autoconf, libglib2.0-dev, libzephyr-dev, libncurses5-dev, libncursesw5-dev, libkrb5-dev, libperl-dev, pkg-config, zip
-Standards-Version: 3.7.2
-
-Package: barnowl
-Architecture: any
-Depends: ${shlibs:Depends}, ${perl:Depends}, libnet-dns-perl, libauthen-sasl-perl, libdigest-sha1-perl, libgssapi-perl, libio-socket-ssl-perl, libpar-perl
-Suggests: zephyr-clients
-Description: A curses-based tty Jabber and Zephyr client
- A curses-based instant-messaging client supporting the Jabber, IRC, AIM 
- and Zephyr  protocols.  Much of the functionality is written in
- Perl, which is supported as an extension language.
- .
- This is a fork of ktools software's owl Zephyr/AIM client.
-
-Package: barnowl-irc
-Architecture: all
-Depends: ${shlibs:Depends}, ${perl:Depends}, libnet-irc-perl, libclass-accessor-perl, barnowl
-Priority: extra
-Description: Provide IRC support for the BarnOwl Zephyr client
- Install the Perl-based IRC module which will add IRC support to
- BarnOwl the next time it is reloaded.
- .
- BarnOwl is a curses-based instant-messaging client supporting the
- Zephyr, Jabber, IRC and AIM protocols. Much of the functionality is
- written in Perl, which is supported as an etension language.
- .
- BarnOwl is a fork of ktools software's owl Zephyr/AIM client.
Index: bian/control.in
===================================================================
--- debian/control.in	(revision 4041f8e5187b4c0c130e493bae831cd32eb336d3)
+++ 	(revision )
@@ -1,30 +1,0 @@
-Source: barnowl
-Section: net
-Priority: optional
-Maintainer: Sam Hartman <hartmans@debian.org>
-Build-Depends: @cdbs@, libglib2.0-dev, libzephyr-dev, libncurses5-dev, libncursesw5-dev, libkrb5-dev, libperl-dev, pkg-config, zip
-Standards-Version: 3.7.2
-
-Package: barnowl
-Architecture: any
-Depends: ${shlibs:Depends}, ${perl:Depends}, libnet-dns-perl, libauthen-sasl-perl, libdigest-sha1-perl, libgssapi-perl, libio-socket-ssl-perl, libpar-perl
-Suggests: zephyr-clients
-Description: A curses-based tty Jabber and Zephyr client
- A curses-based instant-messaging client supporting the Jabber, IRC, AIM and Zephyr  protocols.  Much of the functionality is written in
- Perl, which is supported as an extension language.
- .
- This is a fork of ktools software's owl Zephyr/AIM client.
-
-Package: barnowl-irc
-Architecture: all
-Depends: ${shlibs:Depends}, ${perl:Depends}, libnet-irc-perl, libclass-accessor-perl, barnowl
-Priority: extra
-Description: Provide IRC support for the BarnOwl Zephyr client
- Install the Perl-based IRC module which will add IRC support to
- BarnOwl the next time it is reloaded.
- .
- BarnOwl is a curses-based instant-messaging client supporting the
- Zephyr, Jabber, IRC and AIM protocols. Much of the functionality is
- written in Perl, which is supported as an etension language.
- .
- BarnOwl is a fork of ktools software's owl Zephyr/AIM client.
Index: bian/copyright
===================================================================
--- debian/copyright	(revision 645a8d94576b36c97fe32a0360eb4021fa68f534)
+++ 	(revision )
@@ -1,73 +1,0 @@
-This package was debianized by Gregory Nathan Price <price@mit.edu> on
-2008-04-06.
-
-It was downloaded by svn from file:///afs/sipb.mit.edu/project/barnowl/src/svn
-
-Upstream Authors: barnowl-dev@mit.edu
-
-Barnowl was written primarily by Nelson Elhage and Alejandro Sedeno,
-of the Student Information Processing Board of the Massachusetts
-Institute of Technology.
-
-The original owl was primarily written by James Kretchmar at the
-Massachusetts Institute of Technology, with substantial contributions
-and improvements from Erik Nygren.
-
-Copyright:
-Copyright (c) 2006-2008 The BarnOwl Developers. All rights reserved.
-Copyright (c) 2004 James Kretchmar. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-  * Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-
-  * Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in
-    the documentation and/or other materials provided with the
-    distribution.
-
-  * Redistributions in any form must be accompanied by information on
-    how to obtain complete source code for the BarnOwl software and
-    any accompanying software that uses the BarnOwl software. The
-    source code must either be included in the distribution or be
-    available for no more than the cost of distribution plus a nominal
-    fee, and must be freely redistributable under reasonable
-    conditions. For an executable file, complete source code means the
-    source code for all modules it contains. It does not include
-    source code for modules or files that typically accompany the
-    major components of the operating system on which the executable
-    file runs.
-
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-======================================================================
-
-Files under perl/modules/Jabber/lib/Net and perl/modules/lib/XML are
-Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-
-   This library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Library General Public
-   License as published by the Free Software Foundation; either
-   version 2 of the License, or (at your option) any later version.
-
-   This library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-On Debian GNU/Linux systems, the complete text of the GNU General
-Public License can be found in `/usr/share/common-licenses/LGPL-2'.
Index: bian/rules
===================================================================
--- debian/rules	(revision 24de1f7a256d092b48332da03820c4d3860b7fe3)
+++ 	(revision )
@@ -1,17 +1,0 @@
-#!/usr/bin/make -f
-
-DEB_AUTO_UPDATE_AUTOCONF = 2.50
-
-
-include /usr/share/cdbs/1/rules/debhelper.mk
-include /usr/share/cdbs/1/class/autotools.mk
-
-DEB_DH_INSTALL_SOURCEDIR = $(DEB_DESTDIR)
-CFLAGS += -DOWL_VERSION_STRING=\"\\\"$(shell dpkg-parsechangelog | sed -ne 's/Version: //p')\\\"\"
-
-clean::
-	rm -f configure
-	rm -f perl/modules/Jabber/Makefile.old
-	rm -f perl/modules/Jabber/Jabber.par
-	rm -f perl/modules/IRC/Makefile.old
-	rm -f perl/modules/IRC/IRC.par
Index: bian/shlibs.local
===================================================================
--- debian/shlibs.local	(revision 1b3023e70800b46584987bd943109fdde1a54075)
+++ 	(revision )
@@ -1,1 +1,0 @@
-libzephyr 3 libzephyr3
Index: ct.c
===================================================================
--- dict.c	(revision af1920fd98d8d860245a197dee998e0e5c337285)
+++ 	(revision )
@@ -1,186 +1,0 @@
-/* Dictionary data abstraction.  
- * Maps from strings to pointers.
- * Stores as a sorted list of key/value pairs.
- * O(n) on inserts and deletes.
- * O(n) on searches, although it should switch to a binary search for O(log n)
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-
-#define INITSIZE 30
-#define GROWAT 2
-#define GROWBY 1.5
-
-int owl_dict_create(owl_dict *d) {
-  d->size=0;
-  d->els=(owl_dict_el *)owl_malloc(INITSIZE*sizeof(owl_dict_el));
-  d->avail=INITSIZE;
-  if (d->els==NULL) return(-1);
-  return(0);
-}
-
-int owl_dict_get_size(owl_dict *d) {
-  return(d->size);
-}
-
-/* Finds the position of an element with key k, or of the element where
- * this element would logically go, and stores the index in pos.
- * TODO: optimize to do a binary search.
- * Returns 1 if found, else 0. */
-int _owl_dict_find_pos(owl_dict *d, char *k, int *pos) {
-  int i;
-  for (i=0; (i<d->size) && strcmp(k,d->els[i].k)>0; i++);
-  *pos = i;
-  if (i>=d->size || strcmp(k,d->els[i].k)) {
-    return(0);
-  } else {
-    return(1);
-  }
-}
-
-/* returns the value corresponding to key k */
-void *owl_dict_find_element(owl_dict *d, char *k) {
-  int found, pos;
-  found = _owl_dict_find_pos(d, k, &pos);
-  if (!found) {
-    return(NULL);
-  }
-  return(d->els[pos].v);
-}
-
-/* creates a list and fills it in with keys.  duplicates the keys, 
- * so they will need to be freed by the caller. */
-int owl_dict_get_keys(owl_dict *d, owl_list *l) {
-  int i;
-  char *dupk;
-  if (owl_list_create(l)) return(-1);
-  for (i=0; i<d->size; i++) {
-    if ((dupk = owl_strdup(d->els[i].k)) == NULL) return(-1);
-    owl_list_append_element(l, (void*)dupk);
-  }
-  return(0);
-}
-
-void owl_dict_noop_free(void *x) {
-  return;
-}
-
-/* Returns 0 on success.  Will copy the key but make 
-   a reference to the value.  Will clobber an existing 
-   entry with the same key iff free_on_replace!=NULL,
-   and will run free_on_replace on the old element.
-   Will return -2 if replace=NULL and match was found.
-*/
-int owl_dict_insert_element(owl_dict *d, char *k, void *v, void (*free_on_replace)(void *old)) {
-  int pos, found;
-  char *dupk;
-  found = _owl_dict_find_pos(d, k, &pos);
-  if (found && free_on_replace) {
-    free_on_replace(d->els[pos].v);
-    d->els[pos].v = v;
-    return(0);
-  } else if (found && !free_on_replace) {
-    return(-2);
-  } else {
-    if ((d->size+1) > (d->avail/GROWAT)) {
-      d->els=owl_realloc(d->els, d->avail*GROWBY*sizeof(void *));
-      d->avail=d->avail*GROWBY;
-      if (d->els==NULL) return(-1);
-    }
-    if ((dupk = owl_strdup(k)) == NULL) return(-1);
-    if (pos!=d->size) {
-      /* shift forward to leave us a slot */
-      memmove((void*)(d->els+pos+1), (void*)(d->els+pos), 
-	      sizeof(owl_dict_el)*(d->size-pos));
-    }
-    d->size++;
-    d->els[pos].k = dupk;
-    d->els[pos].v = v;    
-    return(0);
-  }
-}
-
-/* Doesn't free the value of the element, but does
- * return it so the caller can free it. */
-void *owl_dict_remove_element(owl_dict *d, char *k) {
-  int i;
-  int pos, found;
-  void *v;
-  found = _owl_dict_find_pos(d, k, &pos);
-  if (!found) return(NULL);
-  owl_free(d->els[pos].k);
-  v = d->els[pos].v;
-  for (i=pos; i<d->size-1; i++) {
-    d->els[i]=d->els[i+1];
-  }
-  d->size--;
-  return(v);
-}
-
-/* elefree should free the value as well */
-void owl_dict_free_all(owl_dict *d, void (*elefree)(void *)) {
-  int i;
-
-  for (i=0; i<d->size; i++) {
-    owl_free(d->els[i].k);
-    if (elefree) (elefree)(d->els[i].v);
-  }
-  if (d->els) owl_free(d->els);
-}
-
-void owl_dict_free_simple(owl_dict *d) {
-  owl_dict_free_all(d, NULL);
-}
-
-
-
-/************* REGRESSION TESTS **************/
-#ifdef OWL_INCLUDE_REG_TESTS
-
-#include "test.h"
-
-int owl_dict_regtest(void) {
-  owl_dict d;
-  owl_list l;
-  int numfailed=0;
-  char *av="aval", *bv="bval", *cv="cval", *dv="dval";
-
-  printf("# BEGIN testing owl_dict\n");
-  FAIL_UNLESS("create", 0==owl_dict_create(&d));
-  FAIL_UNLESS("insert b", 0==owl_dict_insert_element(&d, "b", (void*)bv, owl_dict_noop_free));
-  FAIL_UNLESS("insert d", 0==owl_dict_insert_element(&d, "d", (void*)dv, owl_dict_noop_free));
-  FAIL_UNLESS("insert a", 0==owl_dict_insert_element(&d, "a", (void*)av, owl_dict_noop_free));
-  FAIL_UNLESS("insert c", 0==owl_dict_insert_element(&d, "c", (void*)cv, owl_dict_noop_free));
-  FAIL_UNLESS("reinsert d (no replace)", -2==owl_dict_insert_element(&d, "d", (void*)dv, 0));
-  FAIL_UNLESS("find a", (void*)av==owl_dict_find_element(&d, "a"));
-  FAIL_UNLESS("find b", (void*)bv==owl_dict_find_element(&d, "b"));
-  FAIL_UNLESS("find c", (void*)cv==owl_dict_find_element(&d, "c"));
-  FAIL_UNLESS("find d", (void*)dv==owl_dict_find_element(&d, "d"));
-  FAIL_UNLESS("find e (non-existent)", NULL==owl_dict_find_element(&d, "e"));
-  FAIL_UNLESS("remove d", (void*)dv==owl_dict_remove_element(&d, "d"));
-  FAIL_UNLESS("find d (post-removal)", NULL==owl_dict_find_element(&d, "d"));
-
-  FAIL_UNLESS("get_size", 3==owl_dict_get_size(&d));
-  FAIL_UNLESS("get_keys", 0==owl_dict_get_keys(&d, &l));
-  FAIL_UNLESS("get_keys result size", 3==owl_list_get_size(&l));
-  
-  /* these assume the returned keys are sorted */
-  FAIL_UNLESS("get_keys result val",0==strcmp("a",owl_list_get_element(&l,0)));
-  FAIL_UNLESS("get_keys result val",0==strcmp("b",owl_list_get_element(&l,1)));
-  FAIL_UNLESS("get_keys result val",0==strcmp("c",owl_list_get_element(&l,2)));
-
-  owl_list_free_all(&l, owl_free);
-  owl_dict_free_all(&d, NULL);
-
-  /*  if (numfailed) printf("*** WARNING: failures encountered with owl_dict\n"); */
-  printf("# END testing owl_dict (%d failures)\n", numfailed);
-  return(numfailed);
-}
-
-#endif /* OWL_INCLUDE_REG_TESTS */
Index: c/advanced.txt
===================================================================
--- doc/advanced.txt	(revision c82b055f7e68fdc0972d575b4222a19fff792159)
+++ 	(revision )
@@ -1,201 +1,0 @@
-                     ========================
-                     Owl Advanced Users Guide
-                     ========================
-
-
-=========================
-Section X: COMMAND ALISES
-=========================
-
-[see Section 4 in intro.txt, which may want to be moved here]
-
-=======================
-Section X: KEY BINDINGS
-=======================
-
-[see Section 4 in intro.txt, which may want to be moved here]
-
-=========================
-Section X: CUSTOM FILTERS
-=========================
-
-For example, the following
-command will create a filter called 'mail' that maches any messages
-sent to the zephyr class 'mail':
-
-     filter mail class ^mail$
-
-The first argument after the filter command specifies the name of the
-filter to be created.  The text after that indicates that matching
-messages must have the zephyr class "mail".  For help understanding
-the '^' and '$' characters, consult a reference on regular
-expressions.  Note that all pattern matching in Owl is
-case-insensitive.
-
-The message fields that can be used in a filter command include:
-
-     sender        message sender
-     recipient     message recipient
-     class         zephyr class name
-     instance      zephyr instance name
-     opcode        zephyr opcode
-     realm         zephyr realm
-     body          message body
-     type          message type ('zephyr', 'aim', 'admin')
-     direction     either 'in' 'out' or 'none'\n"
-     login         either 'login' 'logout' or 'none'\n" 
-
-You can also use the operators 'and' 'or' and 'not' as well as the
-values 'true' and 'false'.  Parentheses can be used to group
-expressions, though there must be spaces present before and after all
-parenthesis.  For example:
-
-   filter myfilt ( class ^foo$ ) or ( class ^quux$ and instance ^bar$ )
-
-If you define a filter using a filter name that already exists, it
-will overwrite the existing filter.  This can be a useful way to
-override the built-in filters.
-
-
-=========================================
-Section 6: THE PERL EXTENSION CONFIG FILE
-=========================================
-
-*** WARNING: This interface is still evolving and may change over time ***
-
-The ~/.owlconf file is interpreted by the perl interpreter. 
-You may specify an alternate file by running owl with "owl -c <configfile>".
-
-Subroutines created with the names below will be executed at the
-specified times:
-
-    subroutine name    properties
-    ---------------    ----------
-    owl::startup()     run when owl first starts
-    owl::shutdown()    run when owl exits
-    owl::format_msg()  run to format messages when using the perl style.
-		       The return value is used to display the message on the
-                       screen. 
-    owl::receive_msg() run when a message is received, and after
-		       it has been added to the message list
-
-It is possible to call back into owl and execute owl commands
-from within these functions.  This is particularly useful
-in owl::startup for setting up your initial owl environment.
-If you wish to execute an owl command use the function owl::command().  i.e.
-
-     owl::command('set zsigproc "/mit/kretch/bin/getzsig foo"');
-
-will set the owl variable zsigproc to 
-the value "/mit/kretch/bin/getzsig foo".
-Note that you will need to watch out for perl quoting issues.
-[It may be worth talking about them a little here...]
-
-Both owl::format_msg and owl::receive_msg are passed perl owl::Message
-objects which have methods for accessing the attributes of the message.  
-
-(Caveat: Note that these owl::Message objects are currently only
-	 snapshots of the message contents that are created as needed.  As
-	 such, there could be multiple owl::Message objects for the same owl
-	 message.  Use the msgid if you want to uniquely identify individual
-	 messages.)
-
-All owl::Message objects contain the following methods:
-
-    type      - returns the type of the message ("zephyr", "aim", "admin")
-    direction - returns "in" or "out" for incoming or outgoing messages
-    time      - returns a string of the time when the message showed up
-    id	      - returns a unique id for the message
-    body      - returns the body text of the message
-    sender    - returns the sender of the message
-    recipient - returns the recipient of the message
-    login     - returns either "login", "logout", or "none"
-    is_login  - returns true if this is a login message
-    is_logout - returns true if this is a logout message
-    is_loginout - returns true if this is a login or logout message
-    is_incoming - returns true if this is an incoming message
-    is_outgoing - returns true if this is an outgoing message
-    is_deleted  - returns true if this message is marked for deletion
-    is_<type>	- returns true if the message is of type <type> (eg, is_zephyr)
-    delete	- marks the message for deletion
-    undelete	- unmarks the message from deletion
-    pretty_sender - returns a cleaned up version of the sender
-
-The following owl::Message methods are only applicable to
-various message types:
-
-    header	- returns the admin message header line  (admin)
-    is_personal - returns true if this is a personal message (aim,zephyr)
-    is_private  - returns true if this was a private message (zephyr)
-    login_tty	- returns the login tty for login messages (zephyr)
-    login_host  - returns the login host for login messages (zephyr)
-    zwriteline  - returns the zwrite command line for outgoing zephyrs (zephyr)
-    zsig	- returns the zsig (zephyr)
-    is_ping	- returns true if this was a zephyr ping (zephyr)
-    is_mail	- returns true if this was a new mail notification (zephyr)
-    class	- returns the zephyr class (zephyr)
-    instance	- returns the zephyr instance (zephyr)
-    realm	- returns the zephyr realm (zephyr)
-    opcode	- returns the zephyr opcode (zephyr)
-    hostname	- returns the zephyr sender's hostname (zephyr)
-    fields	- returns the zephyr fields as a perl list (zephyr)
-    auth	- returns whether this zephyr was authentic (zephyr)
-
-An example formatting function that formats messages so that they only
-list the direction, sender, and time would be:
-
-    sub owl::format_msg {
-	my ($m) = @_;    # assigns the message object passed
-			 # to this function to $m
-	return sprintf "[direction=%s] from sender %s at %s\n",
-		       $m->direction,
-		       $m->sender,
-		       $m->time;
-    }
-
-In the above, $m is the owl::Message object and 
-its methods are called with $m->METHODNAME.
-
-An example receiver function that tags all zephyr pings for 
-deletion would be:
-
-    sub owl::receive_msg {
-	my ($m) = @_;    # assigns the message object passed
-			 # to this function to $m
-	if ($m->is_zephyr and $m->is_ping) {
-	   $m->delete();
-	}
-    }
-
-
-=================
-Section X: STYLES
-=================
-
-
-
-
-
-========================================
-Section 7: PERL COMMANDS FROM WITHIN OWL
-========================================
-
-Perl code may be executed from within owl with:
-
-  perl <perlcode>
-
-If you use pperl instead of perl, the return value
-of the perl command will be displayed in a pop-up window.
-This is particularly useful within key bindings 
-and aliases.  For example:
-
-  alias finger pperl $x=owl::getcurmsg()->hostname; `finger \@$x`;
-
-Will cause the "finger" command to be used to finger at the host
-where the current message came from.  You can then bind this 
-to the "f" key with:
-
-   bindkey recv f command finger
-
-See the section above for detailss of commands and functions
-that are available from within the perl interpreter.
Index: c/barnowl.1
===================================================================
--- doc/barnowl.1	(revision fa1b15b6aa7075915078e2657f066dd24929b772)
+++ 	(revision )
@@ -1,92 +1,0 @@
-.TH barnowl 1 "23 Jun 2008"
-.SH NAME
-barnowl \- tty based zephyr client
-.SH SYNOPSIS
-.B barnowl
-[ \-n
-]
-[ \-d
-]
-[ \-D
-]
-[ \-v
-]
-[ \-h
-]
-[ \-c
-.I configfile
-]
-[ \-t
-.I tty
-]
-[ \-s
-.I configdir
-]
-.br
-.SH DESCRIPTION
-.B BarnOwl
-is a fully integrated tty based instant messaging client.  Currently
-it supports AOL Instant Messenger, MIT Zephyr, and Jabber.  It is
-curses-based, allows for emacs-style editing of outgoing messages and
-uses perl as an extension and configuration language.  BarnOwl will
-also run happily without a configuration file.
-
-Once BarnOwl is started, typing 'h' will display a help screen.
-Typing \':\' enters command mode, allowing the user to type a barnowl
-command line.
-
-.PP
-.SH USE
-The following command line options are avilable when running barnowl:
-
-.B \-n
-.IP
-Do not subscribe to zephyr messages on startup.  By default BarnOwl
-subscribes to the default subscriptions and to anything found in
-~/.zephyr.subs.  When this option is used no subscriptions are loaded.
-.LP
-
-.B \-c \fIconfigfile\fP
-.IP
-Specifiy an alternate config file for BarnOwl to use.  By default,
-barnowl uses ~/.barnowlconf if it exists, and ~/.owlconf otherwise.
-.LP
-
-.B \-s \fIconfigdir\fP
-.IP
-Specify an alternate configuration directory. By default, BarnOwl uses
-~/.owl/.
-.LP
-
-.B \-t \fItty\fP
-.IP
-Specifiy the tty name to use for the zephyr location.
-.LP
-
-.B \-v
-.IP
-Print the version number of barnowl and exit.
-.LP
-
-.B \-d
-.IP
-Enable debugging.  By default debugging information is placed in
-/var/tmp/owldebug.
-.LP
-
-.B \-D
-.IP
-Enable debugging, but first delete any existing debugging file.
-.LP
-
-.B \-h
-.IP
-Print command line option help.
-.LP
-
-.SH AUTHOR
-Written by Nelson Elhage and Alejandro Sedeno at the Massachusetts
-Institute of Technology. Based on Owl by James Kretchmar.
-
-Comments, questions, and bug reports may be mailed to
-\fBbug-barnowl@mit.edu\fP.
Index: c/code.txt
===================================================================
--- doc/code.txt	(revision 61d27fb7d4fede825fd1c05d45c6ce98aca792ba)
+++ 	(revision )
@@ -1,199 +1,0 @@
-
-$Id$
-
-
-TYPES / CLASSES / SOURCE FILES
-------------------------------
-
-cmd:	     Underlying implementation of command table management
-	     and command dispatching.  Also handles the implementation
-	     of command aliases.
-
-commands:    Dispatching for commands and handling of their arguments.
-	     (Commands are the interface exported to the user.)
-	     Many commands tend to be backed by functions.
-	     In general, a command takes a string as an argument
-	     and optionally returns a string.
-	     At the top of the file is a table mapping
-	     command names and help to functions implementing them.
-	     The standard entrypoint for executing a command
-	     is owl_function_command("foo");
-	     Commands are only active within specific contexts,
-	     and attempts to call them from invalid contexts will fail.	     
-
-context:     A context specifies the current state of owl, in terms 
-	     of which modal window is active and which point
-	     in its life owl is in (eg, in startup, or running).
-	     This is implemented as a bitmask and there is 
-	     some hierarchy.  Commands may restrict themselves
-	     to only running in a limited number of contexts
-	     to prevent commands from being executed at points
-	     when they not make sense.  Also, the data from
-	     the active context (eg, a pointer to an active window)
-	     may be passed to a command.
-
-dict:	     Simple dictionary abstraction mapping from strings to pointers.
-
-editwin:     Text editing window (both multiline and single line).
-	     Sometimes also referred to as typewin.
-
-filter:	     Patterns which match messages.  These may 
-	     contain multiple filterelements which may be 
-	     combined together (eg, by "and" and "or").
-	     
-filterelement: An element of a filter which matches on some 
-	       attribute of a message.
-
-fmtext:      Formatted text routines (handles things like @i{foo}).
-	     These are particularly useful for building up
-	     text regions that are to be rendered on-screen,
-	     as they resize memory as needed, and they have 
-	     routines for cropping as needed.
-
-functions:   Where most features are implemented.
-	     Users should always interact with functions through commands.
-	     In general, functions are abstract entrypoints into the
-	     system and attempt to hide access to global state.
-
-global:	     Global state and variables and toplevel objects.
-	     owl.h defines "g" as a singleton instance of owl_global.
-	     Where possible/appropriate, most accesses to global data should
-	     be from a limited number of files (eg, from owl.c and 
-	     functions.c).  Consider whether you really need to before
-	     adding in uses of global.
-
-help:	     Help strings for commands and key bindings.
-	     Most of this is now in keys.c, commands.c, and variables.c,
-	     along with the definition of commands and keybindings.
-
-keys:	     Default key binding definitions for all keymaps.
-	     This also includes default actions for keymaps.
-
-keybinding:  Binding between a sequence of keypresses and a command.
-	     When executed, this executes the commands.  The sequence
-	     of keypresses is kept as a stack.  Keybindings are a part
-	     of keymaps.
-
-keypress:    Utility routines for translating between keypress values and
-	     and human-readable key names.
-
-keymap:      Contains both keymap and keyhandler.  A keymap is contains a
-	     list of keybindings, a sub-keymap, and optionally a
-	     default handler function.  The sub-keymap is a more
-	     general keymap which is consulted if the specific keymap
-	     doesn't contain a match.  (For example, the "global"
-	     keymap is the ancestor of all other keymaps.)  The
-	     keyhandler is a collection of keymaps which handles
-	     checking for key matches within keymaps.  It maintains a
-	     stack of keypresses and compares them against the
-	     bindings in keymaps.  It also handles ESC as a prefix for
-	     Meta.  At any one time, there is exactly one active
-	     keymap which determines where keybindings are looked for
-	     (along with its submaps).
-
-list:	     Simple list abstraction.  (Uses realloc to resize the list.)
-
-logging:     Interface to incoming / outgoing zephyr logging.
-
-mainwin:     Window that displays the list of messages.
-	     (Sometimes also referred to as recwin.)
-
-message:     Abstraction to messages.  Currently, messages
-	     are either of type zephyr or of type admin.
-
-messagelist: List of messages.
-
-owl.c:	     main() and signal handlers and other initial setup.
-	     Also contains the main loop, which is roughly:
-	     - handle scheduled resizes, and anything that might result
-	     - while zephyrs are pending, grab incoming zephyrs 
-	       and handle them (which includes formatting them
-	       with either perl extension or default formatter
-	       as part of owl_message_create_from_zephyr).
-	     - updates mainwin display if there are new zephyrs
-	     - displays and updates popwins and the terminal as necessary
-	     - sends characters to the popwin, recwin/mainwin, 
-	       or typewin/editwin
-
-
-owl.h:	     Prototypes for all types, as well as global constants.
-
-owl_prototypes.h:  Autogenerated prototypes for all functions.
-		   Created by codelist.pl.
-
-popwin:      Modal pop-up window container. 
-	     Usually contains a viewwin for read-only scrolling text.
-
-readconfig:  Perl extension interface.
-
-text:	     Text formatting utilities (ie, indenting, truncating, etc)
-
-util:	     Misc utility functions that don't fit anywhere yet:
-	     - sepbar rendering 
-	     - tokenizing and parsing utilities
-	     - downstr
-	     - stristr
-	     - owl_malloc/free/realloc
-
-variable:    Interface to setting and getting variables.
-	     Current variable types include bool, int, string, and other.
-	     There's also an enum type which is variant of int.
-	     Variables can be created and customized here as well.
-
-varstubs.c:  Autogenerated headers for accessing global variables
-
-view:	     A collection of messages determined by a filter.
-	     Many operations may be performed on the members
-	     of a view, and a view can be narrowed-to for display.
-
-viewwin:     Read-only scrolling text displayed in a modal popwin.
-	     This is also sometimes called "popless".
-
-zephyr:	     Routines for interfacing to zephyr.
-
-zwrite:	     Outgoing zephyrs.  Sends pings on creation,
-	     handles command arguments, etc.
-
-
-===========================================================================
-
-CURSES WINDOWS
---------------
-
-The four curses windows on the screen are
-
-  recwin - receiving window
-  sepwin - seperator window
-  msgwin - message window
-  typwin - typing window
-
-
-===========================================================================
-
-
-MISC THINGS
------------
-
-userclue:  right now userclue is just used to decide if you sub to
-	   classes other than the default.  If you don't it doesn't bother
-	   making your personal messages bold since there's no point in
-	   making every message bold.
-
-
-
-===========================================================================
-
-Conventions and Design Criteria
--------------------------------
-
-	There are no hard rules for memory allocation.  In general I
-	have the caller allocate memory for objects themselves and any
-	memory the object creates gets freed with object_free().
-	Functions should document if the caller needs to free
-	something, and this should be the exception to the rule.
-
-	Owl should be generally useful out-of-the-box without 
-	extensive configuration, for most people's needs.  
-	People shouldn't have to spend days tweaking
-	with config files before being happy switching to it.
-
Index: c/intro.txt
===================================================================
--- doc/intro.txt	(revision aa1bbf6085c95394ceff671058e7ec5130185acb)
+++ 	(revision )
@@ -1,462 +1,0 @@
-                     ========================
-                     Quick Guide To Using Owl
-                     ========================
-
-=======================
-Section 1: INTRODUCTION
-=======================
-
-Owl is a tty, curses-based instant messaging client.  This is a quick
-guide to learning how to use it.  Currently Owl supports AIM & zephyr,
-but other messaging protocols, including Jabber, are on the way.  Some
-major features of owl include:
-
-   o) As a tty client it can be run over telnet, rlogin or text ssh
-      sessions
-
-   o) It uses a perl configuration file for setting preferences and
-      formatting messages
-
-   o) Emacs style editing of messages
-
-   o) It is easy to use and runs without a configfile.
-
-   o) Advanced sorting and coloring of messages
-
-==========================
-Section 2: GETTING STARTED
-==========================
-
-Owl will run happily without a configuration file, so to get started
-just run the program.  Owl will take over the terminal window it is
-started in, so you may wish to have another terminal window available
-at the same time.
-
-On Athena you can find owl in the ktools locker.  To run it, type:
-
-     add ktools
-     owl
-
-at the Athena% prompt.  If you wish to run the latest beta release of
-owl use:
-
-     add ktools
-     owl-beta
-
-instead.  The beta release will often have newer features, but is not
-as tried and true as the production release.  As a result it may be
-less stable.
-
-The Screen Layout
------------------
-There are three main parts to the owl screen.  The large top portion
-of the screen is where messages are displayed.  The status bar
-separates this area from the one below and displays owl status
-information.  The space below that is used to type messages and is
-also used by owl to give warnings and information to the user.
-
-On Line Help
-------------
-Owl has a full on line help system.  Pressing the 'h' key will bring
-up the basic help screen.  Further help can be obtained using the help
-command, described later.
-
-Sending a Zephyr
-----------------
-To send a zephyr press the 'z' key.  This will start a zwrite command,
-which you can finish by typing the name of the user you wish to send
-to, followed by enter.  Begin typing your message.  You will notice
-that most emacs-style editing is available.  When you are ready to
-send the message type Control-D or a dot ('.') on a line by itself.
-If instead you wish to cancel the message type Control-C.
-
-If you wish to send to a class/instance pair simply supply -c and -i
-arguments to the zwrite command as you normally would.
-
-Sending an AIM message
-----------------------
-
-Before sending an AIM message you must login to AOL Instant Messenger.
-Use the 'aimlogin' command, with your screenname as an argument:
-
-     aimlogin <screenname>
-
-You will be prompted for your password, which you must enter.  Once
-you are successfully logged in you can send an AIM message by pressing
-the 'a' key, which will bring up an 'aimwrite' command:
-
-     aimwrite <screenname>
-
-Supply the screen name you wish to write to as an argument and then
-send the message just as you would send a zephyr, as described above.
-
-Manipulating Messages
----------------------
-When there are zephyrs in the message window, one of them will be the
-'current' message.  Owl will indicate which one it is with an arrow
-that looks like this: -> The following keys will move you to different
-messages:
-
-     n		  move to the next non-deleted message
-     p		  move to the previous non-deleted message
-     C-n or down  move to the next message
-     C-p or up	  move to the previous message
-     <		  move to the first message
-     >		  move to the last message
-     C-v          page down
-     M-v          page up
-     right        scroll the screen to the right
-     left         scroll the screen to the left
-     P            move to the next personal message
-     M-P          move to the previous personal message
-
-When you are ready to delete a message you can mark it for deletion
-with the 'd' key, and a 'D' will appear to the left of the message.
-Messages will not actually be removed until you perform an expunge.
-The following keys are used to delete, undelete and expunge messages:
-
-     d		  mark a message for deletion
-     u		  unmark a message for deletion
-     x		  expunge deleted messages
-     T		  mark all 'trash' messages for deletion
-     M-D          mark all messages in the view for deletion
-     M-u          unmark all messages in the view for deletion
-
-If you would like to respond to a message sent to you there is a reply
-shortcut:
-
-     r            Reply.  Personal messages get a personal reply,
-                       group messages get a group reply.
-     R            Reply to sender.  Always replies personally
-                       to the sender.
-     M-r          Reply but allow editing of the command line.
-     M-R          Reply to sender but allow editing of the
-                       command line.
-
-In the event that the current message is too large to fit on the
-screen, you can scroll within the message using the following keys:
-
-     SPACE        page down
-     b            page up
-     RETURN       line down
-     BACKSPACE    line up
-
-The message pointer will change to indicate that the message is not
-starting at the first line.
-
-Two other keys that relate to the current message:
-
-     i 		  print detailed information about the message
-     w            instruct netscape to visit a URL in the message
-
-Other Functions
-----------------
-Some other functions that can be performed with a single keystroke:
-
-     A            toggle zephyr zaway on or off
-     C-l          refresh and resize the screen
-     C-z          suspend
-
-Command Mode
-------------
-Owl has a command mode from which you can enter more detailed commands
-for Owl to process.  To enter command mode press the colon (':') key:
-
-     :		  begin command mode
-
-Owl will give you a command prompt and you can begin typing your
-command.  Type Enter to execute the command, Control-C to cancel.
-There are many commands.  The basic commands are listed on the basic
-help screen (by pressing 'h').  If you'd like a list of all commands
-you can use the command:
-
-     show commands
-
-And for detailed information on the syntax and use of a command you
-can use:
-
-     help <command>
-
-For example "help zwrite" will display all the options available when
-using the zwrite command.
-
-Variables
----------
-Owl has a number of internal variables that can be used to change the
-behavior the program.  The 'print' command will let you view the value
-of a variable and the 'set' commmand will let you set the value of a
-variable.  For example:
-
-     set personalbell on 
-
-will set the value of the variable 'personalbell' to 'on'.  The
-command:
-
-     print personalbell
-
-will show you the current value.  The 'print' command with no
-arguments:
-
-     print
-
-Owl will show you the value of all variables.  You can also use
-
-     show variables
-
-     show variable <variable>
-
-To display further information on owl variables.
-
-
-================
-Section 3: VIEWS
-================
-
-Owl always displays a current "view" of messages.  The view describes
-which set of messages should be included on the display.  The default
-view is called "all" and includes every message.  However, you can
-narrow the view to a particular set of messages:
-
-     M-n          Narrow view to the selected conversation
-     M-N          Narrow view to selected conversation by instance
-     V            Return to the home view (the 'all' view)
-     X            Expunge messages and return to home view
-
-If you press M-n while the pointer is on a personal message, the view
-will be narrowed to the conversation with that user only.  If used on
-a group message the conversation will be narrowed to that group.
-
-There are also some Owl commands related to views:
-
-     viewclass <class>     Narrow the view to the named zephyr class
-     viewuser <user>       Narrow the view to the named user
-
-More information on views and how they work is included in the section
-on "FILTERS AND COLORS".
-
-=============================
-Section 4: FILTERS AND COLORS
-=============================
-
-Filters
--------
-Owl will allow you to create custom message filters.  A message filter
-is an expression that matches a set of messages based on certain
-criteria.  Owl comes with a number of build-in filters already.  You can
-view a list of them with the command:
-
-     show filters
-
-The default filters include:
-
-     all              Matches all messages
-     none             Matches no messages
-     personal         Only personal messages (no group messages)
-     login            Login/Logout notifications
-     auto             Messages generated by automated programs
-     out              Messages sent from you to another user
-     aim              AIM messages
-     zephyr           Zephyr messages
-     trash            "Trash" messages
-     ping             Zephyr pings
-     reply-lockout    Messages for which the reply commands
-                          should not work
-
-If you wish to view the messages that match a particular filter, use
-the 'view' command.  For example:
-
-     view personal
-
-This will display only personal messages on the screen.  You can
-change back to the 'all' view by pressing the 'V' key (capitalized).
-Note that the 'v' key (not capitalized) is a shortcut to bring up the
-'view' command.
-
-You can also create your own filters.  For more information on this,
-consult the Owl Advanced Users Guide.
-
-Colors
-------
-Every filter can have a color associated with it.  Messages matching
-the filter will then be displayed in that color if your terminal
-supports it.  The color for a filter can be set by using the '-c'
-option to the filter command.  For example:
-
-     filter personal -c white
-
-This cause all messages in the 'personal' filter to be displayed in
-white.  You can produce a list of the colors available to Owl with the
-command:
-
-     show colors
-
-If a message matches more than one filter it will be displayed in the
-color specified in the last filter listed in the 'show filters'
-command.
-
-If you would like your color settings to persist, such that they are
-preset every time you start Owl, please read the "Saving Your
-Settings" section below.
-
-===============================
-Section 5: SAVING YOUR SETTINGS
-===============================
-
-Any changes you make to Owl are lost when the program is terminated,
-unless you specify otherwise.  If you would like a setting to persist
-such that it is available every time you start Owl you can use the
-word 'startup' before any command.  For example:
-
-     startup filter personal -c white
-
-Will instruct Owl to color personal messages white both in the current
-session and in any future Owl session.  You may revert this behavior
-with the 'unstartup' command:
-
-     unstartup filter personal -c white
-
-which will not affect the current session, but will cause future
-sessions not to take this action.
-
-Here is another example, this instructs Owl to display zephyr ping
-messages:
-
-     startup set rxping on
-
-==========================
-Section 6: THE CONFIG FILE
-==========================
-
-*** WARNING: This interface may change substantially in the near future ***
-
-The ~/.owlconf file is interpreted by the perl interpreter.  You may
-specify an alternate file by running owl with "owl -c <configfile>".
-
-If you wish to execute an owl command from .owlconf use the function
-owl::command().  i.e.:
-
-     owl::command('set zsigproc "/mit/kretch/bin/getzsig foo"');
-
-Subroutines created with the names below will be executed at the
-specified times:
-
-    subroutine name    properties
-    ---------------    ----------
-    owl::startup()     run when owl first starts
-    owl::shutdown()    run when owl exits
-    owl::format_msg()  run to format messages when using the perl style.
-		       The return value is used to display the message on the
-                       screen. 
-    owl::receive_msg() run when a message is received, and after
-		       it has been added to the message list
-
-Both owl::format_msg and owl::receive_msg are passed perl owl::Message
-objects which contain attributes of the message.  Please see the
-advanced.txt file for further documentation of the Perl extension API.
-
-The "appendtosepbar" variable may be set in owl::format_msg() to set
-text to be appended to sepbar that separates the received message list
-from the edit window.
-
-
-==========================================
-Section 4: KEYBINDINGS AND COMMAND ALIASES
-==========================================
-
-Aliases
--------
-
-Command aliases allow users to create shortcuts
-for commonly used commands.  Aliases can be created wit
-the alias command:
-
-    alias NAME VALUE
-
-For example:
-
-    alias zw zwrite
-
-Will make "zw" an alias for the zwrite command.  As such, "zw aphacker"
-will be expanded to "zwrite aphacker".  If the value of an
-alias is multiple words, use of the alias will result in the alias
-command name being replaced by the sequence of words.
-Any arguments following the alias name will be appended
-after the expanded alias value.  For example:
-
-   alias vs view -s
-
-will result in "vs standard" being expanded to "view -s standard".
-There is not yet any way to allow an alias to take arguments
-that will be inserted in the middle of the expansion.
-
-
-Separating Commands
--------------------
-
-Multiple commands can be grouped together with parentheses
-and then separated by semicolons.  For example:
-
-   ( smartnarrow ; delete view ; expunge ; view all )
-
-Will result in the four commands being executed
-in sequence.  This is particularly useful with key bindings
-and coommands.  For example:
-
-   alias sn-delete ( smartnarrow ; delete view )
-
-will create an "sn-delete" alias that will smartnarrow
-to a view and them mark the view for deletion.
-
-Using "show commands" will list all existing aliases.
-
-
-Key Bindings
-------------
-
-New key bindings may be created with the "bindkey" command.  Each key
-binding is associated with a particular keymap which is applicable in
-a particular context/situation.  When the key associated with a
-binding is pressed in the right context, it will result in an owl
-command being run.  The syntax is:
-
-   bindkey <keymap> <keyseq> command <command>
-
-For example:
-
-   bindkey recv C-k command delete 
-
-will bind Control-k to the delete command, but only in the 
-recv window context.
-
-Some keymaps inherit their bindings from more 
-general keymaps.  The valid keymaps are:
-
-  - global	      - owl-wide defaults (apply everywhere)
-    |-edit	      - all text editing and command windows
-    |  |-editmulti    - multi-line text editing windows
-    |  |-editline     - single-line editing and command windows
-    |  |-editresponse - single-line responses to questions
-    |-popless	      - scrolling pop-up windows
-    |-recv	      - the main message list window 
-			where received messages are displayed
-
-The existing key bindings can be shown with "show keymaps".
-The use of "show commands" will list all available commands.
-Note that not all commands may be used in all contexts.
-
-Key sequences may be surrounded by quotes and include 
-a sequence of keys that must be pressed in order
-to execute the command.  For example:
-
-   bindkey recv "C-s v" command view -s vt
-
-will result in "Control-s" followed by "v" in the recv window
-causing the command "view -s vt" to be run.
-
-
-
-==============================
-Section 6: FURTHER INFORMATION
-==============================
-
-$Id$
Index: itwin.c
===================================================================
--- editwin.c	(revision e9bb404064914673e4c9588dccf789ce2c5d2fbc)
+++ 	(revision )
@@ -1,1223 +1,0 @@
-#include "owl.h"
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-
-static const char fileIdent[] = "$Id$";
-
-#define INCR 5000
-
-/* initialize the editwin e.
- * 'win' is an already initialzed curses window that will be used by editwin
- */
-void owl_editwin_init(owl_editwin *e, WINDOW *win, int winlines, int wincols, int style, owl_history *hist)
-{
-  e->buff=owl_malloc(INCR);  
-  e->buff[0]='\0';
-  e->bufflen=0;
-  e->hist=hist;
-  e->allocated=INCR;
-  e->buffx=0;
-  e->buffy=0;
-  e->topline=0;
-  e->winlines=winlines;
-  e->wincols=wincols;
-  e->fillcol=owl_editwin_limit_maxcols(wincols-7, owl_global_get_edit_maxfillcols(&g));
-  e->wrapcol=owl_editwin_limit_maxcols(wincols-7, owl_global_get_edit_maxwrapcols(&g));
-  e->curswin=win;
-  e->style=style;
-  if ((style!=OWL_EDITWIN_STYLE_MULTILINE) &&
-      (style!=OWL_EDITWIN_STYLE_ONELINE)) {
-    e->style=OWL_EDITWIN_STYLE_MULTILINE;
-  }
-  e->lock=0;
-  e->dotsend=0;
-  e->echochar='\0';
-
-  /* We get initialized multiple times, but we need to hold on to
-     the callbacks, so we can't NULL them here. */
-  /*
-    e->command = NULL;
-    e->callback = NULL;
-    e->cbdata = NULL;
-  */
-  if (win) werase(win);
-}
-
-void owl_editwin_set_curswin(owl_editwin *e, WINDOW *w, int winlines, int wincols)
-{
-  e->curswin=w;
-  e->winlines=winlines;
-  e->wincols=wincols;
-  e->fillcol=owl_editwin_limit_maxcols(wincols-7, owl_global_get_edit_maxfillcols(&g));
-  e->wrapcol=owl_editwin_limit_maxcols(wincols-7, owl_global_get_edit_maxwrapcols(&g));
-}
-
-/* echo the character 'ch' for each normal character keystroke,
- * excepting locktext.  This is useful for entering passwords etc.  If
- * ch=='\0' characters are echo'd normally
- */
-void owl_editwin_set_echochar(owl_editwin *e, int ch)
-{
-  e->echochar=ch;
-}
-
-WINDOW *owl_editwin_get_curswin(owl_editwin *e)
-{
-  return(e->curswin);
-}
-
-void owl_editwin_set_history(owl_editwin *e, owl_history *h)
-{
-  e->hist=h;
-}
-
-owl_history *owl_editwin_get_history(owl_editwin *e)
-{
-  return(e->hist);
-}
-
-void owl_editwin_set_dotsend(owl_editwin *e)
-{
-  e->dotsend=1;
-}
-
-void owl_editwin_set_command(owl_editwin *e, char *command) {
-  if(e->command) owl_free(e->command);
-  e->command = owl_strdup(command);
-}
-
-char *owl_editwin_get_command(owl_editwin *e) {
-  if(e->command) return e->command;
-  return "";
-}
-
-void owl_editwin_set_callback(owl_editwin *e, void (*cb)(owl_editwin*)) {
-  e->callback = cb;
-}
-
-void (*owl_editwin_get_callback(owl_editwin *e))(owl_editwin*) {
-  return e->callback;
-}
-
-void owl_editwin_set_cbdata(owl_editwin *e, void *data) {
-  e->cbdata = data;
-}
-
-void* owl_editwin_get_cbdata(owl_editwin *e) {
-  return e->cbdata;
-}
-
-void owl_editwin_do_callback(owl_editwin *e) {
-  void (*cb)(owl_editwin*);
-  cb=owl_editwin_get_callback(e);
-  if(!cb) {
-    owl_function_error("Internal error: No editwin callback!");
-  } else {
-    /* owl_function_error("text: |%s|", owl_editwin_get_text(e)); */
-    cb(e);
-  }
-}
-
-int owl_editwin_limit_maxcols(int v, int maxv)
-{
-  if (maxv > 5 && v > maxv) {
-    return(maxv);
-  } else {
-    return(v);
-  }
-}
-
-/* set text to be 'locked in' at the beginning of the buffer, any
- * previous text (including locked text) will be overwritten
- */
-void owl_editwin_set_locktext(owl_editwin *e, char *text)
-{
-  
-  int x, y;
-
-  x=e->buffx;
-  y=e->buffy;
-  e->buffx=0;
-  e->buffy=0;
-  owl_editwin_overwrite_string(e, text);
-  owl_editwin_overwrite_char(e, '\0');
-  e->lock=strlen(text);
-  /* if (text[e->lock-1]=='\n') e->lock--; */
-  /*  e->buffx=x; */
-  /*  e->buffy=y; */
-  _owl_editwin_set_xy_by_index(e, e->lock);
-  owl_editwin_redisplay(e, 0);
-}
-
-int owl_editwin_get_style(owl_editwin *e)
-{
-  return(e->style);
-}
-
-void owl_editwin_new_style(owl_editwin *e, int newstyle, owl_history *h)
-{
-  char *ptr;
-
-  owl_editwin_set_history(e, h);
-  if (e->style==newstyle) return;
-
-  if (newstyle==OWL_EDITWIN_STYLE_MULTILINE) {
-    e->style=newstyle;
-  } else if (newstyle==OWL_EDITWIN_STYLE_ONELINE) {
-    e->style=newstyle;
-
-    /* nuke everything after the first line */
-    if (e->bufflen > 0) {
-      ptr=strchr(e->buff, '\n')-1;
-      if (ptr) {
-	e->bufflen=ptr - e->buff;
-	e->buff[e->bufflen]='\0';
-	e->buffx=0;
-	e->buffy=0;
-      }
-    }
-  }
-}
-
-/* completly reinitialize the buffer */
-void owl_editwin_fullclear(owl_editwin *e)
-{
-  owl_free(e->buff);
-  owl_editwin_init(e, e->curswin, e->winlines, e->wincols, e->style, e->hist);
-}
-
-/* clear all text except for locktext and put the cursor at the
- * beginning
- */
-void owl_editwin_clear(owl_editwin *e)
-{
-
-  int lock;
-  int dotsend=e->dotsend;
-  char *locktext=NULL;
-  char echochar=e->echochar;
-
-  lock=0;
-  if (e->lock > 0) {
-    lock=1;
-
-    locktext=owl_malloc(e->lock+20);
-    strncpy(locktext, e->buff, e->lock);
-    locktext[e->lock]='\0';
-  }
-
-  owl_free(e->buff);
-  owl_editwin_init(e, e->curswin, e->winlines, e->wincols, e->style, e->hist);
-
-  if (lock > 0) {
-    owl_editwin_set_locktext(e, locktext);
-  }
-  if (dotsend) {
-    owl_editwin_set_dotsend(e);
-  }
-  if (echochar) {
-    owl_editwin_set_echochar(e, echochar);
-  }
-
-  if (locktext) owl_free(locktext);
-  owl_editwin_adjust_for_locktext(e);
-}
-
-/* malloc more space for the buffer */
-void _owl_editwin_addspace(owl_editwin *e)
-{
-  e->buff=owl_realloc(e->buff, e->allocated+INCR);
-  if (!e->buff) {
-    /* error */
-    return;
-  }
-  e->allocated+=INCR;
-}
-
-void owl_editwin_recenter(owl_editwin *e)
-{
-  e->topline=e->buffy-(e->winlines/2);
-  if (e->topline<0) e->topline=0;
-  if (e->topline>owl_editwin_get_numlines(e)) e->topline=owl_editwin_get_numlines(e);
-}
-
-/* regenerate the text on the curses window */
-/* if update == 1 then do a doupdate(), otherwise do not */
-void owl_editwin_redisplay(owl_editwin *e, int update)
-{
-  
-  char *ptr1, *ptr2, *ptr3, *buff;
-  int i;
-
-  werase(e->curswin);
-  wmove(e->curswin, 0, 0);
-
-  /* start at topline */
-  ptr1 = e->buff;
-  for (i = 0; i < e->topline; i++) {
-    ptr2 = strchr(ptr1, '\n');
-    if (!ptr2) {
-      /* we're already on the last line */
-      break;
-    }
-    ptr1 = ptr2 + 1;
-  }
-  /* ptr1 now stores the starting point */
-
-  /* find the ending point and store it in ptr3 */
-  ptr2 = ptr1;
-  ptr3 = ptr1;
-  for (i = 0; i < e->winlines; i++) {
-    ptr3 = strchr(ptr2, '\n');
-    if (!ptr3) {
-      /* we've hit the last line */
-      /* print everything to the end */
-      ptr3 = e->buff + e->bufflen - 1;
-      ptr3--;
-      break;
-    }
-    ptr2 = ptr3 + 1;
-  }
-  ptr3 += 2;
-
-  buff = owl_malloc(ptr3 - ptr1 + 50);
-  strncpy(buff, ptr1, ptr3 - ptr1);
-  buff[ptr3 - ptr1] = '\0';
-  if (e->echochar == '\0') {
-    waddstr(e->curswin, buff);
-  } else {
-    /* translate to echochar, *except* for the locktext */
-    int len;
-    int dolocklen = e->lock - (ptr1 - e->buff);
-    char *locktext;
-    char tmp = e->buff[dolocklen];
-
-    e->buff[dolocklen] = '\0';
-    locktext = owl_strdup(e->buff);
-    e->buff[dolocklen] = tmp;
-
-    waddstr(e->curswin, locktext);
-    
-    len = strlen(buff);
-    for (i = 0; i < len-dolocklen; i++) {
-      waddch(e->curswin, e->echochar);
-    }
-  }
-  wmove(e->curswin, e->buffy-e->topline, e->buffx + _owl_editwin_cursor_adjustment(e));
-  wnoutrefresh(e->curswin);
-  if (update == 1) {
-    doupdate();
-  }
-  owl_free(buff);
-}
-
-/* Remove n bytes at cursor. */
-void _owl_editwin_remove_bytes(owl_editwin *e, int n) /*noproto*/
-{
-  int i = _owl_editwin_get_index_from_xy(e) + n;
-  for (; i < e->bufflen; i++) {
-    e->buff[i-n] = e->buff[i];
-  }
-  
-  e->bufflen -= n;
-  e->buff[e->bufflen] = '\0';
-}
-
-/* Insert n bytes at cursor.*/
-void _owl_editwin_insert_bytes(owl_editwin *e, int n) /*noproto*/
-{
-  int i, z;
-
-  if ((e->bufflen + n) > (e->allocated - 5)) {
-    _owl_editwin_addspace(e);
-  }
-
-  z = _owl_editwin_get_index_from_xy(e);
-
-  if(z != e->bufflen) {
-    for (i = e->bufflen + n - 1; i > z; i--) {
-      e->buff[i] = e->buff[i - n];
-    }
-  }
-
-  e->bufflen += n;
-  e->buff[e->bufflen] = '\0';
-
-}
-
-
-/* linewrap the word just before the cursor.
- * returns 0 on success
- * returns -1 if we could not wrap.
- */
-int _owl_editwin_linewrap_word(owl_editwin *e)
-{
-  int x, y;
-  int i;
-  char *ptr1, *start;
-  gunichar c;
-
-  /* saving values */
-  x = e->buffx;
-  y = e->buffy;
-  start = e->buff + e->lock;
-
-  ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
-  ptr1 = g_utf8_find_prev_char(start, ptr1);
-
-  while (ptr1) {
-    c = g_utf8_get_char(ptr1);
-    if (owl_util_can_break_after(c)) {
-      if (c != ' ') {
-        i = ptr1 - e->buff;
-        _owl_editwin_set_xy_by_index(e, i);
-        _owl_editwin_insert_bytes(e, 1);
-        /* _owl_editwin_insert_bytes may move e->buff. */
-        ptr1 = e->buff + i;
-      }
-      *ptr1 = '\n';
-      return 0;
-    }
-    else if (c == '\n') {
-      return 0;
-    }
-    ptr1 = g_utf8_find_prev_char(start, ptr1);
-  }
-  return -1;
-}
-
-/* insert a character at the current point (shift later
- * characters over)
- */
-void owl_editwin_insert_char(owl_editwin *e, gunichar c)
-{
-  int z, i, ret, len;
-  char tmp[6];
-  memset(tmp, '\0', 6);
-
-  /* \r is \n */
-  if (c == '\r') {
-    c = '\n';
-  }
-
-  if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
-    /* perhaps later this will change some state that allows the string
-       to be read */
-    return;
-  }
-
-  g_unichar_to_utf8(c, tmp);
-  len = strlen(tmp);
-
-  /* make sure there is enough memory for the new text */
-  if ((e->bufflen + len) > (e->allocated - 5)) {
-    _owl_editwin_addspace(e);
-  }
-
-  /* get the insertion point */
-  z = _owl_editwin_get_index_from_xy(e);
-
-  /* If we're going to insert at the last column do word wrapping, unless it's a \n */
-  if ((e->buffx + 1 == e->wrapcol) && (c != '\n')) {
-    ret = _owl_editwin_linewrap_word(e);
-    if (ret == -1) {
-      /* we couldn't wrap, insert a hard newline instead */
-      owl_editwin_insert_char(e, '\n');
-    }
-  }
-
-  /* shift all the other characters right */
-  _owl_editwin_insert_bytes(e, len);
-
-  /* insert the new character */
-  for(i = 0; i < len; i++) {
-    e->buff[z + i] = tmp[i];
-  }
-
-  /* advance the cursor */
-  z += len;
-  _owl_editwin_set_xy_by_index(e, z);
-}
-
-/* overwrite the character at the current point with 'c' */
-void owl_editwin_overwrite_char(owl_editwin *e, gunichar c)
-{
-  int z, oldlen, newlen, i;
-  char tmp[6];
-  memset(tmp, '\0', 6);
-
-  /* \r is \n */
-  if (c == '\r') {
-    c = '\n';
-  }
-  
-  if (c == '\n' && e->style == OWL_EDITWIN_STYLE_ONELINE) {
-    /* perhaps later this will change some state that allows the string
-       to be read */
-    return;
-  }
-
-  g_unichar_to_utf8(c, tmp);
-  newlen = strlen(tmp);
-
-  z = _owl_editwin_get_index_from_xy(e);
-  {
-    char *t = g_utf8_find_next_char(e->buff + z, NULL);
-    oldlen = (t ? (t - (e->buff + z)) : 0);
-  }
-
-  /* only if we are at the end of the buffer do we create new space here */
-  if (z == e->bufflen) {
-    if ((e->bufflen+newlen) > (e->allocated-5)) {
-      _owl_editwin_addspace(e);
-    }
-  }
-  /* if not at the end of the buffer, adjust based in char size difference. */ 
-  else if (oldlen > newlen) {
-    _owl_editwin_remove_bytes(e, oldlen-newlen);
-  }
-  else /* oldlen < newlen */ {
-    _owl_editwin_insert_bytes(e, newlen-oldlen);
-  }
-  /* Overwrite the old char*/
-  for (i = 0; i < newlen; i++) {
-    e->buff[z+i] = tmp[i];
-  }
-       
-  /* housekeeping */
-  if (z == e->bufflen) {
-    e->bufflen += newlen;
-    e->buff[e->bufflen] = '\0';
-  }
-  
-  /* advance the cursor */
-  z += newlen;
-  _owl_editwin_set_xy_by_index(e, z);
-}
-
-/* delete the character at the current point, following chars
- * shift left.
- */ 
-void owl_editwin_delete_char(owl_editwin *e)
-{
-  int z;
-  char *p1, *p2;
-  gunichar c;
-
-  if (e->bufflen == 0) return;
-  
-  /* get the deletion point */
-  z = _owl_editwin_get_index_from_xy(e);
-
-  if (z == e->bufflen) return;
-
-  p1 = e->buff + z;
-  p2 = g_utf8_next_char(p1);
-  c = g_utf8_get_char(p2);
-  while (g_unichar_ismark(c)) {
-    p2 = g_utf8_next_char(p2);
-    c = g_utf8_get_char(p2);
-  }
-  _owl_editwin_remove_bytes(e, p2-p1);
-}
-
-/* Swap the character at point with the character at point-1 and
- * advance the pointer.  If point is at beginning of buffer do
- * nothing.  If point is after the last character swap point-1 with
- * point-2.  (Behaves as observed in tcsh and emacs).  
- */
-void owl_editwin_transpose_chars(owl_editwin *e)
-{
-  int z;
-  char *p1, *p2, *p3, *tmp;
-
-  if (e->bufflen == 0) return;
-  
-  /* get the cursor point */
-  z = _owl_editwin_get_index_from_xy(e);
-
-  if (z == e->bufflen) {
-    /* point is after last character */
-    z--;
-  }  
-
-  if (z - 1 < e->lock) {
-    /* point is at beginning of buffer, do nothing */
-    return;
-  }
-
-  /* Transpose two utf-8 unicode glyphs. */
-  p1 = e->buff + z;
-
-  p2 = g_utf8_find_next_char(p1, NULL);
-  while (p2 != NULL && g_unichar_ismark(g_utf8_get_char(p2))) {
-    p2 = g_utf8_find_next_char(p2, NULL);
-  }
-  if (p2 == NULL) return;
-
-  p3 = g_utf8_find_prev_char(e->buff, p1);
-  while (p3 != NULL && g_unichar_ismark(g_utf8_get_char(p3))) {
-    p3 = g_utf8_find_prev_char(p3, NULL);
-  }
-  if (p3 == NULL) return;
-
-  tmp = owl_malloc(p2 - p3 + 5);
-  *tmp = '\0';
-  strncat(tmp, p1, p2 - p1);
-  strncat(tmp, p3, p1 - p3);
-  strncpy(p3, tmp, p2 - p3);
-  owl_free(tmp);
-  _owl_editwin_set_xy_by_index(e, p3 - e->buff);
-}
-
-/* insert 'string' at the current point, later text is shifted
- * right
- */
-void owl_editwin_insert_string(owl_editwin *e, char *string)
-{
-  char *p;
-  gunichar c;
-  if (!g_utf8_validate(string, -1, NULL)) {
-    owl_function_debugmsg("owl_editwin_insert_string: received non-utf-8 string.");
-    return;
-  }
-  p = string;
-  c = g_utf8_get_char(p);
-  while (c) {
-    _owl_editwin_process_char(e, c);
-    p = g_utf8_next_char(p);
-    c = g_utf8_get_char(p);
-  }
-}
-
-/* write 'string' at the current point, overwriting text that is
- * already there
- */
-
-void owl_editwin_overwrite_string(owl_editwin *e, char *string)
-{
-  char *p;
-  gunichar c;
-
-  if (!g_utf8_validate(string, -1, NULL)) {
-    owl_function_debugmsg("owl_editwin_overwrite_string: received non-utf-8 string.");
-    return;
-  }
-  p = string;
-  c = g_utf8_get_char(p);
-  while (c) {
-    owl_editwin_overwrite_char(e, c);
-    p = g_utf8_next_char(p);
-    c = g_utf8_get_char(p);
-  }
-}
-
-/* get the index into e->buff for the current cursor
- * position.
- */
-int _owl_editwin_get_index_from_xy(owl_editwin *e)
-{
-  int i;
-  char *ptr1, *ptr2;
-  gunichar c;
-
-  if (e->bufflen == 0) return(0);
-  
-  /* first go to the yth line */
-  ptr1 = e->buff;
-  for (i = 0; i < e->buffy; i++) {
-    ptr2= strchr(ptr1, '\n');
-    if (!ptr2) {
-      /* we're already on the last line */
-      break;
-    }
-    ptr1 = ptr2 + 1;
-  }
-
-  /* now go to the xth cell */
-  ptr2 = ptr1;
-  i = 0;
-  while (ptr2 != NULL && i < e->buffx && (ptr2 - e->buff) < e->bufflen) {
-    c = g_utf8_get_char(ptr2);
-    i += (c == '\n' ? 1 : mk_wcwidth(c));
-    ptr2 = g_utf8_next_char(ptr2);
-  }
-  while(ptr2 != NULL && g_unichar_ismark(g_utf8_get_char(ptr2))) {
-    ptr2 = g_utf8_next_char(ptr2);
-  }
-  if (ptr2 == NULL) return e->bufflen;
-  return(ptr2 - e->buff);
-}
-
-/* We assume x,y are not set to point to a mid-char */
-gunichar _owl_editwin_get_char_at_xy(owl_editwin *e)
-{
-  return g_utf8_get_char(e->buff + _owl_editwin_get_index_from_xy(e));
-}
-
-
-void _owl_editwin_set_xy_by_index(owl_editwin *e, int index)
-{
-  char *ptr1, *ptr2, *target;
-  gunichar c;
-
-  e->buffx = 0;
-  e->buffy = 0;
-
-  ptr1 = e->buff;
-  target = ptr1 + index;
-  /* target sanitizing */
-  if ((target[0] & 0x80) && (~target[0] & 0x40)) {
-    /* middle of a utf-8 character, back up to previous character. */
-    target = g_utf8_find_prev_char(e->buff, target);
-  }
-  c = g_utf8_get_char(target);
-  while (g_unichar_ismark(c) && target > e->buff) {
-    /* Adjust the target off of combining characters and the like. */
-    target = g_utf8_find_prev_char(e->buff, target);
-    c = g_utf8_get_char(target);
-  }
-  /* If we start with a mark, something is wrong.*/
-  if (g_unichar_ismark(c)) return;
-
-  /* Now our target should be acceptable. */
-  ptr2 = strchr(ptr1, '\n');
-  while (ptr2 != NULL && ptr2 < target) {
-    e->buffy++;
-    ptr1 = ptr2 + 1;
-    ptr2 = strchr(ptr1, '\n');
-  }
-  ptr2 = ptr1;
-  while (ptr2 != NULL && ptr2 < target) {
-    c = g_utf8_get_char(ptr2);
-    e->buffx += mk_wcwidth(c);
-    ptr2 = g_utf8_next_char(ptr2);
-  }
-}
-
-int _owl_editwin_cursor_adjustment(owl_editwin *e)
-{
-  char *ptr1, *ptr2;
-  gunichar c;
-  int x, i;
-
-  /* Find line */
-  ptr1 = e->buff;
-  ptr2 = strchr(ptr1, '\n');
-  for (i = 0; ptr2 != NULL && i < e->buffy; i++) {
-    ptr1 = ptr2 + 1;
-    ptr2 = strchr(ptr1, '\n');
-  }
-  ptr2 = ptr1;
-
-  /* Find char */
-  x = 0;
-  while (ptr2 != NULL && x < e->buffx) {
-    if (*ptr2 == '\n') return 0;
-    c = g_utf8_get_char(ptr2);
-    x += mk_wcwidth(c);
-    ptr2 = g_utf8_next_char(ptr2);
-  }
-  
-  /* calculate x offset */
-  return x - e->buffx;
-}
-
-void owl_editwin_adjust_for_locktext(owl_editwin *e)
-{
-  /* if we happen to have the cursor over locked text
-   * move it to be out of the locktext region */
-  if (_owl_editwin_get_index_from_xy(e) < e->lock) {
-    _owl_editwin_set_xy_by_index(e, e->lock);
-  }
-}
-
-void owl_editwin_backspace(owl_editwin *e)
-{
-  /* delete the char before the current one
-   * and shift later chars left
-   */
-  if (_owl_editwin_get_index_from_xy(e) > e->lock) {
-    owl_editwin_key_left(e);
-    owl_editwin_delete_char(e);
-  }
-  owl_editwin_adjust_for_locktext(e);
-}
-
-void owl_editwin_key_up(owl_editwin *e)
-{
-  if (e->buffy > 0) e->buffy--;
-  if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
-    e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
-  }
-
-  /* do we need to scroll? */
-  if (e->buffy-e->topline < 0) {
-    e->topline-=e->winlines/2;
-  }
-
-  owl_editwin_adjust_for_locktext(e);
-}
-
-void owl_editwin_key_down(owl_editwin *e)
-{
-  /* move down if we can */
-  if (e->buffy+1 < owl_editwin_get_numlines(e)) e->buffy++;
-
-  /* if we're past the last character move back */
-  if (e->buffx >= owl_editwin_get_numcells_on_line(e, e->buffy)) {
-    e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
-  }
-
-  /* do we need to scroll? */
-  if (e->buffy-e->topline > e->winlines) {
-    e->topline+=e->winlines/2;
-  }
-
-  /* adjust for locktext */
-  owl_editwin_adjust_for_locktext(e);
-}
-
-void owl_editwin_key_left(owl_editwin *e)
-{
-  int i;
-  char * p;
-  i = _owl_editwin_get_index_from_xy(e);
-  p = e->buff + i;
-  p = g_utf8_find_prev_char(e->buff, p);
-  while (p && g_unichar_ismark(g_utf8_get_char(p))) {
-    p = g_utf8_find_prev_char(e->buff, p);
-  }
-  if (p == NULL) p = e->buff;
-  _owl_editwin_set_xy_by_index(e, p - e->buff);
-
-  if (e->buffy - e->topline < 0) {
-    e->topline -= e->winlines / 2;
-  }
-
-  /* make sure to avoid locktext */
-  owl_editwin_adjust_for_locktext(e);
-}
-
-void owl_editwin_key_right(owl_editwin *e)
-{
-  int i;
-  char * p;
-  i = _owl_editwin_get_index_from_xy(e);
-  p = e->buff + i;
-  p = g_utf8_find_next_char(p, NULL);
-  while (p && g_unichar_ismark(g_utf8_get_char(p))) {
-    p = g_utf8_find_next_char(p, NULL);
-  }
-  if (p == NULL) {
-    _owl_editwin_set_xy_by_index(e, e->bufflen);
-  }
-  else {
-    _owl_editwin_set_xy_by_index(e, p - e->buff);
-  }
-
-  /* do we need to scroll down? */
-  if (e->buffy - e->topline >= e->winlines) {
-    e->topline += e->winlines / 2;
-  }
-}
-
-void owl_editwin_move_to_nextword(owl_editwin *e)
-{
-  int i, x;
-  gunichar c = '\0';
-
-  /* if we're starting on a space, find the first non-space */
-  i=_owl_editwin_get_index_from_xy(e);
-  if (e->buff[i]==' ') {
-    for (x=i; x<e->bufflen; x++) {
-      if (e->buff[x]!=' ' && e->buff[x]!='\n') {
-	_owl_editwin_set_xy_by_index(e, x);
-	break;
-      }
-    }
-  }
-
-  /* find the next space, newline or end of line and go
-     there, if already at the end of the line, continue on to the next */
-  i=owl_editwin_get_numcells_on_line(e, e->buffy);
-  c = _owl_editwin_get_char_at_xy(e);
-  if (e->buffx < i) {
-    /* move right till end of line */
-    while (e->buffx < i) {
-      owl_editwin_key_right(e);
-      c = _owl_editwin_get_char_at_xy(e);
-      if (c == ' ') return;
-      if (e->buffx == i) return;
-    }
-  } else if (e->buffx == i) {
-    /* try to move down */
-    if (e->style==OWL_EDITWIN_STYLE_MULTILINE) {
-      if (e->buffy+1 < owl_editwin_get_numlines(e)) {
-	e->buffx=0;
-	e->buffy++;
-	owl_editwin_move_to_nextword(e);
-      }
-    }
-  }
-}
-
-/* go backwards to the last non-space character
- */
-void owl_editwin_move_to_previousword(owl_editwin *e)
-{
-  int i;
-  gunichar c;
-  char *ptr1, *ptr2;
-
-  /* are we already at the beginning of the word? */
-  c = _owl_editwin_get_char_at_xy(e);
-  i = _owl_editwin_get_index_from_xy(e);
-  ptr1 = e->buff + i;
-  if (*ptr1 != ' ' && *ptr1 != '\n' && *ptr1 != '\0' ) {
-    ptr1 = g_utf8_find_prev_char(e->buff, ptr1);
-    c = g_utf8_get_char(ptr1);
-    if (c == ' ' || c == '\n') {
-      owl_editwin_key_left(e);      
-    }
-  }
-
-  /* are we starting on a space character? */
-  i = _owl_editwin_get_index_from_xy(e);
-  while (i > e->lock && (e->buff[i] == ' ' || e->buff[i] == '\n' || e->buff[i] == '\0')) {
-    /* find the first non-space */
-    owl_editwin_key_left(e);      
-    i = _owl_editwin_get_index_from_xy(e);
-  }
-
-  /* find the last non-space */
-  ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
-  while (ptr1 >= e->buff + e->lock) {
-    ptr2 = g_utf8_find_prev_char(e->buff, ptr1);
-    if (!ptr2) break;
-    
-    c = g_utf8_get_char(ptr2);
-    if (c == ' ' || c == '\n'){
-      break;
-    }
-    owl_editwin_key_left(e);
-    ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
-  }
-}
-
-
-void owl_editwin_delete_nextword(owl_editwin *e)
-{
-  char *ptr1, *start;
-  gunichar c;
-
-  if (e->bufflen==0) return;
-
-  start = ptr1 = e->buff + _owl_editwin_get_index_from_xy(e);
-  /* if we start out on a space character then jump past all the
-     spaces up first */
-  while (*ptr1 == ' ' || *ptr1 == '\n') {
-    ++ptr1;
-  }
-
-  /* then jump past the next word */
-  
-  while (ptr1 && ptr1 - e->buff < e->bufflen) {
-    c = g_utf8_get_char(ptr1);
-    if (c == ' ' || c == '\n' || c == '\0') break;
-    ptr1 = g_utf8_find_next_char(ptr1, NULL);
-  }
-
-  if (ptr1) { /* We broke on a space, */
-    ptr1 = g_utf8_find_next_char(ptr1, NULL);
-    if (ptr1) { /* and there's a character after it, */
-      /* nuke everything back to our starting point. */
-      _owl_editwin_remove_bytes(e, ptr1 - start);
-      return;
-    }
-  }
-  
-  /* If we get here, we ran out of string, drop what's left. */
-  *start = '\0';
-  e->bufflen = start - e->buff;
-}
-
-void owl_editwin_delete_previousword(owl_editwin *e)
-{
-  /* go backwards to the last non-space character, then delete chars */
-  int startpos, endpos;
-
-  startpos = _owl_editwin_get_index_from_xy(e);
-  owl_editwin_move_to_previousword(e);
-  endpos = _owl_editwin_get_index_from_xy(e);
-  _owl_editwin_remove_bytes(e, startpos-endpos);
-}
-
-void owl_editwin_delete_to_endofline(owl_editwin *e)
-{
-  int i;
-
-  if (owl_editwin_get_numchars_on_line(e, e->buffy) > e->buffx) {
-    /* normal line */
-    i=_owl_editwin_get_index_from_xy(e);
-    while(i < e->bufflen) {
-      if (e->buff[i]!='\n') {
-	owl_editwin_delete_char(e);
-      } else if ((e->buff[i]=='\n') && (i==e->bufflen-1)) {
-	owl_editwin_delete_char(e);
-      } else {
-	return;
-      }
-    }
-  } else if (e->buffy+1 < owl_editwin_get_numlines(e)) {
-    /* line with cursor at the end but not on very last line */
-    owl_editwin_key_right(e);
-    owl_editwin_backspace(e);
-  }
-}
-
-void owl_editwin_move_to_line_end(owl_editwin *e)
-{
-  e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
-}
-
-void owl_editwin_move_to_line_start(owl_editwin *e)
-{
-  e->buffx=0;
-  owl_editwin_adjust_for_locktext(e);
-}
-
-void owl_editwin_move_to_end(owl_editwin *e)
-{
-  /* go to last char */
-  e->buffy=owl_editwin_get_numlines(e)-1;
-  e->buffx=owl_editwin_get_numcells_on_line(e, e->buffy);
-  owl_editwin_key_right(e);
-
-  /* do we need to scroll? */
-  /*
-  if (e->buffy-e->topline > e->winlines) {
-    e->topline+=e->winlines/2;
-  }
-  */
-  owl_editwin_recenter(e);
-}
-
-void owl_editwin_move_to_top(owl_editwin *e)
-{
-  _owl_editwin_set_xy_by_index(e, 0);
-
-  /* do we need to scroll? */
-  e->topline=0;
-
-  owl_editwin_adjust_for_locktext(e);
-}
-
-void owl_editwin_fill_paragraph(owl_editwin *e)
-{
-  int i, save;
-
-  /* save our starting point */
-  save=_owl_editwin_get_index_from_xy(e);
-
-  /* scan back to the beginning of this paragraph */
-  for (i=save; i>=e->lock; i--) {
-    if ( (i<=e->lock) ||
-	 ((e->buff[i]=='\n') && (e->buff[i-1]=='\n'))) {
-      _owl_editwin_set_xy_by_index(e, i+1);
-      break;
-    }
-  }
-
-  /* main loop */
-  while (1) {
-    i = _owl_editwin_get_index_from_xy(e);
-
-    /* bail if we hit the end of the buffer */
-    if (i >= e->bufflen || e->buff[i] == '\0') break;
-
-    /* bail if we hit the end of the paragraph */
-    if (e->buff[i] == '\n' && e->buff[i+1] == '\n') break;
-
-    /* if we've travelled too far, linewrap */
-    if ((e->buffx) >= e->fillcol) {
-      int len = e->bufflen;
-      _owl_editwin_linewrap_word(e);
-      /* we may have added a character. */
-      if (i < save) save += e->bufflen - len;
-      _owl_editwin_set_xy_by_index(e, i);
-    }
-
-    /* did we hit the end of a line too soon? */
-    /* asedeno: Here we replace a newline with a space. We may want to
-       consider removing the space if the characters to either side
-       are CJK ideograms.*/
-    i = _owl_editwin_get_index_from_xy(e);
-    if (e->buff[i] == '\n' && e->buffx < e->fillcol - 1) {
-      /* ********* we need to make sure we don't pull in a word that's too long ***********/
-      e->buff[i]=' ';
-    }
-
-    /* fix spacing */
-    i = _owl_editwin_get_index_from_xy(e);
-    if (e->buff[i] == ' ' && e->buff[i+1] == ' ') {
-      if (e->buff[i-1] == '.' || e->buff[i-1] == '!' || e->buff[i-1] == '?') {
-	owl_editwin_key_right(e);
-      } else {
-	owl_editwin_delete_char(e);
-	/* if we did this ahead of the save point, adjust it. Changing
-           by one is fine here because we're only removing an ASCII
-           space. */
-	if (i < save) save--;
-      }
-    } else {
-      owl_editwin_key_right(e);
-    }
-  }
-
-  /* put cursor back at starting point */
-  _owl_editwin_set_xy_by_index(e, save);
-
-  /* do we need to scroll? */
-  if (e->buffy-e->topline < 0) {
-    e->topline-=e->winlines/2;
-  }
-}
-
-/* returns true if only whitespace remains */
-int owl_editwin_is_at_end(owl_editwin *e)
-{
-  int cur=_owl_editwin_get_index_from_xy(e);
-  return (only_whitespace(e->buff+cur));
-}
-
-int owl_editwin_check_dotsend(owl_editwin *e)
-{
-  char *p, *p_n, *p_p;
-  gunichar c;
-
-  if (!e->dotsend) return(0);
-
-  p = g_utf8_find_prev_char(e->buff, e->buff + e->bufflen);
-  p_n = g_utf8_find_next_char(p, NULL);
-  p_p = g_utf8_find_prev_char(e->buff, p);
-  c = g_utf8_get_char(p);
-  while (p != NULL) {
-    if (*p == '.'
-	&& p_p != NULL && (*p_p == '\n' || *p_p == '\r')
-	&& p_n != NULL && (*p_n == '\n' || *p_n == '\r')) {
-      e->bufflen = p - e->buff;
-      e->buff[e->bufflen] = '\0';
-      return(1);
-    }
-    if (c != '\0' && !g_unichar_isspace(c)) return(0);
-    p_n = p;
-    p = p_p;
-    c = g_utf8_get_char(p);
-    p_p = g_utf8_find_prev_char(e->buff, p);
-  }
-  return(0);
-}
-
-void owl_editwin_post_process_char(owl_editwin *e, owl_input j)
-{
-  /* check if we need to scroll down */
-  if (e->buffy-e->topline >= e->winlines) {
-    e->topline+=e->winlines/2;
-  }
-  if ((j.ch==13 || j.ch==10) && owl_editwin_check_dotsend(e)) {
-    owl_command_editmulti_done(e);
-    return;
-  }
-  owl_editwin_redisplay(e, 0);  
-}
-
-void _owl_editwin_process_char(owl_editwin *e, gunichar j)
-{
-  if (!(g_unichar_iscntrl(j) && (j != 10) && (j != 13))) {
-    owl_editwin_insert_char(e, j);
-  }
-}
-
-
-void owl_editwin_process_char(owl_editwin *e, owl_input j)
-{
-  if (j.ch == ERR) return;
-  /* Ignore ncurses control characters. */
-  if (j.ch < 0x100) { 
-    _owl_editwin_process_char(e, j.uch);
-  }
-}
-
-char *owl_editwin_get_text(owl_editwin *e)
-{
-  return(e->buff+e->lock);
-}
-
-int owl_editwin_get_numchars_on_line(owl_editwin *e, int line)
-{
-  int i;
-  char *ptr1, *ptr2;
-
-  if (e->bufflen==0) return(0);
-  
-  /* first go to the yth line */
-  ptr1=e->buff;
-  for (i=0; i<line; i++) {
-    ptr2=strchr(ptr1, '\n');
-    if (!ptr2) {
-      /* we're already on the last line */
-      return(0);
-    }
-    ptr1=ptr2+1;
-  }
-
-  /* now count characters */
-  i = 0;
-  ptr2 = ptr1;
-  while (ptr2 - e->buff < e->bufflen
-	 && *ptr2 != '\n') {
-    ++i;
-    ptr2 = g_utf8_next_char(ptr2);
-  }
-  return i;
-}
-
-int owl_editwin_get_numcells_on_line(owl_editwin *e, int line)
-{
-  int i;
-  char *ptr1, *ptr2;
-  gunichar c;
-
-  if (e->bufflen==0) return(0);
-  
-  /* first go to the yth line */
-  ptr1=e->buff;
-  for (i=0; i<line; i++) {
-    ptr2=strchr(ptr1, '\n');
-    if (!ptr2) {
-      /* we're already on the last line */
-      return(0);
-    }
-    ptr1=ptr2+1;
-  }
-
-  /* now count cells */
-  i = 0;
-  ptr2 = ptr1;
-  while (ptr2 - e->buff < e->bufflen
-	 && *ptr2 != '\n') {
-    c = g_utf8_get_char(ptr2);
-    i += mk_wcwidth(c);
-    ptr2 = g_utf8_next_char(ptr2);
-  }
-  return i;
-}
-
-int owl_editwin_get_numlines(owl_editwin *e)
-{
-  return(owl_text_num_lines(e->buff));
-}
-
Index: capsulate.pl
===================================================================
--- encapsulate.pl	(revision f1e629de3f6889c21f5f9dd7225e11c4fe9408b4)
+++ 	(revision )
@@ -1,20 +1,0 @@
-#!/usr/bin/perl
-#
-# $Id$
-#
-
-my $infile = $ARGV[0] or die "Usage: $0 infile structname";
-my $structname = $ARGV[1] or die "Usage: $0 infile structname";;
-open INF, "<$infile" or die "Unable to open $infile";
-
-print "/* This file was autogenerated from $infile.  DO NOT EDIT !!!! */\n\n";
-print "char *$structname = \n";
-for my $x (<INF>) {
-    chomp $x;
-    $x =~ s/\\/\\\\/g;
-    $x =~ s/"/\\"/g;
-    print qq(   "$x\\n"\n);
-}
-print "   ;\n";
-
-close INF;
Index: rqueue.c
===================================================================
--- errqueue.c	(revision ec6ff526f80f4544b68f01e84ccd88c783e54326)
+++ 	(revision )
@@ -1,23 +1,0 @@
-#include "owl.h"
-
-void owl_errqueue_init(owl_errqueue *eq)
-{
-  owl_list_create(&(eq->errlist));
-}
-
-void owl_errqueue_append_err(owl_errqueue *eq, char *msg)
-{
-  owl_list_append_element(&(eq->errlist), owl_strdup(msg));
-}
-
-/* fmtext should already be initialized */
-void owl_errqueue_to_fmtext(owl_errqueue *eq, owl_fmtext *fm)
-{
-  int i, j;
-
-  j=owl_list_get_size(&(eq->errlist));
-  for (i=0; i<j; i++) {
-    owl_fmtext_append_normal(fm, owl_list_get_element(&(eq->errlist), i));
-    owl_fmtext_append_normal(fm, "\n");
-  }
-}
Index: amples/owlconf.erik
===================================================================
--- examples/owlconf.erik	(revision 160d3f421ceb80ae77fe01b5158f58cba7f61960)
+++ 	(revision )
@@ -1,476 +1,0 @@
-### The owlconf config file   -*- perl -*-  
-###  $Id$
-###
-### !!!!!WARNING!!!!! !!!!!WARNING!!!!! !!!!!WARNING!!!!! !!!!!WARNING!!!!!
-### This is an example file intended to demonstrate how to use 
-### various features of owl.  Some of the key bindings, in particular,
-### are more for examples than things you may actually want to use.
-### Make sure to read through it first and understand it before just using it.
-### Don't blame me if anything in here ends up vaporizing your dog.
-### !!!!!WARNING!!!!! !!!!!WARNING!!!!! !!!!!WARNING!!!!! !!!!!WARNING!!!!!
-###
-###
-### This file is interpreted by the perl interpreter.
-### If you wish to execute an owl command use the
-### function owl::command().  i.e.
-###
-###      owl::command("set zsigproc /mit/kretch/bin/getzsig");
-###
-### will set the owl variable zsigproc.  Subroutines created with
-### the names below will be executed at the specified times:
-###
-###     subroutine name    properties
-###     ---------------    ----------
-###     owl::startup()     run when owl first starts
-###     owl::shutdown()    run when owl exits
-###     owl::format_msg()  formats messages that are passed to it
-###     owl::receive_msg() run when a message is received, and after
-###	  	           it has been added to the message list
-###
-### The format_msg and receive_msg functions are passed owl::Message objects.
-### The message attributes may be dereferenced with $m->attribute
-###
-###    
-
-# tokens for sepbar are:
-#    .username = ping
-#    >username = login
-#    <username = logout
-#    :username = personal message
-#    M         = mail received
-my @sepbartokens = ();
-
-# Map for mail messages from msg id to pop msg id
-my %mail_id_map = ();
-
-# (originally from jdaniel)
-sub mail_add_message ($) {
-    my ($m) = @_;
-    my $from = `from -t`;
-    # example value:
-    # You have 188 messages (667593 bytes) on PO11.MIT.EDU.
-    my ($msg_num) = $from =~ m/(\d+)/;
-    $mail_id_map{$m->id} = $msg_num;
-}
-
-
-sub mail_pop_curmsg () {
-    my $m = owl::getcurmsg();
-    if (!$m->is_mail || !defined $mail_id_map{$m->id}) {
-	&owl::command("pop-message");
-    } else {
-	&owl::command(sprintf 'pexec pop -request c -request "retr %d" -request q',
-		      $mail_id_map{$m->id});
-    }
-}
-
-sub zlocatesender {
-    my $m = owl::getcurmsg();
-    if ($m->{"type"} eq "zephyr") {
-	my $sender = $m->{"sender"};
-        owl::command("zlocate $sender");
-    }
-}
-
-# adds a sepbartoken and also updates the appendtosepbar variable
-sub sepbartokens_add {
-    my ($token) = @_;
-    $token =~ s/"//g;  # "
-    unshift @sepbartokens, $token;
-    pop @sepbartokens if (@sepbartokens > 80);
-    sepbartokens_set();
-}
-
-# trims a sepbartoken from the list also updates the appendtosepbar variable
-sub sepbartokens_trim {
-    my ($token) = @_;
-    @sepbartokens = map { if ($_ ne $token) { $_; } else { (); } } @sepbartokens;
-    sepbartokens_set();
-}
-
-my $loopctr=0;
-
-# trims a sepbartoken from the list also updates the appendtosepbar variable
-sub sepbartokens_set {
-    owl::command(sprintf "set -q appendtosepbar \"%s %s %s\"", (scalar localtime), (join " ", @sepbartokens));
-}
-
-my $restoreview = undef;
-sub swapview {
-    my $curview = owl::command("getview");
-    if ($restoreview) {
-        owl::command("view $restoreview");
-        $restoreview = undef;
-    } else {
-        $restoreview = $curview;
-        owl::command("smartnarrow");
-    }
-}
-
-my $lastcolored = undef;
-sub colorthread {
-    if ($lastcolored) {
-        owl::command("filter $lastcolored -c default");
-    }
-    my $smartfilt = owl::command("smartfilter");
-    if (!$smartfilt or $smartfilt eq $lastcolored) {
-        owl::command("filter $lastcolored -c default");
-        $lastcolored = undef;
-    } else {
-        owl::command("filter $smartfilt -c green");
-        $lastcolored = $smartfilt;
-    }
-}
-
-# Load in things which don't belong in an owlconf 
-# that people might use as an example...
-sub personal_startup {
-    my $personalconf = $ENV{"HOME"}."/.owl/personalconf";
-    if (-f $personalconf) {
-	my $b = "";
-	open INB, $personalconf;
-	for (<INB>) { $b .= $_; }
-	close INB;
-	eval $b;
-    }
-}
-
-sub owl::startup {
-    owl::command("set -q logging on");
-    owl::command("set -q logpath ~/.zlog/owl/personal");
-    owl::command("set -q classlogpath ~/.zlog/owl/class");
-    owl::command("set -q logging on");
-    owl::command("set -q startuplogin off");
-    owl::command("set -q shutdownlogout off");
-    #owl::command("set personalbell on");
-    owl::command("set -q _burningears on");
-    owl::command("set -q rxping on");
-    owl::command("set -q typewinsize 5");
-    owl::command("filter me recipient %me% or ( sender %me% and class message and instance personal ) or class mail or type aim");
-    owl::command("filter owl instance ^owl.*");
-
-    owl::command(q(alias finger pperl $x=owl::getcurmsg()->hostname; `finger \@$x`;));
-    owl::command("bindkey recv f command finger");
-
-    owl::command("alias z zwrite");
-    owl::command("alias zw zwrite");
-    owl::command("alias v view");
-
-    owl::command("alias popmail perl mail_pop_curmsg();");
-
-    # toggle between a view and a smartnarrow with TAB
-    owl::command("alias swapview perl swapview();");
-    owl::command("bindkey recv C-i command swapview");
-
-    # color the current thread
-    owl::command("alias colorthread perl colorthread();");
-    owl::command("bindkey recv M-c command colorthread");
-
-    # zlocate current sender
-    owl::command("bindkey recv L command perl zlocatesender();");
-
-    # Declare styles
-    &owl::command("style vt     perl format_msg_vt");
-    &owl::command("style brief  perl format_msg_brief");
-    &owl::command("style custom perl format_msg_custom");
-    &owl::command("style debug  perl format_msg_debug");
-    &owl::command("set -q default_style custom");
-
-    # Change to different view styles
-    owl::command("bindkey recv \"C-s v\" command view -s vt");
-    owl::command("bindkey recv \"C-s c\" command view -s custom");
-    owl::command("bindkey recv \"C-s b\" command view -s brief");
-    owl::command("bindkey recv \"C-s d\" command view -s debug");
-    owl::command("bindkey recv \"C-s o\" command view -s standard");
-
-    # For fast-reading of zephyrs
-    owl::command("bindkey recv M-k command ( smartnarrow ; delete view )");
-    owl::command("bindkey recv M-l command ( expunge ; view all )");
-    owl::command("bindkey recv M-K command ( smartnarrow ; delete view ; expunge ; view all )");
-
-    # Support for scroll mice
-    &owl::command("bindkey recv \"M-[ A\" command recv:prev");
-    &owl::command("bindkey recv \"M-[ B\" command recv:next");
-
-    # This overrides the default "M" keybinding
-    owl::command("bindkey recv M command popmail");
-
-    sepbartokens_add("...");
-
-    personal_startup();
-}
-
-sub owl::shutdown {
-#    not doing anything at the moment...
-}
-
-
-# run when a message is received, and after
-# it has been added to the message list.
-sub owl::receive_msg {
-    my ($m) = @_;
-    my ($out, $tmp);
-
-    if ($m->is_admin && !$m->is_outgoing) {
-	$m->delete();
-	return 1;
-    }
-
-    return 0 if (!$m->is_zephyr && !$m->is_aim);
-
-    my $sender = $m->pretty_sender;
-
-    if ($m->is_ping) {
-	sepbartokens_add(".$sender");
-        $m->delete();
-    } elsif ($m->is_loginout) {
-        $m->delete();
-	if ($m->is_login) {
-	    sepbartokens_add(">$sender");
-	    sepbartokens_trim("<$sender");
-	} elsif ($m->is_logout) {
-	    sepbartokens_add("<$sender");
-	    sepbartokens_trim(">$sender");
-	} 
-    } elsif ($m->is_mail) {
-	mail_add_message($m);
-        $m->delete();
-	sepbartokens_add("M");
-    }
-
-    if ($m->is_personal) {
-	sepbartokens_trim(".$sender");
-	sepbartokens_add(":$sender");
-    }
-
-    return 1;
-}
-
-sub indent4 {
-    my ($b) = @_;
-    $b=~s/^/    /g;
-    $b=~s/\n/\n    /g;    
-    return $b;
-}
-
-# run to format a message
-sub format_msg_custom {
-    my ($m) = @_;
-    my ($out, $tmp);
-
-    if ($m->is_admin) {
-	$out = "\@bold([owl admin]) ".$m->header."\n";
-	$out.=indent4($m->body);
-	return $out."\n";
-    }
-
-    my $sender=$m->pretty_sender;
-
-    if (($m->is_aim or $m->is_zephyr) && $m->is_loginout) {
-
-	if ($m->is_login) {
-	    $out="\@bold(LOGIN)";
-	} elsif ($m->is_logout) {
-	    $out="\@bold(LOGOUT)";
-	} else {
-	    $out="\@bold(UNKNOWN)";
-	}
-	$out.=" for \@bold($sender) on ".$m->type;
-	if ($m->is_zephyr) {
-	    $out.=" at ".($m->login_host)." on ".($m->login_tty);
-	}
-	return("$out\n");
-    }
-
-    if (!$m->is_zephyr && !$m->is_aim) { 
-	return "Unknown message type: ".$m->type."\n";
-    }
-
-    if ($m->is_outgoing) {
-	my $target = $m->recipient;
-	if ($m->is_zephyr) {
-	    $target = $m->zwriteline;
-	    $target =~ s/^zwrite //;
-	}
-	$out = sprintf "\@bold([outgoing %s to %s]) / %s\n", $m->type, $target, $m->time;
-	$out.=indent4($m->body);
-	return "$out\n";
-    }
-
-    if ($m->is_zephyr && $m->is_ping) {
-	return("\@bold(PING) from \@bold($sender)\n");
-    } elsif ($m->is_zephyr && $m->is_mail) {
-	$out = "\@bold(MAIL) ";
-	if ($m->body =~ /^From:\s+(.+)\s*$/m) { $out .= "From $1 "; }
-	if ($m->body =~ /^To:\s+(.+)\s*$/m) { $out .= "To $1 "; }
-	if ($m->body =~ /^Subject:\s+(.+)\s*$/m) { $out .= "Subject $1 "; }
-	return("$out\n");
-    }
-
-    if ($m->is_zephyr) {
-	$out = sprintf "[mit,%s,%s] / %s / %s", lc($m->class), 
-	lc($m->instance), $m->time, lc($m->host);
-	if ($m->opcode ne "") {$out.=" op:".$m->opcode;}
-	$out.="\n";
-	$out.= "  \@bold($sender)> ";
-	if ($m->zsig ne "") {
-	    my $zsig = $m->zsig;
-	    $zsig =~ s/(\n.*)+$/ [...]/;
-	    if (length($zsig)+5+length($sender) > 70) {
-		$out.="# ...";
-	    } else {
-		$out.="# $zsig";
-	    }
-	}
-	$out.="\n";		
-    } else {
-	$out = sprintf "[%s] / %s\n", lc($m->type), $m->time;
-	$out.= "  \@bold($sender)> ";
-	$out.="\n";		
-    }
-
-    $out.=indent4($m->body);
-
-    # make personal messages bold
-    if ($m->is_personal) {
-	$out="\@bold{".$out."}";
-    }
-
-    return($out."\n");
-}
-
-sub format_msg_debug {
-    my ($m) = @_;
-    return "\@bold(-------------MESSAGE-------------)\n".($m->serialize).".\n";
-}
-
-sub format_msg_brief {
-    my ($m) = @_;
-    my $out = format_msg_vt($m);
-    $out =~ s/\n/ /g;
-    $out =~ s/                        / /g;
-    return($out."\n");
-}
-
-
-sub format_msg_vt {
-    my ($m) = @_;
-    my ($out, $tmp);
-
-    if ($m->is_admin) {
-	$out = sprintf "%-29s \@i(%s)", "\@bold(OWL ADMIN)", $m->header;
-	$tmp=$m->body;
-	$tmp=~s/^/                       /g;
-	$tmp=~s/\n/\n                       /g;
-	$out.="\n".$tmp;
-	return $out;
-    }
-
-    my $sender=$m->pretty_sender;
-
-    if ($m->is_outgoing) {
-	my $target = $m->recipient;
-	if ($m->is_zephyr) {
-	    $target = $m->zwriteline;
-	    $target =~ s/^zwrite //;
-	}
-	$out = sprintf "%-15s %-13s", "\@bold(OUTGOING)", "to $target via ".$m->type.": ";
-	my $pagewidth = owl::getnumcols()-6;
-	$out .= fill_text($m->body, $pagewidth, 22, 1);
-	return $out;
-    }
-
-    if (!$m->is_zephyr && !$m->is_aim) { 
-	return "Unknown message type: ".$m->type."\n";
-    }
-
-    if ($m->is_zephyr && $m->is_ping) {
-	return (sprintf "%-15s %-13s\n", "\@bold(PING)", $sender);
-    } elsif ($m->is_loginout) {
-	my $state;
-	if ($m->is_login) {
-	    $state="\@bold(LOGIN)";
-	} elsif ($m->is_logout) {
-	    $state="\@bold(LOGOUT)";
-	} else {
-	    $state="\@bold(UNKNOWN)";
-	}
-	my $out = sprintf "%-15s %-13s ", $state, $sender;
-	if ($m->is_zephyr) {
-	    $out .= sprintf "via %s on %s at %s", $m->type, $m->login_host, $m->login_tty;
-	} else {
-	    $out .= sprintf "via %s", $m->type;
-	}
-	return "$out\n";
-		
-    } elsif ($m->is_zephyr && $m->is_mail) {
-	my $body = $m->body;
-	$out = sprintf "%-15s %-13s ", "\@bold(MAIL)", "";
-	if ($body =~ /^From:\s+(.+)\s*$/m) { $out .= "From $1 "; }
-	if ($body =~ /^To:\s+(.+)\s*$/m) { $out .= "To $1 "; }
-	if ($body =~ /^Subject:\s+(.+)\s*$/m) { $out .= "Subject $1 "; }
-	return($out."\n");
-    }
-
-    my $channel = "";
-    my $body = $m->body;
-    
-    if ($m->is_zephyr) {
-	my $inst = $m->instance;
-	$channel = $m->class;
-	if (lc($m->class) ne "message" and lc($m->instance) eq "personal") {
-	    $inst = "";
-	}
-	$channel .= "[".$inst."]";
-	$channel = substr($channel,0,13);
-    } else {
-	$channel = "[".$m->type."]";
-    }
-
-    $header = sprintf "%-8s %-13s ", lc($sender), lc($channel);
-
-    if ($body =~ /=/) {
-	# indent it
-	$out.=$header."\n".indent4($body);
-    } else {
-	# fill it
-	my $pagewidth = owl::getnumcols()-6;
-	$out .= $header;
-	$out .= fill_text($body, $pagewidth, 22, 1);
-    }
-
-    # note: no zsig added in this version
-
-    # make personal messages bold
-    if ($m->is_personal) {
-	$out="\@bold{".$out."}";
-    }
-    return($out);
-}
-
-sub fill_text {
-    my ($in, $width, $indent, $unindent_first) = @_;
-    $indent = 0 if (@_ < 3);
-    my $unindent = $indent if ($unindent_first);
-    my @words = split " ", $in;
-    my $out = "";
-    my $outline = "";
-    if (!$unindent_first) {
-	my $outline = " "x$indent;
-    }
-    for my $w (@words) {
-	if (($outline ne "") 
-	    && (length($outline)+length($w) > $width-$unindent)) {
-	    $out .= $outline."\n";
-	    $outline = " "x$indent;
-	    $unindent = 0;
-	}
-	if ($outline =~ /.*\.$/) {
-	    $outline .= "  ";
-	} elsif ($outline ne "") {
-	    $outline .= " ";
-	}
-	$outline .= $w;
-    }
-    $out .= $outline . "\n";    
-}
Index: amples/owlconf.simple
===================================================================
--- examples/owlconf.simple	(revision 160d3f421ceb80ae77fe01b5158f58cba7f61960)
+++ 	(revision )
@@ -1,270 +1,0 @@
-### The owlconf config file   -*- perl -*-  
-###  $Id$
-
-### !!!!!WARNING!!!!! !!!!!WARNING!!!!! !!!!!WARNING!!!!! !!!!!WARNING!!!!!
-### This is an example file intended to demonstrate how to use 
-### various features of owl.  Some of the key bindings, in particular,
-### are more for examples than things you may actually want to use.
-### Make sure to read through it first and understand it before just using it.
-### Don't blame me if anything in here ends up vaporizing your dog.
-### !!!!!WARNING!!!!! !!!!!WARNING!!!!! !!!!!WARNING!!!!! !!!!!WARNING!!!!!
-
-###
-### This file is interpreted by the perl interpreter.
-### If you wish to execute an owl command use the
-### function owl::command().  i.e.
-###
-###      owl::command("set zsigproc /mit/kretch/bin/getzsig");
-###
-### will set the owl variable zsigproc.  Subroutines created with
-### the names below will be executed at the specified times:
-###
-###     subroutine name    properties
-###     ---------------    ----------
-###     owl::startup()     run when owl first starts
-###     owl::shutdown()    run when owl exits
-###     owl::format_msg()  run when a new message arrives, the return
-###                           value is used to display the message on the
-###                           screen
-###     owl::receive_msg() run when a message is received, and after
-###	  	           it has been added to the message list
-###
-###
-### The following variables will be set each time a message is recevied
-### and when owl::format_msg() and owl::receive_msg() are run.
-###
-###     $owl::class, $owl::instance, $owl::recipient, $owl::direction,
-###     $owl::sender, $owl::opcode, $owl::zsig,
-###     $owl::msg, $owl::time, $owl::host, @owl::fields, $owl::id
-###    
-
-# NOTE: Lines beginning with a "#" are perl comments.
-
-
-# This subroutine is run whenever owl starts up.
-# The owl::command("foo") lines execute the owl command "foo".
-sub owl::startup {
-
-    ################################################################
-    ## The following set the values of variables.
-    ## Doing "help" will show you more about each variable.
-    ## These lines will set things to the default.
-    ## You can uncomment them and then change the value to get 
-    ## a different behavior (remove the "#" to an alternate value).
-    ################################################################
-
-    ## Set this to off to disable the terminal bell.
-    # owl::command('set -q bell on');
-
-    ## Set this to off to disable the terminal bell on personal zephyrs.
-    # owl::command('set -q personalbell off');
-
-    ## Set this to on to enable logging of personal zephyrs
-    # owl::command('set -q logging off');  
-
-    ## This directory must exist and is where personal zephyrs are logged.
-    ## By default, this is the ~/zlog/personal/ directory
-    # owl::command('set -q logpath '.$ENV{'HOME'}.'/zlog/personal/');
-
-    ## Set this to on to enable logging of classes
-    # owl::command('set -q classlogging off');  
-
-    ## This directory must exist and is where class zephyrs are logged.
-    ## By default, this is the ~/zlog/class/ directory
-    # owl::command('set -q classlogpath '.$ENV{'HOME'}.'/zlog/class/');
-
-    ## If set to on, this will make is so that C-d doesn't
-    ## send zephyrs by accident.
-    # owl::command('set -q disable-ctrl-d off');
-
-    ## If set to on, outgoing messages will be displayed.
-    # owl::command('set -q displayoutgoing on');
-
-    ## Displays received pings?
-    # owl::command('set -q rxping off');
-
-    ## Send pings?
-    # owl::command('set -q txping on');
-
-    ## Size of typing window at the bottom of the screen
-    # owl::command('set -q typewinsize 8');
-
-    ## Which view to switch to after the 'V' or 'X' commands.
-    # owl::command('set -q view_home all');
-
-
-    ## Default message to send when zaway is on (toggle with 'A')
-    # owl::command('set -q zaway_msg_default "Not here now..."');
-
-    ## Default zephyr signature.
-    # owl::command('set -q zsig "meep"');
-
-    ## Program to generate a zsig.
-    # owl::command('set -q zsigproc "/mit/foo/bin/randzsig"');
-
-
-    ################################################################
-    ## The following create filters.  Filters can be used to select
-    ## on multiple zephyrs for operations.  With 'views' you can 
-    ## look at only the zephyrs matching a particular filter.
-    ## Use the 'view <filtername>' command or the 'v' key to switch views.
-    ## The 'V' key will switch you back to your 'view_home' view.
-    ## The M-D key will delete all messages in the current view
-    ##
-    ##
-    ## The filter command creates a filter with the specified name,
-    ## or if one already exists it is replaced.  Example filter
-    ## syntax would be:                                        
-    ##
-    ##    filter myfilter -c red ( class ^foobar$ ) or ( class ^quux$ and instance ^bar$ )
-    ##
-    ## Valid matching fields are class, instance, recipient, sender, opcode
-    ## and realm.  Valid operations are 'and', 'or' and 'not'.  Spaces must be
-    ## present before and after parenthesis.  If the optional color argument
-    ## is used it specifies the color that messages matching this filter
-    ## should be displayed in.  Do 'show colors' to see the available colors.
-    ## 
-    ################################################################
-
-    ## This would create a shortcut to only show personal messages
-    ## with filter 'me' and to color them yellow.
-    ## Replace myusername with yours.
-    # owl::command('filter me -c yellow recipient myusername');
-
-    ## This would create a 'quiet' filter to not show messages
-    ## on noisy classes and instances.
-    # owl::command('filter quiet not ( class ^foo|bar|quux$ or instance ( ^baaz$ ) ');
-
-    ## The 'trash' filter is used when you press 'T' to mark things
-    ## for autodeletion.
-    # owl::command('filter trash class ^mail$ or opcode ^ping$ or type ^admin$ or class ^login$');   
-
-}
-
-## This is run when owl exits.  Currently this does nothing.
-sub owl::shutdown {
-}
-
-## This is run to format the contents of the message.
-## It returns a string which is a formatted message.
-## The following variables will be set each time before this is run:
-##
-##     $owl::class, $owl::instance, $owl::recipient,
-##     $owl::sender, $owl::opcode, $owl::zsig,
-##     $owl::msg, $owl::time, $owl::host, @owl::fields, $owl::id
-
-sub owl::format_msg {
-    my $out, $tmp;
-
-    ## Strip out noise from the sender string.
-    $owl::sender=~s/\@ATHENA\.MIT\.EDU$//;
-    $owl::sender=~s/\@local-realm$//;
-    $owl::recipient=~s/\@ATHENA\.MIT\.EDU$//;
-    $owl::recipient=~s/\@local-realm$//;
-
-    ## Format ping, login, and mail messages.
-    ## uc(foo) upcases the string and "eq" does string comparison.
-    if (uc($owl::opcode) eq "PING") {
-	return("\@bold(PING) from \@bold($owl::sender)\n");
-    } elsif (uc($owl::class) eq "LOGIN") {
-	if (uc($owl::opcode) eq "USER_LOGIN") {
-	    $out="\@bold(LOGIN)";
-	} elsif (uc($owl::opcode) eq "USER_LOGOUT") {
-	    $out="\@bold(LOGOUT)";
-	} else {
-	    $out="\@bold(UNKNOWN)";
-	}
-	$out.=" for \@bold($owl::sender) at $fields[0] on $fields[2]\n";
-	return($out);
-    } elsif (uc($owl::class) eq "MAIL" and uc($owl::instance) eq "INBOX") {
-	$out = "\@bold(MAIL) ";
-	if ($owl::msg =~ /^From:\s+(.+)\s*$/m) { $out .= "From $1 "; }
-	if ($owl::msg =~ /^To:\s+(.+)\s*$/m) { $out .= "To $1 "; }
-	if ($owl::msg =~ /^Subject:\s+(.+)\s*$/m) { $out .= "Subject $1 "; }
-	return($out."\n");
-    }
-
-    ## The remainder formats normal messages (eg, to classes and instances).
-    ## Outgoing messages have different headers than incoming messages.
-    ## Note that:
-    ##   $out .= "foo";  appends "foo" to the end of the variable $out.
-    ##   lc(bar) will convert bar to lowercase.    
-    ##   "ne" does "not equal" for string comparison.
-    ##   sprintf fills in the %s's with the arguments later on the line.
-    ##   "foo"."bar" will append the two strings together.
-
-
-    if ($owl::direction eq "out") {
-	# Outgoing messages
-
-	$out .= sprintf "[outgoing to %s] / %s", $owl::recipient, $owl::time;
-	if ($owl::opcode ne "") {$out.=" op:$owl::opcode";}
-	$out.="\n";
-	$out.= "  \@bold($owl::sender)> ";
-	if ($owl::zsig ne "") {
-	    my $zsig = $owl::zsig;
-	    $zsig =~ s/(\n.*)+$/ [...]/;
-	    if (length($zsig)+5+length($owl::sender) > 70) {
-		$out.="# ...";
-	    } else {
-		$out.="# $zsig";
-	    }
-	}
-    } else {
-	# Incoming messages
-
-	$out .= sprintf "[mit,%s,%s] / %s / %s", lc($owl::class), 
-	                lc($owl::instance), $owl::time, lc($owl::host);
-	if ($owl::opcode ne "") {$out.=" op:$owl::opcode";}
-	$out.="\n";
-	$out.= "  \@bold($owl::sender)> ";
-	if ($owl::zsig ne "") {
-	    my $zsig = $owl::zsig;
-	    $zsig =~ s/(\n.*)+$/ [...]/;
-	    if (length($zsig)+5+length($owl::sender) > 70) {
-		$out.="# ...";
-	    } else {
-		$out.="# $zsig";
-	    }
-	}
-    }
-    $out.="\n";		
-
-    # This indents the body of the message and then appends it on.
-    $tmp=$owl::msg;
-    $tmp=~s/^/    /g;
-    $tmp=~s/\n/\n    /g;
-    $out.=$tmp;
-
-    # This makes personal messages bold.
-    if (uc($owl::class) eq "MESSAGE" &&
-	uc($owl::instance) eq "PERSONAL" &&
-       $owl::direction eq "in") {
-	$out="\@bold{".$out."}";
-    }
-
-    # Finally, this appends a newline and returns the formatted message.
-    return($out."\n");
-}
-
-## This is run when a message is received, and after
-## it has been added to the message list.
-## In most cases you won't need anything here.
-sub owl::receive_msg() {
-    
-    ## If this is uncommented, it would mark all messages
-    ## with opcode "PING" for immediate deletion:
-    #
-    # if (uc($owl::opcode) eq "PING") {
-    #    owl::command("delete -id $owl::id");
-    # }
-
-    ## If this is uncommented, it would mark all messages
-    ## with class "LOGIN" for immediate deletion:
-    #
-    # if (uc($owl::login) eq "LOGIN") {
-    #    owl::command("delete -id $owl::id");
-    # }
-
-    return 1;
-}
Index: amples/owlconf.vtformat
===================================================================
--- examples/owlconf.vtformat	(revision 7d4fbcdd0df83802711454fdafce2c9d592bf431)
+++ 	(revision )
@@ -1,141 +1,0 @@
-### The owlconf config file   -*- perl -*-  
-###  $Id$
-###
-### This file is interpreted by the perl interpreter.
-### If you wish to execute an owl command use the
-### function owl::command().  i.e.
-###
-###      owl::command("set zsigproc /mit/kretch/bin/getzsig");
-###
-### will set the owl variable zsigproc.  Subroutines created with
-### the names below will be executed at the specified times:
-###
-###     subroutine name    properties
-###     ---------------    ----------
-###     owl::startup()     run when owl first starts
-###     owl::shutdown()    run when owl exits
-###     owl::format_msg()  run when a new message arrives, the return
-###                           value is used to display the message on the
-###                           screen
-###
-### The following variables will be set each time a message is recevied:
-###
-###     $owl::class, $owl::instance, $owl::recipient,
-###     $owl::sender, $owl::opcode, $owl::zsig,
-###     $owl::msg, $owl::time, $owl::host, @owl::fields
-###    
-
-# classes will be appreviated this way
-my %class_abbrev = (
-		   "message"         => "",
-		   "spleen"          => "sp",
-		   "ccare"           => "cc",
-		   "implied-consent" => "ic",
-		   "syseng"          => "se",
-		   "install"         => "i",
-		   );
-
-sub owl::startup {
-    owl::command("set logging off");
-    #owl::command("set zsigproc /home/nygren/bin/owlzsigs");
-    owl::command("set startuplogin off");
-    owl::command("set shutdownlogout off");
-    #owl::command("set personalbell on");
-    owl::command("set rxping on");
-    owl::command("set typewinsize 5");
-}
-
-sub owl::shutdown {
-#    system("/mit/kretch/bin/zkill > /dev/null 2> /dev/null");
-}
-
-sub owl::format_msg {
-    my ($out, $tmp);
-
-    $owl::sender=~s/\@ATHENA\.MIT\.EDU$//;
-    $owl::sender=~s/\@local-realm$//;
-
-    if (uc($owl::opcode) eq "PING") {
-	return("\@bold(PING) from \@bold($owl::sender)\n");
-    } elsif (uc($owl::class) eq "LOGIN") {
-	if (uc($owl::opcode) eq "USER_LOGIN") {
-	    $out="\@bold(LOGIN)";
-	} elsif (uc($owl::opcode) eq "USER_LOGOUT") {
-	    $out="\@bold(LOGOUT)";
-	} else {
-	    $out="\@bold(UNKNOWN)";
-	}
-	$out.=" for \@bold($owl::sender) at $fields[0] on $fields[2]\n";
-	return($out);
-    } elsif (uc($owl::class) eq "MAIL") {
-	$out = "\@bold(MAIL) ";
-	if ($owl::msg =~ /^From:\s+(.+)\s*$/m) { $out .= "From $1 "; }
-	if ($owl::msg =~ /^To:\s+(.+)\s*$/m) { $out .= "To $1 "; }
-	if ($owl::msg =~ /^Subject:\s+(.+)\s*$/m) { $out .= "Subject $1 "; }
-	return($out."\n");
-    }
-
-    my $channel = $owl::class;
-    if (defined $class_abbrev{lc($owl::class)}) {
-	$channel = $class_abbrev{lc($owl::class)};
-    }
-    if (lc($owl::class) ne "message" and lc($owl::instance) eq "personal") {
-	$owl::instance = "";
-    }
-    $channel .= "[".$owl::instance."]";
-    $channel = substr($channel,0,13);
-
-    $header = sprintf "%-8s %-13s ", lc($owl::sender), lc($channel);
-
-    if ($owl::msg =~ /=/) {
-	# indent it
-	$tmp=$owl::msg;
-	$tmp=~s/^/    /g;
-	$tmp=~s/\n/\n    /g;
-	$out.=$header."\n".$tmp;
-    } else {
-	# fill it
-	my $pagewidth = 74;
-	$out .= $header;
-	$out .= fill_text($owl::msg, $pagewidth, 22, 1);
-    }
-
-    # note: no zsig added in this version
-
-    # make personal messages bold
-    if (uc($owl::class) eq "MESSAGE" &&
-	uc($owl::instance) eq "PERSONAL") {
-	$out="\@bold{".$out."}\n";
-    }
-
-    return($out);
-}
-
-
-
-sub fill_text {
-    my ($in, $width, $indent, $unindent_first) = @_;
-    $indent = 0 if (@_ < 3);
-    my $unindent = $indent if ($unindent_first);
-    my @words = split " ", $in;
-    my $out = "";
-    my $outline = "";
-    if (!$unindent_first) {
-	my $outline = " "x$indent;
-    }
-    for my $w (@words) {
-	if (($outline ne "") 
-	    && (length($outline)+length($w) > $width-$unindent)) {
-	    $out .= $outline."\n";
-	    $outline = " "x$indent;
-	    $unindent = 0;
-	}
-	if ($outline =~ /.*\.$/) {
-	    $outline .= "  ";
-	} elsif ($outline ne "") {
-	    $outline .= " ";
-	}
-	$outline .= $w;
-    }
-    $out .= $outline . "\n";    
-}
Index: lter.c
===================================================================
--- filter.c	(revision 9711a6ed78d99195d08bc9f693d8d203fea0cc12)
+++ 	(revision )
@@ -1,372 +1,0 @@
-#include <string.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-int owl_filter_init_fromstring(owl_filter *f, char *name, char *string)
-{
-  char **argv;
-  int argc, out;
-
-  argv=owl_parseline(string, &argc);
-  out=owl_filter_init(f, name, argc, argv);
-  owl_parsefree(argv, argc);
-  return(out);
-}
-
-int owl_filter_init(owl_filter *f, char *name, int argc, char **argv)
-{
-  f->name=owl_strdup(name);
-  f->polarity=0;
-  f->fgcolor=OWL_COLOR_DEFAULT;
-  f->bgcolor=OWL_COLOR_DEFAULT;
-  f->cachedmsgid=-1;
-
-  /* first take arguments that have to come first */
-  /* set the color */
-  while ( argc>=2 && ( !strcmp(argv[0], "-c") ||
-		       !strcmp(argv[0], "-b") ) ) {
-    if (owl_util_string_to_color(argv[1])==OWL_COLOR_INVALID) {
-      owl_function_error("The color '%s' is not available, using default.", argv[1]);
-    } else {
-      switch (argv[0][1]) {
-      case 'c':
-	f->fgcolor=owl_util_string_to_color(argv[1]);
-	break;
-      case 'b':
-	f->bgcolor=owl_util_string_to_color(argv[1]);
-	break;
-      }
-    }
-    argc-=2;
-    argv+=2;
-  }
-
-  if(!(f->root = owl_filter_parse_expression(argc, argv, NULL)))
-    return(-1);
-
-  /* Now check for recursion. */
-  if (owl_filter_is_toodeep(f)) {
-    owl_function_error("Filter loop!");
-    owl_filter_free(f);
-    return(-1);
-  }
-
-  return(0);
-}
-
-
-/* A primitive expression is one without any toplevel ``and'' or ``or''s*/
-
-static owl_filterelement * owl_filter_parse_primitive_expression(int argc, char **argv, int *next)
-{
-  owl_filterelement *fe, *op;
-  int i = 0, skip;
-
-  if(!argc) return NULL;
-
-  fe = owl_malloc(sizeof(owl_filterelement));
-  owl_filterelement_create(fe);
-
-  if(!strcasecmp(argv[i], "(")) {
-    i++;
-    op = owl_filter_parse_expression(argc-i, argv+i, &skip);
-    if(!op) goto err;
-    i += skip;
-    if(i >= argc) goto err;
-    if(strcasecmp(argv[i++], ")")) goto err;
-    owl_filterelement_create_group(fe, op);
-  } else if(!strcasecmp(argv[i], "not")) {
-    i++;
-    op = owl_filter_parse_primitive_expression(argc-i, argv+i, &skip);
-    if(!op) goto err;
-    i += skip;
-    owl_filterelement_create_not(fe, op);
-  } else if(!strcasecmp(argv[i], "true")) {
-    i++;
-    owl_filterelement_create_true(fe);
-  } else if(!strcasecmp(argv[i], "false")) {
-    i++;
-    owl_filterelement_create_false(fe);
-  } else {
-    if(argc == 1) goto err;
-    if(!strcasecmp(*argv, "filter")) {
-      owl_filterelement_create_filter(fe, *(argv+1));
-    } else if(!strcasecmp(*argv, "perl")) {
-      owl_filterelement_create_perl(fe, *(argv+1));
-    } else {
-      owl_filterelement_create_re(fe, *argv, *(argv+1));
-    }
-    i += 2;
-  }
-
-  if(next) {
-    *next = i;
-  } else if(i != argc) {
-    goto err;
-  }
-  return fe;
-err:
-  owl_filterelement_free(fe);
-  owl_free(fe);
-  return NULL;
-}
-
-owl_filterelement * owl_filter_parse_expression(int argc, char **argv, int *next)
-{
-  int i = 0, skip;
-  owl_filterelement * op1 = NULL, * op2 = NULL, *tmp;
-
-  op1 = owl_filter_parse_primitive_expression(argc-i, argv+i, &skip);
-  i += skip;
-  if(!op1) goto err;
-
-  while(i < argc) {
-    if(strcasecmp(argv[i], "and") &&
-       strcasecmp(argv[i], "or")) break;
-    op2 = owl_filter_parse_primitive_expression(argc-i-1, argv+i+1, &skip);
-    if(!op2) goto err;
-    tmp = owl_malloc(sizeof(owl_filterelement));
-    if(!strcasecmp(argv[i], "and")) {
-      owl_filterelement_create_and(tmp, op1, op2);
-    } else {
-      owl_filterelement_create_or(tmp, op1, op2);
-    }
-    op1 = tmp;
-    op2 = NULL;
-    i += skip+1;
-  }
-
-  if(next) {
-    *next = i;
-  } else if(i != argc) {
-    goto err;
-  }
-  return op1;
-err:
-  if(op1) {
-    owl_filterelement_free(op1);
-    owl_free(op1);
-  }
-  return NULL;
-}
-
-char *owl_filter_get_name(owl_filter *f)
-{
-  return(f->name);
-}
-
-void owl_filter_set_polarity_match(owl_filter *f)
-{
-  f->polarity=0;
-}
-
-void owl_filter_set_polarity_unmatch(owl_filter *f)
-{
-  f->polarity=1;
-}
-
-void owl_filter_set_fgcolor(owl_filter *f, int color)
-{
-  f->fgcolor=color;
-}
-
-int owl_filter_get_fgcolor(owl_filter *f)
-{
-  return(f->fgcolor);
-}
-
-void owl_filter_set_bgcolor(owl_filter *f, int color)
-{
-  f->bgcolor=color;
-}
-
-int owl_filter_get_bgcolor(owl_filter *f)
-{
-  return(f->bgcolor);
-}
-
-void owl_filter_set_cachedmsgid(owl_filter *f, int cachedmsgid)
-{
-  f->cachedmsgid=cachedmsgid;
-}
-
-int owl_filter_get_cachedmsgid(owl_filter *f)
-{
-  return(f->cachedmsgid);
-}
-
-/* return 1 if the message matches the given filter, otherwise
- * return 0.
- */
-int owl_filter_message_match(owl_filter *f, owl_message *m)
-{
-  int ret;
-  if(!f->root) return 0;
-  ret = owl_filterelement_match(f->root, m);
-  if(f->polarity) ret = !ret;
-  return ret;
-}
-
-
-char* owl_filter_print(owl_filter *f)
-{
-  GString *out = g_string_new("");
-
-  if (f->fgcolor!=OWL_COLOR_DEFAULT) {
-    g_string_append(out, "-c ");
-    if (f->fgcolor < 8) {
-      g_string_append(out, owl_util_color_to_string(f->fgcolor));
-    }
-    else {
-      g_string_append_printf(out, "%i",f->fgcolor);
-    }
-    g_string_append(out, " ");
-  }
-  if (f->bgcolor!=OWL_COLOR_DEFAULT) {
-    g_string_append(out, "-b ");
-    if (f->bgcolor < 8) {
-      g_string_append(out, owl_util_color_to_string(f->bgcolor));
-    }
-    else {
-      g_string_append_printf(out, "%i",f->fgcolor);
-    }
-    g_string_append(out, " ");
-  }
-  if(f->root) {
-    owl_filterelement_print(f->root, out);
-    g_string_append(out, "\n");
-  }
-
-  return g_string_free(out, 0);
-}
-
-/* Return 1 if the filters 'a' and 'b' are equivalent, 0 otherwise */
-int owl_filter_equiv(owl_filter *a, owl_filter *b)
-{
-  char *buffa, *buffb;
-  int ret;
-
-  buffa = owl_filter_print(a);
-  buffb = owl_filter_print(b);
-
-  ret = !strcmp(buffa, buffb);
-  ret = ret && !strcmp(owl_filter_get_name(a),
-                       owl_filter_get_name(b));
-
-  owl_free(buffa);
-  owl_free(buffb);
-
-  return ret;
-}
-
-
-int owl_filter_is_toodeep(owl_filter *f)
-{
-  return owl_filterelement_is_toodeep(f, f->root);
-}
-
-void owl_filter_free(owl_filter *f)
-{
-  if(f->root) {
-    owl_filterelement_free(f->root);
-    owl_free(f->root);
-  }
-  if (f->name) owl_free(f->name);
-}
-
-/**************************************************************************/
-/************************* REGRESSION TESTS *******************************/
-/**************************************************************************/
-
-#ifdef OWL_INCLUDE_REG_TESTS
-
-int owl_filter_test_string(char * filt, owl_message *m, int shouldmatch) /* noproto */ {
-  owl_filter f;
-  int ok;
-  int failed = 0;
-  if(owl_filter_init_fromstring(&f, "test-filter", filt)) {
-    printf("not ok can't parse %s\n", filt);
-    failed = 1;
-    goto out;
-  }
-  ok = owl_filter_message_match(&f, m);
-  if((shouldmatch && !ok) || (!shouldmatch && ok)) {
-    printf("not ok match %s (got %d, expected %d)\n", filt, ok, shouldmatch);
-    failed = 1;
-  }
- out:
-  owl_filter_free(&f);
-  if(!failed) {
-    printf("ok %s %s\n", shouldmatch ? "matches" : "doesn't match", filt);
-  }
-  return failed;
-}
-
-
-#include "test.h"
-
-
-int owl_filter_regtest(void) {
-  int numfailed=0;
-  owl_message m;
-  owl_filter f1, f2, f3, f4, f5;
-
-  owl_list_create(&(g.filterlist));
-  owl_message_init(&m);
-  owl_message_set_type_zephyr(&m);
-  owl_message_set_direction_in(&m);
-  owl_message_set_class(&m, "owl");
-  owl_message_set_instance(&m, "tester");
-  owl_message_set_sender(&m, "owl-user");
-  owl_message_set_recipient(&m, "joe");
-  owl_message_set_attribute(&m, "foo", "bar");
-
-#define TEST_FILTER(f, e) numfailed += owl_filter_test_string(f, &m, e)
-
-
-  TEST_FILTER("true", 1);
-  TEST_FILTER("false", 0);
-  TEST_FILTER("( true )", 1);
-  TEST_FILTER("not false", 1);
-  TEST_FILTER("( true ) or ( false )", 1);
-  TEST_FILTER("true and false", 0);
-  TEST_FILTER("( true or true ) or ( ( false ) )", 1);
-
-  TEST_FILTER("class owl", 1);
-  TEST_FILTER("class ^owl$", 1);
-  TEST_FILTER("instance test", 1);
-  TEST_FILTER("instance ^test$", 0);
-  TEST_FILTER("instance ^tester$", 1);
-
-  TEST_FILTER("foo bar", 1);
-  TEST_FILTER("class owl and instance tester", 1);
-  TEST_FILTER("type ^zephyr$ and direction ^in$ and ( class ^owl$ or instance ^owl$ )", 1);
-
-  /* Order of operations and precedence */
-  TEST_FILTER("not true or false", 0);
-  TEST_FILTER("true or true and false", 0);
-  TEST_FILTER("true and true and false or true", 1);
-  TEST_FILTER("false and false or true", 1);
-  TEST_FILTER("true and false or false", 0);
-
-  owl_filter_init_fromstring(&f1, "f1", "class owl");
-  owl_global_add_filter(&g, &f1);
-  TEST_FILTER("filter f1", 1);
-
-  /* Test recursion prevention */
-  FAIL_UNLESS("self reference", owl_filter_init_fromstring(&f2, "test", "filter test"));
-
-  /* mutual recursion */
-  owl_filter_init_fromstring(&f3, "f3", "filter f4");
-  owl_global_add_filter(&g, &f3);
-  FAIL_UNLESS("mutual recursion",   owl_filter_init_fromstring(&f4, "f4", "filter f3"));
-
-  /* support referencing a filter several times */
-  FAIL_UNLESS("DAG", !owl_filter_init_fromstring(&f5, "dag", "filter f1 or filter f1"));
-
-  return 0;
-}
-
-
-#endif /* OWL_INCLUDE_REG_TESTS */
Index: lterelement.c
===================================================================
--- filterelement.c	(revision f4464544a8d8ed67998d75c5715219161f0bae5f)
+++ 	(revision )
@@ -1,340 +1,0 @@
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-static char * owl_filterelement_get_field(owl_message *m, char * field)
-{
-  char *match;
-  if (!strcasecmp(field, "class")) {
-    match=owl_message_get_class(m);
-  } else if (!strcasecmp(field, "instance")) {
-    match=owl_message_get_instance(m);
-  } else if (!strcasecmp(field, "sender")) {
-    match=owl_message_get_sender(m);
-  } else if (!strcasecmp(field, "recipient")) {
-    match=owl_message_get_recipient(m);
-  } else if (!strcasecmp(field, "body")) {
-    match=owl_message_get_body(m);
-  } else if (!strcasecmp(field, "opcode")) {
-    match=owl_message_get_opcode(m);
-  } else if (!strcasecmp(field, "realm")) {
-    match=owl_message_get_realm(m);
-  } else if (!strcasecmp(field, "type")) {
-    match=owl_message_get_type(m);
-  } else if (!strcasecmp(field, "hostname")) {
-    match=owl_message_get_hostname(m);
-  } else if (!strcasecmp(field, "direction")) {
-    if (owl_message_is_direction_out(m)) {
-      match="out";
-    } else if (owl_message_is_direction_in(m)) {
-      match="in";
-    } else if (owl_message_is_direction_none(m)) {
-      match="none";
-    } else {
-      match="";
-    }
-  } else if (!strcasecmp(field, "login")) {
-    if (owl_message_is_login(m)) {
-      match="login";
-    } else if (owl_message_is_logout(m)) {
-      match="logout";
-    } else {
-      match="none";
-    }
-  } else {
-    match = owl_message_get_attribute_value(m,field);
-    if(match == NULL) match = "";
-  }
-
-  return match;
-}
-
-static int owl_filterelement_match_false(owl_filterelement *fe, owl_message *m)
-{
-  return 0;
-}
-
-static int owl_filterelement_match_true(owl_filterelement *fe, owl_message *m)
-{
-  return 1;
-}
-
-static int owl_filterelement_match_re(owl_filterelement *fe, owl_message *m)
-{
-  char * val = owl_filterelement_get_field(m, fe->field);
-  return !owl_regex_compare(&(fe->re), val);
-}
-
-static int owl_filterelement_match_filter(owl_filterelement *fe, owl_message *m)
-{
-  owl_filter *subfilter;
-  subfilter=owl_global_get_filter(&g, fe->field);
-  if (!subfilter) {
-    /* the filter does not exist, maybe because it was deleted.
-     * Default to not matching
-     */
-    return 0;
-  } 
-  return owl_filter_message_match(subfilter, m);
-}
-
-static int owl_filterelement_match_perl(owl_filterelement *fe, owl_message *m)
-{
-  char *subname, *perlrv;
-  int   tf=0;
-
-  subname = fe->field;
-  if (!owl_perlconfig_is_function(subname)) {
-    return 0;
-  }
-  perlrv = owl_perlconfig_call_with_message(subname, m);
-  if (perlrv) {
-    if (0 == strcmp(perlrv, "1")) {
-      tf=1;
-    }
-    owl_free(perlrv);
-  }
-  return tf;
-}
-
-static int owl_filterelement_match_group(owl_filterelement *fe, owl_message *m)
-{
-  return owl_filterelement_match(fe->left, m);
-}
-
-/* XXX: Our boolea operators short-circuit here. The original owl did
-   not. Do we care?
-*/
-
-static int owl_filterelement_match_and(owl_filterelement *fe, owl_message *m)
-{
-  return owl_filterelement_match(fe->left, m) &&
-    owl_filterelement_match(fe->right, m);
-}
-
-static int owl_filterelement_match_or(owl_filterelement *fe, owl_message *m)
-{
-  return owl_filterelement_match(fe->left, m) ||
-    owl_filterelement_match(fe->right, m);
-}
-
-static int owl_filterelement_match_not(owl_filterelement *fe, owl_message *m)
-{
-  return !owl_filterelement_match(fe->left, m);
-}
-
-/* Print methods */
-
-static void owl_filterelement_print_true(owl_filterelement *fe, GString *buf)
-{
-  g_string_append(buf, "true");
-}
-
-static void owl_filterelement_print_false(owl_filterelement *fe, GString *buf)
-{
-  g_string_append(buf, "false");
-}
-
-static void owl_filterelement_print_re(owl_filterelement *fe, GString *buf)
-{
-  char *re, *q;
-  g_string_append(buf, fe->field);
-  g_string_append(buf, " ");
-
-  re = owl_regex_get_string(&(fe->re));
-  q = owl_getquoting(re);
-  g_string_append(buf, q);
-  g_string_append(buf, re);
-  g_string_append(buf, q);
-}
-
-static void owl_filterelement_print_filter(owl_filterelement *fe, GString *buf)
-{
-  g_string_append(buf, "filter ");
-  g_string_append(buf, fe->field);
-}
-
-static void owl_filterelement_print_perl(owl_filterelement *fe, GString *buf)
-{
-  g_string_append(buf, "perl ");
-  g_string_append(buf, fe->field);
-}
-
-static void owl_filterelement_print_group(owl_filterelement *fe, GString *buf)
-{
-  g_string_append(buf, "( ");
-  owl_filterelement_print(fe->left, buf) ;
-  g_string_append(buf, " )");
-}
-
-static void owl_filterelement_print_or(owl_filterelement *fe, GString *buf)
-{
-  owl_filterelement_print(fe->left, buf);
-  g_string_append(buf, " or ");
-  owl_filterelement_print(fe->right, buf);
-}
-
-static void owl_filterelement_print_and(owl_filterelement *fe, GString *buf)
-{
-  owl_filterelement_print(fe->left, buf);
-  g_string_append(buf, " and ");
-  owl_filterelement_print(fe->right, buf);
-}
-
-static void owl_filterelement_print_not(owl_filterelement *fe, GString *buf)
-{
-  g_string_append(buf, " not ");
-  owl_filterelement_print(fe->left, buf);
-}
-
-/* Constructors */
-
-void owl_filterelement_create(owl_filterelement *fe) {
-  fe->field = NULL;
-  fe->left = fe->right = NULL;
-  fe->match_message = NULL;
-  fe->print_elt = NULL;
-  owl_regex_init(&(fe->re));
-}
-
-
-void owl_filterelement_create_true(owl_filterelement *fe)
-{
-  owl_filterelement_create(fe);
-  fe->match_message = owl_filterelement_match_true;
-  fe->print_elt = owl_filterelement_print_true;
-}
-
-void owl_filterelement_create_false(owl_filterelement *fe)
-{
-  owl_filterelement_create(fe);
-  fe->match_message = owl_filterelement_match_false;
-  fe->print_elt = owl_filterelement_print_false;
-}
-
-void owl_filterelement_create_re(owl_filterelement *fe, char *field, char *re)
-{
-  owl_filterelement_create(fe);
-  fe->field=owl_strdup(field);
-  owl_regex_create(&(fe->re), re);
-  fe->match_message = owl_filterelement_match_re;
-  fe->print_elt = owl_filterelement_print_re;
-}
-
-void owl_filterelement_create_filter(owl_filterelement *fe, char *name)
-{
-  owl_filterelement_create(fe);
-  fe->field=owl_strdup(name);
-  fe->match_message = owl_filterelement_match_filter;
-  fe->print_elt = owl_filterelement_print_filter;
-}
-
-void owl_filterelement_create_perl(owl_filterelement *fe, char *name)
-{
-  owl_filterelement_create(fe);
-  fe->field=owl_strdup(name);
-  fe->match_message = owl_filterelement_match_perl;
-  fe->print_elt = owl_filterelement_print_perl;
-}
-
-void owl_filterelement_create_group(owl_filterelement *fe, owl_filterelement *in)
-{
-  owl_filterelement_create(fe);
-  fe->left = in;
-  fe->match_message = owl_filterelement_match_group;
-  fe->print_elt = owl_filterelement_print_group;
-}
-
-void owl_filterelement_create_not(owl_filterelement *fe, owl_filterelement *in)
-{
-  owl_filterelement_create(fe);
-  fe->left = in;
-  fe->match_message = owl_filterelement_match_not;
-  fe->print_elt = owl_filterelement_print_not;
-}
-
-void owl_filterelement_create_and(owl_filterelement *fe, owl_filterelement *lhs, owl_filterelement *rhs)
-{
-  owl_filterelement_create(fe);
-  fe->left = lhs;
-  fe->right = rhs;
-  fe->match_message = owl_filterelement_match_and;
-  fe->print_elt = owl_filterelement_print_and;
-}
-
-void owl_filterelement_create_or(owl_filterelement *fe, owl_filterelement *lhs, owl_filterelement *rhs)
-{
-  owl_filterelement_create(fe);
-  fe->left = lhs;
-  fe->right = rhs;
-  fe->match_message = owl_filterelement_match_or;
-  fe->print_elt = owl_filterelement_print_or;
-}
-
-int owl_filterelement_match(owl_filterelement *fe, owl_message *m)
-{
-  if(!fe) return 0;
-  if(!fe->match_message) return 0;
-  return fe->match_message(fe, m);
-}
-
-static int fe_visiting = 0;
-static int fe_visited  = 1;
-
-int owl_filterelement_is_toodeep(owl_filter *f, owl_filterelement *fe)
-{
-  int rv;
-  owl_dict filters;
-  owl_dict_create(&filters);
-
-  owl_dict_insert_element(&filters, f->name, &fe_visiting, owl_dict_noop_free);
-
-  rv = _owl_filterelement_is_toodeep(fe, &filters);
-
-  owl_dict_free_simple(&filters);
-  return rv;
-}
-
-int _owl_filterelement_is_toodeep(owl_filterelement *fe, owl_dict *seen)
-{
-  int rv = 0;
-  owl_filter *f;
-
-  if(fe->match_message == owl_filterelement_match_filter) {
-    int *nval = owl_dict_find_element(seen, fe->field);
-    if(nval == &fe_visiting) {
-      return 1;
-    } else if (nval == NULL) {
-      f = owl_global_get_filter(&g, fe->field);
-      owl_dict_insert_element(seen, fe->field, &fe_visiting, owl_dict_noop_free);
-      if(f) rv = _owl_filterelement_is_toodeep(f->root, seen);
-      owl_dict_insert_element(seen, fe->field, &fe_visited, owl_dict_noop_free);
-    }
-  } else {
-    if(fe->left)
-      rv = rv || _owl_filterelement_is_toodeep(fe->left, seen);
-    if(fe->right)
-      rv = rv || _owl_filterelement_is_toodeep(fe->right, seen);
-  }
-  return rv;
-}
-
-void owl_filterelement_free(owl_filterelement *fe)
-{
-  if (fe->field) owl_free(fe->field);
-  if (fe->left) {
-    owl_filterelement_free(fe->left);
-    owl_free(fe->left);
-  }
-  if (fe->right) {
-    owl_filterelement_free(fe->right);
-    owl_free(fe->right);
-  }
-  owl_regex_free(&(fe->re));
-}
-
-void owl_filterelement_print(owl_filterelement *fe, GString *buf)
-{
-  if(!fe || !fe->print_elt) return;
-  fe->print_elt(fe, buf);
-}
Index: text.c
===================================================================
--- fmtext.c	(revision 2aaca9484520a9cea0bdc795273de2fd34751c20)
+++ 	(revision )
@@ -1,886 +1,0 @@
-#include "owl.h"
-#include <stdlib.h>
-#include <string.h>
-
-static const char fileIdent[] = "$Id$";
-
-/* initialize an fmtext with no data */
-void owl_fmtext_init_null(owl_fmtext *f)
-{
-  f->textlen = 0;
-  f->bufflen = 5;
-  f->textbuff = owl_malloc(5);
-  f->textbuff[0] = 0;
-  f->default_attrs = OWL_FMTEXT_ATTR_NONE;
-  f->default_fgcolor = OWL_COLOR_DEFAULT;
-  f->default_bgcolor = OWL_COLOR_DEFAULT;
-}
-
-/* Clear the data from an fmtext, but don't deallocate memory. This
-   fmtext can then be appended to again. */
-void owl_fmtext_clear(owl_fmtext *f)
-{
-  f->textlen = 0;
-  f->textbuff[0] = 0;
-  f->default_attrs = OWL_FMTEXT_ATTR_NONE;
-  f->default_fgcolor = OWL_COLOR_DEFAULT;
-  f->default_bgcolor = OWL_COLOR_DEFAULT;
-}
-
-void _owl_fmtext_realloc(owl_fmtext *f, int newlen) /*noproto*/
-{
-    if(newlen + 1 > f->bufflen) {
-      f->textbuff = owl_realloc(f->textbuff, newlen + 1);
-      f->bufflen = newlen+1;
-  }
-}
-
-int owl_fmtext_is_format_char(gunichar c)
-{
-  if ((c & ~OWL_FMTEXT_UC_ATTR_MASK) == OWL_FMTEXT_UC_ATTR) return 1;
-  if ((c & ~(OWL_FMTEXT_UC_ALLCOLOR_MASK)) == OWL_FMTEXT_UC_COLOR_BASE) return 1;
-  return 0;
-}
-/* append text to the end of 'f' with attribute 'attr' and color
- * 'color'
- */
-void owl_fmtext_append_attr(owl_fmtext *f, char *text, char attr, short fgcolor, short bgcolor)
-{
-  char attrbuff[6];
-  int newlen, a = 0, fg = 0, bg = 0;
-  
-  if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
-  if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
-  if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
-
-  /* Plane-16 characters in UTF-8 are 4 bytes long. */
-  newlen = strlen(f->textbuff) + strlen(text) + (8 * (a + fg + bg));
-  _owl_fmtext_realloc(f, newlen);
-
-  /* Set attributes */
-  if (a) {
-    memset(attrbuff,0,6);
-    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
-    strcat(f->textbuff, attrbuff);      
-  }
-  if (fg) {
-    memset(attrbuff,0,6);
-    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
-    strcat(f->textbuff, attrbuff);      
-  }
-  if (bg) {
-    memset(attrbuff,0,6);
-    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
-    strcat(f->textbuff, attrbuff);      
-  }
-  
-  strcat(f->textbuff, text);
-
-  /* Reset attributes */
-  if (bg) strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
-  if (fg) strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
-  if (a)  strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
-  f->textlen=newlen;
-}
-
-/* Append normal, uncolored text 'text' to 'f' */
-void owl_fmtext_append_normal(owl_fmtext *f, char *text)
-{
-  owl_fmtext_append_attr(f, text, OWL_FMTEXT_ATTR_NONE, OWL_COLOR_DEFAULT, OWL_COLOR_DEFAULT);
-}
-
-/* Append normal text 'text' to 'f' with color 'color' */
-void owl_fmtext_append_normal_color(owl_fmtext *f, char *text, int fgcolor, int bgcolor)
-{
-  owl_fmtext_append_attr(f, text, OWL_FMTEXT_ATTR_NONE, fgcolor, bgcolor);
-}
-
-/* Append bold text 'text' to 'f' */
-void owl_fmtext_append_bold(owl_fmtext *f, char *text)
-{
-  owl_fmtext_append_attr(f, text, OWL_FMTEXT_ATTR_BOLD, OWL_COLOR_DEFAULT, OWL_COLOR_DEFAULT);
-}
-
-/* Append reverse video text 'text' to 'f' */
-void owl_fmtext_append_reverse(owl_fmtext *f, char *text)
-{
-  owl_fmtext_append_attr(f, text, OWL_FMTEXT_ATTR_REVERSE, OWL_COLOR_DEFAULT, OWL_COLOR_DEFAULT);
-}
-
-/* Append reversed and bold, uncolored text 'text' to 'f' */
-void owl_fmtext_append_reversebold(owl_fmtext *f, char *text)
-{
-  owl_fmtext_append_attr(f, text, OWL_FMTEXT_ATTR_REVERSE | OWL_FMTEXT_ATTR_BOLD, OWL_COLOR_DEFAULT, OWL_COLOR_DEFAULT);
-}
-
-/* Add the attribute 'attr' to the default atts for the text in 'f' */
-void owl_fmtext_addattr(owl_fmtext *f, char attr)
-{
-  /* add the attribute to all text */
-  f->default_attrs |= attr;
-}
-
-/* Set the default foreground color for this fmtext to 'color'.
- * Only affects text that is colored default.
- */
-void owl_fmtext_colorize(owl_fmtext *f, int color)
-{
-  f->default_fgcolor = color;
-}
-
-/* Set the default foreground color for this fmtext to 'color'.
- * Only affects text that is colored default.
- */
-void owl_fmtext_colorizebg(owl_fmtext *f, int color)
-{
-  f->default_bgcolor = color;
-}
-
-/* Internal function. Parse attrbute character. */
-void _owl_fmtext_update_attributes(gunichar c, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
-{
-  if ((c & OWL_FMTEXT_UC_ATTR) == OWL_FMTEXT_UC_ATTR) {
-    *attr = c & OWL_FMTEXT_UC_ATTR_MASK;
-  }
-  else if ((c & OWL_FMTEXT_UC_COLOR_BASE) == OWL_FMTEXT_UC_COLOR_BASE) {
-    if ((c & OWL_FMTEXT_UC_BGCOLOR) == OWL_FMTEXT_UC_BGCOLOR) {
-      *bgcolor = (c == OWL_FMTEXT_UC_BGDEFAULT
-                  ? OWL_COLOR_DEFAULT
-                  : c & OWL_FMTEXT_UC_COLOR_MASK);
-    }
-    else if ((c & OWL_FMTEXT_UC_FGCOLOR) == OWL_FMTEXT_UC_FGCOLOR) {
-      *fgcolor = (c == OWL_FMTEXT_UC_FGDEFAULT
-                  ? OWL_COLOR_DEFAULT
-                  : c & OWL_FMTEXT_UC_COLOR_MASK);
-    }
-  }
-}
-
-/* Internal function. Scan for attribute characters. */
-void _owl_fmtext_scan_attributes(owl_fmtext *f, int start, char *attr, short *fgcolor, short *bgcolor) /*noproto*/
-{
-  char *p;
-  p = strchr(f->textbuff, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-  while (p && p < f->textbuff + start) {
-    _owl_fmtext_update_attributes(g_utf8_get_char(p), attr, fgcolor, bgcolor);
-    p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-  }
-}  
-
-/* Internal function.  Append text from 'in' between index 'start' and
- * 'stop' to the end of 'f'
- */
-void _owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in, int start, int stop) /*noproto*/
-{
-  char attrbuff[6];
-  int newlen, a = 0, fg = 0, bg = 0;
-  char attr = 0;
-  short fgcolor = OWL_COLOR_DEFAULT;
-  short bgcolor = OWL_COLOR_DEFAULT;
-
-  _owl_fmtext_scan_attributes(in, start, &attr, &fgcolor, &bgcolor);
-  if (attr != OWL_FMTEXT_ATTR_NONE) a=1;
-  if (fgcolor != OWL_COLOR_DEFAULT) fg=1;
-  if (bgcolor != OWL_COLOR_DEFAULT) bg=1;
-
-  /* We will reset to defaults after appending the text. We may need
-     to set initial attributes. */
-  newlen=strlen(f->textbuff)+(stop-start+1) + (4 * (a + fg + bg)) + 12;
-  _owl_fmtext_realloc(f, newlen);
-
-  if (a) {
-    memset(attrbuff,0,6);
-    g_unichar_to_utf8(OWL_FMTEXT_UC_ATTR | attr, attrbuff);
-    strcat(f->textbuff, attrbuff);      
-  }
-  if (fg) {
-    memset(attrbuff,0,6);
-    g_unichar_to_utf8(OWL_FMTEXT_UC_FGCOLOR | fgcolor, attrbuff);
-    strcat(f->textbuff, attrbuff);      
-  }
-  if (bg) {
-    memset(attrbuff,0,6);
-    g_unichar_to_utf8(OWL_FMTEXT_UC_BGCOLOR | bgcolor, attrbuff);
-    strcat(f->textbuff, attrbuff);      
-  }
-
-  strncat(f->textbuff, in->textbuff+start, stop-start+1);
-
-  /* Reset attributes */
-  strcat(f->textbuff, OWL_FMTEXT_UTF8_BGDEFAULT);
-  strcat(f->textbuff, OWL_FMTEXT_UTF8_FGDEFAULT);
-  strcat(f->textbuff, OWL_FMTEXT_UTF8_ATTR_NONE);
-
-  f->textbuff[newlen]='\0';
-  f->textlen=newlen;
-}
-
-/* append fmtext 'in' to 'f' */
-void owl_fmtext_append_fmtext(owl_fmtext *f, owl_fmtext *in)
-{
-  _owl_fmtext_append_fmtext(f, in, 0, in->textlen);
-
-}
-
-/* Append 'nspaces' number of spaces to the end of 'f' */
-void owl_fmtext_append_spaces(owl_fmtext *f, int nspaces)
-{
-  int i;
-  for (i=0; i<nspaces; i++) {
-    owl_fmtext_append_normal(f, " ");
-  }
-}
-
-/* Return a plain version of the fmtext.  Caller is responsible for
- * freeing the return
- */
-char *owl_fmtext_print_plain(owl_fmtext *f)
-{
-  return owl_strip_format_chars(f->textbuff);
-}
-
-void _owl_fmtext_wattrset(WINDOW *w, int attrs) /*noproto*/
-{
-  wattrset(w, A_NORMAL);
-  if (attrs & OWL_FMTEXT_ATTR_BOLD) wattron(w, A_BOLD);
-  if (attrs & OWL_FMTEXT_ATTR_REVERSE) wattron(w, A_REVERSE);
-  if (attrs & OWL_FMTEXT_ATTR_UNDERLINE) wattron(w, A_UNDERLINE);
-}
-
-void _owl_fmtext_update_colorpair(short fg, short bg, short *pair) /*noproto*/
-{
-  if (owl_global_get_hascolors(&g)) {
-    *pair = owl_fmtext_get_colorpair(fg, bg);
-  }
-}
-
-void _owl_fmtext_wcolor_set(WINDOW *w, short pair) /*noproto*/
-{
-  if (owl_global_get_hascolors(&g)) {
-      wcolor_set(w,pair,NULL);
-  }
-}
-
-/* add the formatted text to the curses window 'w'.  The window 'w'
- * must already be initiatlized with curses
- */
-void _owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w, int do_search) /*noproto*/
-{
-  /* char *tmpbuff; */
-  /* int position, trans1, trans2, trans3, len, lastsame; */
-  char *s, *p;
-  char attr;
-  short fg, bg, pair;
-  int search_results, search_len;
-  
-  if (w==NULL) {
-    owl_function_debugmsg("Hit a null window in owl_fmtext_curs_waddstr.");
-    return;
-  }
-
-  search_results = (do_search
-		    ? owl_fmtext_search(f, owl_global_get_search_string(&g))
-		    : 0);
-  search_len = (search_results
-		? strlen(owl_global_get_search_string(&g))
-		: 0);
-  s = f->textbuff;
-  /* Set default attributes. */
-  attr = f->default_attrs;
-  fg = f->default_fgcolor;
-  bg = f->default_bgcolor;
-  _owl_fmtext_wattrset(w, attr);
-  _owl_fmtext_update_colorpair(fg, bg, &pair);
-  _owl_fmtext_wcolor_set(w, pair);
-
-  /* Find next possible format character. */
-  p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-  while(p) {
-    if (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
-      /* Deal with all text from last insert to here. */
-      char tmp;
-   
-      tmp = p[0];
-      p[0] = '\0';
-      if (search_results) {
-	/* Search is active, so highlight search results. */
-	char tmp2, *ss;
-	ss = stristr(s, owl_global_get_search_string(&g));
-	while (ss) {
-	  /* Found search string, highlight it. */
-
-	  tmp2 = ss[0];
-	  ss[0] = '\0';
-	  waddstr(w, s);
-	  ss[0] = tmp2;
-
-	  _owl_fmtext_wattrset(w, attr ^ OWL_FMTEXT_ATTR_REVERSE);
-	  _owl_fmtext_wcolor_set(w, pair);
-	  
-	  tmp2 = ss[search_len];
-	  ss[search_len] = '\0';
-	  waddstr(w, ss);
-	  ss[search_len] = tmp2;
-
-	  _owl_fmtext_wattrset(w, attr);
-	  _owl_fmtext_wcolor_set(w, pair);
-
-	  s = ss + search_len;
-	  ss = stristr(s, owl_global_get_search_string(&g));
-	}
-      }
-      /* Deal with remaining part of string. */
-      waddstr(w, s);
-      p[0] = tmp;
-
-      /* Deal with new attributes. Initialize to defaults, then
-	 process all consecutive formatting characters. */
-      attr = f->default_attrs;
-      fg = f->default_fgcolor;
-      bg = f->default_bgcolor;
-      while (p && owl_fmtext_is_format_char(g_utf8_get_char(p))) {
-	_owl_fmtext_update_attributes(g_utf8_get_char(p), &attr, &fg, &bg);
-	p = g_utf8_next_char(p);
-      }
-      _owl_fmtext_wattrset(w, attr | f->default_attrs);
-      if (fg == OWL_COLOR_DEFAULT) fg = f->default_fgcolor;
-      if (bg == OWL_COLOR_DEFAULT) bg = f->default_bgcolor;
-      _owl_fmtext_update_colorpair(fg, bg, &pair);
-      _owl_fmtext_wcolor_set(w, pair);
-
-      /* Advance to next non-formatting character. */
-      s = p;
-      p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-    }
-    else {
-      p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-    }
-  }
-  if (s) {
-    waddstr(w, s);
-  }
-}
-
-void owl_fmtext_curs_waddstr(owl_fmtext *f, WINDOW *w)
-{
-  _owl_fmtext_curs_waddstr(f, w, owl_global_is_search_active(&g));
-}
-
-void owl_fmtext_curs_waddstr_without_search(owl_fmtext *f, WINDOW *w)
-{
-  _owl_fmtext_curs_waddstr(f, w, 0);
-}
-
-/* start with line 'aline' (where the first line is 0) and print
- * 'lines' number of lines into 'out'
- */
-int owl_fmtext_truncate_lines(owl_fmtext *in, int aline, int lines, owl_fmtext *out)
-{
-  char *ptr1, *ptr2;
-  int i, offset;
-  
-  /* find the starting line */
-  ptr1 = in->textbuff;
-  for (i = 0; i < aline; i++) {
-    ptr1 = strchr(ptr1, '\n');
-    if (!ptr1) return(-1);
-    ptr1++;
-  }
-  
-  /* ptr1 now holds the starting point */
-
-  /* copy the default attributes */
-  out->default_attrs = in->default_attrs;
-  out->default_fgcolor = in->default_fgcolor;
-  out->default_bgcolor = in->default_bgcolor;
-    
-  /* copy in the next 'lines' lines */
-  if (lines < 1) return(-1);
-
-  for (i = 0; i < lines; i++) {
-    offset = ptr1 - in->textbuff;
-    ptr2 = strchr(ptr1, '\n');
-    if (!ptr2) {
-      _owl_fmtext_append_fmtext(out, in, offset, (in->textlen) - 1);
-      return(-1);
-    }
-    _owl_fmtext_append_fmtext(out, in, offset, (ptr2 - ptr1) + offset);
-    ptr1 = ptr2 + 1;
-  }
-  return(0);
-}
-
-/* Truncate the message so that each line begins at column 'acol' and
- * ends at 'bcol' or sooner.  The first column is number 0.  The new
- * message is placed in 'out'.  The message is * expected to end in a
- * new line for now. NOTE: This needs to be modified to deal with
- * backing up if we find a SPACING COMBINING MARK at the end of a
- * line. If that happens, we should back up to the last non-mark
- * character and stop there.
- */
-void owl_fmtext_truncate_cols(owl_fmtext *in, int acol, int bcol, owl_fmtext *out)
-{
-  char *ptr_s, *ptr_e, *ptr_c, *last;
-  int col, st, padding, chwidth;
-
-  /* copy the default attributes */
-  out->default_attrs = in->default_attrs;
-  out->default_fgcolor = in->default_fgcolor;
-  out->default_bgcolor = in->default_bgcolor;
-
-  last=in->textbuff+in->textlen-1;
-  ptr_s=in->textbuff;
-  while (ptr_s <= last) {
-    ptr_e=strchr(ptr_s, '\n');
-    if (!ptr_e) {
-      /* but this shouldn't happen if we end in a \n */
-      break;
-    }
-    
-    if (ptr_e == ptr_s) {
-      owl_fmtext_append_normal(out, "\n");
-      ++ptr_s;
-      continue;
-    }
-
-    col = 0;
-    st = 0;
-    padding = 0;
-    chwidth = 0;
-    ptr_c = ptr_s;
-    while(ptr_c < ptr_e) {
-      gunichar c = g_utf8_get_char(ptr_c);
-      if (!owl_fmtext_is_format_char(c)) {
-	chwidth = mk_wcwidth(c);
-	if (col + chwidth > bcol) break;
-	
-	if (col >= acol) {
-	  if (st == 0) {
-	    ptr_s = ptr_c;
-	    padding = col - acol;
-	    ++st;
-	  }
-	}
-	col += chwidth;
-	chwidth = 0;
-      }
-      ptr_c = g_utf8_next_char(ptr_c);
-    }
-    if (st) {
-      /* lead padding */
-      owl_fmtext_append_spaces(out, padding);
-      if (ptr_c == ptr_e) {
-	/* We made it to the newline. */
-	_owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
-      }
-      else {
-	if (chwidth > 1) {
-	  /* Last char is wide, truncate. */
-	  _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff - 1);
-	  owl_fmtext_append_normal(out, "\n");
-	}
-	else {
-	  /* Last char fits perfectly, leave alone.*/
-	  _owl_fmtext_append_fmtext(out, in, ptr_s - in->textbuff, ptr_c - in->textbuff);
-	}
-      }
-    }
-    else {
-      owl_fmtext_append_normal(out, "\n");
-    }
-    ptr_s = g_utf8_next_char(ptr_e);
-  }
-}
-
-/* Return the number of lines in 'f' */
-int owl_fmtext_num_lines(owl_fmtext *f)
-{
-  int lines, i;
-
-  if (f->textlen==0) return(0);
-  
-  lines=0;
-  for (i=0; i<f->textlen; i++) {
-    if (f->textbuff[i]=='\n') lines++;
-  }
-
-  /* if the last char wasn't a \n there's one more line */
-  if (f->textbuff[i-1]!='\n') lines++;
-
-  return(lines);
-}
-
-char *owl_fmtext_get_text(owl_fmtext *f)
-{
-  return(f->textbuff);
-}
-
-/* set the charater at 'index' to be 'char'.  If index is out of
- * bounds don't do anything. If c or char at index is not ASCII, don't
- * do anything because it's not UTF-8 safe. */
-void owl_fmtext_set_char(owl_fmtext *f, int index, char ch)
-{
-  if ((index < 0) || (index > f->textlen-1)) return;
-  /* NOT ASCII*/
-  if (f->textbuff[index] & 0x80 || ch & 0x80) return; 
-  f->textbuff[index]=ch;
-}
-
-/* Make a copy of the fmtext 'src' into 'dst' */
-void owl_fmtext_copy(owl_fmtext *dst, owl_fmtext *src)
-{
-  int mallocsize;
-
-  if (src->textlen==0) {
-    mallocsize=5;
-  } else {
-    mallocsize=src->textlen+2;
-  }
-  dst->textlen=src->textlen;
-  dst->bufflen=mallocsize;
-  dst->textbuff=owl_malloc(mallocsize);
-  memcpy(dst->textbuff, src->textbuff, src->textlen+1);
-  dst->default_attrs = src->default_attrs;
-  dst->default_fgcolor = src->default_fgcolor;
-  dst->default_bgcolor = src->default_bgcolor;
-}
-
-/* return 1 if the string is found, 0 if not.  This is a case
- *  insensitive search.
- */
-int owl_fmtext_search(owl_fmtext *f, char *string)
-{
-  if (stristr(f->textbuff, string)) return(1);
-  return(0);
-}
-
-
-/* Append the text 'text' to 'f' and interpret the zephyr style
- * formatting syntax to set appropriate attributes.
- */
-void owl_fmtext_append_ztext(owl_fmtext *f, char *text)
-{
-  int stacksize, curattrs, curcolor;
-  char *ptr, *txtptr, *buff, *tmpptr;
-  int attrstack[32], chrstack[32], colorstack[32];
-
-  curattrs=OWL_FMTEXT_ATTR_NONE;
-  curcolor=OWL_COLOR_DEFAULT;
-  stacksize=0;
-  txtptr=text;
-  while (1) {
-    ptr=strpbrk(txtptr, "@{[<()>]}");
-    if (!ptr) {
-      /* add all the rest of the text and exit */
-      owl_fmtext_append_attr(f, txtptr, curattrs, curcolor, OWL_COLOR_DEFAULT);
-      return;
-    } else if (ptr[0]=='@') {
-      /* add the text up to this point then deal with the stack */
-      buff=owl_malloc(ptr-txtptr+20);
-      strncpy(buff, txtptr, ptr-txtptr);
-      buff[ptr-txtptr]='\0';
-      owl_fmtext_append_attr(f, buff, curattrs, curcolor, OWL_COLOR_DEFAULT);
-      owl_free(buff);
-
-      /* update pointer to point at the @ */
-      txtptr=ptr;
-
-      /* now the stack */
-
-      /* if we've hit our max stack depth, print the @ and move on */
-      if (stacksize==32) {
-        owl_fmtext_append_attr(f, "@", curattrs, curcolor, OWL_COLOR_DEFAULT);
-        txtptr++;
-        continue;
-      }
-
-      /* if it's an @@, print an @ and continue */
-      if (txtptr[1]=='@') {
-        owl_fmtext_append_attr(f, "@", curattrs, curcolor, OWL_COLOR_DEFAULT);
-        txtptr+=2;
-        continue;
-      }
-        
-      /* if there's no opener, print the @ and continue */
-      tmpptr=strpbrk(txtptr, "(<[{ ");
-      if (!tmpptr || tmpptr[0]==' ') {
-        owl_fmtext_append_attr(f, "@", curattrs, curcolor, OWL_COLOR_DEFAULT);
-        txtptr++;
-        continue;
-      }
-
-      /* check what command we've got, push it on the stack, start
-         using it, and continue ... unless it's a color command */
-      buff=owl_malloc(tmpptr-ptr+20);
-      strncpy(buff, ptr, tmpptr-ptr);
-      buff[tmpptr-ptr]='\0';
-      if (!strcasecmp(buff, "@bold")) {
-        attrstack[stacksize]=OWL_FMTEXT_ATTR_BOLD;
-        chrstack[stacksize]=tmpptr[0];
-	colorstack[stacksize]=curcolor;
-        stacksize++;
-        curattrs|=OWL_FMTEXT_ATTR_BOLD;
-        txtptr+=6;
-        owl_free(buff);
-        continue;
-      } else if (!strcasecmp(buff, "@b")) {
-        attrstack[stacksize]=OWL_FMTEXT_ATTR_BOLD;
-        chrstack[stacksize]=tmpptr[0];
-	colorstack[stacksize]=curcolor;
-        stacksize++;
-        curattrs|=OWL_FMTEXT_ATTR_BOLD;
-        txtptr+=3;
-        owl_free(buff);
-        continue;
-      } else if (!strcasecmp(buff, "@i")) {
-        attrstack[stacksize]=OWL_FMTEXT_ATTR_UNDERLINE;
-        chrstack[stacksize]=tmpptr[0];
-	colorstack[stacksize]=curcolor;
-        stacksize++;
-        curattrs|=OWL_FMTEXT_ATTR_UNDERLINE;
-        txtptr+=3;
-        owl_free(buff);
-        continue;
-      } else if (!strcasecmp(buff, "@italic")) {
-        attrstack[stacksize]=OWL_FMTEXT_ATTR_UNDERLINE;
-        chrstack[stacksize]=tmpptr[0];
-	colorstack[stacksize]=curcolor;
-        stacksize++;
-        curattrs|=OWL_FMTEXT_ATTR_UNDERLINE;
-        txtptr+=8;
-        owl_free(buff);
-        continue;
-      } else if (!strcasecmp(buff, "@")) {
-	attrstack[stacksize]=OWL_FMTEXT_ATTR_NONE;
-	chrstack[stacksize]=tmpptr[0];
-	colorstack[stacksize]=curcolor;
-        stacksize++;
-        txtptr+=2;
-        owl_free(buff);
-        continue;
-
-        /* if it's a color read the color, set the current color and
-           continue */
-      } else if (!strcasecmp(buff, "@color") 
-                 && owl_global_get_hascolors(&g)
-                 && owl_global_is_colorztext(&g)) {
-        owl_free(buff);
-        txtptr+=7;
-        tmpptr=strpbrk(txtptr, "@{[<()>]}");
-        if (tmpptr &&
-            ((txtptr[-1]=='(' && tmpptr[0]==')') ||
-             (txtptr[-1]=='<' && tmpptr[0]=='>') ||
-             (txtptr[-1]=='[' && tmpptr[0]==']') ||
-             (txtptr[-1]=='{' && tmpptr[0]=='}'))) {
-
-          /* grab the color name */
-          buff=owl_malloc(tmpptr-txtptr+20);
-          strncpy(buff, txtptr, tmpptr-txtptr);
-          buff[tmpptr-txtptr]='\0';
-
-          /* set it as the current color */
-          curcolor=owl_util_string_to_color(buff);
-          if (curcolor==-1) curcolor=OWL_COLOR_DEFAULT;
-          owl_free(buff);
-          txtptr=tmpptr+1;
-          continue;
-
-        } else {
-
-        }
-
-      } else {
-        /* if we didn't understand it, we'll print it.  This is different from zwgc
-         * but zwgc seems to be smarter about some screw cases than I am
-         */
-        owl_fmtext_append_attr(f, "@", curattrs, curcolor, OWL_COLOR_DEFAULT);
-        txtptr++;
-        continue;
-      }
-
-    } else if (ptr[0]=='}' || ptr[0]==']' || ptr[0]==')' || ptr[0]=='>') {
-      /* add the text up to this point first */
-      buff=owl_malloc(ptr-txtptr+20);
-      strncpy(buff, txtptr, ptr-txtptr);
-      buff[ptr-txtptr]='\0';
-      owl_fmtext_append_attr(f, buff, curattrs, curcolor, OWL_COLOR_DEFAULT);
-      owl_free(buff);
-
-      /* now deal with the closer */
-      txtptr=ptr;
-
-      /* first, if the stack is empty we must bail (just print and go) */
-      if (stacksize==0) {
-        buff=owl_malloc(5);
-        buff[0]=ptr[0];
-        buff[1]='\0';
-        owl_fmtext_append_attr(f, buff, curattrs, curcolor, OWL_COLOR_DEFAULT);
-        owl_free(buff);
-        txtptr++;
-        continue;
-      }
-
-      /* if the closing char is what's on the stack, turn off the
-         attribue and pop the stack */
-      if ((ptr[0]==')' && chrstack[stacksize-1]=='(') ||
-          (ptr[0]=='>' && chrstack[stacksize-1]=='<') ||
-          (ptr[0]==']' && chrstack[stacksize-1]=='[') ||
-          (ptr[0]=='}' && chrstack[stacksize-1]=='{')) {
-        int i;
-        stacksize--;
-        curattrs=OWL_FMTEXT_ATTR_NONE;
-	curcolor = colorstack[stacksize];
-        for (i=0; i<stacksize; i++) {
-          curattrs|=attrstack[i];
-        }
-        txtptr+=1;
-        continue;
-      } else {
-        /* otherwise print and continue */
-        buff=owl_malloc(5);
-        buff[0]=ptr[0];
-        buff[1]='\0';
-        owl_fmtext_append_attr(f, buff, curattrs, curcolor, OWL_COLOR_DEFAULT);
-        owl_free(buff);
-        txtptr++;
-        continue;
-      }
-    } else {
-      /* we've found an unattached opener, print everything and move on */
-      buff=owl_malloc(ptr-txtptr+20);
-      strncpy(buff, txtptr, ptr-txtptr+1);
-      buff[ptr-txtptr+1]='\0';
-      owl_fmtext_append_attr(f, buff, curattrs, curcolor, OWL_COLOR_DEFAULT);
-      owl_free(buff);
-      txtptr=ptr+1;
-      continue;
-    }
-  }
-}
-
-/* requires that the list values are strings or NULL.
- * joins the elements together with join_with. 
- * If format_fn is specified, passes it the list element value
- * and it will return a string which this needs to free. */
-void owl_fmtext_append_list(owl_fmtext *f, owl_list *l, char *join_with, char *(format_fn)(char *))
-{
-  int i, size;
-  char *elem;
-  char *text;
-
-  size = owl_list_get_size(l);
-  for (i=0; i<size; i++) {
-    elem = (char*)owl_list_get_element(l,i);
-    if (elem && format_fn) {
-      text = format_fn(elem);
-      if (text) {
-        owl_fmtext_append_normal(f, text);
-        owl_free(text);
-      }
-    } else if (elem) {
-      owl_fmtext_append_normal(f, elem);
-    }
-    if ((i < size-1) && join_with) {
-      owl_fmtext_append_normal(f, join_with);
-    }
-  }
-}
-
-/* Free all memory allocated by the object */
-void owl_fmtext_free(owl_fmtext *f)
-{
-  if (f->textbuff) owl_free(f->textbuff);
-}
-
-/*** Color Pair manager ***/
-void owl_fmtext_init_colorpair_mgr(owl_colorpair_mgr *cpmgr)
-{
-  /* This could be a bitarray if we wanted to save memory. */
-  short i, j;
-  cpmgr->next = 8;
-  
-  /* The test is <= because we allocate COLORS+1 entries. */
-  cpmgr->pairs = owl_malloc((COLORS+1) * sizeof(short*));
-  for(i = 0; i <= COLORS; i++) {
-    cpmgr->pairs[i] = owl_malloc((COLORS+1) * sizeof(short));
-    for(j = 0; j <= COLORS; j++) {
-      cpmgr->pairs[i][j] = -1;
-    }
-  }
-  if (owl_global_get_hascolors(&g)) {
-    for(i = 0; i < 8; i++) {
-      short fg, bg;
-      if (i >= COLORS) continue;
-      pair_content(i, &fg, &bg);
-      cpmgr->pairs[fg+1][bg+1] = i;
-    }
-  }
-}
-
-/* Reset used list */
-void owl_fmtext_reset_colorpairs()
-{
-  if (owl_global_get_hascolors(&g)) {
-    short i, j;
-    owl_colorpair_mgr *cpmgr = owl_global_get_colorpair_mgr(&g);
-    cpmgr->next = 8;
-    
-    /* The test is <= because we allocated COLORS+1 entries. */
-    for(i = 0; i <= COLORS; i++) {
-      for(j = 0; j <= COLORS; j++) {
-	cpmgr->pairs[i][j] = -1;
-      }
-    }
-    for(i = 0; i < 8; i++) {
-      short fg, bg;
-      if (i >= COLORS) continue;
-      pair_content(i, &fg, &bg);
-      cpmgr->pairs[fg+1][bg+1] = i;
-    }
-  }
-}
-
-/* Assign pairs by request */
-short owl_fmtext_get_colorpair(int fg, int bg)
-{
-  owl_colorpair_mgr *cpmgr;
-  short pair, default_bg;
-
-  /* Sanity (Bounds) Check */
-  if (fg > COLORS || fg < OWL_COLOR_DEFAULT) fg = OWL_COLOR_DEFAULT;
-  if (bg > COLORS || bg < OWL_COLOR_DEFAULT) bg = OWL_COLOR_DEFAULT;
-	    
-#ifdef HAVE_USE_DEFAULT_COLORS
-  if (fg == OWL_COLOR_DEFAULT) fg = -1;
-  default_bg = OWL_COLOR_DEFAULT;
-#else
-  if (fg == OWL_COLOR_DEFAULT) fg = 0;
-  if (bg == OWL_COLOR_DEFAULT) bg = 0;
-  default_bg = COLOR_BLACK;
-#endif
-
-  /* looking for a pair we already set up for this draw. */
-  cpmgr = owl_global_get_colorpair_mgr(&g);
-  pair = cpmgr->pairs[fg+1][bg+1];
-  if (!(pair != -1 && pair < cpmgr->next)) {
-    /* If we didn't find a pair, search for a free one to assign. */
-    pair = (cpmgr->next < COLOR_PAIRS) ? cpmgr->next : -1;
-    if (pair != -1) {
-      /* We found a free pair, initialize it. */
-      init_pair(pair, fg, bg);
-      cpmgr->pairs[fg+1][bg+1] = pair;
-      cpmgr->next++;
-    }
-    else if (bg != OWL_COLOR_DEFAULT) {
-      /* We still don't have a pair, drop the background color. Too bad. */
-      owl_function_debugmsg("colorpairs: color shortage - dropping background color.");
-      pair = owl_fmtext_get_colorpair(fg, OWL_COLOR_DEFAULT);
-    }
-    else {
-      /* We still don't have a pair, defaults all around. */
-      owl_function_debugmsg("colorpairs: color shortage - dropping foreground and background color.");
-      pair = 0;
-    }
-  }
-  return pair;
-}
Index: nctions.c
===================================================================
--- functions.c	(revision 9b70dd4730dcdc958150fe126007d358cec3c713)
+++ 	(revision )
@@ -1,3578 +1,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <signal.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-void owl_function_noop(void)
-{
-  return;
-}
-
-char *owl_function_command(char *cmdbuff)
-{
-  owl_function_debugmsg("executing command: %s", cmdbuff);
-  return owl_cmddict_execute(owl_global_get_cmddict(&g), 
-			     owl_global_get_context(&g), cmdbuff);
-}
-
-char *owl_function_command_argv(char **argv, int argc)
-{
-  return owl_cmddict_execute_argv(owl_global_get_cmddict(&g),
-                                  owl_global_get_context(&g),
-                                  argv, argc);
-}
-
-void owl_function_command_norv(char *cmdbuff)
-{
-  char *rv;
-  rv=owl_function_command(cmdbuff);
-  if (rv) owl_free(rv);
-}
-
-void owl_function_command_alias(char *alias_from, char *alias_to)
-{
-  owl_cmddict_add_alias(owl_global_get_cmddict(&g), alias_from, alias_to);
-}
-
-owl_cmd *owl_function_get_cmd(char *name)
-{
-  return owl_cmddict_find(owl_global_get_cmddict(&g), name);
-}
-
-void owl_function_show_commands()
-{
-  owl_list l;
-  owl_fmtext fm;
-
-  owl_fmtext_init_null(&fm);
-  owl_fmtext_append_bold(&fm, "Commands:  ");
-  owl_fmtext_append_normal(&fm, "(use 'show command <name>' for details)\n");
-  owl_cmddict_get_names(owl_global_get_cmddict(&g), &l);
-  owl_fmtext_append_list(&fm, &l, "\n", owl_function_cmd_describe);
-  owl_fmtext_append_normal(&fm, "\n");
-  owl_function_popless_fmtext(&fm);
-  owl_cmddict_namelist_free(&l);
-  owl_fmtext_free(&fm);
-}
-
-void owl_function_show_view(char *viewname)
-{
-  owl_view *v;
-  owl_fmtext fm;
-
-  /* we only have the one view right now */
-  v=owl_global_get_current_view(&g);
-  if (viewname && strcmp(viewname, owl_view_get_name(v))) {
-    owl_function_error("No view named '%s'", viewname);
-    return;
-  }
-
-  owl_fmtext_init_null(&fm);
-  owl_view_to_fmtext(v, &fm);
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-}
-
-void owl_function_show_styles() {
-  owl_list l;
-  owl_fmtext fm;
-
-  owl_fmtext_init_null(&fm);
-  owl_fmtext_append_bold(&fm, "Styles:\n");
-  owl_global_get_style_names(&g, &l);
-  owl_fmtext_append_list(&fm, &l, "\n", owl_function_style_describe);
-  owl_fmtext_append_normal(&fm, "\n");
-  owl_function_popless_fmtext(&fm);
-  owl_list_free_all(&l, owl_free);
-  owl_fmtext_free(&fm);
-}
-
-char *owl_function_style_describe(char *name) {
-  char *desc, *s;
-  owl_style *style;
-  style = owl_global_get_style_by_name(&g, name);
-  if (style) {
-    desc = owl_style_get_description(style);
-  } else {
-    desc = "???";
-  }
-  s = owl_sprintf("%-20s - %s%s", name, 
-		  0==owl_style_validate(style)?"":"[INVALID] ",
-		  desc);
-  return s;
-}
-
-char *owl_function_cmd_describe(char *name)
-{
-  owl_cmd *cmd = owl_cmddict_find(owl_global_get_cmddict(&g), name);
-  if (cmd) return owl_cmd_describe(cmd);
-  else return(NULL);
-}
-
-void owl_function_show_command(char *name)
-{
-  owl_function_help_for_command(name);
-}
-
-void owl_function_show_license()
-{
-  char *text;
-
-  text=""
-    "barnowl version " OWL_VERSION_STRING "\n"
-    "Copyright (c) 2006-2008 The BarnOwl Developers. All rights reserved.\n"
-    "Copyright (c) 2004 James Kretchmar. All rights reserved.\n"
-    "\n"
-    "Redistribution and use in source and binary forms, with or without\n"
-    "modification, are permitted provided that the following conditions are\n"
-    "met:\n"
-    "\n"
-    "   * Redistributions of source code must retain the above copyright\n"
-    "     notice, this list of conditions and the following disclaimer.\n"
-    "\n"
-    "   * Redistributions in binary form must reproduce the above copyright\n"
-    "     notice, this list of conditions and the following disclaimer in\n"
-    "     the documentation and/or other materials provided with the\n"
-    "     distribution.\n"
-    "\n"
-    "   * Redistributions in any form must be accompanied by information on\n"
-    "     how to obtain complete source code for the Owl software and any\n"
-    "     accompanying software that uses the Owl software. The source code\n"
-    "     must either be included in the distribution or be available for no\n"
-    "     more than the cost of distribution plus a nominal fee, and must be\n"
-    "     freely redistributable under reasonable conditions. For an\n"
-    "     executable file, complete source code means the source code for\n"
-    "     all modules it contains. It does not include source code for\n"
-    "     modules or files that typically accompany the major components of\n"
-    "     the operating system on which the executable file runs.\n"
-    "\n"
-    "THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n"
-    "IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\n"
-    "WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR\n"
-    "NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE\n"
-    "LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n"
-    "CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n"
-    "SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n"
-    "BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n"
-    "WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\n"
-    "OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN\n"
-    "IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n";
-  owl_function_popless_text(text);
-}
-
-void owl_function_show_quickstart()
-{
-    char *message =
-    "Move between messages with the arrow keys, and press 'r' to reply.\n"
-    "For more info, press 'h' or visit http://barnowl.mit.edu/\n\n"
-#ifdef HAVE_LIBZEPHYR
-    "@b(Zephyr:)\n"
-    "To send a message to a user, type ':zwrite @b(username)'. You can also\n"
-    "press 'z' and then type the username. To subscribe to a class, type\n"
-    "':sub @b(class)', and then type ':zwrite -c @b(class)' to send.\n\n"
-#endif
-    "@b(AIM:)\n"
-    "Log in to AIM with ':aimlogin @b(screenname)'. Use ':aimwrite @b(screenname)',\n"
-    "or 'a' and then the screen name, to send someone a message.\n\n"
-    ;
-
-    if (owl_perlconfig_is_function("BarnOwl::Hooks::_get_quickstart")) {
-        char *perlquickstart = owl_perlconfig_execute("BarnOwl::Hooks::_get_quickstart()");
-        if (perlquickstart) {
-            char *result = owl_sprintf("%s%s", message, perlquickstart);
-            owl_function_adminmsg("BarnOwl Quickstart", result);
-            owl_free(result);
-            owl_free(perlquickstart);
-            return;
-        }
-    }
-    owl_function_adminmsg("BarnOwl Quickstart", message);
-}
-
-
-/* Create an admin message, append it to the global list of messages
- * and redisplay if necessary.
- */
-void owl_function_adminmsg(char *header, char *body)
-{
-  owl_message *m;
-
-  m=owl_malloc(sizeof(owl_message));
-  owl_message_create_admin(m, header, body);
-  
-  /* add it to the global list and current view */
-  owl_messagelist_append_element(owl_global_get_msglist(&g), m);
-  owl_view_consider_message(owl_global_get_current_view(&g), m);
-
-  /* do followlast if necessary */
-  if (owl_global_should_followlast(&g)) owl_function_lastmsg_noredisplay();
-
-  /* redisplay etc. */
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
-    owl_popwin_refresh(owl_global_get_popwin(&g));
-  }
-  wnoutrefresh(owl_global_get_curs_recwin(&g));
-  owl_global_set_needrefresh(&g);
-}
-
-/* Create an outgoing zephyr message and return a pointer to it.  Does
- * not put it on the global queue, use owl_function_add_message() for
- * that.
- */
-owl_message *owl_function_make_outgoing_zephyr(char *body, char *zwriteline, char *zsig)
-{
-  owl_message *m;
-  owl_zwrite z;
-  
-  /* create a zwrite for the purpose of filling in other message fields */
-  owl_zwrite_create_from_line(&z, zwriteline);
-
-  /* create the message */
-  m=owl_malloc(sizeof(owl_message));
-  owl_message_create_from_zwriteline(m, zwriteline, body, zsig);
-  owl_zwrite_free(&z);
-
-  return(m);
-}
-
-/* Create an outgoing AIM message, returns a pointer to the created
- * message or NULL if we're not logged into AIM (and thus unable to
- * create the message).  Does not put it on the global queue.  Use
- * owl_function_add_message() for that .
- */
-owl_message *owl_function_make_outgoing_aim(char *body, char *to)
-{
-  owl_message *m;
-
-  /* error if we're not logged into aim */
-  if (!owl_global_is_aimloggedin(&g)) return(NULL);
-  
-  m=owl_malloc(sizeof(owl_message));
-  owl_message_create_aim(m,
-			 owl_global_get_aim_screenname(&g),
-			 to,
-			 body,
-			 OWL_MESSAGE_DIRECTION_OUT,
-			 0);
-  return(m);
-}
-
-/* Create an outgoing loopback message and return a pointer to it.
- * Does not append it to the global queue, use
- * owl_function_add_message() for that.
- */
-owl_message *owl_function_make_outgoing_loopback(char *body)
-{
-  owl_message *m;
-
-  /* create the message */
-  m=owl_malloc(sizeof(owl_message));
-  owl_message_create_loopback(m, body);
-  owl_message_set_direction_out(m);
-
-  return(m);
-}
-
-void owl_function_zwrite_setup(char *line)
-{
-  owl_editwin *e;
-  char buff[1024];
-  owl_zwrite z;
-  int ret;
-
-  /* check the arguments */
-  ret=owl_zwrite_create_from_line(&z, line);
-  if (ret) {
-    owl_function_error("Error in zwrite arguments");
-    owl_zwrite_free(&z);
-    return;
-  }
-
-  /* send a ping if necessary */
-  if (owl_global_is_txping(&g)) {
-    owl_zwrite_send_ping(&z);
-  }
-  owl_zwrite_free(&z);
-
-  /* create and setup the editwin */
-  e=owl_global_get_typwin(&g);
-  owl_editwin_new_style(e, OWL_EDITWIN_STYLE_MULTILINE, owl_global_get_msg_history(&g));
-
-  if (!owl_global_get_lockout_ctrld(&g)) {
-    owl_function_makemsg("Type your zephyr below.  End with ^D or a dot on a line by itself.  ^C will quit.");
-  } else {
-    owl_function_makemsg("Type your zephyr below.  End with a dot on a line by itself.  ^C will quit.");
-  }
-
-  owl_editwin_clear(e);
-  owl_editwin_set_dotsend(e);
-  strcpy(buff, "----> ");
-  strncat(buff, line, 1016);
-  strcat(buff, "\n");
-  owl_editwin_set_locktext(e, buff);
-
-  /* make it active */
-  owl_global_set_typwin_active(&g);
-
-  owl_global_set_buffercommand(&g, line);
-  owl_global_set_buffercallback(&g, &owl_callback_zwrite);
-}
-
-void owl_function_aimwrite_setup(char *line)
-{
-  owl_editwin *e;
-  char buff[1024];
-
-  /* check the arguments */
-
-  /* create and setup the editwin */
-  e=owl_global_get_typwin(&g);
-  owl_editwin_new_style(e, OWL_EDITWIN_STYLE_MULTILINE, owl_global_get_msg_history(&g));
-
-  if (!owl_global_get_lockout_ctrld(&g)) {
-    owl_function_makemsg("Type your message below.  End with ^D or a dot on a line by itself.  ^C will quit.");
-  } else {
-    owl_function_makemsg("Type your message below.  End with a dot on a line by itself.  ^C will quit.");
-  }
-
-  owl_editwin_clear(e);
-  owl_editwin_set_dotsend(e);
-  strcpy(buff, "----> ");
-  strcat(buff, line);
-  strcat(buff, "\n");
-  owl_editwin_set_locktext(e, buff);
-
-  /* make it active */
-  owl_global_set_typwin_active(&g);
-
-  owl_global_set_buffercommand(&g, line);
-  owl_global_set_buffercallback(&g, &owl_callback_aimwrite);
-}
-
-void owl_function_loopwrite_setup()
-{
-  owl_editwin *e;
-
-  /* create and setup the editwin */
-  e=owl_global_get_typwin(&g);
-  owl_editwin_new_style(e, OWL_EDITWIN_STYLE_MULTILINE, owl_global_get_msg_history(&g));
-
-  if (!owl_global_get_lockout_ctrld(&g)) {
-    owl_function_makemsg("Type your message below.  End with ^D or a dot on a line by itself.  ^C will quit.");
-  } else {
-    owl_function_makemsg("Type your message below.  End with a dot on a line by itself.  ^C will quit.");
-  }
-
-  owl_editwin_clear(e);
-  owl_editwin_set_dotsend(e);
-  owl_editwin_set_locktext(e, "----> loopwrite\n");
-
-  /* make it active */
-  owl_global_set_typwin_active(&g);
-
-  owl_global_set_buffercommand(&g, "loopwrite");
-  owl_global_set_buffercallback(&g, &owl_callback_loopwrite);
-}
-
-void owl_callback_zwrite(owl_editwin *e) {
-  owl_function_zwrite(owl_editwin_get_command(e),
-                      owl_editwin_get_text(e));
-}
-
-/* send, log and display an outgoing zephyr.  If 'msg' is NULL
- * the message is expected to be set from the zwrite line itself
- */
-void owl_function_zwrite(char *line, char *msg)
-{
-  owl_zwrite z;
-  char *mymsg;
-  owl_message *m;
-
-  if(!strncmp(line, "zcrypt", strlen("zcrypt"))) {
-    owl_function_zcrypt(line, msg);
-    return;
-  }
-
-  /* create the zwrite and send the message */
-  owl_zwrite_create_from_line(&z, line);
-  owl_zwrite_populate_zsig(&z);
-  if (msg) {
-    owl_zwrite_set_message(&z, msg);
-  }
-  owl_zwrite_send_message(&z);
-  owl_function_makemsg("Waiting for ack...");
-
-  /* If it's personal */
-  if (owl_zwrite_is_personal(&z)) {
-    /* create the outgoing message */
-    mymsg=owl_zwrite_get_message(&z);
-    m=owl_function_make_outgoing_zephyr(mymsg, line, owl_zwrite_get_zsig(&z));
-
-    if (m) {
-      owl_global_messagequeue_addmsg(&g, m);
-    } else {
-      owl_function_error("Could not create outgoing zephyr message");
-    }
-  }
-
-  /* free the zwrite */
-  owl_zwrite_free(&z);
-}
-
-/* send, log and display an outgoing zcrypt zephyr.  If 'msg' is NULL
- * the message is expected to be set from the zwrite line itself
- */
-void owl_function_zcrypt(char *line, char *msg)
-{
-  owl_zwrite z;
-  char *mymsg;
-  char *cryptmsg;
-  owl_message *m;
-#ifdef OWL_ENABLE_ZCRYPT
-  int ret;
-#endif
-
-  /* create the zwrite and send the message */
-  owl_zwrite_create_from_line(&z, line);
-  owl_zwrite_populate_zsig(&z);
-  if (msg) {
-    owl_zwrite_set_message(&z, msg);
-  }
-
-  mymsg=owl_zwrite_get_message(&z);
-#ifdef OWL_ENABLE_ZCRYPT
-  /* Allocate enough space for the crypted message. For each byte of
-   * the message, the encoded cyphertext will have two bytes. Block
-   * size is 8 bytes of input, or 16 bytes of output, so make sure we
-   * have at least one block worth of space allocated. If the message
-   * is empty, no blocks are sent, but we still allocate one
-   * block. The additional 16 bytes also provide space for the null
-   * terminator, as we will never use all of it for cyphertext.
-   */
-  cryptmsg=owl_malloc((strlen(mymsg)*2)+16);
-  ret=owl_zcrypt_encrypt(cryptmsg, mymsg, owl_zwrite_get_class(&z), owl_zwrite_get_instance(&z));
-  if (ret) {
-    owl_function_error("Error in zcrypt, possibly no key found.  Message not sent.");
-    owl_function_beep();
-    owl_free(cryptmsg);
-    owl_zwrite_free(&z);
-    return;
-  }
-#else
-  cryptmsg=owl_strdup(mymsg);
-#endif
-
-  owl_zwrite_set_message(&z, cryptmsg);
-  owl_zwrite_set_opcode(&z, "crypt");
-  mymsg=cryptmsg;
-    
-  owl_zwrite_send_message(&z);
-  owl_function_makemsg("Waiting for ack...");
-
-  /* If it's personal */
-  if (owl_zwrite_is_personal(&z)) {
-    /* create the outgoing message */
-    mymsg=owl_zwrite_get_message(&z);
-    m=owl_function_make_outgoing_zephyr(mymsg, line, owl_zwrite_get_zsig(&z));
-    if (m) {
-      owl_global_messagequeue_addmsg(&g, m);
-    } else {
-      owl_function_error("Could not create outgoing zephyr message");
-    }
-  }
-
-  /* free the zwrite */
-  owl_free(cryptmsg);
-  owl_zwrite_free(&z);
-}
-
-void owl_callback_aimwrite(owl_editwin *e) {
-  owl_function_aimwrite(owl_editwin_get_command(e),
-                        owl_editwin_get_text(e));
-}
-
-void owl_function_aimwrite(char *line, char *msg)
-{
-  int ret;
-  char *to, *format_msg;
-  owl_message *m;
-
-  to = line + 9;
-
-  /* make a formatted copy of the message */
-  format_msg=owl_strdup(msg);
-  owl_text_wordunwrap(format_msg);
-  
-  /* send the message */
-  ret=owl_aim_send_im(to, format_msg);
-  if (!ret) {
-    owl_function_makemsg("AIM message sent.");
-  } else {
-    owl_function_error("Could not send AIM message.");
-  }
-
-  /* create the outgoing message */
-  m=owl_function_make_outgoing_aim(msg, to);
-
-  if (m) {
-    owl_global_messagequeue_addmsg(&g, m);
-  } else {
-    owl_function_error("Could not create outgoing AIM message");
-  }
-
-  owl_free(format_msg);
-}
-
-void owl_function_send_aimawymsg(char *to, char *msg)
-{
-  int ret;
-  char *format_msg;
-  owl_message *m;
-
-  /* make a formatted copy of the message */
-  format_msg=owl_strdup(msg);
-  owl_text_wordunwrap(format_msg);
-  
-  /* send the message */
-  ret=owl_aim_send_awaymsg(to, format_msg);
-  if (!ret) {
-    /* owl_function_makemsg("AIM message sent."); */
-  } else {
-    owl_function_error("Could not send AIM message.");
-  }
-
-  /* create the message */
-  m=owl_function_make_outgoing_aim(msg, to);
-  if (m) {
-    owl_global_messagequeue_addmsg(&g, m);
-  } else {
-    owl_function_error("Could not create AIM message");
-  }
-  owl_free(format_msg);
-}
-
-void owl_callback_loopwrite(owl_editwin *e) {
-  owl_function_loopwrite(owl_editwin_get_text(e));
-}
-
-void owl_function_loopwrite(char *msg)
-{
-  owl_message *min, *mout;
-
-  /* create a message and put it on the message queue.  This simulates
-   * an incoming message */
-  min=owl_malloc(sizeof(owl_message));
-  mout=owl_function_make_outgoing_loopback(msg);
-
-  if (owl_global_is_displayoutgoing(&g)) {
-    owl_global_messagequeue_addmsg(&g, mout);
-  } else {
-    owl_message_free(mout);
-  }
-
-  owl_message_create_loopback(min, msg);
-  owl_message_set_direction_in(min);
-  owl_global_messagequeue_addmsg(&g, min);
-
-  /* fake a makemsg */
-  owl_function_makemsg("loopback message sent");
-}
-
-/* If filter is non-null, looks for the next message matching
- * that filter.  If skip_deleted, skips any deleted messages. 
- * If last_if_none, will stop at the last message in the view
- * if no matching messages are found.  */
-void owl_function_nextmsg_full(char *filter, int skip_deleted, int last_if_none)
-{
-  int curmsg, i, viewsize, found;
-  owl_view *v;
-  owl_filter *f = NULL;
-  owl_message *m;
-
-  v=owl_global_get_current_view(&g);
-
-  if (filter) {
-    f=owl_global_get_filter(&g, filter);
-    if (!f) {
-      owl_function_error("No %s filter defined", filter);
-      return;
-    }
-  }
-
-  curmsg=owl_global_get_curmsg(&g);
-  viewsize=owl_view_get_size(v);
-  found=0;
-
-  /* just check to make sure we're in bounds... */
-  if (curmsg>viewsize-1) curmsg=viewsize-1;
-  if (curmsg<0) curmsg=0;
-
-  for (i=curmsg+1; i<viewsize; i++) {
-    m=owl_view_get_element(v, i);
-    if (skip_deleted && owl_message_is_delete(m)) continue;
-    if (f && !owl_filter_message_match(f, m)) continue;
-    found = 1;
-    break;
-  }
-
-  if (i>owl_view_get_size(v)-1) i=owl_view_get_size(v)-1;
-  if (i<0) i=0;
-
-  if (!found) {
-    owl_function_makemsg("already at last%s message%s%s%s",
-			 skip_deleted?" non-deleted":"",
-			 filter?" in ":"", filter?filter:"",
-			 owl_mainwin_is_curmsg_truncated(owl_global_get_mainwin(&g)) ?
-			 ", press Enter to scroll" : "");
-    /* if (!skip_deleted) owl_function_beep(); */
-  }
-
-  if (last_if_none || found) {
-    owl_global_set_curmsg(&g, i);
-    owl_function_calculate_topmsg(OWL_DIRECTION_DOWNWARDS);
-    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-    owl_global_set_direction_downwards(&g);
-  }
-}
-
-void owl_function_prevmsg_full(char *filter, int skip_deleted, int first_if_none)
-{
-  int curmsg, i, viewsize, found;
-  owl_view *v;
-  owl_filter *f = NULL;
-  owl_message *m;
-
-  v=owl_global_get_current_view(&g);
-
-  if (filter) {
-    f=owl_global_get_filter(&g, filter);
-    if (!f) {
-      owl_function_error("No %s filter defined", filter);
-      return;
-    }
-  }
-
-  curmsg=owl_global_get_curmsg(&g);
-  viewsize=owl_view_get_size(v);
-  found=0;
-
-  /* just check to make sure we're in bounds... */
-  if (curmsg<0) curmsg=0;
-
-  for (i=curmsg-1; i>=0; i--) {
-    m=owl_view_get_element(v, i);
-    if (skip_deleted && owl_message_is_delete(m)) continue;
-    if (f && !owl_filter_message_match(f, m)) continue;
-    found = 1;
-    break;
-  }
-
-  if (i<0) i=0;
-
-  if (!found) {
-    owl_function_makemsg("already at first%s message%s%s",
-			 skip_deleted?" non-deleted":"",
-			 filter?" in ":"", filter?filter:"");
-    /* if (!skip_deleted) owl_function_beep(); */
-  }
-
-  if (first_if_none || found) {
-    owl_global_set_curmsg(&g, i);
-    owl_function_calculate_topmsg(OWL_DIRECTION_UPWARDS);
-    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-    owl_global_set_direction_upwards(&g);
-  }
-}
-
-void owl_function_nextmsg()
-{
-  owl_function_nextmsg_full(NULL, 0, 1);
-}
-
-void owl_function_prevmsg()
-{
-  owl_function_prevmsg_full(NULL, 0, 1);
-}
-
-void owl_function_nextmsg_notdeleted()
-{
-  owl_function_nextmsg_full(NULL, 1, 1);
-}
-
-void owl_function_prevmsg_notdeleted()
-{
-  owl_function_prevmsg_full(NULL, 1, 1);
-}
-
-void owl_function_nextmsg_personal()
-{
-  owl_function_nextmsg_full("personal", 0, 0);
-}
-
-void owl_function_prevmsg_personal()
-{
-  owl_function_prevmsg_full("personal", 0, 0);
-}
-
-
-/* if move_after is 1, moves after the delete */
-void owl_function_deletecur(int move_after)
-{
-  int curmsg;
-  owl_view *v;
-
-  v=owl_global_get_current_view(&g);
-
-  /* bail if there's no current message */
-  if (owl_view_get_size(v) < 1) {
-    owl_function_error("No current message to delete");
-    return;
-  }
-
-  /* mark the message for deletion */
-  curmsg=owl_global_get_curmsg(&g);
-  owl_view_delete_element(v, curmsg);
-
-  if (move_after) {
-    /* move the poiner in the appropriate direction 
-     * to the next undeleted msg */
-    if (owl_global_get_direction(&g)==OWL_DIRECTION_UPWARDS) {
-      owl_function_prevmsg_notdeleted();
-    } else {
-      owl_function_nextmsg_notdeleted();
-    }
-  }
-}
-
-void owl_function_undeletecur(int move_after)
-{
-  int curmsg;
-  owl_view *v;
-
-  v=owl_global_get_current_view(&g);
-  
-  if (owl_view_get_size(v) < 1) {
-    owl_function_error("No current message to undelete");
-    return;
-  }
-  curmsg=owl_global_get_curmsg(&g);
-
-  owl_view_undelete_element(v, curmsg);
-
-  if (move_after) {
-    if (owl_global_get_direction(&g)==OWL_DIRECTION_UPWARDS) {
-      if (curmsg>0) {
-	owl_function_prevmsg();
-      } else {
-	owl_function_nextmsg();
-      }
-    } else {
-      owl_function_nextmsg();
-    }
-  }
-
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-}
-
-void owl_function_expunge()
-{
-  int curmsg;
-  owl_message *m;
-  owl_messagelist *ml;
-  owl_view *v;
-  int lastmsgid=0;
-
-  curmsg=owl_global_get_curmsg(&g);
-  v=owl_global_get_current_view(&g);
-  ml=owl_global_get_msglist(&g);
-
-  m=owl_view_get_element(v, curmsg);
-  if (m) lastmsgid = owl_message_get_id(m);
-
-  /* expunge the message list */
-  owl_messagelist_expunge(ml);
-
-  /* update all views (we only have one right now) */
-  owl_view_recalculate(v);
-
-  /* find where the new position should be
-     (as close as possible to where we last where) */
-  curmsg = owl_view_get_nearest_to_msgid(v, lastmsgid);
-  if (curmsg>owl_view_get_size(v)-1) curmsg = owl_view_get_size(v)-1;
-  if (curmsg<0) curmsg = 0;
-  owl_global_set_curmsg(&g, curmsg);
-  owl_function_calculate_topmsg(OWL_DIRECTION_NONE);
-  /* if there are no messages set the direction to down in case we
-     delete everything upwards */
-  owl_global_set_direction_downwards(&g);
-  
-  owl_function_makemsg("Messages expunged");
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-}
-
-void owl_function_firstmsg()
-{
-  owl_global_set_curmsg(&g, 0);
-  owl_global_set_topmsg(&g, 0);
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  owl_global_set_direction_downwards(&g);
-}
-
-void owl_function_lastmsg_noredisplay()
-{
-  int oldcurmsg, curmsg;
-  owl_view *v;
-
-  v=owl_global_get_current_view(&g);
-  oldcurmsg=owl_global_get_curmsg(&g);
-  curmsg=owl_view_get_size(v)-1;  
-  if (curmsg<0) curmsg=0;
-  owl_global_set_curmsg(&g, curmsg);
-  if (oldcurmsg < curmsg) {
-    owl_function_calculate_topmsg(OWL_DIRECTION_DOWNWARDS);
-  } else if (curmsg<owl_view_get_size(v)) {
-    /* If already at the end, blank the screen and move curmsg
-     * past the end of the messages. */
-    owl_global_set_topmsg(&g, curmsg+1);
-    owl_global_set_curmsg(&g, curmsg+1);
-  } 
-  /* owl_mainwin_redisplay(owl_global_get_mainwin(&g)); */
-  owl_global_set_direction_downwards(&g);
-}
-
-void owl_function_lastmsg()
-{
-  owl_function_lastmsg_noredisplay();
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));  
-}
-
-void owl_function_shift_right()
-{
-  owl_global_set_rightshift(&g, owl_global_get_rightshift(&g)+10);
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  owl_global_set_needrefresh(&g);
-}
-
-void owl_function_shift_left()
-{
-  int shift;
-
-  shift=owl_global_get_rightshift(&g);
-  if (shift>=10) {
-    owl_global_set_rightshift(&g, shift-10);
-    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-    owl_global_set_needrefresh(&g);
-  } else {
-    owl_function_beep();
-    owl_function_makemsg("Already full left");
-  }
-}
-
-void owl_function_unsuball()
-{
-  unsuball();
-  owl_function_makemsg("Unsubscribed from all messages.");
-}
-
-
-/* Load zephyr subscriptions from the named 'file' and load zephyr's
- * default subscriptions as well.  An error message is printed if
- * 'file' can't be opened or if zephyr reports an error in
- * subscribing.
- *
- * If 'file' is NULL, this look for the default filename
- * $HOME/.zephyr.subs.  If the file can not be opened in this case
- * only, no error message is printed.
- */
-void owl_function_loadsubs(char *file)
-{
-  int ret, ret2;
-  char *foo, *path;
-
-  if (file==NULL) {
-    ret=owl_zephyr_loadsubs(NULL, 0);
-  } else {
-    path = owl_util_makepath(file);
-    ret=owl_zephyr_loadsubs(path, 1);
-    free(path);
-  }
-
-  /* for backwards compatibility for now */
-  ret2=owl_zephyr_loaddefaultsubs();
-
-  if (!owl_context_is_interactive(owl_global_get_context(&g))) return;
-
-  foo=file?file:"file";
-  if (ret==0 && ret2==0) {
-    if (!file) {
-      owl_function_makemsg("Subscribed to messages.");
-    } else {
-      owl_function_makemsg("Subscribed to messages from %s", file);
-    }
-  } else if (ret==-1) {
-    owl_function_error("Could not read %s", foo);
-  } else {
-    owl_function_error("Error subscribing to messages");
-  }
-}
-
-void owl_function_loadloginsubs(char *file)
-{
-  int ret;
-
-  ret=owl_zephyr_loadloginsubs(file);
-
-  if (!owl_context_is_interactive(owl_global_get_context(&g))) return;
-  if (ret==0) {
-    owl_function_makemsg("Subscribed to login messages from file.");
-  } else if (ret==-1) {
-    owl_function_error("Could not open file for login subscriptions.");
-  } else {
-    owl_function_error("Error subscribing to login messages from file.");
-  }
-}
-
-void owl_callback_aimlogin(owl_editwin *e) {
-  owl_function_aimlogin(owl_editwin_get_command(e),
-                        owl_editwin_get_text(e));
-}
-
-void owl_function_aimlogin(char *user, char *passwd) {
-  int ret;
-
-  /* clear the buddylist */
-  owl_buddylist_clear(owl_global_get_buddylist(&g));
-
-  /* try to login */
-  ret=owl_aim_login(user, passwd);
-  if (ret) owl_function_makemsg("Warning: login for %s failed.\n", user);
-}
-
-void owl_function_suspend()
-{
-  endwin();
-  printf("\n");
-  kill(getpid(), SIGSTOP);
-
-  /* resize to reinitialize all the windows when we come back */
-  owl_command_resize();
-}
-
-void owl_function_zaway_toggle()
-{
-  if (!owl_global_is_zaway(&g)) {
-    owl_global_set_zaway_msg(&g, owl_global_get_zaway_msg_default(&g));
-    owl_function_zaway_on();
-  } else {
-    owl_function_zaway_off();
-  }
-}
-
-void owl_function_zaway_on()
-{
-  owl_global_set_zaway_on(&g);
-  owl_function_makemsg("zaway set (%s)", owl_global_get_zaway_msg(&g));
-}
-
-void owl_function_zaway_off()
-{
-  owl_global_set_zaway_off(&g);
-  owl_function_makemsg("zaway off");
-}
-
-void owl_function_aaway_toggle()
-{
-  if (!owl_global_is_aaway(&g)) {
-    owl_global_set_aaway_msg(&g, owl_global_get_aaway_msg_default(&g));
-    owl_function_aaway_on();
-  } else {
-    owl_function_aaway_off();
-  }
-}
-
-void owl_function_aaway_on()
-{
-  owl_global_set_aaway_on(&g);
-  /* owl_aim_set_awaymsg(owl_global_get_zaway_msg(&g)); */
-  owl_function_makemsg("AIM away set (%s)", owl_global_get_aaway_msg(&g));
-}
-
-void owl_function_aaway_off()
-{
-  owl_global_set_aaway_off(&g);
-  /* owl_aim_set_awaymsg(""); */
-  owl_function_makemsg("AIM away off");
-}
-
-void owl_function_quit()
-{
-  char *ret;
-  
-  /* zlog out if we need to */
-  if (owl_global_is_shutdownlogout(&g)) {
-    owl_zephyr_zlog_out();
-  }
-
-  /* execute the commands in shutdown */
-  ret = owl_perlconfig_execute("BarnOwl::Hooks::_shutdown();");
-  if (ret) owl_free(ret);
-
-  /* signal our child process, if any */
-  if (owl_global_get_newmsgproc_pid(&g)) {
-    kill(owl_global_get_newmsgproc_pid(&g), SIGHUP);
-  }
-
-  /* Quit zephyr */
-  owl_zephyr_shutdown();
-  
-  /* Quit AIM */
-  if (owl_global_is_aimloggedin(&g)) {
-    owl_aim_logout();
-  }
-
-  /* done with curses */
-  endwin();
-
-  /* restore terminal settings */
-  tcsetattr(0, TCSAFLUSH, owl_global_get_startup_tio(&g));
-
-  owl_function_debugmsg("Quitting Owl");
-  exit(0);
-}
-
-void owl_function_calculate_topmsg(int direction)
-{
-  int recwinlines, topmsg, curmsg;
-  owl_view *v;
-
-  v=owl_global_get_current_view(&g);
-  curmsg=owl_global_get_curmsg(&g);
-  topmsg=owl_global_get_topmsg(&g);
-  recwinlines=owl_global_get_recwin_lines(&g);
-
-  /*
-  if (owl_view_get_size(v) < 1) {
-    return;
-  }
-  */
-
-  switch (owl_global_get_scrollmode(&g)) {
-  case OWL_SCROLLMODE_TOP:
-    topmsg = owl_function_calculate_topmsg_top(direction, v, curmsg, topmsg, recwinlines);
-    break;
-  case OWL_SCROLLMODE_NEARTOP:
-    topmsg = owl_function_calculate_topmsg_neartop(direction, v, curmsg, topmsg, recwinlines);
-    break;
-  case OWL_SCROLLMODE_CENTER:
-    topmsg = owl_function_calculate_topmsg_center(direction, v, curmsg, topmsg, recwinlines);
-    break;
-  case OWL_SCROLLMODE_PAGED:
-    topmsg = owl_function_calculate_topmsg_paged(direction, v, curmsg, topmsg, recwinlines, 0);
-    break;
-  case OWL_SCROLLMODE_PAGEDCENTER:
-    topmsg = owl_function_calculate_topmsg_paged(direction, v, curmsg, topmsg, recwinlines, 1);
-    break;
-  case OWL_SCROLLMODE_NORMAL:
-  default:
-    topmsg = owl_function_calculate_topmsg_normal(direction, v, curmsg, topmsg, recwinlines);
-  }
-  owl_function_debugmsg("Calculated a topmsg of %i", topmsg);
-  owl_global_set_topmsg(&g, topmsg);
-}
-
-/* Returns what the new topmsg should be.  
- * Passed the last direction of movement, 
- * the current view,
- * the current message number in the view,
- * the top message currently being displayed,
- * and the number of lines in the recwin.
- */
-int owl_function_calculate_topmsg_top(int direction, owl_view *v, int curmsg, int topmsg, int recwinlines)
-{
-  return(curmsg);
-}
-
-int owl_function_calculate_topmsg_neartop(int direction, owl_view *v, int curmsg, int topmsg, int recwinlines)
-{
-  if (curmsg>0 
-      && (owl_message_get_numlines(owl_view_get_element(v, curmsg-1))
-	  <  recwinlines/2)) {
-    return(curmsg-1);
-  } else {
-    return(curmsg);
-  }
-}
-  
-int owl_function_calculate_topmsg_center(int direction, owl_view *v, int curmsg, int topmsg, int recwinlines)
-{
-  int i, last, lines;
-
-  last = curmsg;
-  lines = 0;
-  for (i=curmsg-1; i>=0; i--) {
-    lines += owl_message_get_numlines(owl_view_get_element(v, i));
-    if (lines > recwinlines/2) break;
-    last = i;
-  }
-  return(last);
-}
-  
-int owl_function_calculate_topmsg_paged(int direction, owl_view *v, int curmsg, int topmsg, int recwinlines, int center_on_page)
-{
-  int i, last, lines, savey;
-  
-  /* If we're off the top of the screen, scroll up such that the 
-   * curmsg is near the botton of the screen. */
-  if (curmsg < topmsg) {
-    last = curmsg;
-    lines = 0;
-    for (i=curmsg; i>=0; i--) {
-      lines += owl_message_get_numlines(owl_view_get_element(v, i));
-      if (lines > recwinlines) break;
-    last = i;
-    }
-    if (center_on_page) {
-      return(owl_function_calculate_topmsg_center(direction, v, curmsg, 0, recwinlines));
-    } else {
-      return(last);
-    }
-  }
-
-  /* Find number of lines from top to bottom of curmsg (store in savey) */
-  savey=0;
-  for (i=topmsg; i<=curmsg; i++) {
-    savey+=owl_message_get_numlines(owl_view_get_element(v, i));
-  }
-
-  /* if we're off the bottom of the screen, scroll down */
-  if (savey > recwinlines) {
-    if (center_on_page) {
-      return(owl_function_calculate_topmsg_center(direction, v, curmsg, 0, recwinlines));
-    } else {
-      return(curmsg);
-    }
-  }
-
-  /* else just stay as we are... */
-  return(topmsg);
-}
-
-int owl_function_calculate_topmsg_normal(int direction, owl_view *v, int curmsg, int topmsg, int recwinlines)
-{
-  int savey, i, foo, y;
-
-  if (curmsg<0) return(topmsg);
-    
-  /* If we're off the top of the screen then center */
-  if (curmsg<topmsg) {
-    topmsg=owl_function_calculate_topmsg_center(direction, v, curmsg, 0, recwinlines);
-  }
-
-  /* If curmsg is so far past topmsg that there are more messages than
-     lines, skip the line counting that follows because we're
-     certainly off screen.  */
-  savey=curmsg-topmsg;
-  if (savey <= recwinlines) {
-    /* Find number of lines from top to bottom of curmsg (store in savey) */
-    savey = 0;
-    for (i=topmsg; i<=curmsg; i++) {
-      savey+=owl_message_get_numlines(owl_view_get_element(v, i));
-    }
-  }
-
-  /* If we're off the bottom of the screen, set the topmsg to curmsg
-   * and scroll upwards */
-  if (savey > recwinlines) {
-    topmsg=curmsg;
-    savey=owl_message_get_numlines(owl_view_get_element(v, curmsg));
-    direction=OWL_DIRECTION_UPWARDS;
-  }
-  
-  /* If our bottom line is less than 1/4 down the screen then scroll up */
-  if (direction == OWL_DIRECTION_UPWARDS || direction == OWL_DIRECTION_NONE) {
-    if (savey < (recwinlines / 4)) {
-      y=0;
-      for (i=curmsg; i>=0; i--) {
-	foo=owl_message_get_numlines(owl_view_get_element(v, i));
-	/* will we run the curmsg off the screen? */
-	if ((foo+y) >= recwinlines) {
-	  i++;
-	  if (i>curmsg) i=curmsg;
-	  break;
-	}
-	/* have saved 1/2 the screen space? */
-	y+=foo;
-	if (y > (recwinlines / 2)) break;
-      }
-      if (i<0) i=0;
-      return(i);
-    }
-  }
-
-  if (direction == OWL_DIRECTION_DOWNWARDS || direction == OWL_DIRECTION_NONE) {
-    /* If curmsg bottom line is more than 3/4 down the screen then scroll down */
-    if (savey > ((recwinlines * 3)/4)) {
-      y=0;
-      /* count lines from the top until we can save 1/2 the screen size */
-      for (i=topmsg; i<curmsg; i++) {
-	y+=owl_message_get_numlines(owl_view_get_element(v, i));
-	if (y > (recwinlines / 2)) break;
-      }
-      if (i==curmsg) {
-	i--;
-      }
-      return(i+1);
-    }
-  }
-
-  return(topmsg);
-}
-
-void owl_function_resize()
-{
-  owl_global_set_resize_pending(&g);
-}
-
-void owl_function_run_buffercommand()
-{
-  owl_editwin_do_callback(owl_global_get_typwin(&g));
-}
-
-void owl_function_debugmsg(char *fmt, ...)
-{
-  FILE *file;
-  time_t now;
-  char buff1[LINE], buff2[LINE];
-  va_list ap;
-  va_start(ap, fmt);
-
-  if (!owl_global_is_debug_fast(&g)) return;
-
-  file=fopen(owl_global_get_debug_file(&g), "a");
-  if (!file) return;
-
-  now=time(NULL);
-  strcpy(buff1, ctime(&now));
-  buff1[strlen(buff1)-1]='\0';
-
-  owl_global_get_runtime_string(&g, buff2);
-  
-  fprintf(file, "[%i -  %s - %s]: ", (int) getpid(), buff1, buff2);
-  vfprintf(file, fmt, ap);
-  fprintf(file, "\n");
-  fclose(file);
-
-  va_end(ap);
-}
-
-void owl_function_refresh()
-{
-  owl_function_resize();
-}
-
-void owl_function_beep()
-{
-  if (owl_global_is_bell(&g)) {
-    beep();
-    owl_global_set_needrefresh(&g); /* do we really need this? */
-  }
-}
-
-int owl_function_subscribe(char *class, char *inst, char *recip)
-{
-  int ret;
-
-  ret=owl_zephyr_sub(class, inst, recip);
-  if (ret) {
-    owl_function_error("Error subscribing.");
-  } else {
-    owl_function_makemsg("Subscribed.");
-  }
-  return(ret);
-}
-
-void owl_function_unsubscribe(char *class, char *inst, char *recip)
-{
-  int ret;
-
-  ret=owl_zephyr_unsub(class, inst, recip);
-  if (ret) {
-    owl_function_error("Error subscribing.");
-  } else {
-    owl_function_makemsg("Unsubscribed.");
-  }
-}
-
-void owl_function_set_cursor(WINDOW *win)
-{
-  wnoutrefresh(win);
-}
-
-void owl_function_full_redisplay()
-{
-  redrawwin(owl_global_get_curs_recwin(&g));
-  redrawwin(owl_global_get_curs_sepwin(&g));
-  /* Work around curses segfualts with windows off the screen */
-  if (g.lines >= owl_global_get_typwin_lines(&g)+2)
-      redrawwin(owl_global_get_curs_typwin(&g));
-  if (g.lines >= 2)
-      redrawwin(owl_global_get_curs_msgwin(&g));
-
-  wnoutrefresh(owl_global_get_curs_recwin(&g));
-  wnoutrefresh(owl_global_get_curs_sepwin(&g));
-  wnoutrefresh(owl_global_get_curs_typwin(&g));
-  wnoutrefresh(owl_global_get_curs_msgwin(&g));
-
-  if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
-    owl_popwin_refresh(owl_global_get_popwin(&g));
-  }
-  
-  sepbar("");
-  owl_function_makemsg("");
-
-  owl_global_set_needrefresh(&g);
-}
-
-void owl_function_popless_text(char *text)
-{
-  owl_popwin *pw;
-  owl_viewwin *v;
-
-  pw=owl_global_get_popwin(&g);
-  v=owl_global_get_viewwin(&g);
-
-  owl_popwin_up(pw);
-  owl_viewwin_init_text(v, owl_popwin_get_curswin(pw),
-			owl_popwin_get_lines(pw), owl_popwin_get_cols(pw),
-			text);
-  owl_popwin_refresh(pw);
-  owl_viewwin_redisplay(v, 0);
-  owl_global_set_needrefresh(&g);
-}
-
-void owl_function_popless_fmtext(owl_fmtext *fm)
-{
-  owl_popwin *pw;
-  owl_viewwin *v;
-
-  pw=owl_global_get_popwin(&g);
-  v=owl_global_get_viewwin(&g);
-
-  owl_popwin_up(pw);
-  owl_viewwin_init_fmtext(v, owl_popwin_get_curswin(pw),
-		   owl_popwin_get_lines(pw), owl_popwin_get_cols(pw),
-		   fm);
-  owl_popwin_refresh(pw);
-  owl_viewwin_redisplay(v, 0);
-  owl_global_set_needrefresh(&g);
-}
-
-void owl_function_popless_file(char *filename)
-{
-  owl_fmtext fm;
-  FILE *file;
-  char buff[1024];
-
-  file=fopen(filename, "r");
-  if (!file) {
-    owl_function_error("Could not open file: %s", filename);
-    return;
-  }
-
-  owl_fmtext_init_null(&fm);
-  while (fgets(buff, 1024, file)) {
-    owl_fmtext_append_normal(&fm, buff);
-    /*    owl_fmtext_append_normal(&fm, "\n"); */
-  }
-
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-  fclose(file);
-}
-
-void owl_function_about()
-{
-  char buff[5000];
-
-  sprintf(buff, "This is barnowl version %s\n\n", OWL_VERSION_STRING);
-  strcat(buff, "barnowl is a fork of the Owl zephyr client, written and\n");
-  strcat(buff, "maintained by Alejandro Sedeno and Nelson Elhage at the\n");
-  strcat(buff, "Massachusetts Institute of Technology. \n");
-  strcat(buff, "\n");
-  strcat(buff, "Owl was written by James Kretchmar. The first version, 0.5, was\n");
-  strcat(buff, "released in March 2002.\n");
-  strcat(buff, "\n");
-  strcat(buff, "The name 'owl' was chosen in reference to the owls in the\n");
-  strcat(buff, "Harry Potter novels, who are tasked with carrying messages\n");
-  strcat(buff, "between Witches and Wizards. The name 'barnowl' was chosen\n");
-  strcat(buff, "because we feel our owls should live closer to our ponies.\n");
-  strcat(buff, "\n");
-  strcat(buff, "Copyright (c) 2006-2008 The BarnOwl Developers. All rights reserved.\n");
-  strcat(buff, "Copyright (c) 2004 James Kretchmar. All rights reserved.\n");
-  strcat(buff, "Copyright 2002 Massachusetts Institute of Technology\n");
-  strcat(buff, "\n");
-  strcat(buff, "This program is free software. You can redistribute it and/or\n");
-  strcat(buff,  "modify under the terms of the Sleepycat License. Use the \n");
-  strcat(buff,  "':show license' command to display the full license\n");
-  owl_function_popless_text(buff);
-}
-
-void owl_function_info()
-{
-  owl_message *m;
-  owl_fmtext fm, attrfm;
-  char buff[10000];
-  owl_view *v;
-#ifdef HAVE_LIBZEPHYR
-  ZNotice_t *n;
-#endif
-
-  owl_fmtext_init_null(&fm);
-  
-  v=owl_global_get_current_view(&g);
-  m=owl_view_get_element(v, owl_global_get_curmsg(&g));
-  if (!m || owl_view_get_size(v)==0) {
-    owl_function_error("No message selected\n");
-    return;
-  }
-
-  owl_fmtext_append_bold(&fm, "General Information:\n");
-  owl_fmtext_append_normal(&fm, "  Msg Id    : ");
-  sprintf(buff, "%i", owl_message_get_id(m));
-  owl_fmtext_append_normal(&fm, buff);
-  owl_fmtext_append_normal(&fm, "\n");
-
-  owl_fmtext_append_normal(&fm, "  Type      : ");
-  owl_fmtext_append_bold(&fm, owl_message_get_type(m));
-  owl_fmtext_append_normal(&fm, "\n");
-
-  if (owl_message_is_direction_in(m)) {
-    owl_fmtext_append_normal(&fm, "  Direction : in\n");
-  } else if (owl_message_is_direction_out(m)) {
-    owl_fmtext_append_normal(&fm, "  Direction : out\n");
-  } else if (owl_message_is_direction_none(m)) {
-    owl_fmtext_append_normal(&fm, "  Direction : none\n");
-  } else {
-    owl_fmtext_append_normal(&fm, "  Direction : unknown\n");
-  }
-
-  owl_fmtext_append_normal(&fm, "  Time      : ");
-  owl_fmtext_append_normal(&fm, owl_message_get_timestr(m));
-  owl_fmtext_append_normal(&fm, "\n");
-
-  if (!owl_message_is_type_admin(m)) {
-    owl_fmtext_append_normal(&fm, "  Sender    : ");
-    owl_fmtext_append_normal(&fm, owl_message_get_sender(m));
-    owl_fmtext_append_normal(&fm, "\n");
-    
-    owl_fmtext_append_normal(&fm, "  Recipient : ");
-    owl_fmtext_append_normal(&fm, owl_message_get_recipient(m));
-    owl_fmtext_append_normal(&fm, "\n");
-  }
-    
-  if (owl_message_is_type_zephyr(m)) {
-    owl_fmtext_append_bold(&fm, "\nZephyr Specific Information:\n");
-    
-    owl_fmtext_append_normal(&fm, "  Class     : ");
-    owl_fmtext_append_normal(&fm, owl_message_get_class(m));
-    owl_fmtext_append_normal(&fm, "\n");
-    owl_fmtext_append_normal(&fm, "  Instance  : ");
-    owl_fmtext_append_normal(&fm, owl_message_get_instance(m));
-    owl_fmtext_append_normal(&fm, "\n");
-    owl_fmtext_append_normal(&fm, "  Opcode    : ");
-    owl_fmtext_append_normal(&fm, owl_message_get_opcode(m));
-    owl_fmtext_append_normal(&fm, "\n");
-    
-    owl_fmtext_append_normal(&fm, "  Time      : ");
-    owl_fmtext_append_normal(&fm, owl_message_get_timestr(m));
-    owl_fmtext_append_normal(&fm, "\n");
-#ifdef HAVE_LIBZEPHYR
-    if (owl_message_is_direction_in(m)) {
-      char *ptr, tmpbuff[1024];
-      int i, j, fields, len;
-
-      n=owl_message_get_notice(m);
-
-      if (!owl_message_is_pseudo(m)) {
-	owl_fmtext_append_normal(&fm, "  Kind      : ");
-	if (n->z_kind==UNSAFE) {
-	  owl_fmtext_append_normal(&fm, "UNSAFE\n");
-	} else if (n->z_kind==UNACKED) {
-	  owl_fmtext_append_normal(&fm, "UNACKED\n");
-	} else if (n->z_kind==ACKED) {
-	  owl_fmtext_append_normal(&fm, "ACKED\n");
-	} else if (n->z_kind==HMACK) {
-	  owl_fmtext_append_normal(&fm, "HMACK\n");
-	} else if (n->z_kind==HMCTL) {
-	  owl_fmtext_append_normal(&fm, "HMCTL\n");
-	} else if (n->z_kind==SERVACK) {
-	  owl_fmtext_append_normal(&fm, "SERVACK\n");
-	} else if (n->z_kind==SERVNAK) {
-	  owl_fmtext_append_normal(&fm, "SERVNACK\n");
-	} else if (n->z_kind==CLIENTACK) {
-	  owl_fmtext_append_normal(&fm, "CLIENTACK\n");
-	} else if (n->z_kind==STAT) {
-	  owl_fmtext_append_normal(&fm, "STAT\n");
-	} else {
-	  owl_fmtext_append_normal(&fm, "ILLEGAL VALUE\n");
-	}
-      }
-      owl_fmtext_append_normal(&fm, "  Host      : ");
-      owl_fmtext_append_normal(&fm, owl_message_get_hostname(m));
-
-      if (!owl_message_is_pseudo(m)) {
-	owl_fmtext_append_normal(&fm, "\n");
-	sprintf(buff, "  Port      : %i\n", ntohs(n->z_port));
-	owl_fmtext_append_normal(&fm, buff);
-
-	owl_fmtext_append_normal(&fm,    "  Auth      : ");
-	owl_fmtext_append_normal(&fm, owl_zephyr_get_authstr(n));
-	owl_fmtext_append_normal(&fm, "\n");
-	
-	/* fix this */
-	sprintf(buff, "  Checkd Ath: %i\n", n->z_checked_auth);
-	sprintf(buff + strlen(buff), "  Multi notc: %s\n", n->z_multinotice);
-	sprintf(buff + strlen(buff), "  Num other : %i\n", n->z_num_other_fields);
-	sprintf(buff + strlen(buff), "  Msg Len   : %i\n", n->z_message_len);
-	owl_fmtext_append_normal(&fm, buff);
-	
-	sprintf(buff, "  Fields    : %i\n", owl_zephyr_get_num_fields(n));
-	owl_fmtext_append_normal(&fm, buff);
-	
-	fields=owl_zephyr_get_num_fields(n);
-	for (i=0; i<fields; i++) {
-	  sprintf(buff, "  Field %i   : ", i+1);
-	  
-	  ptr=owl_zephyr_get_field_as_utf8(n, i+1);
-	  len=strlen(ptr);
-	  if (len<30) {
-	    strncpy(tmpbuff, ptr, len);
-	    tmpbuff[len]='\0';
-	  } else {
-	    strncpy(tmpbuff, ptr, 30);
-	    tmpbuff[30]='\0';
-	    strcat(tmpbuff, "...");
-	  }
-	  owl_free(ptr);
-	  
-	  for (j=0; j<strlen(tmpbuff); j++) {
-	    if (tmpbuff[j]=='\n') tmpbuff[j]='~';
-	    if (tmpbuff[j]=='\r') tmpbuff[j]='!';
-	  }
-	  
-	  strcat(buff, tmpbuff);
-	  strcat(buff, "\n");
-	  owl_fmtext_append_normal(&fm, buff);
-	}
-	owl_fmtext_append_normal(&fm, "  Default Fm:");
-	owl_fmtext_append_normal(&fm, n->z_default_format);
-      }
-      
-    }
-#endif    
-  }
-
-  owl_fmtext_append_bold(&fm, "\nOwl Message Attributes:\n");
-  owl_message_attributes_tofmtext(m, &attrfm);
-  owl_fmtext_append_fmtext(&fm, &attrfm);
-  
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-  owl_fmtext_free(&attrfm);
-}
-
-/* print the current message in a popup window.
- * Use the 'default' style regardless of whatever
- * style the user may be using
- */
-void owl_function_curmsg_to_popwin()
-{
-  owl_popwin *pw;
-  owl_view *v;
-  owl_message *m;
-  owl_style *s;
-  owl_fmtext fm;
-
-  v=owl_global_get_current_view(&g);
-  s=owl_global_get_style_by_name(&g, "default");
-  pw=owl_global_get_popwin(&g);
-
-  m=owl_view_get_element(v, owl_global_get_curmsg(&g));
-
-  if (!m || owl_view_get_size(v)==0) {
-    owl_function_error("No current message");
-    return;
-  }
-
-  owl_fmtext_init_null(&fm);
-  owl_style_get_formattext(s, &fm, m);
-
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-}
-
-void owl_function_page_curmsg(int step)
-{
-  /* scroll down or up within the current message IF the message is truncated */
-
-  int offset, curmsg, lines;
-  owl_view *v;
-  owl_message *m;
-
-  offset=owl_global_get_curmsg_vert_offset(&g);
-  v=owl_global_get_current_view(&g);
-  curmsg=owl_global_get_curmsg(&g);
-  m=owl_view_get_element(v, curmsg);
-  if (!m || owl_view_get_size(v)==0) return;
-  lines=owl_message_get_numlines(m);
-
-  if (offset==0) {
-    /* Bail if the curmsg isn't the last one displayed */
-    if (curmsg != owl_mainwin_get_last_msg(owl_global_get_mainwin(&g))) {
-      owl_function_makemsg("The entire message is already displayed");
-      return;
-    }
-    
-    /* Bail if we're not truncated */
-    if (!owl_mainwin_is_curmsg_truncated(owl_global_get_mainwin(&g))) {
-      owl_function_makemsg("The entire message is already displayed");
-      return;
-    }
-  }
-  
-  
-  /* don't scroll past the last line */
-  if (step>0) {
-    if (offset+step > lines-1) {
-      owl_global_set_curmsg_vert_offset(&g, lines-1);
-    } else {
-      owl_global_set_curmsg_vert_offset(&g, offset+step);
-    }
-  }
-
-  /* would we be before the beginning of the message? */
-  if (step<0) {
-    if (offset+step<0) {
-      owl_global_set_curmsg_vert_offset(&g, 0);
-    } else {
-      owl_global_set_curmsg_vert_offset(&g, offset+step);
-    }
-  }
-  
-  /* redisplay */
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  owl_global_set_needrefresh(&g);
-}
-
-void owl_function_resize_typwin(int newsize)
-{
-  owl_global_set_typwin_lines(&g, newsize);
-  owl_function_resize();
-}
-
-void owl_function_typwin_grow()
-{
-  int i;
-
-  i=owl_global_get_typwin_lines(&g);
-  owl_function_resize_typwin(i+1);
-}
-
-void owl_function_typwin_shrink()
-{
-  int i;
-
-  i=owl_global_get_typwin_lines(&g);
-  if (i>2) {
-    owl_function_resize_typwin(i-1);
-  }
-}
-
-void owl_function_mainwin_pagedown()
-{
-  int i;
-
-  i=owl_mainwin_get_last_msg(owl_global_get_mainwin(&g));
-  if (i<0) return;
-  if (owl_mainwin_is_last_msg_truncated(owl_global_get_mainwin(&g))
-      && (owl_global_get_curmsg(&g) < i)
-      && (i>0)) {
-    i--;
-  }
-  owl_global_set_curmsg(&g, i);
-  owl_function_nextmsg();
-}
-
-void owl_function_mainwin_pageup()
-{
-  owl_global_set_curmsg(&g, owl_global_get_topmsg(&g));
-  owl_function_prevmsg();
-}
-
-void owl_function_getsubs()
-{
-  char *buff;
-
-  buff=owl_zephyr_getsubs();
-
-  if (buff) {
-    owl_function_popless_text(buff);
-  } else {
-    owl_function_popless_text("Error getting subscriptions");
-  }
-	   
-  owl_free(buff);
-}
-
-#define PABUFLEN 5000
-void owl_function_printallvars()
-{
-  char buff[PABUFLEN], *pos, *name;
-  owl_list varnames;
-  int i, numvarnames, rem;
-
-  pos = buff;
-  pos += sprintf(pos, "%-20s = %s\n", "VARIABLE", "VALUE");
-  pos += sprintf(pos, "%-20s   %s\n",  "--------", "-----");
-  owl_variable_dict_get_names(owl_global_get_vardict(&g), &varnames);
-  rem = (buff+PABUFLEN)-pos-1;
-  numvarnames = owl_list_get_size(&varnames);
-  for (i=0; i<numvarnames; i++) {
-    name = owl_list_get_element(&varnames, i);
-    if (name && name[0]!='_') {
-      rem = (buff+PABUFLEN)-pos-1;    
-      pos += snprintf(pos, rem, "\n%-20s = ", name);
-      rem = (buff+PABUFLEN)-pos-1;    
-      owl_variable_get_tostring(owl_global_get_vardict(&g), name, pos, rem);
-      pos = buff+strlen(buff);
-    }
-  }
-  rem = (buff+PABUFLEN)-pos-1;    
-  snprintf(pos, rem, "\n");
-  owl_variable_dict_namelist_free(&varnames);
-  
-  owl_function_popless_text(buff);
-}
-
-void owl_function_show_variables()
-{
-  owl_list varnames;
-  owl_fmtext fm;  
-  int i, numvarnames;
-  char *varname;
-
-  owl_fmtext_init_null(&fm);
-  owl_fmtext_append_bold(&fm, 
-      "Variables: (use 'show variable <name>' for details)\n");
-  owl_variable_dict_get_names(owl_global_get_vardict(&g), &varnames);
-  numvarnames = owl_list_get_size(&varnames);
-  for (i=0; i<numvarnames; i++) {
-    varname = owl_list_get_element(&varnames, i);
-    if (varname && varname[0]!='_') {
-      owl_variable_describe(owl_global_get_vardict(&g), varname, &fm);
-    }
-  }
-  owl_variable_dict_namelist_free(&varnames);
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-}
-
-void owl_function_show_variable(char *name)
-{
-  owl_fmtext fm;  
-
-  owl_fmtext_init_null(&fm);
-  owl_variable_get_help(owl_global_get_vardict(&g), name, &fm);
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);  
-}
-
-/* note: this applies to global message list, not to view.
- * If flag is 1, deletes.  If flag is 0, undeletes. */
-void owl_function_delete_by_id(int id, int flag)
-{
-  owl_messagelist *ml;
-  owl_message *m;
-  ml = owl_global_get_msglist(&g);
-  m = owl_messagelist_get_by_id(ml, id);
-  if (m) {
-    if (flag == 1) {
-      owl_message_mark_delete(m);
-    } else if (flag == 0) {
-      owl_message_unmark_delete(m);
-    }
-    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-    owl_global_set_needrefresh(&g);
-  } else {
-    owl_function_error("No message with id %d: unable to mark for (un)delete",id);
-  }
-}
-
-void owl_function_delete_automsgs()
-{
-  /* mark for deletion all messages in the current view that match the
-   * 'trash' filter */
-
-  int i, j, count;
-  owl_message *m;
-  owl_view *v;
-  owl_filter *f;
-
-  /* get the trash filter */
-  f=owl_global_get_filter(&g, "trash");
-  if (!f) {
-    owl_function_error("No trash filter defined");
-    return;
-  }
-
-  v=owl_global_get_current_view(&g);
-
-  count=0;
-  j=owl_view_get_size(v);
-  for (i=0; i<j; i++) {
-    m=owl_view_get_element(v, i);
-    if (owl_filter_message_match(f, m)) {
-      count++;
-      owl_message_mark_delete(m);
-    }
-  }
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  owl_function_makemsg("%i messages marked for deletion", count);
-  owl_global_set_needrefresh(&g);
-}
-
-void owl_function_status()
-{
-  char buff[MAXPATHLEN+1];
-  time_t start;
-  int up, days, hours, minutes;
-  owl_fmtext fm;
-
-  owl_fmtext_init_null(&fm);
-
-  start=owl_global_get_starttime(&g);
-
-  owl_fmtext_append_normal(&fm, "General Information:\n");
-
-  owl_fmtext_append_normal(&fm, "  Version: ");
-  owl_fmtext_append_normal(&fm, OWL_VERSION_STRING);
-  owl_fmtext_append_normal(&fm, "\n");
-
-  owl_fmtext_append_normal(&fm, "  Startup Arguments: ");
-  owl_fmtext_append_normal(&fm, owl_global_get_startupargs(&g));
-  owl_fmtext_append_normal(&fm, "\n");
-
-  owl_fmtext_append_normal(&fm, "  Current Directory: ");
-  if(getcwd(buff, MAXPATHLEN) == NULL) {
-    owl_fmtext_append_normal(&fm, "<Error in getcwd>");
-  } else {
-    owl_fmtext_append_normal(&fm, buff);
-  }
-  owl_fmtext_append_normal(&fm, "\n");
-
-  sprintf(buff, "  Startup Time: %s", ctime(&start));
-  owl_fmtext_append_normal(&fm, buff);
-
-  up=owl_global_get_runtime(&g);
-  days=up/86400;
-  up-=days*86400;
-  hours=up/3600;
-  up-=hours*3600;
-  minutes=up/60;
-  up-=minutes*60;
-  sprintf(buff, "  Run Time: %i days %2.2i:%2.2i:%2.2i\n", days, hours, minutes, up);
-  owl_fmtext_append_normal(&fm, buff);
-
-  owl_fmtext_append_normal(&fm, "\nProtocol Options:\n");
-  owl_fmtext_append_normal(&fm, "  Zephyr included    : ");
-  if (owl_global_is_havezephyr(&g)) {
-    owl_fmtext_append_normal(&fm, "yes\n");
-  } else {
-    owl_fmtext_append_normal(&fm, "no\n");
-  }
-  owl_fmtext_append_normal(&fm, "  AIM included       : yes\n");
-  owl_fmtext_append_normal(&fm, "  Loopback included  : yes\n");
-
-
-  owl_fmtext_append_normal(&fm, "\nBuild Options:\n");
-  owl_fmtext_append_normal(&fm, "  Stderr redirection : ");
-#if OWL_STDERR_REDIR
-  owl_fmtext_append_normal(&fm, "yes\n");
-#else
-  owl_fmtext_append_normal(&fm, "no\n");
-#endif
-  
-
-  owl_fmtext_append_normal(&fm, "\nAIM Status:\n");
-  owl_fmtext_append_normal(&fm, "  Logged in: ");
-  if (owl_global_is_aimloggedin(&g)) {
-    owl_fmtext_append_normal(&fm, owl_global_get_aim_screenname(&g));
-    owl_fmtext_append_normal(&fm, "\n");
-  } else {
-    owl_fmtext_append_normal(&fm, "(not logged in)\n");
-  }
-
-  owl_fmtext_append_normal(&fm, "  Processing events: ");
-  if (owl_global_is_doaimevents(&g)) {
-    owl_fmtext_append_normal(&fm, "yes\n");
-  } else {
-    owl_fmtext_append_normal(&fm, "no\n");
-  }
-
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-}
-
-void owl_function_show_term()
-{
-  owl_fmtext fm;
-  char buff[LINE];
-
-  owl_fmtext_init_null(&fm);
-  sprintf(buff, "Terminal Lines: %i\nTerminal Columns: %i\n",
-	  owl_global_get_lines(&g),
-	  owl_global_get_cols(&g));
-  owl_fmtext_append_normal(&fm, buff);
-
-  if (owl_global_get_hascolors(&g)) {
-    owl_fmtext_append_normal(&fm, "Color: Yes\n");
-    sprintf(buff, "Number of color pairs: %i\n", owl_global_get_colorpairs(&g));
-    owl_fmtext_append_normal(&fm, buff);
-    sprintf(buff, "Can change colors: %s\n", can_change_color() ? "yes" : "no");
-    owl_fmtext_append_normal(&fm, buff);
-  } else {
-    owl_fmtext_append_normal(&fm, "Color: No\n");
-  }
-
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-}
-
-/* if type = 0 then normal reply.
- * if type = 1 then it's a reply to sender
- * if enter = 0 then allow the command to be edited
- * if enter = 1 then don't wait for editing
- */
-void owl_function_reply(int type, int enter)
-{
-  char *buff=NULL;
-  owl_message *m;
-  owl_filter *f;
-  
-  if (owl_view_get_size(owl_global_get_current_view(&g))==0) {
-    owl_function_error("No message selected");
-  } else {
-    
-    m=owl_view_get_element(owl_global_get_current_view(&g), owl_global_get_curmsg(&g));
-    if (!m) {
-      owl_function_error("No message selected");
-      return;
-    }
-
-    /* first check if we catch the reply-lockout filter */
-    f=owl_global_get_filter(&g, "reply-lockout");
-    if (f) {
-      if (owl_filter_message_match(f, m)) {
-	owl_function_error("Sorry, replies to this message have been disabled by the reply-lockout filter");
-	return;
-      }
-    }
-
-    /* then check if it's a question and just bring up the command prompt */
-    if (owl_message_is_question(m)) {
-      owl_function_start_command("");
-      return;
-    }
-
-    char *cmd;
-    if((type == 0 &&
-        (cmd=owl_perlconfig_message_call_method(m, "replycmd", 0, NULL))) ||
-       (type == 1 &&
-        (cmd=owl_perlconfig_message_call_method(m, "replysendercmd", 0, NULL)))) {
-      buff = cmd;
-    }
-
-    if(!buff) {
-        owl_function_error("I don't know how to reply to that message.");
-        return;
-    }
-
-    if (enter) {
-      owl_history *hist = owl_global_get_cmd_history(&g);
-      owl_history_store(hist, buff);
-      owl_history_reset(hist);
-      owl_function_command_norv(buff);
-    } else {
-      owl_function_start_command(buff);
-    }
-    owl_free(buff);
-  }
-}
-
-void owl_function_zlocate(int argc, char **argv, int auth)
-{
-  owl_fmtext fm;
-  char *ptr, buff[LINE];
-  int i;
-
-  owl_fmtext_init_null(&fm);
-
-  for (i=0; i<argc; i++) {
-    ptr=long_zuser(argv[i]);
-    owl_zephyr_zlocate(ptr, buff, auth);
-    owl_fmtext_append_normal(&fm, buff);
-    owl_free(ptr);
-  }
-
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-}
-
-void owl_function_start_command(char *line)
-{
-  owl_editwin *tw;
-
-  tw=owl_global_get_typwin(&g);
-  owl_global_set_typwin_active(&g);
-  owl_editwin_new_style(tw, OWL_EDITWIN_STYLE_ONELINE, 
-			owl_global_get_cmd_history(&g));
-
-  owl_editwin_set_locktext(tw, "command: ");
-  owl_global_set_needrefresh(&g);
-
-  owl_editwin_insert_string(tw, line);
-  owl_editwin_redisplay(tw, 0);
-
-  owl_context_set_editline(owl_global_get_context(&g), tw);
-  owl_function_activate_keymap("editline");
-}
-
-void owl_function_start_question(char *line)
-{
-  owl_editwin *tw;
-
-  tw=owl_global_get_typwin(&g);
-  owl_global_set_typwin_active(&g);
-  owl_editwin_new_style(tw, OWL_EDITWIN_STYLE_ONELINE, owl_global_get_cmd_history(&g));
-
-  owl_editwin_set_locktext(tw, line);
-  owl_global_set_needrefresh(&g);
-
-  owl_editwin_redisplay(tw, 0);
-
-  owl_context_set_editresponse(owl_global_get_context(&g), tw);
-  owl_function_activate_keymap("editresponse");
-}
-
-void owl_function_start_password(char *line)
-{
-  owl_editwin *tw;
-
-  tw=owl_global_get_typwin(&g);
-  owl_global_set_typwin_active(&g);
-  owl_editwin_new_style(tw, OWL_EDITWIN_STYLE_ONELINE, owl_global_get_cmd_history(&g));
-  owl_editwin_set_echochar(tw, '*');
-
-  owl_editwin_set_locktext(tw, line);
-  owl_global_set_needrefresh(&g);
-
-  owl_editwin_redisplay(tw, 0);
-
-  owl_context_set_editresponse(owl_global_get_context(&g), tw);
-  owl_function_activate_keymap("editresponse");
-}
-
-char *owl_function_exec(int argc, char **argv, char *buff, int type)
-{
-  /* if type == 1 display in a popup
-   * if type == 2 display an admin messages
-   * if type == 0 return output
-   * else display in a popup
-   */
-  char *newbuff, *redirect = " 2>&1 < /dev/null";
-  char *out, buff2[1024];
-  int size;
-  FILE *p;
-
-#if OWL_STDERR_REDIR
-  redirect = " < /dev/null";
-#endif 
-
-  if (argc<2) {
-    owl_function_error("Wrong number of arguments to the exec command");
-    return NULL;
-  }
-
-  buff = skiptokens(buff, 1);
-  newbuff = owl_malloc(strlen(buff)+strlen(redirect)+1);
-  strcpy(newbuff, buff);
-  strcat(newbuff, redirect);
-
-  if (type == 1) {
-    owl_popexec_new(newbuff);
-  } else {
-    p=popen(newbuff, "r");
-    out=owl_malloc(1024);
-    size=1024;
-    strcpy(out, "");
-    while (fgets(buff2, 1024, p)!=NULL) {
-      size+=1024;
-      out=owl_realloc(out, size);
-      strcat(out, buff2);
-    }
-    pclose(p);
-    
-    if (type==1) {
-      owl_function_popless_text(out);
-    } else if (type==0) {
-      return out;
-    } else if (type==2) {
-      owl_function_adminmsg(buff, out);
-    } else {
-      owl_function_popless_text(out);
-    }
-    owl_free(out);
-  }
-  return NULL;
-}
-
-char *owl_function_perl(int argc, char **argv, char *buff, int type)
-{
-  /* if type == 1 display in a popup
-   * if type == 2 display an admin messages
-   * if type == 0 return output
-   * else display in a popup
-   */
-  char *perlout;
-
-  if (argc<2) {
-    owl_function_error("Wrong number of arguments to perl command");
-    return NULL;
-  }
-
-  /* consume first token (argv[0]) */
-  buff = skiptokens(buff, 1);
-
-  perlout = owl_perlconfig_execute(buff);
-  if (perlout) { 
-    if (type==1) {
-      owl_function_popless_text(perlout);
-    } else if (type==2) {
-      owl_function_adminmsg(buff, perlout);
-    } else if (type==0) {
-      return perlout;
-    } else {
-      owl_function_popless_text(perlout);
-    }
-    owl_free(perlout);
-  }
-  return NULL;
-}
-
-/* Change the filter associated with the current view.
- * This also figures out which message in the new filter
- * should have the pointer.
- */
-void owl_function_change_currentview_filter(char *filtname)
-{
-  owl_view *v;
-  owl_filter *f;
-  int curid=-1, newpos, curmsg;
-  owl_message *curm=NULL;
-
-  v=owl_global_get_current_view(&g);
-
-  curmsg=owl_global_get_curmsg(&g);
-  if (curmsg==-1) {
-    owl_function_debugmsg("Hit the curmsg==-1 case in change_view");
-  } else {
-    curm=owl_view_get_element(v, curmsg);
-    if (curm) {
-      curid=owl_message_get_id(curm);
-      owl_view_save_curmsgid(v, curid);
-    }
-  }
-
-  f=owl_global_get_filter(&g, filtname);
-  if (!f) {
-    owl_function_error("Unknown filter %s", filtname);
-    return;
-  }
-
-  owl_view_new_filter(v, f);
-
-  /* Figure out what to set the current message to.
-   * - If the view we're leaving has messages in it, go to the closest message
-   *   to the last message pointed to in that view. 
-   * - If the view we're leaving is empty, try to restore the position
-   *   from the last time we were in the new view.  */
-  if (curm) {
-    newpos = owl_view_get_nearest_to_msgid(v, curid);
-  } else {
-    newpos = owl_view_get_nearest_to_saved(v);
-  }
-
-  owl_global_set_curmsg(&g, newpos);
-  owl_function_calculate_topmsg(OWL_DIRECTION_DOWNWARDS);
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  owl_global_set_direction_downwards(&g);
-}
-
-/* Create a new filter, or replace an existing one
- * with a new definition.
- */
-void owl_function_create_filter(int argc, char **argv)
-{
-  owl_filter *f;
-  owl_view *v;
-  int ret, inuse=0;
-
-  if (argc < 2) {
-    owl_function_error("Wrong number of arguments to filter command");
-    return;
-  }
-
-  owl_function_debugmsg("owl_function_create_filter: starting to create filter named %s", argv[1]);
-
-  v=owl_global_get_current_view(&g);
-
-  /* don't touch the all filter */
-  if (!strcmp(argv[1], "all")) {
-    owl_function_error("You may not change the 'all' filter.");
-    return;
-  }
-
-  /* deal with the case of trying change the filter color */
-  if (argc==4 && !strcmp(argv[2], "-c")) {
-    f=owl_global_get_filter(&g, argv[1]);
-    if (!f) {
-      owl_function_error("The filter '%s' does not exist.", argv[1]);
-      return;
-    }
-    if (owl_util_string_to_color(argv[3])==OWL_COLOR_INVALID) {
-      owl_function_error("The color '%s' is not available.", argv[3]);
-      return;
-    }
-    owl_filter_set_fgcolor(f, owl_util_string_to_color(argv[3]));
-    owl_global_set_needrefresh(&g);
-    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-    return;
-  }
-  if (argc==4 && !strcmp(argv[2], "-b")) {
-    f=owl_global_get_filter(&g, argv[1]);
-    if (!f) {
-      owl_function_error("The filter '%s' does not exist.", argv[1]);
-      return;
-    }
-    if (owl_util_string_to_color(argv[3])==OWL_COLOR_INVALID) {
-      owl_function_error("The color '%s' is not available.", argv[3]);
-      return;
-    }
-    owl_filter_set_bgcolor(f, owl_util_string_to_color(argv[3]));
-    owl_global_set_needrefresh(&g);
-    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-    return;
-  }
-
-  /* create the filter and check for errors */
-  f=owl_malloc(sizeof(owl_filter));
-  ret=owl_filter_init(f, argv[1], argc-2, argv+2);
-  if (ret==-1) {
-    owl_free(f);
-    owl_function_error("Invalid filter");
-    return;
-  }
-
-  /* if the named filter is in use by the current view, remember it */
-  if (!strcmp(owl_view_get_filtname(v), argv[1])) {
-    inuse=1;
-  }
-
-  /* if the named filter already exists, nuke it */
-  if (owl_global_get_filter(&g, argv[1])) {
-    owl_global_remove_filter(&g, argv[1]);
-  }
-
-  /* add the filter */
-  owl_global_add_filter(&g, f);
-
-  /* if it was in use by the current view then update */
-  if (inuse) {
-    owl_function_change_currentview_filter(argv[1]);
-  }
-  owl_global_set_needrefresh(&g);
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-}
-
-/* If 'filtername' does not start with 'not-' create a filter named
- * 'not-<filtername>' defined as "not filter <filtername>".  If the
- * filter 'not-<filtername>' already exists, do not overwrite it.  If
- * 'filtername' begins with 'not-' and a filter 'filtername' already
- * exists, then do nothing.  If the filter 'filtername' does not
- * exist, create it and define it as 'not filter <filtername>'
- *
- * Returns the name of the negated filter, which the caller must free.
- */
-char *owl_function_create_negative_filter(char *filtername)
-{
-  char *newname;
-  owl_filter *tmpfilt;
-  char *argv[5];
-
-  owl_function_debugmsg("owl_function_create_negative_filter");
-  
-  if (!strncmp(filtername, "not-", 4)) {
-    newname=owl_strdup(filtername+4);
-  } else {
-    newname=owl_sprintf("not-%s", filtername);
-  }
-
-  tmpfilt=owl_global_get_filter(&g, newname);
-  if (!tmpfilt) {
-    argv[0]="filter"; /* anything is fine here */
-    argv[1]=newname;
-    argv[2]="not";
-    argv[3]="filter";
-    argv[4]=filtername;
-    owl_function_create_filter(5, argv);
-  }
-
-  owl_function_debugmsg("owl_function_create_negative_filter: returning with %s", newname);
-  return(newname);
-}
-
-void owl_function_show_filters()
-{
-  owl_list *l;
-  owl_filter *f;
-  int i, j;
-  owl_fmtext fm;
-
-  owl_fmtext_init_null(&fm);
-
-  l=owl_global_get_filterlist(&g);
-  j=owl_list_get_size(l);
-
-  owl_fmtext_append_bold(&fm, "Filters:\n");
-
-  for (i=0; i<j; i++) {
-    f=owl_list_get_element(l, i);
-    owl_fmtext_append_normal(&fm, "   ");
-    if (owl_global_get_hascolors(&g)) {
-      owl_fmtext_append_normal_color(&fm, owl_filter_get_name(f), owl_filter_get_fgcolor(f), owl_filter_get_bgcolor(f));
-    } else {
-      owl_fmtext_append_normal(&fm, owl_filter_get_name(f));
-    }
-    owl_fmtext_append_normal(&fm, "\n");
-  }
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-}
-
-void owl_function_show_filter(char *name)
-{
-  owl_filter *f;
-  char *buff, *tmp;
-
-  f=owl_global_get_filter(&g, name);
-  if (!f) {
-    owl_function_error("There is no filter named %s", name);
-    return;
-  }
-  tmp = owl_filter_print(f);
-  buff = owl_sprintf("%s: %s", owl_filter_get_name(f), tmp);
-  owl_function_popless_text(buff);
-  owl_free(buff);
-  owl_free(tmp);
-}
-
-void owl_function_show_zpunts()
-{
-  owl_filter *f;
-  owl_list *fl;
-  char buff[5000];
-  char *tmp;
-  owl_fmtext fm;
-  int i, j;
-
-  owl_fmtext_init_null(&fm);
-
-  fl=owl_global_get_puntlist(&g);
-  j=owl_list_get_size(fl);
-  owl_fmtext_append_bold(&fm, "Active zpunt filters:\n");
-
-  for (i=0; i<j; i++) {
-    f=owl_list_get_element(fl, i);
-    snprintf(buff, sizeof(buff), "[% 2d] ", i+1);
-    owl_fmtext_append_normal(&fm, buff);
-    tmp = owl_filter_print(f);
-    owl_fmtext_append_normal(&fm, tmp);
-    owl_free(tmp);
-    owl_fmtext_append_normal(&fm, buff);
-  }
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-}
-
-/* Create a filter for a class, instance if one doesn't exist.  If
- * instance is NULL then catch all messgaes in the class.  Returns the
- * name of the filter, which the caller must free.
- */
-char *owl_function_classinstfilt(char *c, char *i) 
-{
-  owl_list *fl;
-  owl_filter *f;
-  char *argbuff, *filtname;
-  char *tmpclass, *tmpinstance = NULL;
-  char *class, *instance = NULL;
-  int len;
-
-  class = owl_util_baseclass(c);
-  if(i) {
-    instance = owl_util_baseclass(i);
-  }
-
-  fl=owl_global_get_filterlist(&g);
-
-  /* name for the filter */
-  len=strlen(class)+30;
-  if (instance) len+=strlen(instance);
-  filtname=owl_malloc(len);
-  if (!instance) {
-    sprintf(filtname, "class-%s", class);
-  } else {
-    sprintf(filtname, "class-%s-instance-%s", class, instance);
-  }
-  /* downcase it */
-  {
-    char *temp = g_utf8_strdown(filtname, -1);
-    if (temp) {
-      owl_free(filtname);
-      filtname = temp;
-    }
-  }
-  /* turn spaces, single quotes, and double quotes into dots */
-  owl_text_tr(filtname, ' ', '.');
-  owl_text_tr(filtname, '\'', '.');
-  owl_text_tr(filtname, '"', '.');
-  
-  /* if it already exists then go with it.  This lets users override */
-  if (owl_global_get_filter(&g, filtname)) {
-    return(filtname);
-  }
-
-  /* create the new filter */
-  tmpclass=owl_text_quote(class, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
-  owl_text_tr(tmpclass, ' ', '.');
-  owl_text_tr(tmpclass, '\'', '.');
-  owl_text_tr(tmpclass, '"', '.');
-  if (instance) {
-    tmpinstance=owl_text_quote(instance, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
-    owl_text_tr(tmpinstance, ' ', '.');
-    owl_text_tr(tmpinstance, '\'', '.');
-    owl_text_tr(tmpinstance, '"', '.');
-  }
-  len = strlen(tmpclass);
-  if(tmpinstance) len += strlen(tmpinstance);
-  len += 60;
-  argbuff = owl_malloc(len);
-  sprintf(argbuff, "class ^(un)*%s(\\.d)*$", tmpclass);
-  if (tmpinstance) {
-    sprintf(argbuff + strlen(argbuff), " and ( instance ^(un)*%s(\\.d)*$ )", tmpinstance);
-  }
-  owl_free(tmpclass);
-  if (tmpinstance) owl_free(tmpinstance);
-
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, filtname, argbuff);
-
-  /* add it to the global list */
-  owl_global_add_filter(&g, f);
-
-  owl_free(argbuff);
-  owl_free(class);
-  if (instance) {
-    owl_free(instance);
-  }
-  return(filtname);
-}
-
-/* Create a filter for personal zephyrs to or from the specified
- * zephyr user.  Includes login/logout notifications for the user.
- * The name of the filter will be 'user-<user>'.  If a filter already
- * exists with this name, no new filter will be created.  This allows
- * the configuration to override this function.  Returns the name of
- * the filter, which the caller must free.
- */
-char *owl_function_zuserfilt(char *user)
-{
-  owl_filter *f;
-  char *argbuff, *longuser, *esclonguser, *shortuser, *filtname;
-
-  /* stick the local realm on if it's not there */
-  longuser=long_zuser(user);
-  shortuser=short_zuser(user);
-
-  /* name for the filter */
-  filtname=owl_sprintf("user-%s", shortuser);
-
-  /* if it already exists then go with it.  This lets users override */
-  if (owl_global_get_filter(&g, filtname)) {
-    return(owl_strdup(filtname));
-  }
-
-  /* create the new-internal filter */
-  f=owl_malloc(sizeof(owl_filter));
-
-  esclonguser = owl_text_quote(longuser, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
-
-  argbuff=owl_sprintf("( type ^zephyr$ and filter personal and "
-      "( ( direction ^in$ and sender ^%1$s$ ) or ( direction ^out$ and "
-      "recipient ^%1$s$ ) ) ) or ( ( class ^login$ ) and ( sender ^%1$s$ ) )",
-      esclonguser);
-
-  owl_filter_init_fromstring(f, filtname, argbuff);
-
-  /* add it to the global list */
-  owl_global_add_filter(&g, f);
-
-  /* free stuff */
-  owl_free(argbuff);
-  owl_free(longuser);
-  owl_free(esclonguser);
-  owl_free(shortuser);
-
-  return(filtname);
-}
-
-/* Create a filter for AIM IM messages to or from the specified
- * screenname.  The name of the filter will be 'aimuser-<user>'.  If a
- * filter already exists with this name, no new filter will be
- * created.  This allows the configuration to override this function.
- * Returns the name of the filter, which the caller must free.
- */
-char *owl_function_aimuserfilt(char *user)
-{
-  owl_filter *f;
-  char *argbuff, *filtname;
-  char *escuser;
-
-  /* name for the filter */
-  filtname=owl_sprintf("aimuser-%s", user);
-
-  /* if it already exists then go with it.  This lets users override */
-  if (owl_global_get_filter(&g, filtname)) {
-    return(owl_strdup(filtname));
-  }
-
-  /* create the new-internal filter */
-  f=owl_malloc(sizeof(owl_filter));
-
-  escuser = owl_text_quote(user, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
-
-  argbuff = owl_sprintf(
-      "( type ^aim$ and ( ( sender ^%1$s$ and recipient ^%2$s$ ) or "
-      "( sender ^%2$s$ and recipient ^%1$s$ ) ) )",
-      escuser, owl_global_get_aim_screenname_for_filters(&g));
-
-  owl_filter_init_fromstring(f, filtname, argbuff);
-
-  /* add it to the global list */
-  owl_global_add_filter(&g, f);
-
-  /* free stuff */
-  owl_free(argbuff);
-  owl_free(escuser);
-
-  return(filtname);
-}
-
-char *owl_function_typefilt(char *type)
-{
-  owl_filter *f;
-  char *argbuff, *filtname, *esctype;
-
-  /* name for the filter */
-  filtname=owl_sprintf("type-%s", type);
-
-  /* if it already exists then go with it.  This lets users override */
-  if (owl_global_get_filter(&g, filtname)) {
-    return filtname;
-  }
-
-  /* create the new-internal filter */
-  f=owl_malloc(sizeof(owl_filter));
-
-  esctype = owl_text_quote(type, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
-
-  argbuff = owl_sprintf("type ^%s$", esctype);
-
-  owl_filter_init_fromstring(f, filtname, argbuff);
-
-  /* add it to the global list */
-  owl_global_add_filter(&g, f);
-
-  /* free stuff */
-  owl_free(argbuff);
-  owl_free(esctype);
-
-  return filtname;
-}
-
-/* If flag is 1, marks for deletion.  If flag is 0,
- * unmarks for deletion. */
-void owl_function_delete_curview_msgs(int flag)
-{
-  owl_view *v;
-  int i, j;
-
-  v=owl_global_get_current_view(&g);
-  j=owl_view_get_size(v);
-  for (i=0; i<j; i++) {
-    if (flag == 1) {
-      owl_message_mark_delete(owl_view_get_element(v, i));
-    } else if (flag == 0) {
-      owl_message_unmark_delete(owl_view_get_element(v, i));
-    }
-  }
-
-  owl_function_makemsg("%i messages marked for %sdeletion", j, flag?"":"un");
-
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));  
-}
-
-/* Create a filter based on the current message.  Returns the name of
- * a filter or null.  The caller must free this name.
- *
- * if the curmsg is a personal zephyr return a filter name
- *    to the zephyr converstaion with that user.
- * If the curmsg is a zephyr class message, instance foo, recip *,
- *    return a filter name to the class, inst.
- * If the curmsg is a zephyr class message and type==0 then 
- *    return a filter name for just the class.
- * If the curmsg is a zephyr class message and type==1 then 
- *    return a filter name for the class and instance.
- * If the curmsg is a personal AIM message returna  filter
- *    name to the AIM conversation with that user 
- */
-char *owl_function_smartfilter(int type)
-{
-  owl_view *v;
-  owl_message *m;
-  char *zperson, *filtname=NULL;
-  char *argv[1];
-  
-  v=owl_global_get_current_view(&g);
-  m=owl_view_get_element(v, owl_global_get_curmsg(&g));
-
-  if (!m || owl_view_get_size(v)==0) {
-    owl_function_error("No message selected\n");
-    return(NULL);
-  }
-
-  /* very simple handling of admin messages for now */
-  if (owl_message_is_type_admin(m)) {
-    return(owl_function_typefilt("admin"));
-  }
-
-  /* very simple handling of loopback messages for now */
-  if (owl_message_is_type_loopback(m)) {
-    return(owl_function_typefilt("loopback"));
-  }
-
-  /* aim messages */
-  if (owl_message_is_type_aim(m)) {
-    if (owl_message_is_direction_in(m)) {
-      filtname=owl_function_aimuserfilt(owl_message_get_sender(m));
-    } else if (owl_message_is_direction_out(m)) {
-      filtname=owl_function_aimuserfilt(owl_message_get_recipient(m));
-    }
-    return(filtname);
-  }
-
-  /* narrow personal and login messages to the sender or recip as appropriate */
-  if (owl_message_is_type_zephyr(m)) {
-    if (owl_message_is_personal(m) || owl_message_is_loginout(m)) {
-      if (owl_message_is_direction_in(m)) {
-        zperson=short_zuser(owl_message_get_sender(m));
-      } else {
-        zperson=short_zuser(owl_message_get_recipient(m));
-      }
-      filtname=owl_function_zuserfilt(zperson);
-      owl_free(zperson);
-      return(filtname);
-    }
-
-    /* narrow class MESSAGE, instance foo, recip * messages to class, inst */
-    if (!strcasecmp(owl_message_get_class(m), "message")) {
-      filtname=owl_function_classinstfilt(owl_message_get_class(m), owl_message_get_instance(m));
-      return(filtname);
-    }
-
-    /* otherwise narrow to the class */
-    if (type==0) {
-      filtname=owl_function_classinstfilt(owl_message_get_class(m), NULL);
-    } else if (type==1) {
-      filtname=owl_function_classinstfilt(owl_message_get_class(m), owl_message_get_instance(m));
-    }
-    return(filtname);
-  }
-
-  /* pass it off to perl */
-  if(type) {
-    argv[0] = "-i";
-  };
-  return owl_perlconfig_message_call_method(m, "smartfilter", type ? 1 : 0, argv);
-}
-
-void owl_function_smartzpunt(int type)
-{
-  /* Starts a zpunt command based on the current class,instance pair. 
-   * If type=0, uses just class.  If type=1, uses instance as well. */
-  owl_view *v;
-  owl_message *m;
-  char *cmd, *cmdprefix, *mclass, *minst;
-  
-  v=owl_global_get_current_view(&g);
-  m=owl_view_get_element(v, owl_global_get_curmsg(&g));
-
-  if (!m || owl_view_get_size(v)==0) {
-    owl_function_error("No message selected\n");
-    return;
-  }
-
-  /* for now we skip admin messages. */
-  if (owl_message_is_type_admin(m)
-      || owl_message_is_loginout(m)
-      || !owl_message_is_type_zephyr(m)) {
-    owl_function_error("smartzpunt doesn't support this message type.");
-    return;
-  }
-
-  mclass = owl_message_get_class(m);
-  minst = owl_message_get_instance(m);
-  if (!mclass || !*mclass || *mclass==' '
-      || (!strcasecmp(mclass, "message") && !strcasecmp(minst, "personal"))
-      || (type && (!minst || !*minst|| *minst==' '))) {
-    owl_function_error("smartzpunt can't safely do this for <%s,%s>",
-			 mclass, minst);
-  } else {
-    cmdprefix = "start-command zpunt ";
-    cmd = owl_malloc(strlen(cmdprefix)+strlen(mclass)+strlen(minst)+10);
-    strcpy(cmd, cmdprefix);
-    strcat(cmd, owl_getquoting(mclass));
-    strcat(cmd, mclass);
-    strcat(cmd, owl_getquoting(mclass));
-    if (type) {
-      strcat(cmd, " ");
-      strcat(cmd, owl_getquoting(minst));
-      strcat(cmd, minst);
-      strcat(cmd, owl_getquoting(minst));
-    } else {
-      strcat(cmd, " *");
-    }
-    owl_function_command(cmd);
-    owl_free(cmd);
-  }
-}
-
-/* Set the color of the current view's filter to
- * be 'color'
- */
-void owl_function_color_current_filter(char *fgcolor, char *bgcolor)
-{
-  char *name;
-
-  name=owl_view_get_filtname(owl_global_get_current_view(&g));
-  owl_function_color_filter(name, fgcolor, bgcolor);
-}
-
-/* Set the color of the filter 'filter' to be 'color'.  If the color
- * name does not exist, return -1, if the filter does not exist or is
- * the "all" filter, return -2.  Return 0 on success
- */
-int owl_function_color_filter(char *filtname, char *fgcolor, char *bgcolor)
-{
-  owl_filter *f;
-
-  f=owl_global_get_filter(&g, filtname);
-  if (!f) {
-    owl_function_error("Unknown filter");
-    return(-2);
-  }
-
-  /* don't touch the all filter */
-  if (!strcmp(filtname, "all")) {
-    owl_function_error("You may not change the 'all' filter.");
-    return(-2);
-  }
-
-  if (owl_util_string_to_color(fgcolor)==OWL_COLOR_INVALID) {
-    owl_function_error("No color named '%s' avilable.", fgcolor);
-    return(-1);
-  }
-
-
-  if (bgcolor != NULL) {
-    if (owl_util_string_to_color(bgcolor)==OWL_COLOR_INVALID) {
-      owl_function_error("No color named '%s' avilable.", bgcolor);
-      return(-1);
-    }
-    owl_filter_set_bgcolor(f, owl_util_string_to_color(bgcolor));
-  }
-  owl_filter_set_fgcolor(f, owl_util_string_to_color(fgcolor));
-  
-  owl_global_set_needrefresh(&g);
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  return(0);
-}
-
-void owl_function_show_colors()
-{
-  owl_fmtext fm;
-  int i; 
-  
-  owl_fmtext_init_null(&fm);
-  owl_fmtext_append_normal(&fm, "default: ");
-  owl_fmtext_append_normal_color(&fm, "default\n", OWL_COLOR_DEFAULT, OWL_COLOR_DEFAULT);
-
-  owl_fmtext_append_normal(&fm,"red:      ");
-  owl_fmtext_append_normal_color(&fm, "red\n", OWL_COLOR_RED, OWL_COLOR_DEFAULT);
-
-  owl_fmtext_append_normal(&fm,"green:    ");
-  owl_fmtext_append_normal_color(&fm, "green\n", OWL_COLOR_GREEN, OWL_COLOR_DEFAULT);
-
-  owl_fmtext_append_normal(&fm,"yellow:   ");
-  owl_fmtext_append_normal_color(&fm, "yellow\n", OWL_COLOR_YELLOW, OWL_COLOR_DEFAULT);
-
-  owl_fmtext_append_normal(&fm,"blue:     ");
-  owl_fmtext_append_normal_color(&fm, "blue\n", OWL_COLOR_BLUE, OWL_COLOR_DEFAULT);
-
-  owl_fmtext_append_normal(&fm,"magenta:  ");
-  owl_fmtext_append_normal_color(&fm, "magenta\n", OWL_COLOR_MAGENTA, OWL_COLOR_DEFAULT);
-
-  owl_fmtext_append_normal(&fm,"cyan:     ");
-  owl_fmtext_append_normal_color(&fm, "cyan\n", OWL_COLOR_CYAN, OWL_COLOR_DEFAULT);
-
-  owl_fmtext_append_normal(&fm,"white:    ");
-  owl_fmtext_append_normal_color(&fm, "white\n", OWL_COLOR_WHITE, OWL_COLOR_DEFAULT);
-
-  for(i = 8; i < COLORS; ++i) {
-    char* str1 = owl_sprintf("%4i:     ",i);
-    char* str2 = owl_sprintf("%i\n",i);
-    owl_fmtext_append_normal(&fm,str1);
-    owl_fmtext_append_normal_color(&fm, str2, i, OWL_COLOR_DEFAULT);
-    owl_free(str1);
-     owl_free(str2);
-  }
-  
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-}
-
-/* add the given class, inst, recip to the punt list for filtering.
- *   if direction==0 then punt
- *   if direction==1 then unpunt
- */
-void owl_function_zpunt(char *class, char *inst, char *recip, int direction)
-{
-  char *buff;
-  char *quoted;
-
-  buff=owl_malloc(strlen(class)+strlen(inst)+strlen(recip)+100);
-  strcpy(buff, "class");
-  if (!strcmp(class, "*")) {
-    strcat(buff, " .*");
-  } else {
-    quoted=owl_text_quote(class, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
-    owl_text_tr(quoted, ' ', '.');
-    owl_text_tr(quoted, '\'', '.');
-    owl_text_tr(quoted, '"', '.');
-    sprintf(buff + strlen(buff), " ^(un)*%s(\\.d)*$", quoted);
-    owl_free(quoted);
-  }
-  if (!strcmp(inst, "*")) {
-    strcat(buff, " and instance .*");
-  } else {
-    quoted=owl_text_quote(inst, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
-    owl_text_tr(quoted, ' ', '.');
-    owl_text_tr(quoted, '\'', '.');
-    owl_text_tr(quoted, '"', '.');
-    sprintf(buff + strlen(buff), " and instance ^(un)*%s(\\.d)*$", quoted);
-    owl_free(quoted);
-  }
-  if (strcmp(recip, "*")) {
-    quoted=owl_text_quote(recip, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
-    owl_text_tr(quoted, ' ', '.');
-    owl_text_tr(quoted, '\'', '.');
-    owl_text_tr(quoted, '"', '.');
-    sprintf(buff + strlen(buff), " and recipient ^%s$", quoted);
-    owl_free(quoted);
-  }
-
-  owl_function_punt(buff, direction);
-  owl_free(buff);
-}
-
-void owl_function_punt(char *filter, int direction)
-{
-  owl_filter *f;
-  owl_list *fl;
-  int ret, i, j;
-  fl=owl_global_get_puntlist(&g);
-
-  /* first, create the filter */
-  f=malloc(sizeof(owl_filter));
-
-  owl_function_debugmsg("About to filter %s", filter);
-  ret=owl_filter_init_fromstring(f, "punt-filter", filter);
-  if (ret) {
-    owl_function_error("Error creating filter for zpunt");
-    owl_filter_free(f);
-    return;
-  }
-
-  /* Check for an identical filter */
-  j=owl_list_get_size(fl);
-  for (i=0; i<j; i++) {
-    if (owl_filter_equiv(f, owl_list_get_element(fl, i))) {
-      owl_function_debugmsg("found an equivalent punt filter");
-      /* if we're punting, then just silently bow out on this duplicate */
-      if (direction==0) {
-	owl_filter_free(f);
-	return;
-      }
-
-      /* if we're unpunting, then remove this filter from the puntlist */
-      if (direction==1) {
-	owl_filter_free(owl_list_get_element(fl, i));
-	owl_list_remove_element(fl, i);
-        owl_filter_free(f);
-	return;
-      }
-    }
-  }
-
-  owl_function_debugmsg("punting");
-  /* If we're punting, add the filter to the global punt list */
-  if (direction==0) {
-    owl_list_append_element(fl, f);
-  }
-}
-
-void owl_function_activate_keymap(char *keymap)
-{
-  if (!owl_keyhandler_activate(owl_global_get_keyhandler(&g), keymap)) {
-    owl_function_error("Unable to activate keymap '%s'", keymap);
-  }
-}
-
-void owl_function_show_keymaps()
-{
-  owl_list l;
-  owl_fmtext fm;
-  owl_keymap *km;
-  owl_keyhandler *kh;
-  int i, numkm;
-  char *kmname;
-
-  kh = owl_global_get_keyhandler(&g);
-  owl_fmtext_init_null(&fm);
-  owl_fmtext_append_bold(&fm, "Keymaps:   ");
-  owl_fmtext_append_normal(&fm, "(use 'show keymap <name>' for details)\n");
-  owl_keyhandler_get_keymap_names(kh, &l);
-  owl_fmtext_append_list(&fm, &l, "\n", owl_function_keymap_summary);
-  owl_fmtext_append_normal(&fm, "\n");
-
-  numkm = owl_list_get_size(&l);
-  for (i=0; i<numkm; i++) {
-    kmname = owl_list_get_element(&l, i);
-    km = owl_keyhandler_get_keymap(kh, kmname);
-    owl_fmtext_append_bold(&fm, "\n\n----------------------------------------------------------------------------------------------------\n\n");
-    owl_keymap_get_details(km, &fm);    
-  }
-  owl_fmtext_append_normal(&fm, "\n");
-  
-  owl_function_popless_fmtext(&fm);
-  owl_keyhandler_keymap_namelist_free(&l);
-  owl_fmtext_free(&fm);
-}
-
-char *owl_function_keymap_summary(char *name)
-{
-  owl_keymap *km 
-    = owl_keyhandler_get_keymap(owl_global_get_keyhandler(&g), name);
-  if (km) return owl_keymap_summary(km);
-  else return(NULL);
-}
-
-/* TODO: implement for real */
-void owl_function_show_keymap(char *name)
-{
-  owl_fmtext fm;
-  owl_keymap *km;
-
-  owl_fmtext_init_null(&fm);
-  km = owl_keyhandler_get_keymap(owl_global_get_keyhandler(&g), name);
-  if (km) {
-    owl_keymap_get_details(km, &fm);
-  } else {
-    owl_fmtext_append_normal(&fm, "No such keymap...\n");
-  }  
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-}
-
-void owl_function_help_for_command(char *cmdname)
-{
-  owl_fmtext fm;
-
-  owl_fmtext_init_null(&fm);
-  owl_cmd_get_help(owl_global_get_cmddict(&g), cmdname, &fm);
-  owl_function_popless_fmtext(&fm);  
-  owl_fmtext_free(&fm);
-}
-
-void owl_function_search_start(char *string, int direction)
-{
-  /* direction is OWL_DIRECTION_DOWNWARDS or OWL_DIRECTION_UPWARDS */
-  owl_global_set_search_active(&g, string);
-  owl_function_search_helper(0, direction);
-}
-
-void owl_function_search_continue(int direction)
-{
-  /* direction is OWL_DIRECTION_DOWNWARDS or OWL_DIRECTION_UPWARDS */
-  owl_function_search_helper(1, direction);
-}
-
-void owl_function_search_helper(int mode, int direction)
-{
-  /* move to a message that contains the string.  If direction is
-   * OWL_DIRECTION_DOWNWARDS then search fowards, if direction is
-   * OWL_DIRECTION_UPWARDS then search backwards.
-   *
-   * If mode==0 then it will stay on the current message if it
-   * contains the string.
-   */
-
-  owl_view *v;
-  int viewsize, i, curmsg, start;
-  owl_message *m;
-
-  v=owl_global_get_current_view(&g);
-  viewsize=owl_view_get_size(v);
-  curmsg=owl_global_get_curmsg(&g);
-  
-  if (viewsize==0) {
-    owl_function_error("No messages present");
-    return;
-  }
-
-  if (mode==0) {
-    start=curmsg;
-  } else if (direction==OWL_DIRECTION_DOWNWARDS) {
-    start=curmsg+1;
-  } else {
-    start=curmsg-1;
-  }
-
-  /* bounds check */
-  if (start>=viewsize || start<0) {
-    owl_function_error("No further matches found");
-    return;
-  }
-
-  for (i=start; i<viewsize && i>=0;) {
-    m=owl_view_get_element(v, i);
-    if (owl_message_search(m, owl_global_get_search_string(&g))) {
-      owl_global_set_curmsg(&g, i);
-      owl_function_calculate_topmsg(direction);
-      owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-      if (direction==OWL_DIRECTION_DOWNWARDS) {
-	owl_global_set_direction_downwards(&g);
-      } else {
-	owl_global_set_direction_upwards(&g);
-      }
-      return;
-    }
-    if (direction==OWL_DIRECTION_DOWNWARDS) {
-      i++;
-    } else {
-      i--;
-    }
-  }
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  owl_function_error("No matches found");
-}
-
-/* strips formatting from ztext and returns the unformatted text. 
- * caller is responsible for freeing. */
-char *owl_function_ztext_stylestrip(char *zt)
-{
-  owl_fmtext fm;
-  char *plaintext;
-
-  owl_fmtext_init_null(&fm);
-  owl_fmtext_append_ztext(&fm, zt);
-  plaintext = owl_fmtext_print_plain(&fm);
-  owl_fmtext_free(&fm);
-  return(plaintext);
-}
-
-/* Popup a buddylisting.  If filename is NULL use the default .anyone */
-void owl_function_buddylist(int aim, int zephyr, char *filename)
-{
-  int i, j, x, idle;
-  owl_fmtext fm;
-  owl_buddylist *bl;
-  owl_buddy *b;
-  owl_list anyone;
-  char *foo, *timestr;
-#ifdef HAVE_LIBZEPHYR
-  char *tmp, *user, *line;
-  ZLocations_t location[200];
-  int numlocs, ret;
-#endif
-
-  owl_fmtext_init_null(&fm);
-
-  /* AIM first */
-  if (aim && owl_global_is_aimloggedin(&g)) {
-    bl=owl_global_get_buddylist(&g);
-
-    owl_fmtext_append_bold(&fm, "AIM users logged in:\n");
-    /* we're assuming AIM for now */
-    j=owl_buddylist_get_size(bl);
-    for (i=0; i<j; i++) {
-      b=owl_buddylist_get_buddy_n(bl, i);
-      idle=owl_buddy_get_idle_time(b);
-      if (idle!=0) {
-	timestr=owl_util_minutes_to_timestr(idle);
-      } else {
-	timestr=owl_strdup("");
-      }
-      foo=owl_sprintf("  %-20.20s %-12.12s\n", owl_buddy_get_name(b), timestr);
-      owl_fmtext_append_normal(&fm, foo);
-      owl_free(timestr);
-      owl_free(foo);
-    }
-  }
-
-#ifdef HAVE_LIBZEPHYR
-  if (zephyr) {
-    if(!owl_global_is_havezephyr(&g)) {
-      owl_function_error("Zephyr currently not available.");
-    } else {
-      owl_fmtext_append_bold(&fm, "Zephyr users logged in:\n");
-      owl_list_create(&anyone);
-      ret=owl_zephyr_get_anyone_list(&anyone, filename);
-      if (ret) {
-        owl_fmtext_append_normal(&fm, "  Error opening file for zephyr buddies.\n");
-      } else {
-        j=owl_list_get_size(&anyone);
-        for (i=0; i<j; i++) {
-          user=owl_list_get_element(&anyone, i);
-          ret=ZLocateUser(user, &numlocs, ZAUTH);
-          if (ret!=ZERR_NONE) {
-            owl_function_error("Error getting location for %s", user);
-            continue;
-          }
-
-          numlocs=200;
-          ret=ZGetLocations(location, &numlocs);
-          if (ret==0) {
-            for (x=0; x<numlocs; x++) {
-              line=owl_malloc(strlen(location[x].host)+strlen(location[x].time)+strlen(location[x].tty)+100);
-              tmp=short_zuser(user);
-              sprintf(line, "  %-10.10s %-24.24s %-12.12s  %20.20s\n",
-                      tmp,
-                      location[x].host,
-                      location[x].tty,
-                      location[x].time);
-              owl_fmtext_append_normal(&fm, line);
-              owl_free(tmp);
-              owl_free(line);
-            }
-            if (numlocs>=200) {
-              owl_fmtext_append_normal(&fm, "  Too many locations found for this user, truncating.\n");
-            }
-          }
-        }
-      }
-      owl_list_free_all(&anyone, owl_free);
-    } 
-  }
-#endif
-
-  if(aim && zephyr) {
-      if(owl_perlconfig_is_function("BarnOwl::Hooks::_get_blist")) {
-          char * perlblist = owl_perlconfig_execute("BarnOwl::Hooks::_get_blist()");
-          if(perlblist) {
-              owl_fmtext_append_ztext(&fm, perlblist);
-              owl_free(perlblist);
-          }
-      }
-  }
-  
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-}
-
-/* Dump messages in the current view to the file 'filename'. */
-void owl_function_dump(char *filename) 
-{
-  int i, j, count;
-  owl_message *m;
-  owl_view *v;
-  FILE *file;
-  char *plaintext;
-
-  v=owl_global_get_current_view(&g);
-
-  /* in the future make it ask yes/no */
-  /*
-  ret=stat(filename, &sbuf);
-  if (!ret) {
-    ret=owl_function_askyesno("File exists, continue? [Y/n]");
-    if (!ret) return;
-  }
-  */
-
-  file=fopen(filename, "w");
-  if (!file) {
-    owl_function_error("Error opening file");
-    return;
-  }
-
-  count=0;
-  j=owl_view_get_size(v);
-  for (i=0; i<j; i++) {
-    m=owl_view_get_element(v, i);
-    plaintext = owl_strip_format_chars(owl_message_get_text(m));
-    if (plaintext) {
-      fputs(plaintext, file);
-      owl_free(plaintext);
-    }
-  }
-  fclose(file);
-  owl_function_makemsg("Messages dumped to %s", filename);
-}
-
-void owl_function_do_newmsgproc(void)
-{
-  if (owl_global_get_newmsgproc(&g) && strcmp(owl_global_get_newmsgproc(&g), "")) {
-    /* if there's a process out there, we need to check on it */
-    if (owl_global_get_newmsgproc_pid(&g)) {
-      owl_function_debugmsg("Checking on newmsgproc pid==%i", owl_global_get_newmsgproc_pid(&g));
-      owl_function_debugmsg("Waitpid return is %i", waitpid(owl_global_get_newmsgproc_pid(&g), NULL, WNOHANG));
-      waitpid(owl_global_get_newmsgproc_pid(&g), NULL, WNOHANG);
-      if (waitpid(owl_global_get_newmsgproc_pid(&g), NULL, WNOHANG)==-1) {
-	/* it exited */
-	owl_global_set_newmsgproc_pid(&g, 0);
-	owl_function_debugmsg("newmsgproc exited");
-      } else {
-	owl_function_debugmsg("newmsgproc did not exit");
-      }
-    }
-    
-    /* if it exited, fork & exec a new one */
-    if (owl_global_get_newmsgproc_pid(&g)==0) {
-      int i, myargc;
-      i=fork();
-      if (i) {
-	/* parent set the child's pid */
-	owl_global_set_newmsgproc_pid(&g, i);
-	owl_function_debugmsg("I'm the parent and I started a new newmsgproc with pid %i", i);
-      } else {
-	/* child exec's the program */
-	char **parsed;
-	parsed=owl_parseline(owl_global_get_newmsgproc(&g), &myargc);
-	if (myargc < 0) {
-	  owl_function_debugmsg("Could not parse newmsgproc '%s': unbalanced quotes?", owl_global_get_newmsgproc(&g));
-	}
-	if (myargc <= 0) {
-	  _exit(127);
-	}
-	parsed=owl_realloc(parsed, sizeof(*parsed) * (myargc+1));
-	parsed[myargc] = NULL;
-	
-	owl_function_debugmsg("About to exec \"%s\" with %d arguments", parsed[0], myargc);
-	
-	execvp(parsed[0], parsed);
-	
-	
-	/* was there an error exec'ing? */
-	owl_function_debugmsg("Cannot run newmsgproc '%s': cannot exec '%s': %s", 
-			      owl_global_get_newmsgproc(&g), parsed[0], strerror(errno));
-	_exit(127);
-      }
-    }
-  }
-}
-
-/* print the xterm escape sequence to raise the window */
-void owl_function_xterm_raise(void)
-{
-  printf("\033[5t");
-}
-
-/* print the xterm escape sequence to deiconify the window */
-void owl_function_xterm_deiconify(void)
-{
-  printf("\033[1t");
-}
-
-/* Add the specified command to the startup file.  Eventually this
- * should be clever, and rewriting settings that will obviosly
- * override earlier settings with 'set' 'bindkey' and 'alias'
- * commands.  For now though we just remove any line that would
- * duplicate this one and then append this line to the end of
- * startupfile.
- */
-void owl_function_addstartup(char *buff)
-{
-  FILE *file;
-  char *filename;
-
-  filename=owl_global_get_startupfile(&g);
-  file=fopen(filename, "a");
-  if (!file) {
-    owl_function_error("Error opening startupfile for new command");
-    return;
-  }
-
-  /* delete earlier copies */
-  owl_util_file_deleteline(filename, buff, 1);
-
-  /* add this line */
-  fprintf(file, "%s\n", buff);
-
-  fclose(file);
-}
-
-/* Remove the specified command from the startup file. */
-void owl_function_delstartup(char *buff)
-{
-  char *filename;
-  filename=owl_global_get_startupfile(&g);
-  owl_util_file_deleteline(filename, buff, 1);
-}
-
-/* Execute owl commands from the given filename.  If the filename
- * is NULL, use the default owl startup commands file.
- */
-void owl_function_source(char *filename)
-{
-  FILE *file;
-  char buff[LINE];
-  int fail_silent = 0;
-
-  if (!filename) {
-    fail_silent = 1;
-    filename=owl_global_get_startupfile(&g);
-  }
-  file=fopen(filename, "r");
-  if (!file) {
-    if (!fail_silent) {
-      owl_function_error("Error opening file: %s", filename);
-    }
-    return;
-  }
-  while (fgets(buff, LINE, file)!=NULL) {
-    if (buff[0] == '#') continue;
-    buff[strlen(buff)-1]='\0';
-    owl_function_command(buff);
-  }
-  fclose(file);
-}
-
-void owl_function_change_style(owl_view *v, char *stylename)
-{
-  owl_style *s;
-
-  s=owl_global_get_style_by_name(&g, stylename);
-  if (!s) {
-    owl_function_error("No style named %s", stylename);
-    return;
-  }
-  owl_view_set_style(v, s);
-  owl_messagelist_invalidate_formats(owl_global_get_msglist(&g));
-  owl_function_calculate_topmsg(OWL_DIRECTION_DOWNWARDS);
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-}
-
-void owl_function_toggleoneline()
-{
-  owl_view *v;
-  owl_style *s;
-
-  v=owl_global_get_current_view(&g);
-  s=owl_view_get_style(v);
-
-  if (!owl_style_matches_name(s, "oneline")) {
-    owl_function_change_style(v, "oneline");
-  } else {
-    owl_function_change_style(v, owl_global_get_default_style(&g));
-  }
-
-  owl_messagelist_invalidate_formats(owl_global_get_msglist(&g));
-  owl_function_calculate_topmsg(OWL_DIRECTION_DOWNWARDS);
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-}
-
-void owl_function_error(char *fmt, ...)
-{
-  va_list ap;
-  char buff[2048], buff2[2048];
-  char *date;
-  time_t now;
-
-  now=time(NULL);
-  date=owl_strdup(ctime(&now));
-  date[strlen(date)-1]='\0';
-
-  va_start(ap, fmt);
-
-  vsnprintf(buff, 2048, fmt, ap);
-  sprintf(buff2, "%s %s", date, buff);
-  owl_function_debugmsg("ERROR: %s", buff);
-  if (owl_global_get_curs_msgwin(&g)) {
-    werase(owl_global_get_curs_msgwin(&g));
-    waddstr(owl_global_get_curs_msgwin(&g), buff);  
-    wnoutrefresh(owl_global_get_curs_msgwin(&g));
-    owl_global_set_needrefresh(&g);
-  }
-  owl_errqueue_append_err(owl_global_get_errqueue(&g), buff2);
-  va_end(ap);
-  owl_free(date);
-}
-
-void owl_function_showerrs()
-{
-  owl_fmtext fm;
-
-  owl_fmtext_init_null(&fm);
-  owl_fmtext_append_normal(&fm, "Errors:\n\n");
-  owl_errqueue_to_fmtext(owl_global_get_errqueue(&g), &fm);
-  owl_function_popless_fmtext(&fm);
-}
-
-void owl_function_makemsg(char *fmt, ...)
-{
-  va_list ap;
-  char buff[2048];
-
-  if (!owl_global_get_curs_msgwin(&g)) return;
-
-  va_start(ap, fmt);
-  werase(owl_global_get_curs_msgwin(&g));
-  
-  vsnprintf(buff, 2048, fmt, ap);
-  owl_function_debugmsg("makemsg: %s", buff);
-  waddstr(owl_global_get_curs_msgwin(&g), buff);  
-  wnoutrefresh(owl_global_get_curs_msgwin(&g));
-  owl_global_set_needrefresh(&g);
-  va_end(ap);
-}
-
-/* get locations for everyone in .anyone.  If 'notify' is '1' then
- * send a pseudo login or logout message for everyone not in sync with
- * the global zephyr buddy list.  The list is updated regardless of
- * the status of 'notify'.
- */
-void owl_function_zephyr_buddy_check(int notify)
-{
-#ifdef HAVE_LIBZEPHYR
-  int i, j;
-  owl_list anyone;
-  owl_message *m;
-  owl_zbuddylist *zbl;
-  char *user;
-  ZLocations_t location[200];
-  int numlocs, ret;
-
-  zbl=owl_global_get_zephyr_buddylist(&g);
-
-  owl_list_create(&anyone);
-  ret=owl_zephyr_get_anyone_list(&anyone, NULL);
-
-  j=owl_list_get_size(&anyone);
-  for (i=0; i<j; i++) {
-    user=owl_list_get_element(&anyone, i);
-    ret=ZLocateUser(user, &numlocs, ZAUTH);
-    if (ret!=ZERR_NONE) {
-      owl_function_error("Error getting location for %s", user);
-      continue;
-    }
-    numlocs=200;
-    ret=ZGetLocations(location, &numlocs);
-    if (ret==0) {
-      if ((numlocs>0) && !owl_zbuddylist_contains_user(zbl, user)) {
-	/* Send a PSEUDO LOGIN! */
-	if (notify) {
-	  m=owl_malloc(sizeof(owl_message));
-	  owl_message_create_pseudo_zlogin(m, 0, user, location[0].host, location[0].time, location[0].tty);
-	  owl_global_messagequeue_addmsg(&g, m);
-	}
-	owl_zbuddylist_adduser(zbl, user);
-	owl_function_debugmsg("owl_function_zephyr_buddy_check: login for %s ", user);
-      } else if ((numlocs==0) && owl_zbuddylist_contains_user(zbl, user)) {
-	/* I don't think this ever happens (if there are 0 locations we should get an error from
-	 * ZGetLocations)
-	 */
-	owl_function_error("owl_function_zephyr_buddy_check: exceptional case logout for %s ",user);
-      }
-    } else if ((ret==ZERR_NOLOCATIONS) && owl_zbuddylist_contains_user(zbl, user)) {
-      /* Send a PSEUDO LOGOUT! */
-      if (notify) {
-	m=owl_malloc(sizeof(owl_message));
-	owl_message_create_pseudo_zlogin(m, 1, user, "", "", "");
-	owl_global_messagequeue_addmsg(&g, m);
-      }
-      owl_zbuddylist_deluser(zbl, user);
-      owl_function_debugmsg("owl_function_zephyr_buddy_check: logout for %s ",user);
-    }
-  }
-
-  owl_list_free_all(&anyone, owl_free);
-#endif
-}
-
-void owl_function_aimsearch_results(char *email, owl_list *namelist)
-{
-  owl_fmtext fm;
-  int i, j;
-
-  owl_fmtext_init_null(&fm);
-  owl_fmtext_append_normal(&fm, "AIM screennames associated with ");
-  owl_fmtext_append_normal(&fm, email);
-  owl_fmtext_append_normal(&fm, ":\n");
-
-  j=owl_list_get_size(namelist);
-  for (i=0; i<j; i++) {
-    owl_fmtext_append_normal(&fm, "  ");
-    owl_fmtext_append_normal(&fm, owl_list_get_element(namelist, i));
-    owl_fmtext_append_normal(&fm, "\n");
-  }
-
-  owl_function_popless_fmtext(&fm);
-  owl_fmtext_free(&fm);
-}
-
-int owl_function_get_color_count()
-{
-     return COLORS;
-}
Index: ib_compat.c
===================================================================
--- glib_compat.c	(revision 731dd1eae56c676c26e76bfa6f93f649afb529ab)
+++ 	(revision )
@@ -1,18 +1,0 @@
-#include "owl.h"
-
-#if (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION < 14)
-/* Our own implementation of g_unichar_is_mark for glib versions that
-   are too old to have one. */
-int g_unichar_ismark(gunichar ucs)
-{
-  GUnicodeType t = g_unichar_type(ucs);
-  switch (t) {
-  case G_UNICODE_NON_SPACING_MARK:
-  case G_UNICODE_COMBINING_MARK:
-  case G_UNICODE_ENCLOSING_MARK:
-       return 1;
-  default:
-       return 0;
-  }
-}
-#endif
Index: obal.c
===================================================================
--- global.c	(revision 5547211b2a49e2fe6b405d8b72af6474b2a7b1a6)
+++ 	(revision )
@@ -1,969 +1,0 @@
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <netdb.h>
-#include <termios.h>
-#include <sys/ioctl.h>
-#include <time.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 256
-#endif
-
-void owl_global_init(owl_global *g) {
-  struct hostent *hent;
-  char hostname[MAXHOSTNAMELEN];
-  char *cd;
-
-  g->malloced=0;
-  g->freed=0;
-
-  gethostname(hostname, MAXHOSTNAMELEN);
-  hent=gethostbyname(hostname);
-  if (!hent) {
-    g->thishost=owl_strdup("localhost");
-  } else {
-    g->thishost=owl_strdup(hent->h_name);
-  }
-
-  owl_context_init(&g->ctx);
-  owl_context_set_startup(&g->ctx);
-  g->curmsg=0;
-  g->topmsg=0;
-  g->needrefresh=1;
-  g->startupargs=NULL;
-
-  owl_variable_dict_setup(&(g->vars));
-  owl_cmddict_setup(&(g->cmds));
-
-  g->lines=LINES;
-  g->cols=COLS;
-
-  g->rightshift=0;
-
-  owl_editwin_init(&(g->tw), NULL, owl_global_get_typwin_lines(g), g->cols, OWL_EDITWIN_STYLE_ONELINE, NULL);
-
-  owl_keyhandler_init(&g->kh);
-  owl_keys_setup_keymaps(&g->kh);
-
-  owl_list_create(&(g->muxevents));
-  owl_list_create(&(g->filterlist));
-  owl_list_create(&(g->puntlist));
-  owl_list_create(&(g->messagequeue));
-  owl_dict_create(&(g->styledict));
-  g->curmsg_vert_offset=0;
-  g->resizepending=0;
-  g->typwinactive=0;
-  g->direction=OWL_DIRECTION_DOWNWARDS;
-  g->zaway=0;
-  if (has_colors()) {
-    g->hascolors=1;
-  }
-  g->colorpairs=COLOR_PAIRS;
-  owl_fmtext_init_colorpair_mgr(&(g->cpmgr));
-  g->debug=OWL_DEBUG;
-  g->searchactive=0;
-  g->searchstring=NULL;
-  g->starttime=time(NULL); /* assumes we call init only a start time */
-  g->lastinputtime=g->starttime;
-  g->newmsgproc_pid=0;
-  
-  owl_global_set_config_format(g, 0);
-  owl_global_set_userclue(g, OWL_USERCLUE_NONE);
-  owl_global_set_no_have_config(g);
-  owl_history_init(&(g->msghist));
-  owl_history_init(&(g->cmdhist));
-  owl_history_set_norepeats(&(g->cmdhist));
-  g->nextmsgid=0;
-
-  _owl_global_setup_windows(g);
-
-  /* Fill in some variables which don't have constant defaults */
-  /* TODO: come back later and check passwd file first */
-  g->homedir=owl_strdup(getenv("HOME"));
-
-  g->confdir = NULL;
-  g->startupfile = NULL;
-  cd = owl_sprintf("%s/%s", g->homedir, OWL_CONFIG_DIR);
-  owl_global_set_confdir(g, cd);
-  owl_free(cd);
-
-  owl_messagelist_create(&(g->msglist));
-  owl_mainwin_init(&(g->mw));
-  owl_popwin_init(&(g->pw));
-
-  g->aim_screenname=NULL;
-  g->aim_screenname_for_filters=NULL;
-  g->aim_loggedin=0;
-  owl_timer_create_countdown(&(g->aim_noop_timer), 30);
-  owl_timer_create_countdown(&(g->aim_ignorelogin_timer), 0);
-  owl_timer_create_countdown(&(g->aim_buddyinfo_timer), 60);
-  owl_buddylist_init(&(g->buddylist));
-    
-  g->havezephyr=0;
-  g->haveaim=0;
-  owl_global_set_no_doaimevents(g);
-
-  owl_errqueue_init(&(g->errqueue));
-  g->got_err_signal=0;
-
-  owl_zbuddylist_create(&(g->zbuddies));
-  owl_timer_create_countdown(&(g->zephyr_buddycheck_timer), 60*3);
-
-  owl_obarray_init(&(g->obarray));
-
-  owl_message_init_fmtext_cache();
-  owl_list_create(&(g->dispatchlist));
-}
-
-void _owl_global_setup_windows(owl_global *g) {
-  int cols, typwin_lines;
-
-  cols=g->cols;
-  typwin_lines=owl_global_get_typwin_lines(g);
-
-  /* set the new window sizes */
-  g->recwinlines=g->lines-(typwin_lines+2);
-  if (g->recwinlines<0) {
-    /* gotta deal with this */
-    g->recwinlines=0;
-  }
-
-  owl_function_debugmsg("_owl_global_setup_windows: about to call newwin(%i, %i, 0, 0)\n", g->recwinlines, cols);
-
-  /* create the new windows */
-  g->recwin=newwin(g->recwinlines, cols, 0, 0);
-  if (g->recwin==NULL) {
-    owl_function_debugmsg("_owl_global_setup_windows: newwin returned NULL\n");
-    endwin();
-    exit(50);
-  }
-      
-  g->sepwin=newwin(1, cols, g->recwinlines, 0);
-  g->msgwin=newwin(1, cols, g->recwinlines+1, 0);
-  g->typwin=newwin(typwin_lines, cols, g->recwinlines+2, 0);
-
-  owl_editwin_set_curswin(&(g->tw), g->typwin, typwin_lines, g->cols);
-
-  idlok(g->typwin, FALSE);
-  idlok(g->recwin, FALSE);
-  idlok(g->sepwin, FALSE);
-  idlok(g->msgwin, FALSE);
-
-  nodelay(g->typwin, 1);
-  keypad(g->typwin, TRUE);
-  wmove(g->typwin, 0, 0);
-
-  meta(g->typwin, TRUE);
-}
-
-owl_context *owl_global_get_context(owl_global *g) {
-  return(&g->ctx);
-}
-			 
-int owl_global_get_lines(owl_global *g) {
-  return(g->lines);
-}
-
-int owl_global_get_cols(owl_global *g) {
-  return(g->cols);
-}
-
-int owl_global_get_recwin_lines(owl_global *g) {
-  return(g->recwinlines);
-}
-
-/* curmsg */
-
-int owl_global_get_curmsg(owl_global *g) {
-  return(g->curmsg);
-}
-
-void owl_global_set_curmsg(owl_global *g, int i) {
-  g->curmsg=i;
-  /* we will reset the vertical offset from here */
-  /* we might want to move this out to the functions later */
-  owl_global_set_curmsg_vert_offset(g, 0);
-}
-
-/* topmsg */
-
-int owl_global_get_topmsg(owl_global *g) {
-  return(g->topmsg);
-}
-
-void owl_global_set_topmsg(owl_global *g, int i) {
-  g->topmsg=i;
-}
-
-/* windows */
-
-owl_mainwin *owl_global_get_mainwin(owl_global *g) {
-  return(&(g->mw));
-}
-
-owl_popwin *owl_global_get_popwin(owl_global *g) {
-  return(&(g->pw));
-}
-
-/* msglist */
-
-owl_messagelist *owl_global_get_msglist(owl_global *g) {
-  return(&(g->msglist));
-}
-
-/* keyhandler */
-
-owl_keyhandler *owl_global_get_keyhandler(owl_global *g) {
-  return(&(g->kh));
-}
-
-/* curses windows */
-
-WINDOW *owl_global_get_curs_recwin(owl_global *g) {
-  return(g->recwin);
-}
-
-WINDOW *owl_global_get_curs_sepwin(owl_global *g) {
-  return(g->sepwin);
-}
-
-WINDOW *owl_global_get_curs_msgwin(owl_global *g) {
-  return(g->msgwin);
-}
-
-WINDOW *owl_global_get_curs_typwin(owl_global *g) {
-  return(g->typwin);
-}
-
-/* typwin */
-
-owl_editwin *owl_global_get_typwin(owl_global *g) {
-  return(&(g->tw));
-}
-
-/* buffercommand */
-
-void owl_global_set_buffercommand(owl_global *g, char *command) {
-  owl_editwin_set_command(owl_global_get_typwin(g), command);
-}
-
-char *owl_global_get_buffercommand(owl_global *g) {
-  return owl_editwin_get_command(owl_global_get_typwin(g));
-}
-
-void owl_global_set_buffercallback(owl_global *g, void (*cb)(owl_editwin*)) {
-  owl_editwin_set_callback(owl_global_get_typwin(g), cb);
-}
-
-void (*owl_global_get_buffercallback(owl_global *g))(owl_editwin*) {
-  return owl_editwin_get_callback(owl_global_get_typwin(g));
-}
-
-/* refresh */
-
-int owl_global_is_needrefresh(owl_global *g) {
-  if (g->needrefresh==1) return(1);
-  return(0);
-}
-
-void owl_global_set_needrefresh(owl_global *g) {
-  g->needrefresh=1;
-}
-
-void owl_global_set_noneedrefresh(owl_global *g) {
-  g->needrefresh=0;
-}
-
-/* variable dictionary */
-
-owl_vardict *owl_global_get_vardict(owl_global *g) {
-  return &(g->vars);
-}
-
-/* command dictionary */
-
-owl_cmddict *owl_global_get_cmddict(owl_global *g) {
-  return &(g->cmds);
-}
-
-/* rightshift */
-
-void owl_global_set_rightshift(owl_global *g, int i) {
-  g->rightshift=i;
-}
-
-int owl_global_get_rightshift(owl_global *g) {
-  return(g->rightshift);
-}
-
-/* typwin */
-
-int owl_global_is_typwin_active(owl_global *g) {
-  if (g->typwinactive==1) return(1);
-  return(0);
-}
-
-void owl_global_set_typwin_active(owl_global *g) {
-  int d = owl_global_get_typewindelta(g);
-  if (d > 0)
-      owl_function_resize_typwin(owl_global_get_typwin_lines(g) + d);
-
-  g->typwinactive=1;
-}
-
-void owl_global_set_typwin_inactive(owl_global *g) {
-  int d = owl_global_get_typewindelta(g);
-  if (d > 0)
-      owl_function_resize_typwin(owl_global_get_typwin_lines(g) - d);
-
-  g->typwinactive=0;
-}
-
-/* resize */
-
-void owl_global_set_resize_pending(owl_global *g) {
-  g->resizepending=1;
-}
-
-char *owl_global_get_homedir(owl_global *g) {
-  if (g->homedir) return(g->homedir);
-  return("/");
-}
-
-char *owl_global_get_confdir(owl_global *g) {
-  if (g->confdir) return(g->confdir);
-  return("/");
-}
-
-/*
- * Setting this also sets startupfile to confdir/startup
- */
-void owl_global_set_confdir(owl_global *g, char *cd) {
-  free(g->confdir);
-  g->confdir = owl_strdup(cd);
-  free(g->startupfile);
-  g->startupfile = owl_sprintf("%s/startup", cd);
-}
-
-char *owl_global_get_startupfile(owl_global *g) {
-  if(g->startupfile) return(g->startupfile);
-  return("/");
-}
-
-int owl_global_get_direction(owl_global *g) {
-  return(g->direction);
-}
-
-void owl_global_set_direction_downwards(owl_global *g) {
-  g->direction=OWL_DIRECTION_DOWNWARDS;
-}
-
-void owl_global_set_direction_upwards(owl_global *g) {
-  g->direction=OWL_DIRECTION_UPWARDS;
-}
-
-/* perl stuff */
-
-void owl_global_set_perlinterp(owl_global *g, void *p) {
-  g->perl=p;
-}
-
-void *owl_global_get_perlinterp(owl_global *g) {
-  return(g->perl);
-}
-
-int owl_global_is_config_format(owl_global *g) {
-  if (g->config_format) return(1);
-  return(0);
-}
-
-void owl_global_set_config_format(owl_global *g, int state) {
-  if (state==1) {
-    g->config_format=1;
-  } else {
-    g->config_format=0;
-  }
-}
-
-void owl_global_set_have_config(owl_global *g) {
-  g->haveconfig=1;
-}
-
-void owl_global_set_no_have_config(owl_global *g) {
-  g->haveconfig=0;
-}
-
-int owl_global_have_config(owl_global *g) {
-  if (g->haveconfig) return(1);
-  return(0);
-}
-
-void owl_global_resize(owl_global *g, int x, int y) {
-  /* resize the screen.  If x or y is 0 use the terminal size */
-  struct winsize size;
-    
-  if (!g->resizepending) return;
-
-  /* delete the current windows */
-  delwin(g->recwin);
-  delwin(g->sepwin);
-  delwin(g->msgwin);
-  delwin(g->typwin);
-  if (!isendwin()) {
-    endwin();
-  }
-
-  refresh();
-
-  /* get the new size */
-  ioctl(STDIN_FILENO, TIOCGWINSZ, &size);
-  if (x==0) {
-    if (size.ws_row) {
-      g->lines=size.ws_row;
-    } else {
-      g->lines=LINES;
-    } 
-  } else {
-      g->lines=x;
-  }
-
-  if (y==0) {
-    if (size.ws_col) {
-      g->cols=size.ws_col;
-    } else {
-      g->cols=COLS;
-    } 
-  } else {
-    g->cols=y;
-  }
-
-#ifdef HAVE_RESIZETERM
-  resizeterm(size.ws_row, size.ws_col);
-#endif
-
-  /* re-initialize the windows */
-  _owl_global_setup_windows(g);
-
-  /* in case any styles rely on the current width */
-  owl_messagelist_invalidate_formats(owl_global_get_msglist(g));
-
-  /* recalculate the topmsg to make sure the current message is on
-   * screen */
-  owl_function_calculate_topmsg(OWL_DIRECTION_NONE);
-
-  /* refresh stuff */
-  g->needrefresh=1;
-  owl_mainwin_redisplay(&(g->mw));
-  sepbar(NULL);
-  owl_editwin_redisplay(&(g->tw), 0);
-  owl_function_full_redisplay(&g);
-
-  /* TODO: this should handle other forms of popwins */
-  if (owl_popwin_is_active(owl_global_get_popwin(g)) 
-      && owl_global_get_viewwin(g)) {
-    owl_popwin_refresh(owl_global_get_popwin(g));
-    owl_viewwin_redisplay(owl_global_get_viewwin(g), 0);
-  }
-
-  owl_function_debugmsg("New size is %i lines, %i cols.", size.ws_row, size.ws_col);
-  owl_function_makemsg("");
-  g->resizepending=0;
-}
-
-/* debug */
-
-int owl_global_is_debug_fast(owl_global *g) {
-  if (g->debug) return(1);
-  return(0);
-}
-
-/* starttime */
-
-time_t owl_global_get_starttime(owl_global *g) {
-  return(g->starttime);
-}
-
-time_t owl_global_get_runtime(owl_global *g) {
-  return(time(NULL)-g->starttime);
-}
-
-time_t owl_global_get_lastinputtime(owl_global *g) {
-  return(g->lastinputtime);
-}
-
-void owl_global_set_lastinputtime(owl_global *g, time_t time) {
-  g->lastinputtime = time;
-}
-
-time_t owl_global_get_idletime(owl_global *g) {
-  return(time(NULL)-g->lastinputtime);
-}
-
-void owl_global_get_runtime_string(owl_global *g, char *buff) {
-  time_t diff;
-
-  diff=time(NULL)-owl_global_get_starttime(g);
-
-  /* print something nicer later */   
-  sprintf(buff, "%i seconds", (int) diff);
-}
-
-char *owl_global_get_hostname(owl_global *g) {
-  if (g->thishost) return(g->thishost);
-  return("");
-}
-
-/* userclue */
-
-void owl_global_set_userclue(owl_global *g, int clue) {
-  g->userclue=clue;
-}
-
-void owl_global_add_userclue(owl_global *g, int clue) {
-  g->userclue|=clue;
-}
-
-int owl_global_get_userclue(owl_global *g) {
-  return(g->userclue);
-}
-
-int owl_global_is_userclue(owl_global *g, int clue) {
-  if (g->userclue & clue) return(1);
-  return(0);
-}
-
-/* viewwin */
-
-owl_viewwin *owl_global_get_viewwin(owl_global *g) {
-  return(&(g->vw));
-}
-
-
-/* vert offset */
-
-int owl_global_get_curmsg_vert_offset(owl_global *g) {
-  return(g->curmsg_vert_offset);
-}
-
-void owl_global_set_curmsg_vert_offset(owl_global *g, int i) {
-  g->curmsg_vert_offset=i;
-}
-
-/* startup args */
-
-void owl_global_set_startupargs(owl_global *g, int argc, char **argv) {
-  int i, len;
-
-  if (g->startupargs) owl_free(g->startupargs);
-  
-  len=0;
-  for (i=0; i<argc; i++) {
-    len+=strlen(argv[i])+5;
-  }
-  g->startupargs=owl_malloc(len+5);
-
-  strcpy(g->startupargs, "");
-  for (i=0; i<argc; i++) {
-    sprintf(g->startupargs + strlen(g->startupargs), "%s ", argv[i]);
-  }
-  g->startupargs[strlen(g->startupargs)-1]='\0';
-}
-
-char *owl_global_get_startupargs(owl_global *g) {
-  if (g->startupargs) return(g->startupargs);
-  return("");
-}
-
-/* history */
-
-owl_history *owl_global_get_msg_history(owl_global *g) {
-  return(&(g->msghist));
-}
-
-owl_history *owl_global_get_cmd_history(owl_global *g) {
-  return(&(g->cmdhist));
-}
-
-/* muxevents */
-
-owl_muxevents *owl_global_get_muxevents(owl_global *g) {
-  return(&(g->muxevents));
-}
-
-/* filterlist */
-
-owl_list *owl_global_get_filterlist(owl_global *g) {
-  return(&(g->filterlist));
-}
-
-owl_filter *owl_global_get_filter(owl_global *g, char *name) {
-  int i, j;
-  owl_filter *f;
-
-  j=owl_list_get_size(&(g->filterlist));
-  for (i=0; i<j; i++) {
-    f=owl_list_get_element(&(g->filterlist), i);
-    if (!strcmp(name, owl_filter_get_name(f))) {
-      return(f);
-    }
-  }
-  return(NULL);
-}
-
-void owl_global_add_filter(owl_global *g, owl_filter *f) {
-  owl_list_append_element(&(g->filterlist), f);
-}
-
-void owl_global_remove_filter(owl_global *g, char *name) {
-  int i, j;
-  owl_filter *f;
-
-  j=owl_list_get_size(&(g->filterlist));
-  for (i=0; i<j; i++) {
-    f=owl_list_get_element(&(g->filterlist), i);
-    if (!strcmp(name, owl_filter_get_name(f))) {
-      owl_filter_free(f);
-      owl_list_remove_element(&(g->filterlist), i);
-      break;
-    }
-  }
-}
-
-/* nextmsgid */
-
-int owl_global_get_nextmsgid(owl_global *g) {
-  return(g->nextmsgid++);
-}
-
-/* current view */
-
-owl_view *owl_global_get_current_view(owl_global *g) {
-  return(&(g->current_view));
-}
-
-/* has colors */
-
-int owl_global_get_hascolors(owl_global *g) {
-  if (g->hascolors) return(1);
-  return(0);
-}
-
-/* color pairs */
-
-int owl_global_get_colorpairs(owl_global *g) {
-  return(g->colorpairs);
-}
-
-owl_colorpair_mgr *owl_global_get_colorpair_mgr(owl_global *g) {
-  return(&(g->cpmgr));
-}
-
-/* puntlist */
-
-owl_list *owl_global_get_puntlist(owl_global *g) {
-  return(&(g->puntlist));
-}
-
-int owl_global_message_is_puntable(owl_global *g, owl_message *m) {
-  owl_list *pl;
-  int i, j;
-
-  pl=owl_global_get_puntlist(g);
-  j=owl_list_get_size(pl);
-  for (i=0; i<j; i++) {
-    if (owl_filter_message_match(owl_list_get_element(pl, i), m)) return(1);
-  }
-  return(0);
-}
-
-int owl_global_should_followlast(owl_global *g) {
-  owl_view *v;
-  
-  if (!owl_global_is__followlast(g)) return(0);
-  
-  v=owl_global_get_current_view(g);
-  
-  if (owl_global_get_curmsg(g)==owl_view_get_size(v)-1) return(1);
-  return(0);
-}
-
-int owl_global_is_search_active(owl_global *g) {
-  if (g->searchactive) return(1);
-  return(0);
-}
-
-void owl_global_set_search_active(owl_global *g, char *string) {
-  g->searchactive=1;
-  if (g->searchstring != NULL) owl_free(g->searchstring);
-  g->searchstring=owl_strdup(string);
-}
-
-void owl_global_set_search_inactive(owl_global *g) {
-  g->searchactive=0;
-}
-
-char *owl_global_get_search_string(owl_global *g) {
-  if (g->searchstring==NULL) return("");
-  return(g->searchstring);
-}
-
-void owl_global_set_newmsgproc_pid(owl_global *g, int i) {
-  g->newmsgproc_pid=i;
-}
-
-int owl_global_get_newmsgproc_pid(owl_global *g) {
-  return(g->newmsgproc_pid);
-}
-
-void owl_global_add_to_malloced(owl_global *g, int i) {
-  g->malloced+=i;
-}
-
-void owl_global_add_to_freed(owl_global *g, int i) {
-  g->freed+=1;
-}
-
-int owl_global_get_malloced(owl_global *g) {
-  return(g->malloced);
-}
-
-int owl_global_get_freed(owl_global *g) {
-  return(g->freed);
-}
-
-int owl_global_get_meminuse(owl_global *g) {
-  return(g->malloced-g->freed);
-}
-
-/* AIM stuff */
-
-int owl_global_is_aimloggedin(owl_global *g)
-{
-  if (g->aim_loggedin) return(1);
-  return(0);
-}
-
-char *owl_global_get_aim_screenname(owl_global *g)
-{
-  if (owl_global_is_aimloggedin(g)) {
-    return (g->aim_screenname);
-  }
-  return("");
-}
-
-char *owl_global_get_aim_screenname_for_filters(owl_global *g)
-{
-  if (owl_global_is_aimloggedin(g)) {
-    return (g->aim_screenname_for_filters);
-  }
-  return("");
-}
-
-void owl_global_set_aimloggedin(owl_global *g, char *screenname)
-{
-  char *sn_escaped, *quote;
-  g->aim_loggedin=1;
-  if (g->aim_screenname) owl_free(g->aim_screenname);
-  if (g->aim_screenname_for_filters) owl_free(g->aim_screenname_for_filters);
-  g->aim_screenname=owl_strdup(screenname);
-  sn_escaped = owl_text_quote(screenname, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
-  quote = owl_getquoting(sn_escaped);
-  g->aim_screenname_for_filters=owl_sprintf("%s%s%s", quote, sn_escaped, quote);
-  owl_free(sn_escaped);
-}
-
-void owl_global_set_aimnologgedin(owl_global *g)
-{
-  g->aim_loggedin=0;
-}
-
-int owl_global_is_doaimevents(owl_global *g)
-{
-  if (g->aim_doprocessing) return(1);
-  return(0);
-}
-
-void owl_global_set_doaimevents(owl_global *g)
-{
-  g->aim_doprocessing=1;
-}
-
-void owl_global_set_no_doaimevents(owl_global *g)
-{
-  g->aim_doprocessing=0;
-}
-
-aim_session_t *owl_global_get_aimsess(owl_global *g)
-{
-  return(&(g->aimsess));
-}
-
-aim_conn_t *owl_global_get_bosconn(owl_global *g)
-{
-  return(&(g->bosconn));
-}
-
-void owl_global_set_bossconn(owl_global *g, aim_conn_t *conn)
-{
-  g->bosconn=*conn;
-}
-
-int owl_global_is_aimnop_time(owl_global *g)
-{
-  if (owl_timer_is_expired(&(g->aim_noop_timer))) return(1);
-  return(0);
-}
-
-void owl_global_aimnop_sent(owl_global *g)
-{
-  owl_timer_reset(&(g->aim_noop_timer));
-}
-
-owl_timer *owl_global_get_aim_login_timer(owl_global *g)
-{
-  return(&(g->aim_ignorelogin_timer));
-}
-
-/* message queue */
-
-void owl_global_messagequeue_addmsg(owl_global *g, owl_message *m)
-{
-  owl_list_append_element(&(g->messagequeue), m);
-}
-
-/* pop off the first message and return it.  Return NULL if the queue
- * is empty.  The caller should free the message after using it, if
- * necessary.
- */
-owl_message *owl_global_messagequeue_popmsg(owl_global *g)
-{
-  owl_message *out;
-
-  if (owl_list_get_size(&(g->messagequeue))==0) return(NULL);
-  out=owl_list_get_element(&(g->messagequeue), 0);
-  owl_list_remove_element(&(g->messagequeue), 0);
-  return(out);
-}
-
-int owl_global_messagequeue_pending(owl_global *g)
-{
-  if (owl_list_get_size(&(g->messagequeue))==0) return(0);
-  return(1);
-}
-
-owl_buddylist *owl_global_get_buddylist(owl_global *g)
-{
-  return(&(g->buddylist));
-}
-  
-/* style */
-
-/* Return the style with name 'name'.  If it does not exist return
- * NULL */
-owl_style *owl_global_get_style_by_name(owl_global *g, char *name)
-{
-  return owl_dict_find_element(&(g->styledict), name);
-}
-
-/* creates a list and fills it in with keys.  duplicates the keys, 
- * so they will need to be freed by the caller. */
-int owl_global_get_style_names(owl_global *g, owl_list *l) {
-  return owl_dict_get_keys(&(g->styledict), l);
-}
-
-void owl_global_add_style(owl_global *g, owl_style *s)
-{
-  /*
-   * If we're redefining the current style, make sure to update
-   * pointers to it.
-   */
-  if(g->current_view.style
-     && !strcmp(owl_style_get_name(g->current_view.style),
-                owl_style_get_name(s)))
-    g->current_view.style = s;
-  owl_dict_insert_element(&(g->styledict), owl_style_get_name(s),
-                          s, (void(*)(void*))owl_style_free);
-}
-
-void owl_global_set_haveaim(owl_global *g)
-{
-  g->haveaim=1;
-}
-
-int owl_global_is_haveaim(owl_global *g)
-{
-  if (g->haveaim) return(1);
-  return(0);
-}
-
-void owl_global_set_havezephyr(owl_global *g)
-{
-  g->havezephyr=1;
-}
-
-int owl_global_is_havezephyr(owl_global *g)
-{
-  if (g->havezephyr) return(1);
-  return(0);
-}
-
-owl_timer *owl_global_get_aim_buddyinfo_timer(owl_global *g)
-{
-  return(&(g->aim_buddyinfo_timer));
-}
-
-owl_errqueue *owl_global_get_errqueue(owl_global *g)
-{
-  return(&(g->errqueue));
-}
-
-void owl_global_set_errsignal(owl_global *g, int signum, siginfo_t *siginfo)
-{
-  g->got_err_signal = signum;
-  if (siginfo) {
-    g->err_signal_info = *siginfo;
-  } else {
-    memset(&(g->err_signal_info), 0, sizeof(siginfo_t));
-  }
-}
-
-int owl_global_get_errsignal_and_clear(owl_global *g, siginfo_t *siginfo)
-{
-  int signum;
-  if (siginfo && g->got_err_signal) {
-    *siginfo = g->err_signal_info;
-  } 
-  signum = g->got_err_signal;
-  g->got_err_signal = 0;
-  return signum;
-}
-
-owl_timer *owl_global_get_zephyr_buddycheck_timer(owl_global *g)
-{
-  return(&(g->zephyr_buddycheck_timer));
-}
-
-owl_zbuddylist *owl_global_get_zephyr_buddylist(owl_global *g)
-{
-  return(&(g->zbuddies));
-}
-
-struct termios *owl_global_get_startup_tio(owl_global *g)
-{
-  return(&(g->startup_tio));
-}
-
-char * owl_global_intern(owl_global *g, char * string)
-{
-  return owl_obarray_insert(&(g->obarray), string);
-}
-
-owl_list *owl_global_get_dispatchlist(owl_global *g)
-{
-  return &(g->dispatchlist);
-}
Index: lp.c
===================================================================
--- help.c	(revision 799b60ea3145bfa2ad773b09544d31a3e30e77ff)
+++ 	(revision )
@@ -1,146 +1,0 @@
-#include "owl.h"
-#include <string.h>
-
-static const char fileIdent[] = "$Id$";
-
-void owl_help()
-{
-  owl_fmtext fm;
-  char *varname;
-  owl_list varnames;
-  int i, numvarnames;
-
-  owl_fmtext_init_null(&fm);
-  owl_fmtext_append_bold
-    (&fm, 
-     "OWL HELP\n\n");
-
-  owl_fmtext_append_normal
-    (&fm, 
-     "  If you're new to BarnOwl, the first thing you should type is\n\n"
-     "    :show quickstart\n\n"
-     "  For help on a specific command use 'help <command>'\n"
-     "  For information on advanced keys, use 'show keymaps'.\n"
-     "  For information on advanced commands, use 'show commands'.\n"
-     "  For information on variables, use 'show variables'.\n\n");
-
-  owl_fmtext_append_bold
-    (&fm, 
-     "  Basic Keys:\n"
-     );
-  owl_fmtext_append_normal
-    (&fm, 
-     "    n             Move to next non-deleted message\n"
-     "    p             Move to previous non-deleted message\n"
-     "    C-n , down    Move to next message\n"
-     "    C-p , up      Move to previous message\n"
-     "    < , >         Move to first, last message\n"
-     "    right , left  Scroll screen left or right\n"
-     "    C-v           Page down\n"
-     "    M-v           Page up\n"
-     "    i             Print more information about a message\n"
-     "    P             Move to the next personal message\n"
-     "    M-P           Move to the previous personal message\n"
-     "\n"
-     "    d             Mark message for deletion\n"
-     "    u             Undelete a message marked for deletion\n"
-     "    x             Expunge deleted messages\n"
-     "    X             Expunge deleted messages and switch to home view\n"
-     "    T             Mark all 'trash' messages for deletion\n"
-     "    M-D           Mark all messages in current view for deletion\n"
-     "    M-u           Unmark all messages in the current view for deletion\n"
-     "\n"
-     "    z             Start a zwrite command\n"
-     "    a             Start an aimwrite command\n"
-     "    r             Reply to the current message\n"
-     "    R             Reply to sender\n"
-     "    C-r           Reply but allow editing of reply line\n"
-     "\n"
-     "    M-n           View zephyrs in selected conversation\n"
-     "    M-N           View zephyrs in selected converstaion of instance\n"
-     "    M-p           View only personal zephyrs\n"
-     "    V             Change to back to home view ('all' by default)\n"
-     "    v             Start a view command\n"
-     "    !             Invert the current view\n"
-     "\n"
-     "    l             Print a zephyr/AIM buddy listing\n"
-     "    A             Toggle zaway\n"
-     "    o             Toggle one-line display mode\n"
-     "    w             Open a URL in the current message\n"
-     "    C-l           Refresh the screen\n"
-     "    C-z           Suspend Owl\n"
-     "    h             Print this help message\n"
-     "    : , M-x       Enter command mode\n"
-     "\n"
-     "    /             Foward search\n"
-     "    ?             Reverse search\n"
-     "\n\n"
-     );
-  owl_fmtext_append_bold
-    (&fm, 
-     "  Basic Commands:\n"
-     );
-  owl_fmtext_append_normal
-    (&fm, 
-     "    quit, exit    Exit owl\n"
-     "    help          Get help about commands\n"
-     "    show          Show information about owl (see detailed help)\n"
-     "\n"
-     "    zwrite        Send a zephyr\n"
-     "    aimlogin      Login to AIM\n"
-     "    aimwrite      Send an AIM message\n"
-     "\n"
-     "    addbuddy      Add a zephyr or AIM buddy\n"
-     "    zaway         Turn zaway on or off, or set the message\n"
-     "    zlocate       Locate a user\n"
-     "    subscribe     Subscribe to a zephyr class or instance\n"
-     "    unsubscribe   Unsubscribe to a zephyr class or instance\n"
-     "    blist         Print a list of zephyr and AIM buddies logged in\n"
-     "    search        Search for a text string\n"
-     "\n"
-     "    set           Set a variable (see list below)\n"
-     "    print         Print a variable's value (variables listed below)\n"
-     "    startup       Set a command to be run at every Owl startup\n"
-     "    unstartup     Remove a command to be run at every Owl startup\n"
-     "\n"
-     "    getsubs       Print a list of current subscriptions\n"
-     "    unsuball      Unsubscribe from all zephyr classes\n"
-     "    load-subs     Load zephyr subscriptions from a file\n"
-     "    zpunt         Supress messages from a zephyr triplet\n"
-     "    zlog          Send a login or logout notification\n"
-     "    zlist         Print a list of zephyr buddies logged in\n"
-     "    alist         Print a list of AIM buddies logged in\n"
-     "    info          Print detailed information about the current message\n"
-     "    filter        Create a message filter\n"
-     "    view          View messages matching a filter\n"
-     "    viewuser      View messages to or from a particular user\n"
-     "    viewclass     View messages to a particular class\n"
-     "    expunge       Expunge messages marked for deletion\n"
-     "    bindkey       Create a new key binding\n"
-     "    alias         Create a command alias\n"
-     "    dump          Dump messagelist as text to a file\n"
-     "\n"
-     "    about         Print information about owl\n"
-     "    status        Print status information about the running owl\n"
-     "    version       Print the version number of owl\n"
-     "\n");
-  
-  /* help for variables */
-  owl_fmtext_append_bold(&fm, 
-			 "Variables:\n");
-  owl_variable_dict_get_names(owl_global_get_vardict(&g), &varnames);
-  numvarnames = owl_list_get_size(&varnames);
-  for (i=0; i<numvarnames; i++) {
-    varname = owl_list_get_element(&varnames, i);
-    if (varname && varname[0]!='_') {
-      owl_variable_describe(owl_global_get_vardict(&g), varname, &fm);
-    }
-  }
-  owl_variable_dict_namelist_free(&varnames);
-
-  owl_fmtext_append_normal(&fm, "\n");
-
-  owl_function_popless_fmtext(&fm);
-
-  owl_fmtext_free(&fm);
-}
Index: story.c
===================================================================
--- history.c	(revision 52f35074cbf1b1c6d354ce19c191f15592eac3df)
+++ 	(revision )
@@ -1,94 +1,0 @@
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-void owl_history_init(owl_history *h)
-{
-  owl_list_create(&(h->hist));
-  h->cur=0;			/* current position in history */
-  h->touched=0;			/* whether we've gone into history */
-  h->partial=0;			/* is the 0th element is partially composed? */
-  h->repeats=1;                 /* by default we'll allow repeat entries */
-}
-
-void owl_history_set_norepeats(owl_history *h)
-{
-  h->repeats=0;
-}
-
-char *owl_history_get_prev(owl_history *h)
-{
-
-  if (!h) return NULL;
-  h->touched=1;
-
-  if (owl_list_get_size(&(h->hist))==0) return(NULL);
-
-  if (h->cur == owl_list_get_size(&(h->hist))-1) {
-    return(NULL);
-  }
-
-  h->cur++;
-
-  return(owl_list_get_element(&(h->hist), h->cur));
-}
-
-char *owl_history_get_next(owl_history *h)
-{
-  if (!h) return NULL;
-  if (owl_list_get_size(&(h->hist))==0) return(NULL);
-  if (h->cur==0) {
-    return(NULL);
-  }
-
-  h->cur--;
-  return(owl_list_get_element(&(h->hist), h->cur));
-}
-
-void owl_history_store(owl_history *h, char *line)
-{
-  int size;
-
-  if (!h) return;
-  size=owl_list_get_size(&(h->hist));
-
-  /* if partial is set, remove the first entry first */
-  if (h->partial) {
-    owl_list_remove_element(&(h->hist), 0);
-  }
-
-  /* if repeats are disallowed, check if the line is the same as the last */
-  if (owl_list_get_size(&(h->hist))>0) {
-    if (!strcmp(line, owl_list_get_element(&(h->hist), 0))) return;
-  }
-
-  /* if we've reached the max history size, pop off the last element */
-  if (size>OWL_HISTORYSIZE) {
-    owl_free(owl_list_get_element(&(h->hist), size-1));
-    owl_list_remove_element(&(h->hist), size-1);
-  }
-
-  /* add the new line */
-  owl_list_prepend_element(&(h->hist), owl_strdup(line));
-}
-
-void owl_history_set_partial(owl_history *h)
-{
-  if (!h) return;
-  h->partial=1;
-}
-
-void owl_history_reset(owl_history *h)
-{
-  if (!h) return;
-  h->cur=0;
-  h->touched=0;
-  h->partial=0;
-}
-
-int owl_history_is_touched(owl_history *h)
-{
-  if (!h) return(0);
-  if (h->touched) return(1);
-  return(0);
-}
Index: ybinding.c
===================================================================
--- keybinding.c	(revision 1716fed8c2650e46892cf6571555eac937266c6e)
+++ 	(revision )
@@ -1,139 +1,0 @@
-#include <ctype.h>
-#include <string.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-/*
- * TODO: Idea for allowing functions to be user-specified --- 
- *      Have function have a context bitmask that says where it 
- *      can be used, and have keymaps also have one, and compare
- *      the two when setting.
- *      
- */
-
-/* sets up a new keybinding for a command */
-int owl_keybinding_init(owl_keybinding *kb, char *keyseq, char *command, void (*function_fn)(void), char *desc)
-{
-  char **ktokens;
-  int    nktokens, i;
-  
-  owl_function_debugmsg("owl_keybinding_init: creating binding for <%s> with desc: <%s>", keyseq, desc);
-  if (command && !function_fn) {
-    kb->type = OWL_KEYBINDING_COMMAND;
-  } else if (!command && function_fn) {
-    kb->type = OWL_KEYBINDING_FUNCTION;
-  } else {
-    return(-1);
-  }
-
-  ktokens = atokenize(keyseq, " ", &nktokens);
-  if (!ktokens) return(-1);
-  if (nktokens > OWL_KEYMAP_MAXSTACK) {
-    atokenize_free(ktokens, nktokens);
-    return(-1);
-  }
-  kb->j = owl_malloc((nktokens+1)*sizeof(int));
-  for (i=0; i<nktokens; i++) {
-    kb->j[i] = owl_keypress_fromstring(ktokens[i]);
-    if (kb->j[i] == ERR) { 
-      atokenize_free(ktokens, nktokens);
-      owl_free(kb->j);
-      return(-1);
-    }
-  }
-  kb->j[i] = 0;
-
-  atokenize_free(ktokens, nktokens);
-
-  if (command) kb->command = owl_strdup(command);
-  kb->function_fn = function_fn;
-  if (desc) kb->desc = owl_strdup(desc);
-  else kb->desc = NULL;
-  return(0);
-}
-
-/* Releases data associated with a keybinding */
-void owl_keybinding_free(owl_keybinding *kb)
-{
-  if (kb->j) owl_free(kb->j);
-  if (kb->desc) owl_free(kb->desc);
-  if (kb->command) owl_free(kb->command);
-}
-
-/* Releases data associated with a keybinding, and the kb itself */
-void owl_keybinding_free_all(owl_keybinding *kb)
-{
-  owl_keybinding_free(kb);
-  owl_free(kb);
-}
-
-/* executes a keybinding */
-void owl_keybinding_execute(owl_keybinding *kb, int j)
-{
-  if (kb->type == OWL_KEYBINDING_COMMAND && kb->command) {
-    owl_function_command_norv(kb->command);
-  } else if (kb->type == OWL_KEYBINDING_FUNCTION && kb->function_fn) {
-    kb->function_fn();
-  }
-}
-
-/* returns 0 on success */
-int owl_keybinding_stack_tostring(int *j, char *buff, int bufflen)
-{
-  char *pos = buff;
-  int   rem = bufflen;
-  int   i, n;
-
-  for (i=0; j[i]; i++) {
-    owl_keypress_tostring(j[i], 0, pos, rem-1);
-    if (j[i+1]) strcat(pos, " ");
-    n = strlen(pos);
-    pos += n;
-    rem -= n;
-  }
-  return 0;
-}
-
-/* returns 0 on success */
-int owl_keybinding_tostring(owl_keybinding *kb, char *buff, int bufflen)
-{
-  return owl_keybinding_stack_tostring(kb->j, buff, bufflen);
-}
-
-char *owl_keybinding_get_desc(owl_keybinding *kb)
-{
-  return kb->desc;
-}
-
-/* returns 0 on no match, 1 on subset match, and 2 on complete match */
-int owl_keybinding_match(owl_keybinding *kb, int *kpstack)
-{
-  int *kbstack = kb->j;
-  
-  while (*kbstack && *kpstack) {
-    if (*kbstack != *kpstack) {
-      return 0;
-    }
-    kbstack++; kpstack++;
-  }
-  if (!*kpstack && !*kbstack) {
-    return 2;
-  } else if (!*kpstack) {
-    return 1;
-  } else {
-    return 0;
-  }
-}
-
-/* returns 1 if keypress sequence is the same */
-int owl_keybinding_equal(owl_keybinding *kb1, owl_keybinding *kb2)
-{
-  int *j1 = kb1->j;
-  int *j2 = kb2->j;
-  while (*j1 && *j2) {
-    if (*(j1++) != *(j2++))  return(0);
-  }
-  if (*j1 != *j2) return(0);
-  return(1);
-}
Index: ymap.c
===================================================================
--- keymap.c	(revision 428834dd2aedac4b5fc2874635c22897ffa16c22)
+++ 	(revision )
@@ -1,295 +1,0 @@
-#include <string.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-/* returns 0 on success */
-int owl_keymap_init(owl_keymap *km, char *name, char *desc, void (*default_fn)(owl_input), void (*prealways_fn)(owl_input), void (*postalways_fn)(owl_input))
-{
-  if (!name || !desc) return(-1);
-  if ((km->name = owl_strdup(name)) == NULL) return(-1);
-  if ((km->desc = owl_strdup(desc)) == NULL) return(-1);
-  if (0 != owl_list_create(&km->bindings)) return(-1);
-  km->submap = NULL;
-  km->default_fn = default_fn;
-  km->prealways_fn = prealways_fn;
-  km->postalways_fn = postalways_fn;
-  return(0);
-}
-
-/* note that this will free the memory for the bindings! */
-void owl_keymap_free(owl_keymap *km)
-{
-  owl_free(km->name);
-  owl_free(km->desc);
-  owl_list_free_all(&km->bindings, (void(*)(void*))owl_keybinding_free_all);
-}
-
-void owl_keymap_set_submap(owl_keymap *km, owl_keymap *submap)
-{
-  km->submap = submap;
-}
-
-/* creates and adds a key binding */
-int owl_keymap_create_binding(owl_keymap *km, char *keyseq, char *command, void (*function_fn)(void), char *desc)
-{
-  owl_keybinding *kb, *curkb;
-  int i;
-
-  if ((kb = owl_malloc(sizeof(owl_keybinding))) == NULL) return(-1);
-  if (0 != owl_keybinding_init(kb, keyseq, command, function_fn, desc)) {
-    owl_free(kb);
-    return(-1);
-  }
-  /* see if another matching binding, and if so remove it.
-   * otherwise just add this one. 
-   */
-  for (i = owl_list_get_size(&km->bindings)-1; i>=0; i--) {
-    curkb = (owl_keybinding*)owl_list_get_element(&km->bindings, i);
-    if (owl_keybinding_equal(curkb, kb)) {
-      owl_list_remove_element(&km->bindings, i);
-      owl_keybinding_free_all(curkb);
-    }
-  }
-  return owl_list_append_element(&km->bindings, kb);  
-}
-
-/* returns a summary line describing this keymap.  the caller must free. */
-char *owl_keymap_summary(owl_keymap *km)
-{
-  char *s;
-  int slen;
-  if (!km || !km->name || !km->desc) return NULL;
-  slen = strlen(km->name)+strlen(km->desc)+20;
-  s = owl_malloc(slen);
-  snprintf(s, slen-1, "%-15s - %s", km->name, km->desc);
-  return s;
-}
-
-/* Appends details about the keymap to fm */
-void owl_keymap_get_details(owl_keymap *km, owl_fmtext *fm)
-{
-  int i, nbindings; 
-  owl_keybinding *kb;
-  
-  owl_fmtext_append_bold(fm, "KEYMAP - ");
-  owl_fmtext_append_bold(fm, km->name);
-  owl_fmtext_append_normal(fm, "\n");
-  if (km->desc) {
-    owl_fmtext_append_normal(fm, OWL_TABSTR "Purpose:    ");
-    owl_fmtext_append_normal(fm, km->desc);
-    owl_fmtext_append_normal(fm, "\n");
-  }
-  if (km->submap) {
-    owl_fmtext_append_normal(fm, OWL_TABSTR "Has submap: ");
-    owl_fmtext_append_normal(fm, km->submap->name);
-    owl_fmtext_append_normal(fm, "\n");
-  }
-    owl_fmtext_append_normal(fm, "\n");
-  if (km->default_fn) {
-    owl_fmtext_append_normal(fm, OWL_TABSTR 
-     "Has a default keypress handler (default_fn).\n");
-  }
-  if (km->prealways_fn) {
-    owl_fmtext_append_normal(fm, OWL_TABSTR
-     "Executes a function (prealways_fn) on every keypress.\n");
-  }
-  if (km->postalways_fn) {
-    owl_fmtext_append_normal(fm, OWL_TABSTR 
-     "Executes a function (postalways_fn) after handling every keypress.\n");
-  }
-
-  owl_fmtext_append_bold(fm, "\nKey bindings:\n\n");  
-  nbindings = owl_list_get_size(&km->bindings);
-  for (i=0; i<nbindings; i++) {
-    char buff[100];
-    owl_cmd *cmd;
-    char *tmpdesc, *desc = "";
-
-    kb = owl_list_get_element(&km->bindings, i);
-    owl_keybinding_tostring(kb, buff, 100);
-    owl_fmtext_append_normal(fm, OWL_TABSTR);
-    owl_fmtext_append_normal(fm, buff);
-    owl_fmtext_append_spaces(fm, 11-strlen(buff));
-    owl_fmtext_append_normal(fm, " - ");
-    if (kb->desc && *kb->desc) {
-      desc = kb->desc;
-    } else if ((cmd=owl_function_get_cmd(kb->command))
-	       && (tmpdesc = owl_cmd_get_summary(cmd))) {
-      desc = tmpdesc;
-    }
-    owl_fmtext_append_normal(fm, desc);
-    if (kb->command && *(kb->command)) {
-      owl_fmtext_append_normal(fm, "   [");
-      owl_fmtext_append_normal(fm, kb->command);
-      owl_fmtext_append_normal(fm, "]");
-    } 
-    owl_fmtext_append_normal(fm, "\n");
-  }
-}
-
-
-
-/***********************************************************************/
-/***************************** KEYHANDLER ******************************/
-/***********************************************************************/
-
-/* NOTE: keyhandler has private access to the internals of keymap */
-
-int owl_keyhandler_init(owl_keyhandler *kh)
-{
-  if (0 != owl_dict_create(&kh->keymaps)) return(-1); 
-  kh->active = NULL;
-  owl_keyhandler_reset(kh);
-  return(0);
-}
-
-/* adds a new keymap */
-void owl_keyhandler_add_keymap(owl_keyhandler *kh, owl_keymap *km)
-{
-  owl_dict_insert_element(&kh->keymaps, km->name, km, NULL);
-}
-
-owl_keymap *owl_keyhandler_create_and_add_keymap(owl_keyhandler *kh, char *name, char *desc, void (*default_fn)(owl_input), void (*prealways_fn)(owl_input), void (*postalways_fn)(owl_input))
-{
-  owl_keymap *km;
-  km = (owl_keymap*)owl_malloc(sizeof(owl_keymap));
-  if (!km) return NULL;
-  owl_keymap_init(km, name, desc, default_fn, prealways_fn, postalways_fn);
-  owl_keyhandler_add_keymap(kh, km);
-  return km;
-}
-
-/* resets state and clears out key stack */
-void owl_keyhandler_reset(owl_keyhandler *kh)
-{
-  kh->in_esc = 0;
-  memset(kh->kpstack, 0, (OWL_KEYMAP_MAXSTACK+1)*sizeof(int));
-  kh->kpstackpos = -1;
-}
-
-owl_keymap *owl_keyhandler_get_keymap(owl_keyhandler *kh, char *mapname)
-{
-  return (owl_keymap*)owl_dict_find_element(&kh->keymaps, mapname);
-}
-
-/* free the list with owl_cmddict_namelist_free */
-void owl_keyhandler_get_keymap_names(owl_keyhandler *kh, owl_list *l)
-{
-  owl_dict_get_keys(&kh->keymaps, l);
-}
-
-void owl_keyhandler_keymap_namelist_free(owl_list *l)
-{
-  owl_list_free_all(l, owl_free);
-}
-
-
-
-/* sets the active keymap, which will also reset any key state.
- * returns the new keymap, or NULL on failure. */
-owl_keymap *owl_keyhandler_activate(owl_keyhandler *kh, char *mapname)
-{
-  owl_keymap *km;
-  if (kh->active && !strcmp(mapname, kh->active->name)) return(kh->active);
-  km = (owl_keymap*)owl_dict_find_element(&kh->keymaps, mapname);
-  if (!km) return(NULL);
-  owl_keyhandler_reset(kh);
-  kh->active = km;
-  return(km);
-}
-
-/* processes a keypress.  returns 0 if the keypress was handled,
- * 1 if not handled, -1 on error, and -2 if j==ERR. */
-int owl_keyhandler_process(owl_keyhandler *kh, owl_input j)
-{
-  owl_keymap     *km;
-  owl_keybinding *kb;
-  int i, match;
-
-  if (!kh->active) {
-    owl_function_makemsg("No active keymap!!!");
-    return(-1);
-  }
-
-  /* temporarily disallow C-`/C-SPACE until we fix associated bugs */
-  if (j.ch == ERR || j.ch == 0) {
-	return(-1);
-  }
-
-  /*
-    owl_function_debugmsg("processkey: got key %d, active keymap %s, stack at %d",
-    j, kh->active->name, kh->kpstackpos);
-  */
-
-  /* deal with ESC prefixing */
-  if (!kh->in_esc && j.ch == 27) {
-    kh->in_esc = 1;
-    return(0);
-  }
-  if (kh->in_esc) {
-    j.ch = OWL_META(j.ch);
-    kh->in_esc = 0;
-  }
-  
-  kh->kpstack[++(kh->kpstackpos)] = j.ch;
-  if (kh->kpstackpos >= OWL_KEYMAP_MAXSTACK) {
-    owl_keyhandler_reset(kh);
-    owl_function_makemsg("Too many prefix keys pressed...");
-    return(-1);
-  }
-
-  /* deal with the always_fn for the map and submaps */
-  for (km=kh->active; km; km=km->submap) {
-    if (km->prealways_fn) {
-      km->prealways_fn(j);
-    }
-  }
-
-  /* search for a match.  goes through active keymap and then
-   * through submaps... TODO:  clean this up so we can pull
-   * keyhandler and keymap apart.  */
-  for (km=kh->active; km; km=km->submap) {
-    for (i=owl_list_get_size(&km->bindings)-1; i>=0; i--) {
-      kb = (owl_keybinding*)owl_list_get_element(&km->bindings, i);
-      match = owl_keybinding_match(kb, kh->kpstack);
-      if (match == 1) {		/* subset match */
-
-	/* owl_function_debugmsg("processkey: found subset match in %s", km->name); */
-	return(0);
-      } else if (match == 2) {	/* exact match */
-	/* owl_function_debugmsg("processkey: found exact match in %s", km->name); */
-	owl_keybinding_execute(kb, j.ch);
-	owl_keyhandler_reset(kh);
-	if (km->postalways_fn) {
-	  km->postalways_fn(j);
-	}
-	return(0);
-      }
-    }
-  }
-
-  /* see if a default action exists for the active keymap */
-  if (kh->active->default_fn && kh->kpstackpos<1) {
-    /*owl_function_debugmsg("processkey: executing default_fn");*/
-
-    kh->active->default_fn(j);
-    owl_keyhandler_reset(kh);
-    if (kh->active->postalways_fn) {
-      kh->active->postalways_fn(j);
-    }
-    return(0);
-  }
-
-  owl_keyhandler_invalidkey(kh);
-  /* unable to handle */
-  return(1);  
-}
-
-void owl_keyhandler_invalidkey(owl_keyhandler *kh)
-{
-    char kbbuff[500];
-    owl_keybinding_stack_tostring(kh->kpstack, kbbuff, 500);
-    owl_function_makemsg("'%s' is not a valid key in this context.", kbbuff);
-    owl_keyhandler_reset(kh);
-}
Index: ypress.c
===================================================================
--- keypress.c	(revision 428834dd2aedac4b5fc2874635c22897ffa16c22)
+++ 	(revision )
@@ -1,212 +1,0 @@
-#include <ctype.h>
-#include <string.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-static struct _owl_keypress_specialmap {
-  int   kj;
-  char *ks;
-} specialmap[] = {
-#ifdef KEY_CODE_YES
-   { KEY_CODE_YES, 	"CODE_YES" }, 
-#endif
-   { KEY_MIN, 		"MIN" }, 
-   { KEY_BREAK, 	"BREAK" }, 
-   { KEY_DOWN, 		"DOWN" }, 
-   { KEY_UP, 		"UP" }, 
-   { KEY_LEFT, 		"LEFT" }, 
-   { KEY_RIGHT, 	"RIGHT" }, 
-   { KEY_HOME, 		"HOME" }, 
-   { KEY_BACKSPACE, 	"BACKSPACE" }, 
-   { KEY_F0, 		"F0" }, 
-   { KEY_F(1), 		"F1" }, 
-   { KEY_F(2), 		"F2" }, 
-   { KEY_F(3), 		"F3" }, 
-   { KEY_F(4), 		"F4" }, 
-   { KEY_F(5), 		"F5" }, 
-   { KEY_F(6), 		"F6" }, 
-   { KEY_F(7), 		"F7" }, 
-   { KEY_F(8), 		"F8" }, 
-   { KEY_F(9), 		"F9" }, 
-   { KEY_F(10),		"F10" }, 
-   { KEY_F(11),		"F11" }, 
-   { KEY_F(12),		"F12" }, 
-   { KEY_DL, 		"DL" }, 
-   { KEY_IL, 		"IL" }, 
-   { KEY_DC, 		"DC" }, 
-   { KEY_IC, 		"IC" }, 
-   { KEY_EIC, 		"EIC" }, 
-   { KEY_CLEAR, 	"CLEAR" }, 
-   { KEY_EOS, 		"EOS" }, 
-   { KEY_EOL, 		"EOL" }, 
-   { KEY_SF, 		"SF" }, 
-   { KEY_SR, 		"SR" }, 
-   { KEY_NPAGE, 	"NPAGE" }, 
-   { KEY_PPAGE, 	"PPAGE" }, 
-   { KEY_STAB, 		"STAB" }, 
-   { KEY_CTAB, 		"CTAB" }, 
-   { KEY_CATAB, 	"CATAB" }, 
-   { KEY_ENTER, 	"ENTER" }, 
-   { KEY_SRESET, 	"SRESET" }, 
-   { KEY_RESET, 	"RESET" }, 
-   { KEY_PRINT, 	"PRINT" }, 
-   { KEY_LL, 		"LL" }, 
-   { KEY_A1, 		"A1" }, 
-   { KEY_A3, 		"A3" }, 
-   { KEY_B2, 		"B2" }, 
-   { KEY_C1, 		"C1" }, 
-   { KEY_C3, 		"C3" }, 
-   { KEY_BTAB, 		"BTAB" }, 
-   { KEY_BEG, 		"BEG" }, 
-   { KEY_CANCEL, 	"CANCEL" }, 
-   { KEY_CLOSE, 	"CLOSE" }, 
-   { KEY_COMMAND, 	"COMMAND" }, 
-   { KEY_COPY, 	        "COPY" }, 
-   { KEY_CREATE, 	"CREATE" }, 
-   { KEY_END, 	        "END" }, 
-   { KEY_EXIT, 	        "EXIT" }, 
-   { KEY_FIND, 	        "FIND" }, 
-   { KEY_HELP, 	        "HELP" }, 
-   { KEY_MARK, 	        "MARK" }, 
-   { KEY_MESSAGE, 	"MESSAGE" }, 
-   { KEY_MOVE, 	        "MOVE" }, 
-   { KEY_NEXT, 	        "NEXT" }, 
-   { KEY_OPEN, 	        "OPEN" }, 
-   { KEY_OPTIONS, 	"OPTIONS" }, 
-   { KEY_PREVIOUS, 	"PREVIOUS" }, 
-   { KEY_REDO, 	        "REDO" }, 
-   { KEY_REFERENCE, 	"REFERENCE" }, 
-   { KEY_REFRESH, 	"REFRESH" }, 
-   { KEY_REPLACE, 	"REPLACE" }, 
-   { KEY_RESTART, 	"RESTART" }, 
-   { KEY_RESUME, 	"RESUME" }, 
-   { KEY_SAVE, 	        "SAVE" }, 
-   { KEY_SBEG, 	        "SBEG" }, 
-   { KEY_SCANCEL, 	"SCANCEL" }, 
-   { KEY_SCOMMAND, 	"SCOMMAND" }, 
-   { KEY_SCOPY, 	"SCOPY" }, 
-   { KEY_SCREATE, 	"SCREATE" }, 
-   { KEY_SDC, 	        "SDC" }, 
-   { KEY_SDL, 	        "SDL" }, 
-   { KEY_SELECT, 	"SELECT" }, 
-   { KEY_SEND, 	        "SEND" }, 
-   { KEY_SEOL, 	        "SEOL" }, 
-   { KEY_SEXIT, 	"SEXIT" }, 
-   { KEY_SFIND, 	"SFIND" }, 
-   { KEY_SHELP, 	"SHELP" }, 
-   { KEY_SHOME, 	"SHOME" }, 
-   { KEY_SIC, 	        "SIC" }, 
-   { KEY_SLEFT, 	"SLEFT" }, 
-   { KEY_SMESSAGE, 	"SMESSAGE" }, 
-   { KEY_SMOVE, 	"SMOVE" }, 
-   { KEY_SNEXT, 	"SNEXT" }, 
-   { KEY_SOPTIONS, 	"SOPTIONS" }, 
-   { KEY_SPREVIOUS, 	"SPREVIOUS" }, 
-   { KEY_SPRINT, 	"SPRINT" }, 
-   { KEY_SREDO, 	"SREDO" }, 
-   { KEY_SREPLACE, 	"SREPLACE" }, 
-   { KEY_SRIGHT, 	"SRIGHT" }, 
-   { KEY_SRSUME, 	"SRSUME" }, 
-   { KEY_SSAVE, 	"SSAVE" }, 
-   { KEY_SSUSPEND, 	"SSUSPEND" }, 
-   { KEY_SUNDO, 	"SUNDO" }, 
-   { KEY_SUSPEND, 	"SUSPEND" }, 
-   { KEY_UNDO, 	        "UNDO" }, 
-   { KEY_MOUSE, 	"MOUSE" }, 
-#ifdef KEY_RESIZE
-   { KEY_RESIZE, 	"RESIZE" }, 
-#endif
-   { KEY_MAX, 	        "MAX" }, 
-   { ' ', 	        "SPACE" }, 
-   { 27, 	        "ESCAPE" }, 
-   { 127, 	        "DELETE" }, 
-   { '\r', 	        "CR" }, 
-   { '\n', 	        "LF" }, 
-   { 0,                 NULL }
-};
-
-#define OWL_CTRL(key) ((key)&037)
-/* OWL_META is definied in owl.h */
-
-/* returns 0 on success */
-int owl_keypress_tostring(int j, int esc, char *buff, int bufflen)
-{
-  char kb[64], kb2[2];
-  struct _owl_keypress_specialmap *sm;
-
-  *kb = '\0';
-  for (sm = specialmap; sm->kj!=0; sm++) {
-    if (j == OWL_META(sm->kj) || (esc && j == sm->kj)) {
-      strcat(kb, "M-");
-      strcat(kb, sm->ks);
-      break;
-    } else if (j == sm->kj) {
-      strcat(kb, sm->ks);
-      break;
-    }
-  }
-  if (!*kb) {
-    if (j & OWL_META(0)) {
-      strcat(kb, "M-");
-      j &= ~OWL_META(0);
-    }
-    if ((OWL_CTRL(j) == j)) {
-      strcat(kb, "C-");
-      j |= 0x40;
-      if (isupper(j)) j = tolower(j);
-
-    }
-    if (isascii(j)) {
-      kb2[0] = j;
-      kb2[1] = 0;
-      strcat(kb, kb2);    
-    }
-    
-  }  
-  if (!*kb) {
-    /* not a valid key */
-    strncpy(buff, "INVALID", bufflen);
-    return(-1);
-  }
-  strncpy(buff, kb, bufflen);
-  return(0);
-}
-
-
-/* returns ERR on failure, else a keycode */
-int owl_keypress_fromstring(char *kb)
-{
-  struct _owl_keypress_specialmap *sm;
-  int ismeta=0, isctrl=0;
-  int j = ERR;
-
-  while (*kb && kb[1] == '-' && (kb[0] == 'C' || kb[0] == 'M')) {
-    if ((kb[0] == 'C') && (kb[1] == '-')) {
-      isctrl = 1;
-      kb+=2;
-    }
-    if ((kb[0] == 'M') && (kb[1] == '-')) {
-      ismeta = 1;
-      kb+=2;
-    }
-  }
-  if (isascii(kb[0]) && !kb[1]) {
-    j = kb[0];
-  } else {
-    for (sm = specialmap; sm->kj!=0; sm++) {
-      if (!strcmp(sm->ks, kb)) {
-	j = sm->kj;
-      }
-    }
-  }
-  if (j==ERR) return(ERR);
-  if (isctrl) {
-    j = OWL_CTRL(j);
-  }
-  if (ismeta) {
-    j = OWL_META(j);
-  }
-  return(j);
-}
-
Index: ys.c
===================================================================
--- keys.c	(revision 9b70dd4730dcdc958150fe126007d358cec3c713)
+++ 	(revision )
@@ -1,336 +1,0 @@
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-#define BIND_CMD(kpress, command, desc) \
-         owl_keymap_create_binding(km, kpress, command, NULL, desc);
-
-#define BIND_FNV(kpress, fn, desc) \
-         owl_keymap_create_binding(km, kpress, NULL, fn, desc);
-
-
-/* sets up the default keymaps */
-void owl_keys_setup_keymaps(owl_keyhandler *kh) {
-  owl_keymap *km, *km_global, *km_editwin, *km_mainwin,
-    *km_ew_multi, *km_ew_onel, *km_viewwin;
-
-  
-  /****************************************************************/
-  /*************************** GLOBAL *****************************/
-  /****************************************************************/
-
-  km_global = km = owl_keyhandler_create_and_add_keymap(kh, "global",
-       "System-wide default key bindings", 
-       owl_keys_default_invalid, NULL, NULL);
-  BIND_CMD("C-z",      "suspend",            "Suspend owl");
-
-  /****************************************************************/
-  /***************************** EDIT *****************************/
-  /****************************************************************/
-
-  km_editwin = km = owl_keyhandler_create_and_add_keymap(kh, "edit",
-       "Text editing and command window", 
-       owl_keys_editwin_default, NULL, owl_keys_editwin_postalways);
-  owl_keymap_set_submap(km_editwin, km_global);
-  /*
-  BIND_CMD("F1",          "help",            "");
-  BIND_CMD("HELP",        "help",            "");
-  BIND_CMD("M-[ 2 8 ~",   "help",            "");
-  */
-
-  BIND_CMD("C-c",         "edit:cancel", "");
-  BIND_CMD("C-g",         "edit:cancel", "");
-
-  BIND_CMD("M-f",         "edit:move-next-word", "");
-  BIND_CMD("M-O 3 C",     "edit:move-next-word", "");
-  BIND_CMD("M-LEFT",      "edit:move-next-word", "");
-  BIND_CMD("M-b",         "edit:move-prev-word", "");
-  BIND_CMD("M-O 3 D",     "edit:move-prev-word", "");
-  BIND_CMD("M-RIGHT",     "edit:move-prev-word", "");
-
-  BIND_CMD("LEFT",        "edit:move-left", "");
-  BIND_CMD("C-b",         "edit:move-left", "");
-  BIND_CMD("RIGHT",       "edit:move-right", "");
-  BIND_CMD("C-f",         "edit:move-right", "");
-
-  BIND_CMD("M-<",         "edit:move-to-buffer-start", "");
-  BIND_CMD("HOME",        "edit:move-to-buffer-start", "");
-  BIND_CMD("M->",         "edit:move-to-buffer-end", "");
-  BIND_CMD("END",         "edit:move-to-buffer-end", "");
-
-  BIND_CMD("C-a",         "edit:move-to-line-start", "");
-  BIND_CMD("C-e",         "edit:move-to-line-end", "");
-
-  BIND_CMD("M-BACKSPACE", "edit:delete-prev-word", "");
-  BIND_CMD("M-DELETE",    "edit:delete-prev-word", "");
-  BIND_CMD("M-d",         "edit:delete-next-word", "");
-  BIND_CMD("M-[ 3 ; 3 ~", "edit:delete-next-word", "");
-
-  BIND_CMD("C-h",         "edit:delete-prev-char", "");
-  BIND_CMD("BACKSPACE",   "edit:delete-prev-char", "");
-  BIND_CMD("DC",          "edit:delete-prev-char", "");
-  BIND_CMD("DELETE",      "edit:delete-prev-char", "");
-
-  BIND_CMD("C-k",         "edit:delete-to-line-end", "");
-
-  BIND_CMD("C-t",         "edit:transpose-chars", "");
-
-  BIND_CMD("M-q",         "edit:fill-paragraph", "");
-
-  BIND_CMD("C-l",         "( edit:recenter ; redisplay )", "");
-
-  BIND_CMD("C-d",     "edit:delete-next-char", "");
-
-
-  /****************************************************************/
-  /**************************** EDITMULTI *************************/
-  /****************************************************************/
-
-  km_ew_multi = km = owl_keyhandler_create_and_add_keymap(kh, "editmulti",
-       "Multi-line text editing", 
-       owl_keys_editwin_default, NULL, owl_keys_editwin_postalways);
-  owl_keymap_set_submap(km_ew_multi, km_editwin);
-
-  BIND_CMD("UP",      "editmulti:move-up-line", "");
-  BIND_CMD("C-p",     "editmulti:move-up-line", "");
-  BIND_CMD("DOWN",    "editmulti:move-down-line", "");
-  BIND_CMD("C-n",     "editmulti:move-down-line", "");
-
-  /* This would be nice, but interferes with C-c to cancel */
-  /*BIND_CMD("C-c C-c", "editmulti:done", "sends the zephyr");*/
-
-  BIND_CMD("M-p",         "edit:history-prev", "");
-  BIND_CMD("M-n",         "edit:history-next", "");
-
-  /* note that changing "disable-ctrl-d" to "on" will change this to 
-   * edit:delete-next-char */
-  BIND_CMD("C-d",     "editmulti:done-or-delete", "sends the zephyr if at the end of the message");
-
-
-  /****************************************************************/
-  /**************************** EDITLINE **************************/
-  /****************************************************************/
-
-  km_ew_onel = km = owl_keyhandler_create_and_add_keymap(kh, "editline",
-       "Single-line text editing", 
-       owl_keys_editwin_default, NULL, owl_keys_editwin_postalways);
-  owl_keymap_set_submap(km_ew_onel, km_editwin);
-
-  BIND_CMD("C-u",         "edit:delete-all", "Clears the entire line");
-
-  BIND_CMD("UP",          "edit:history-prev", "");
-  BIND_CMD("C-p",         "edit:history-prev", "");
-  BIND_CMD("M-p",         "edit:history-prev", "");
-
-  BIND_CMD("DOWN",        "edit:history-next", "");
-  BIND_CMD("C-n",         "edit:history-next", "");
-  BIND_CMD("M-n",         "edit:history-next", "");
-
-  BIND_CMD("LF",          "editline:done", "executes the command");
-  BIND_CMD("CR",          "editline:done", "executes the command");
-
-  
-  /****************************************************************/
-  /**************************** EDITRESPONSE **********************/
-  /****************************************************************/
-
-  km_ew_onel = km = owl_keyhandler_create_and_add_keymap(kh, "editresponse",
-       "Single-line response to question", 
-       owl_keys_editwin_default, NULL, owl_keys_editwin_postalways);
-  owl_keymap_set_submap(km_ew_onel, km_editwin);
-
-  BIND_CMD("C-u",         "edit:delete-all", "Clears the entire line");
-
-  BIND_CMD("LF",          "editresponse:done", "executes the command");
-  BIND_CMD("CR",          "editresponse:done", "executes the command");
-
-
-  /****************************************************************/
-  /**************************** POPLESS ***************************/
-  /****************************************************************/
-
-  km_viewwin = km = owl_keyhandler_create_and_add_keymap(kh, "popless",
-       "Pop-up window (eg, help)", 
-       owl_keys_default_invalid, NULL, owl_keys_popless_postalways);
-  owl_keymap_set_submap(km_viewwin, km_global);
-
-  BIND_CMD("SPACE",       "popless:scroll-down-page", "");
-  BIND_CMD("NPAGE",       "popless:scroll-down-page", "");
-  BIND_CMD("M-n",         "popless:scroll-down-page", "");
-
-  BIND_CMD("b",           "popless:scroll-up-page", "");
-  BIND_CMD("PPAGE",       "popless:scroll-up-page", "")
-  BIND_CMD("M-p",         "popless:scroll-up-page", "");
-
-  BIND_CMD("CR",          "popless:scroll-down-line", "");
-  BIND_CMD("LF",          "popless:scroll-down-line", "");
-  BIND_CMD("DOWN",        "popless:scroll-down-line", "");
-  BIND_CMD("C-n",         "popless:scroll-down-line", "");
-
-  BIND_CMD("UP",          "popless:scroll-up-line", "");
-  BIND_CMD("C-h",         "popless:scroll-up-line", "");
-  BIND_CMD("C-p",         "popless:scroll-up-line", "");
-  BIND_CMD("DELETE",      "popless:scroll-up-line", "");
-  BIND_CMD("BACKSPACE",   "popless:scroll-up-line", "");
-  BIND_CMD("DC",          "popless:scroll-up-line", "");
-
-  BIND_CMD("RIGHT",       "popless:scroll-right 10", "scrolls right");
-  BIND_CMD("LEFT",        "popless:scroll-left  10", "scrolls left");
-
-  BIND_CMD("HOME",        "popless:scroll-to-top", "");
-  BIND_CMD("<",           "popless:scroll-to-top", "");
-  BIND_CMD("M-<",         "popless:scroll-to-top", "");
-
-  BIND_CMD("END",         "popless:scroll-to-bottom", "");
-  BIND_CMD(">",           "popless:scroll-to-bottom", "");
-  BIND_CMD("M->",         "popless:scroll-to-bottom", "");
-
-  BIND_CMD("q",           "popless:quit", "");
-  BIND_CMD("C-c",         "popless:quit", "");
-  BIND_CMD("C-g",         "popless:quit", "");
-
-  BIND_CMD("C-l",         "redisplay", "");
-
-
-  /****************************************************************/
-  /***************************** RECV *****************************/
-  /****************************************************************/
-
-  km_mainwin = km = owl_keyhandler_create_and_add_keymap(kh, "recv",
-	"Main window / message list",
-        owl_keys_default_invalid, owl_keys_recwin_prealways, NULL);
-  owl_keymap_set_submap(km_mainwin, km_global);
-  BIND_CMD("C-x C-c", "start-command quit", "");
-  BIND_CMD("F1",      "help",           "");
-  BIND_CMD("h",       "help",           "");
-  BIND_CMD("HELP",    "help",           "");
-  BIND_CMD("M-[ 2 8 ~",   "help",       "");
-
-  BIND_CMD(":",       "start-command",  "start a new command");
-  BIND_CMD("M-x",     "start-command",  "start a new command");
-
-  BIND_CMD("x",       "expunge",        "");
-  BIND_CMD("u",       "undelete",       "");
-  BIND_CMD("M-u",     "undelete view",  "undelete all messages in view");
-  BIND_CMD("d",       "delete",         "mark message for deletion");
-  BIND_CMD("M-D",     "delete view",    "mark all messages in view for deletion");
-  BIND_CMD("C-x k",   "smartzpunt -i",  "zpunt current <class,instance>");
-
-  BIND_CMD("X",   "( expunge ; view --home )", "expunge deletions and switch to home view");
-
-  BIND_CMD("v",   "start-command view ", "start a view command");
-  BIND_CMD("V",   "view --home",      "change to the home view ('all' by default)");
-  BIND_CMD("!",   "view -r",          "invert the current view filter");
-  BIND_CMD("M-n", "smartnarrow",      "narrow to a view based on the current message");
-  BIND_CMD("M-N", "smartnarrow -i",   "narrow to a view based on the current message, and consider instance pair");
-  BIND_CMD("M-p", "view personal", "");
-  
-  BIND_CMD("/",   "start-command search ", "start a search command");
-  BIND_CMD("?",   "start-command search -r ", "start a reverse search command");
-
-  BIND_CMD("LEFT",   "recv:shiftleft", "");
-  BIND_CMD("M-[ D",  "recv:shiftleft", "");
-  BIND_CMD("RIGHT",  "recv:shiftright","");
-  BIND_CMD("M-[ C",  "recv:shiftleft", "");
-  BIND_CMD("DOWN",   "recv:next",      "");
-  BIND_CMD("C-n",    "recv:next",      "");
-  BIND_CMD("M-[ B",  "recv:next",      "");
-  BIND_CMD("M-C-n",  "recv:next --smart-filter", "move to next message matching the current one"); 
-  BIND_CMD("UP",     "recv:prev",      "");
-  BIND_CMD("M-[ A",  "recv:prev",      "");
-  BIND_CMD("n",      "recv:next-notdel", "");
-  BIND_CMD("p",      "recv:prev-notdel", "");
-  BIND_CMD("C-p",    "recv:prev",        "");
-  BIND_CMD("M-C-p",  "recv:prev --smart-filter", "move to previous message matching the current one");
-  BIND_CMD("P",      "recv:next-personal", "");
-  BIND_CMD("M-P",    "recv:prev-personal", "");
-  BIND_CMD("M-<",    "recv:first",     "");
-  BIND_CMD("<",      "recv:first",     "");
-  BIND_CMD("M->",    "recv:last",      "");
-  BIND_CMD(">",      "recv:last",      "");
-  BIND_CMD("C-v",    "recv:pagedown",  "");
-  BIND_CMD("NPAGE",  "recv:pagedown",  "");
-  BIND_CMD("M-v",    "recv:pageup",    "");
-  BIND_CMD("PPAGE",  "recv:pageup",    "");
-
-  BIND_CMD("SPACE",     "recv:scroll  10", "scroll message down a page");
-  BIND_CMD("CR",        "recv:scroll   1", "scroll message down a line");
-  BIND_CMD("LF",        "recv:scroll   1", "scroll message down a line");
-  BIND_CMD("C-h"  ,     "recv:scroll  -1", "scroll message up a line");
-  BIND_CMD("DELETE",    "recv:scroll  -1", "scroll message up a line");
-  BIND_CMD("BACKSPACE", "recv:scroll  -1", "scroll message up a line");
-  BIND_CMD("DC",        "recv:scroll  -1", "scroll message up a line");
-  BIND_CMD("b",         "recv:scroll -10", "scroll message up a page");
-
-  BIND_CMD("C-l",       "redisplay",       "");
-
-  BIND_CMD("i",   "info",             "");
-  BIND_CMD("l",   "blist",            "");
-  BIND_CMD("B",   "alist",            "");
-  BIND_CMD("M",   "pop-message",      "");
-  BIND_CMD("T",   "delete trash",     "mark all 'trash' messages for deletion");
-
-  BIND_CMD("o",   "toggle-oneline", "");
-
-  BIND_CMD("A",   "away toggle",     "toggles away message on and off");
-
-  BIND_CMD("z",   "start-command zwrite ", "start a zwrite command");
-  BIND_CMD("a",   "start-command aimwrite ", "start an aimwrite command");
-  BIND_CMD("r",   "reply",            "reply to the current message");
-  BIND_CMD("R",   "reply sender",     "reply to sender of the current message");
-  BIND_CMD("C-r", "reply -e",         "reply to the current message, but allow editing of recipient");
-  BIND_CMD("M-r", "reply -e",         "reply to the current message, but allow editing of recipient");
-  BIND_CMD("M-R", "reply -e sender",  "reply to sender of the current message, but allow editing of recipient");
-
-  BIND_CMD("W",   "start-command webzephyr ", "start a webzephyr command");
-
-  BIND_CMD("C-c",  "",                "no effect in this mode");
-  BIND_CMD("C-g",  "",                "no effect in this mode");
-
-
-  /**********************/
-
-  owl_function_activate_keymap("recv");
-
-}
-
-
-/****************************************************************/
-/********************* Support Functions ************************/
-/****************************************************************/
-
-void owl_keys_recwin_prealways(owl_input j) {
-  /* Clear the message line on subsequent key presses */
-  owl_function_makemsg("");
-}
-
-void owl_keys_editwin_default(owl_input j) {
-  owl_editwin *e;
-  if (NULL != (e=owl_global_get_typwin(&g))) {
-       owl_editwin_process_char(e, j);
-  }
-}
-
-void owl_keys_editwin_postalways(owl_input j) {
-  owl_editwin *e;
-  if (NULL != (e=owl_global_get_typwin(&g))) {
-    owl_editwin_post_process_char(e, j);
-  }
-  owl_global_set_needrefresh(&g);
-}
-
-void owl_keys_popless_postalways(owl_input j) {
-  owl_viewwin *v = owl_global_get_viewwin(&g);
-  owl_popwin *pw = owl_global_get_popwin(&g);
-
-  if (pw && owl_popwin_is_active(pw) && v) {
-    owl_viewwin_redisplay(v, 1);
-  }  
-}
-
-void owl_keys_default_invalid(owl_input j) {
-  if (j.ch==ERR) return;
-  if (j.ch==410) return;
-  owl_keyhandler_invalidkey(owl_global_get_keyhandler(&g));
-}
-
Index: bfaim/Makefile.in
===================================================================
--- libfaim/Makefile.in	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,21 +1,0 @@
-CC=@CC@
-LIBS=@LIBS@
-LDFLAGS=@LDFLAGS@
-RANLIB=@RANLIB@
-OBJS=admin.o adverts.o auth.o bos.o buddylist.o bstream.o \
-     chat.o chatnav.o conn.o email.o ft.o icq.o im.o \
-     invite.o md5.o misc.o msgcookie.o locate.o \
-     popups.o rxhandlers.o rxqueue.o search.o service.o \
-     snac.o ssi.o stats.o tlv.o translate.o txqueue.o \
-     util.o odir.o bart.o
-CFLAGS=@CFLAGS@ -I. -DAIM_BUILDDATE=\"x\" -DAIM_BUILDTIME=\"x\"
-
-libfaim: $(OBJS)
-	$(AR) -r libfaim.a $(OBJS)
-	$(RANLIB) libfaim.a
-
-clean:
-	$(RM) *.o libfaim.a
-
-distclean: clean
-	$(RM) config.cache config.log config.status Makefile config.h TAGS *~ core
Index: bfaim/admin.c
===================================================================
--- libfaim/admin.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,238 +1,0 @@
-/*
- * Family 0x0007 - Account Administration.
- *
- * Used for stuff like changing the formating of your screen name, changing your 
- * email address, requesting an account confirmation email, getting account info, 
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-/*
- * Subtype 0x0002 - Request a bit of account info.
- *
- * Info should be one of the following:
- * 0x0001 - Screen name formatting
- * 0x0011 - Email address
- * 0x0013 - Unknown
- *
- */ 
-faim_export int aim_admin_getinfo(aim_session_t *sess, aim_conn_t *conn, fu16_t info)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 14)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0007, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0007, 0x0002, 0x0000, snacid);
-
-	aimbs_put16(&fr->data, info);
-	aimbs_put16(&fr->data, 0x0000);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtypes 0x0003 and 0x0005 - Parse account info.
- *
- * Called in reply to both an information request (subtype 0x0002) and 
- * an information change (subtype 0x0004).
- *
- */
-static int infochange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_rxcallback_t userfunc;
-	char *url=NULL, *sn=NULL, *email=NULL;
-	fu16_t perms, tlvcount, err=0;
-
-	perms = aimbs_get16(bs);
-	tlvcount = aimbs_get16(bs);
-
-	while (tlvcount && aim_bstream_empty(bs)) {
-		fu16_t type, length;
-
-		type = aimbs_get16(bs);
-		length = aimbs_get16(bs);
-
-		switch (type) {
-			case 0x0001: {
-				sn = aimbs_getstr(bs, length);
-			} break;
-
-			case 0x0004: {
-				url = aimbs_getstr(bs, length);
-			} break;
-
-			case 0x0008: {
-				err = aimbs_get16(bs);
-			} break;
-
-			case 0x0011: {
-				if (length == 0) {
-					email = (char*)malloc(13*sizeof(char));
-					strcpy(email, "*suppressed*");
-				} else
-					email = aimbs_getstr(bs, length);
-			} break;
-		}
-
-		tlvcount--;
-	}
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		userfunc(sess, rx, (snac->subtype == 0x0005) ? 1 : 0, perms, err, url, sn, email);
-
-	if (sn) free(sn);
-	if (url) free(url);
-	if (email) free(email);
-
-	return 1;
-}
-
-/*
- * Subtype 0x0004 - Set screenname formatting.
- *
- */
-faim_export int aim_admin_setnick(aim_session_t *sess, aim_conn_t *conn, const char *newnick)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+2+strlen(newnick))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid);
-
-	aim_tlvlist_add_raw(&tl, 0x0001, strlen(newnick), newnick);
-	
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-	
-	aim_tx_enqueue(sess, fr);
-
-
-	return 0;
-}
-
-/*
- * Subtype 0x0004 - Change password.
- *
- */
-faim_export int aim_admin_changepasswd(aim_session_t *sess, aim_conn_t *conn, const char *newpw, const char *curpw)
-{
-	aim_frame_t *fr;
-	aim_tlvlist_t *tl = NULL;
-	aim_snacid_t snacid;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+strlen(curpw)+4+strlen(newpw))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid);
-
-	/* new password TLV t(0002) */
-	aim_tlvlist_add_raw(&tl, 0x0002, strlen(newpw), newpw);
-
-	/* current password TLV t(0012) */
-	aim_tlvlist_add_raw(&tl, 0x0012, strlen(curpw), curpw);
-
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0004 - Change email address.
- *
- */
-faim_export int aim_admin_setemail(aim_session_t *sess, aim_conn_t *conn, const char *newemail)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+2+strlen(newemail))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0007, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0007, 0x0004, 0x0000, snacid);
-
-	aim_tlvlist_add_raw(&tl, 0x0011, strlen(newemail), newemail);
-	
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-	
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0006 - Request account confirmation.
- *
- * This will cause an email to be sent to the address associated with
- * the account.  By following the instructions in the mail, you can
- * get the TRIAL flag removed from your account.
- *
- */
-faim_export int aim_admin_reqconfirm(aim_session_t *sess, aim_conn_t *conn)
-{
-	return aim_genericreq_n(sess, conn, 0x0007, 0x0006);
-}
-
-/*
- * Subtype 0x0007 - Account confirmation request acknowledgement.
- *
- */
-static int accountconfirm(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t status;
-	aim_tlvlist_t *tl;
-
-	status = aimbs_get16(bs);
-	/* This is 0x0013 if unable to confirm at this time */
-
-	tl = aim_tlvlist_read(bs);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, status);
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if ((snac->subtype == 0x0003) || (snac->subtype == 0x0005))
-		return infochange(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0007)
-		return accountconfirm(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int admin_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x0007;
-	mod->version = 0x0001;
-	mod->toolid = 0x0010;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "admin", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/adverts.c
===================================================================
--- libfaim/adverts.c	(revision 862371bb6a5ff5a6491550028e73824b698508bb)
+++ 	(revision )
@@ -1,31 +1,0 @@
-/*
- * Family 0x0005 - Advertisements.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-faim_export int aim_ads_requestads(aim_session_t *sess, aim_conn_t *conn)
-{
-	return aim_genericreq_n(sess, conn, 0x0005, 0x0002);
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	return 0;
-}
-
-faim_internal int adverts_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x0005;
-	mod->version = 0x0001;
-	mod->toolid = 0x0001;
-	mod->toolversion = 0x0001;
-	mod->flags = 0;
-	strncpy(mod->name, "adverts", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/aim.h
===================================================================
--- libfaim/aim.h	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,1484 +1,0 @@
-/* 
- * Main libfaim header.  Must be included in client for prototypes/macros.
- *
- * "come on, i turned a chick lesbian; i think this is the hackish equivalent"
- *                                                -- Josh Myer
- *
- */
-
-#ifndef __AIM_H__
-#define __AIM_H__
-
-#define FAIM_VERSION_MAJOR 0
-#define FAIM_VERSION_MINOR 99
-#define FAIM_VERSION_MINORMINOR 1
-
-#include <faimconfig.h>
-#include <aim_cbtypes.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <time.h>
-
-#ifndef _WIN32
-#include <sys/time.h>
-#include <unistd.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#else
-#include <winsock.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* XXX adjust these based on autoconf-detected platform */
-typedef unsigned char fu8_t;
-typedef unsigned short fu16_t;
-typedef unsigned int fu32_t;
-typedef fu32_t aim_snacid_t;
-typedef fu16_t flap_seqnum_t;
-
-#if defined(mach) && defined(__APPLE__)
-#define gethostbyname(x) gethostbyname2(x, AF_INET) 
-#endif
-
-#if defined(_WIN32) && !defined(WIN32_STATIC)
-/*
- * For a win32 DLL, we define WIN32_INDLL if this file
- * is included while compiling the DLL. If its not 
- * defined (its included in a client app), the symbols
- * will be imported instead of exported.
- */
-#ifdef WIN32_INDLL
-#define faim_export __declspec(dllexport)
-#else 
-#define faim_export __declspec(dllimport)
-#endif /* WIN32_INDLL */
-#define faim_internal
-#else
-/*
- * Nothing normally needed for unix...
- */
-#define faim_export
-#define faim_internal
-#endif
-
-#ifndef FALSE
-#define FALSE (0)
-#endif
-
-#ifndef TRUE
-#define TRUE (!FALSE)
-#endif
-
-#ifndef bool
-#define bool fu8_t
-#endif
-
-/* 
- * Current Maximum Length for Screen Names (not including NULL) 
- *
- * Currently only names up to 16 characters can be registered
- * however it is aparently legal for them to be larger.
- */
-#define MAXSNLEN 97
-
-/*
- * Current Maximum Length for Instant Messages
- *
- * This was found basically by experiment, but not wholly
- * accurate experiment.  It should not be regarded
- * as completely correct.  But its a decent approximation.
- *
- * Note that although we can send this much, its impossible
- * for WinAIM clients (up through the latest (4.0.1957)) to
- * send any more than 1kb.  Amaze all your windows friends
- * with utterly oversized instant messages!
- *
- * XXX: the real limit is the total SNAC size at 8192. Fix this.
- * 
- */
-#define MAXMSGLEN 7987
-
-/*
- * Maximum size of a Buddy Icon.
- */
-#define MAXICONLEN 7168
-#define AIM_ICONIDENT "AVT1picture.id"
-
-/*
- * Current Maximum Length for Chat Room Messages
- *
- * This is actually defined by the protocol to be
- * dynamic, but I have yet to see due cause to 
- * define it dynamically here.  Maybe later.
- *
- */
-#define MAXCHATMSGLEN 512
-
-/**
- * Maximum length for the password of an ICQ account
- */
-#define MAXICQPASSLEN 8
-
-#define AIM_MD5_STRING "AOL Instant Messenger (SM)"
-
-/*
- * Client info.  Filled in by the client and passed in to 
- * aim_send_login().  The information ends up getting passed to OSCAR
- * through the initial login command.
- *
- */
-struct client_info_s {
-	const char *clientstring;
-	fu16_t clientid;
-	fu16_t major;
-	fu16_t minor;
-	fu16_t point;
-	fu16_t build;
-	fu32_t distrib;
-	const char *country; /* two-letter abbrev */
-	const char *lang; /* two-letter abbrev */
-};
-
-/* Needs to be checked */
-#define CLIENTINFO_AIM_3_5_1670 { \
-	"AOL Instant Messenger (SM), version 3.5.1670/WIN32", \
-	0x0004, \
-	0x0003, 0x0005, \
-	0x0000, 0x0686, \
-	0x0000002a, \
-	"us", "en", \
-}
-
-/* Needs to be checked */
-/* Latest winaim without ssi */
-#define CLIENTINFO_AIM_4_1_2010 { \
-	"AOL Instant Messenger (SM), version 4.1.2010/WIN32", \
-	0x0004, \
-	0x0004, 0x0001, \
-	0x0000, 0x07da, \
-	0x0000004b, \
-	"us", "en", \
-}
-
-/* Needs to be checked */
-#define CLIENTINFO_AIM_4_3_2188 { \
-	"AOL Instant Messenger (SM), version 4.3.2188/WIN32", \
-	0x0109, \
-	0x0400, 0x0003, \
-	0x0000, 0x088c, \
-	0x00000086, \
-	"us", "en", \
-}
-
-/* Needs to be checked */
-#define CLIENTINFO_AIM_4_8_2540 { \
-	"AOL Instant Messenger (SM), version 4.8.2540/WIN32", \
-	0x0109, \
-	0x0004, 0x0008, \
-	0x0000, 0x09ec, \
-	0x000000af, \
-	"us", "en", \
-}
-
-/* Needs to be checked */
-#define CLIENTINFO_AIM_5_0_2938 { \
-	"AOL Instant Messenger, version 5.0.2938/WIN32", \
-	0x0109, \
-	0x0005, 0x0000, \
-	0x0000, 0x0b7a, \
-	0x00000000, \
-	"us", "en", \
-}
-
-#define CLIENTINFO_AIM_5_1_3036 { \
-	"AOL Instant Messenger, version 5.1.3036/WIN32", \
-	0x0109, \
-	0x0005, 0x0001, \
-	0x0000, 0x0bdc, \
-	0x000000d2, \
-	"us", "en", \
-}
-
-#define CLIENTINFO_AIM_5_5_3415 { \
-	"AOL Instant Messenger, version 5.5.3415/WIN32", \
-	0x0109, \
-	0x0005, 0x0005, \
-	0x0000, 0x0057, \
-	0x000000ef, \
-	"us", "en", \
-}
-
-#define CLIENTINFO_ICHAT_1_0 { \
-	"Apple iChat", \
-	0x311a, \
-	0x0001, 0x0000, \
-	0x0000, 0x003c, \
-	0x000000c6, \
-	"us", "en", \
-}
-
-/* Needs to be checked */
-#define CLIENTINFO_ICQ_4_65_3281 { \
-	"ICQ Inc. - Product of ICQ (TM) 2000b.4.65.1.3281.85", \
-	0x010a, \
-	0x0004, 0x0041, \
-	0x0001, 0x0cd1, \
-	0x00000055, \
-	"us", "en", \
-}
-
-/* Needs to be checked */
-#define CLIENTINFO_ICQ_5_34_3728 { \
-	"ICQ Inc. - Product of ICQ (TM).2002a.5.34.1.3728.85", \
-	0x010a, \
-	0x0005, 0x0022, \
-	0x0001, 0x0e8f, \
-	0x00000055, \
-	"us", "en", \
-}
-
-#define CLIENTINFO_ICQ_5_45_3777 { \
-	"ICQ Inc. - Product of ICQ (TM).2003a.5.45.1.3777.85", \
-	0x010a, \
-	0x0005, 0x002d, \
-	0x0001, 0x0ec1, \
-	0x00000055, \
-	"us", "en", \
-}
-
-#define CLIENTINFO_ICQBASIC_14_3_1068 { \
-	"ICQBasic", \
-	0x010a, \
-	0x0014, 0x0003, \
-	0x0000, 0x042c, \
-	0x0000043d, \
-	"us", "en", \
-}
-
-#define CLIENTINFO_NETSCAPE_7_0_1 { \
-	"Netscape 2000 an approved user of AOL Instant Messenger (SM)", \
-	0x1d0d, \
-	0x0007, 0x0000, \
-	0x0001, 0x0000, \
-	0x00000058, \
-	"us", "en", \
-}
-
-#define CLIENTINFO_AIM_KNOWNGOOD CLIENTINFO_AIM_5_1_3036
-#define CLIENTINFO_ICQ_KNOWNGOOD CLIENTINFO_ICQ_5_45_3777
-
-/* 
- * These could be arbitrary, but its easier to use the actual AIM values 
- */
-#define AIM_CONN_TYPE_BOS		0x0002
-#define AIM_CONN_TYPE_ADS		0x0005
-#define AIM_CONN_TYPE_AUTH		0x0007
-#define AIM_CONN_TYPE_CHATNAV		0x000d
-#define AIM_CONN_TYPE_CHAT		0x000e
-#define AIM_CONN_TYPE_SEARCH		0x000f
-#define AIM_CONN_TYPE_ICON		0x0010
-#define AIM_CONN_TYPE_EMAIL		0x0018
-
-/* they start getting arbitrary for rendezvous stuff =) */
-#define AIM_CONN_TYPE_RENDEZVOUS	0xfffe /* these do not speak FLAP! */
-#define AIM_CONN_TYPE_LISTENER		0xffff /* socket waiting for accept() */
-
-/*
- * Subtypes, we need these for OFT stuff.
- */
-#define AIM_CONN_SUBTYPE_OFT_DIRECTIM	0x0001
-#define AIM_CONN_SUBTYPE_OFT_GETFILE	0x0002
-#define AIM_CONN_SUBTYPE_OFT_SENDFILE	0x0003
-#define AIM_CONN_SUBTYPE_OFT_BUDDYICON	0x0004
-#define AIM_CONN_SUBTYPE_OFT_VOICE	0x0005
-
-/*
- * Status values returned from aim_conn_new().  ORed together.
- */
-#define AIM_CONN_STATUS_READY		0x0001
-#define AIM_CONN_STATUS_INTERNALERR	0x0002
-#define AIM_CONN_STATUS_RESOLVERR	0x0040
-#define AIM_CONN_STATUS_CONNERR		0x0080
-#define AIM_CONN_STATUS_INPROGRESS	0x0100
-
-#define AIM_FRAMETYPE_FLAP		0x0000
-#define AIM_FRAMETYPE_OFT		0x0001
-
-typedef struct aim_conn_s {
-	int fd;
-	fu16_t type;
-	fu16_t subtype;
-	flap_seqnum_t seqnum;
-	fu32_t status;
-	void *priv; /* misc data the client may want to store */
-	void *internal; /* internal conn-specific libfaim data */
-	time_t lastactivity; /* time of last transmit */
-	int forcedlatency; 
-	void *handlerlist;
-	void *sessv; /* pointer to parent session */
-	void *inside; /* only accessible from inside libfaim */
-	struct aim_conn_s *next;
-} aim_conn_t;
-
-/*
- * Byte Stream type. Sort of.
- *
- * Use of this type serves a couple purposes:
- *   - Buffer/buflen pairs are passed all around everywhere. This turns
- *     that into one value, as well as abstracting it slightly.
- *   - Through the abstraction, it is possible to enable bounds checking
- *     for robustness at the cost of performance.  But a clean failure on
- *     weird packets is much better than a segfault.
- *   - I like having variables named "bs".
- *
- * Don't touch the insides of this struct.  Or I'll have to kill you.
- *
- */
-typedef struct aim_bstream_s {
-	fu8_t *data;
-	fu32_t len;
-	fu32_t offset;
-} aim_bstream_t;
-
-typedef struct aim_frame_s {
-	fu8_t hdrtype; /* defines which piece of the union to use */
-	union {
-		struct { 
-			fu8_t type;
-			flap_seqnum_t seqnum;     
-		} flap;
-		struct {
-			fu8_t magic[4]; /* ODC2 or OFT2 */
-			fu16_t hdrlen;
-			fu16_t type;
-		} rend;
-	} hdr;
-	aim_bstream_t data;	/* payload stream */
-	fu8_t handled;		/* 0 = new, !0 = been handled */
-	fu8_t nofree;		/* 0 = free data on purge, 1 = only unlink */
-	aim_conn_t *conn;	/* the connection it came in on... */
-	struct aim_frame_s *next;
-} aim_frame_t;
-
-typedef struct aim_msgcookie_s {
-	fu8_t cookie[8];
-	int type;
-	void *data;
-	time_t addtime;
-	struct aim_msgcookie_s *next;
-} aim_msgcookie_t;
-
-/*
- * AIM Session: The main client-data interface.  
- *
- */
-typedef struct aim_session_s {
-
-	/* ---- Client Accessible ------------------------ */
-
-	/* Our screen name. */
-	char sn[MAXSNLEN+1];
-
-	/*
-	 * Pointer to anything the client wants to 
-	 * explicitly associate with this session.
-	 *
-	 * This is for use in the callbacks mainly. In any
-	 * callback, you can access this with sess->aux_data.
-	 *
-	 */
-	void *aux_data;
-
-	/* ---- Internal Use Only ------------------------ */
-
-	/* Connection information */
-	aim_conn_t *connlist;
-
-	/*
-	 * Transmit/receive queues.
-	 *
-	 * These are only used when you don't use your own lowlevel
-	 * I/O.  I don't suggest that you use libfaim's internal I/O.
-	 * Its really bad and the API/event model is quirky at best.
-	 *  
-	 */
-	aim_frame_t *queue_outgoing;   
-	aim_frame_t *queue_incoming; 
-
-	/*
-	 * Tx Enqueuing function.
-	 *
-	 * This is how you override the transmit direction of libfaim's
-	 * internal I/O.  This function will be called whenever it needs
-	 * to send something.
-	 *
-	 */
-	int (*tx_enqueue)(struct aim_session_s *, aim_frame_t *);
-
-	void *modlistv;
-
-	struct {
-		char server[128];
-		char username[128];
-		char password[128];
-	} socksproxy;
-
-	bool nonblocking;
-
-	int debug;
-	void (*debugcb)(struct aim_session_s *sess, int level, const char *format, va_list va); /* same as faim_debugging_callback_t */
-
-	/*
-	 * Outstanding snac handling 
-	 *
-	 * XXX: Should these be per-connection? -mid
-	 */
-	void *snac_hash[FAIM_SNAC_HASH_SIZE];
-	aim_snacid_t snacid_next;
-
-	aim_msgcookie_t *msgcookies;
-	struct aim_icq_info *icq_info;
-	struct aim_oft_info *oft_info;
-	struct aim_authresp_info *authinfo;
-	struct aim_emailinfo *emailinfo;
-
-	struct {
-		struct aim_userinfo_s *userinfo;
-		struct userinfo_node *torequest;
-		struct userinfo_node *requested;
-		int waiting_for_response;
-	} locate;
-
-	/* Server-stored information (ssi) */
-	struct {
-		int received_data;
-		fu16_t numitems;
-		struct aim_ssi_item *official;
-		struct aim_ssi_item *local;
-		struct aim_ssi_tmp *pending;
-		time_t timestamp;
-		int waiting_for_ack;
-	} ssi;
-} aim_session_t;
-
-/* Valid for calling aim_icq_setstatus() and for aim_userinfo_t->icqinfo.status */
-#define AIM_ICQ_STATE_NORMAL		0x00000000
-#define AIM_ICQ_STATE_AWAY		0x00000001
-#define AIM_ICQ_STATE_DND		0x00000002
-#define AIM_ICQ_STATE_OUT		0x00000004
-#define AIM_ICQ_STATE_BUSY		0x00000010
-#define AIM_ICQ_STATE_CHAT		0x00000020
-#define AIM_ICQ_STATE_INVISIBLE		0x00000100
-#define AIM_ICQ_STATE_WEBAWARE		0x00010000
-#define AIM_ICQ_STATE_HIDEIP		0x00020000
-#define AIM_ICQ_STATE_BIRTHDAY		0x00080000
-#define AIM_ICQ_STATE_DIRECTDISABLED	0x00100000
-#define AIM_ICQ_STATE_ICQHOMEPAGE	0x00200000
-#define AIM_ICQ_STATE_DIRECTREQUIREAUTH	0x10000000
-#define AIM_ICQ_STATE_DIRECTCONTACTLIST	0x20000000
-
-
-
-/*
- * Get command from connections
- *
- * aim_get_commmand() is the libfaim lowlevel I/O in the receive direction.
- * XXX Make this easily overridable.
- *
- */
-faim_export int aim_get_command(aim_session_t *, aim_conn_t *);
-
-/*
- * Dispatch commands that are in the rx queue.
- */
-faim_export void aim_rxdispatch(aim_session_t *);
-
-faim_export int aim_debugconn_sendconnect(aim_session_t *sess, aim_conn_t *conn);
-
-faim_export int aim_logoff(aim_session_t *);
-
-#if !defined(FAIM_INTERNAL) || defined(FAIM_INTERNAL_INSANE)
-/* the library should never call aim_conn_kill */
-faim_export void aim_conn_kill(aim_session_t *sess, aim_conn_t **deadconn);
-#endif
-
-typedef int (*aim_rxcallback_t)(aim_session_t *, aim_frame_t *, ...);
-
-
-/* auth.c */
-struct aim_clientrelease {
-	char *name;
-	fu32_t build;
-	char *url;
-	char *info;
-};
-
-struct aim_authresp_info {
-	char *sn;
-	fu16_t errorcode;
-	char *errorurl;
-	fu16_t regstatus;
-	char *email;
-	char *bosip;
-	fu16_t cookielen;
-	fu8_t *cookie;
-	char *chpassurl;
-	struct aim_clientrelease latestrelease;
-	struct aim_clientrelease latestbeta;
-};
-
-/* Callback data for redirect. */
-struct aim_redirect_data {
-	fu16_t group;
-	const char *ip;
-	fu16_t cookielen;
-	const fu8_t *cookie;
-	struct { /* group == AIM_CONN_TYPE_CHAT */
-		fu16_t exchange;
-		const char *room;
-		fu16_t instance;
-	} chat;
-};
-
-faim_export int aim_clientready(aim_session_t *sess, aim_conn_t *conn);
-faim_export int aim_sendflapver(aim_session_t *sess, aim_conn_t *conn);
-faim_export int aim_request_login(aim_session_t *sess, aim_conn_t *conn, const char *sn);
-faim_export int aim_send_login(aim_session_t *, aim_conn_t *, const char *, const char *, struct client_info_s *, const char *key);
-faim_export void aim_purge_rxqueue(aim_session_t *);
-faim_export void aim_cleansnacs(aim_session_t *, int maxage);
-
-#define AIM_TX_QUEUED    0 /* default */
-#define AIM_TX_IMMEDIATE 1
-#define AIM_TX_USER      2
-faim_export int aim_tx_setenqueue(aim_session_t *sess, int what, int (*func)(aim_session_t *, aim_frame_t *));
-
-faim_export int aim_tx_flushqueue(aim_session_t *);
-faim_export void aim_tx_purgequeue(aim_session_t *);
-
-faim_export int aim_conn_setlatency(aim_conn_t *conn, int newval);
-
-faim_export int aim_conn_addhandler(aim_session_t *, aim_conn_t *conn, fu16_t family, fu16_t type, aim_rxcallback_t newhandler, fu16_t flags);
-faim_export int aim_clearhandlers(aim_conn_t *conn);
-
-faim_export aim_conn_t *aim_conn_findbygroup(aim_session_t *sess, fu16_t group);
-faim_export aim_session_t *aim_conn_getsess(aim_conn_t *conn);
-faim_export void aim_conn_close(aim_conn_t *deadconn);
-faim_export aim_conn_t *aim_newconn(aim_session_t *, int type, const char *dest);
-faim_export int aim_conngetmaxfd(aim_session_t *);
-faim_export aim_conn_t *aim_select(aim_session_t *, struct timeval *, int *);
-faim_export int aim_conn_in_sess(aim_session_t *sess, aim_conn_t *conn);
-faim_export int aim_conn_isready(aim_conn_t *);
-faim_export int aim_conn_setstatus(aim_conn_t *, int);
-faim_export int aim_conn_completeconnect(aim_session_t *sess, aim_conn_t *conn);
-faim_export int aim_conn_isconnecting(aim_conn_t *conn);
-
-typedef void (*faim_debugging_callback_t)(aim_session_t *sess, int level, const char *format, va_list va);
-faim_export int aim_setdebuggingcb(aim_session_t *sess, faim_debugging_callback_t);
-faim_export void aim_session_init(aim_session_t *, bool nonblocking, int debuglevel);
-faim_export void aim_session_kill(aim_session_t *);
-faim_export void aim_setupproxy(aim_session_t *sess, const char *server, const char *username, const char *password);
-faim_export aim_conn_t *aim_getconn_type(aim_session_t *, int type);
-faim_export aim_conn_t *aim_getconn_type_all(aim_session_t *, int type);
-faim_export aim_conn_t *aim_getconn_fd(aim_session_t *, int fd);
-
-
-
-/* 0x0001 - service.c */
-faim_export int aim_srv_setavailmsg(aim_session_t *sess, char *msg);
-faim_export int aim_srv_setidle(aim_session_t *sess, fu32_t idletime);
-
-
-
-/* misc.c */
-
-#define AIM_VISIBILITYCHANGE_PERMITADD    0x05
-#define AIM_VISIBILITYCHANGE_PERMITREMOVE 0x06
-#define AIM_VISIBILITYCHANGE_DENYADD      0x07
-#define AIM_VISIBILITYCHANGE_DENYREMOVE   0x08
-
-#define AIM_PRIVFLAGS_ALLOWIDLE           0x01
-#define AIM_PRIVFLAGS_ALLOWMEMBERSINCE    0x02
-
-#define AIM_WARN_ANON                     0x01
-
-faim_export int aim_sendpauseack(aim_session_t *sess, aim_conn_t *conn);
-faim_export int aim_nop(aim_session_t *, aim_conn_t *);
-faim_export int aim_flap_nop(aim_session_t *sess, aim_conn_t *conn);
-faim_export int aim_bos_changevisibility(aim_session_t *, aim_conn_t *, int, const char *);
-faim_export int aim_bos_setgroupperm(aim_session_t *, aim_conn_t *, fu32_t mask);
-faim_export int aim_bos_setprivacyflags(aim_session_t *, aim_conn_t *, fu32_t);
-faim_export int aim_reqpersonalinfo(aim_session_t *, aim_conn_t *);
-faim_export int aim_reqservice(aim_session_t *, aim_conn_t *, fu16_t);
-faim_export int aim_bos_reqrights(aim_session_t *, aim_conn_t *);
-faim_export int aim_setextstatus(aim_session_t *sess, fu32_t status);
-
-#define AIM_CLIENTTYPE_UNKNOWN  0x0000
-#define AIM_CLIENTTYPE_MC       0x0001
-#define AIM_CLIENTTYPE_WINAIM   0x0002
-#define AIM_CLIENTTYPE_WINAIM41 0x0003
-#define AIM_CLIENTTYPE_AOL_TOC  0x0004
-faim_export fu16_t aim_im_fingerprint(const fu8_t *msghdr, int len);
-
-#define AIM_RATE_CODE_CHANGE     0x0001
-#define AIM_RATE_CODE_WARNING    0x0002
-#define AIM_RATE_CODE_LIMIT      0x0003
-#define AIM_RATE_CODE_CLEARLIMIT 0x0004
-faim_export int aim_ads_requestads(aim_session_t *sess, aim_conn_t *conn);
-
-
-
-/* im.c */
-#define AIM_OFT_SUBTYPE_SEND_FILE	0x0001
-#define AIM_OFT_SUBTYPE_SEND_DIR	0x0002
-#define AIM_OFT_SUBTYPE_GET_FILE	0x0011
-#define AIM_OPT_SUBTYPE_GET_LIST	0x0012
-
-#define AIM_TRANSFER_DENY_NOTSUPPORTED	0x0000
-#define AIM_TRANSFER_DENY_DECLINE	0x0001
-#define AIM_TRANSFER_DENY_NOTACCEPTING	0x0002
-
-#define AIM_IMPARAM_FLAG_CHANMSGS_ALLOWED	0x00000001
-#define AIM_IMPARAM_FLAG_MISSEDCALLS_ENABLED	0x00000002
-
-/* This is what the server will give you if you don't set them yourself. */
-#define AIM_IMPARAM_DEFAULTS { \
-	0, \
-	AIM_IMPARAM_FLAG_CHANMSGS_ALLOWED | AIM_IMPARAM_FLAG_MISSEDCALLS_ENABLED, \
-	512, /* !! Note how small this is. */ \
-	(99.9)*10, (99.9)*10, \
-	1000 /* !! And how large this is. */ \
-}
-
-/* This is what most AIM versions use. */
-#define AIM_IMPARAM_REASONABLE { \
-	0, \
-	AIM_IMPARAM_FLAG_CHANMSGS_ALLOWED | AIM_IMPARAM_FLAG_MISSEDCALLS_ENABLED, \
-	8000, \
-	(99.9)*10, (99.9)*10, \
-	0 \
-}
-
-struct aim_icbmparameters {
-	fu16_t maxchan;
-	fu32_t flags; /* AIM_IMPARAM_FLAG_ */
-	fu16_t maxmsglen; /* message size that you will accept */
-	fu16_t maxsenderwarn; /* this and below are *10 (999=99.9%) */
-	fu16_t maxrecverwarn;
-	fu32_t minmsginterval; /* in milliseconds? */
-};
-
-struct aim_chat_roominfo {
-	fu16_t exchange;
-	char *name;
-	fu16_t instance;
-};
-
-#define AIM_IMFLAGS_AWAY		0x0001 /* mark as an autoreply */
-#define AIM_IMFLAGS_ACK			0x0002 /* request a receipt notice */
-#define AIM_IMFLAGS_UNICODE		0x0004
-#define AIM_IMFLAGS_ISO_8859_1		0x0008
-#define AIM_IMFLAGS_BUDDYREQ		0x0010 /* buddy icon requested */
-#define AIM_IMFLAGS_HASICON		0x0020 /* already has icon */
-#define AIM_IMFLAGS_SUBENC_MACINTOSH	0x0040 /* damn that Steve Jobs! */
-#define AIM_IMFLAGS_CUSTOMFEATURES 	0x0080 /* features field present */
-#define AIM_IMFLAGS_EXTDATA		0x0100
-#define AIM_IMFLAGS_X			0x0200
-#define AIM_IMFLAGS_MULTIPART		0x0400 /* ->mpmsg section valid */
-#define AIM_IMFLAGS_OFFLINE		0x0800 /* send to offline user */
-#define AIM_IMFLAGS_TYPINGNOT		0x1000 /* typing notification */
-
-/*
- * Multipart message structures.
- */
-typedef struct aim_mpmsg_section_s {
-	fu16_t charset;
-	fu16_t charsubset;
-	fu8_t *data;
-	fu16_t datalen;
-	struct aim_mpmsg_section_s *next;
-} aim_mpmsg_section_t;
-
-typedef struct aim_mpmsg_s {
-	int numparts;
-	aim_mpmsg_section_t *parts;
-} aim_mpmsg_t;
-
-faim_export int aim_mpmsg_init(aim_session_t *sess, aim_mpmsg_t *mpm);
-faim_export int aim_mpmsg_addraw(aim_session_t *sess, aim_mpmsg_t *mpm, fu16_t charset, fu16_t charsubset, const fu8_t *data, fu16_t datalen);
-faim_export int aim_mpmsg_addascii(aim_session_t *sess, aim_mpmsg_t *mpm, const char *ascii);
-faim_export int aim_mpmsg_addunicode(aim_session_t *sess, aim_mpmsg_t *mpm, const fu16_t *unicode, fu16_t unicodelen);
-faim_export void aim_mpmsg_free(aim_session_t *sess, aim_mpmsg_t *mpm);
-
-/*
- * Arguments to aim_send_im_ext().
- *
- * This is really complicated.  But immensely versatile.
- *
- */
-struct aim_sendimext_args {
-
-	/* These are _required_ */
-	const char *destsn;
-	fu32_t flags; /* often 0 */
-
-	/* Only required if not using multipart messages */
-	const char *msg;
-	int msglen;
-
-	/* Required if ->msg is not provided */
-	aim_mpmsg_t *mpmsg;
-
-	/* Only used if AIM_IMFLAGS_HASICON is set */
-	fu32_t iconlen;
-	time_t iconstamp;
-	fu32_t iconsum;
-
-	/* Only used if AIM_IMFLAGS_CUSTOMFEATURES is set */
-	fu8_t *features;
-	fu8_t featureslen;
-
-	/* Only used if AIM_IMFLAGS_CUSTOMCHARSET is set and mpmsg not used */
-	fu16_t charset;
-	fu16_t charsubset;
-};
-
-/*
- * Arguments to aim_send_rtfmsg().
- */
-struct aim_sendrtfmsg_args {
-	const char *destsn;
-	fu32_t fgcolor;
-	fu32_t bgcolor;
-	const char *rtfmsg; /* must be in RTF */
-};
-
-/*
- * This information is provided in the Incoming ICBM callback for
- * Channel 1 ICBM's.  
- *
- * Note that although CUSTOMFEATURES and CUSTOMCHARSET say they
- * are optional, both are always set by the current libfaim code.
- * That may or may not change in the future.  It is mainly for
- * consistency with aim_sendimext_args.
- *
- * Multipart messages require some explanation. If you want to use them,
- * I suggest you read all the comments in im.c.
- *
- */
-struct aim_incomingim_ch1_args {
-
-	/* Always provided */
-	aim_mpmsg_t mpmsg;
-	fu32_t icbmflags; /* some flags apply only to ->msg, not all mpmsg */
-	
-	/* Only provided if message has a human-readable section */
-	char *msg;
-	int msglen;
-
-	/* Only provided if AIM_IMFLAGS_HASICON is set */
-	time_t iconstamp;
-	fu32_t iconlen;
-	fu16_t iconsum;
-
-	/* Only provided if AIM_IMFLAGS_CUSTOMFEATURES is set */
-	fu8_t *features;
-	fu8_t featureslen;
-
-	/* Only provided if AIM_IMFLAGS_EXTDATA is set */
-	fu8_t extdatalen;
-	fu8_t *extdata;
-
-	/* Only used if AIM_IMFLAGS_CUSTOMCHARSET is set */
-	fu16_t charset;
-	fu16_t charsubset;
-};
-
-/* Valid values for channel 2 args->status */
-#define AIM_RENDEZVOUS_PROPOSE	0x0000
-#define AIM_RENDEZVOUS_CANCEL	0x0001
-#define AIM_RENDEZVOUS_ACCEPT	0x0002
-
-struct aim_incomingim_ch2_args {
-	fu16_t status;
-	fu8_t cookie[8];
-	int reqclass;
-	const char *proxyip;
-	const char *clientip;
-	const char *verifiedip;
-	fu16_t port;
-	fu16_t errorcode;
-	const char *msg; /* invite message or file description */
-	const char *encoding;
-	const char *language;
-	union {
-		struct {
-			fu32_t checksum;
-			fu32_t length;
-			time_t timestamp;
-			fu8_t *icon;
-		} icon;
-		struct {
-			struct aim_chat_roominfo roominfo;
-		} chat;
-		struct {
-			fu32_t fgcolor;
-			fu32_t bgcolor;
-			const char *rtfmsg;
-		} rtfmsg;
-		struct {
-			fu16_t subtype;
-			fu16_t totfiles;
-			fu32_t totsize;
-			char *filename;
-		} sendfile;
-	} info;
-	void *destructor; /* used internally only */
-};
-
-/* Valid values for channel 4 args->type */
-#define AIM_ICQMSG_AUTHREQUEST	0x0006
-#define AIM_ICQMSG_AUTHDENIED	0x0007
-#define AIM_ICQMSG_AUTHGRANTED	0x0008
-
-struct aim_incomingim_ch4_args {
-	fu32_t uin; /* Of the sender of the ICBM */
-	fu8_t type;
-	fu8_t flags;
-	char *msg; /* Reason for auth request, deny, or accept */
-	int msglen;
-};
-
-/* SNAC sending functions */
-/* 0x0002 */ faim_export int aim_im_setparams(aim_session_t *sess, struct aim_icbmparameters *params);
-/* 0x0004 */ faim_export int aim_im_reqparams(aim_session_t *sess);
-/* 0x0006 */ faim_export int aim_im_sendch1_ext(aim_session_t *sess, struct aim_sendimext_args *args);
-/* 0x0006 */ faim_export int aim_im_sendch1(aim_session_t *, const char *destsn, fu16_t flags, const char *msg);
-/* 0x0006 */ faim_export int aim_im_sendch2_icon(aim_session_t *sess, const char *sn, const fu8_t *icon, int iconlen, time_t stamp, fu16_t iconsum);
-/* 0x0006 */ faim_export int aim_im_sendch2_rtfmsg(aim_session_t *sess, struct aim_sendrtfmsg_args *args);
-/* 0x0006 */ faim_export int aim_im_sendch2_odcrequest(aim_session_t *sess, fu8_t *cookie, const char *sn, const fu8_t *ip, fu16_t port);
-/* 0x0006 */ faim_export int aim_im_sendch2_sendfile_ask(aim_session_t *sess, struct aim_oft_info *oft_info);
-/* 0x0006 */ faim_export int aim_im_sendch2_sendfile_accept(aim_session_t *sess, struct aim_oft_info *info);
-/* 0x0006 */ faim_export int aim_im_sendch2_sendfile_cancel(aim_session_t *sess, struct aim_oft_info *oft_info);
-/* 0x0006 */ faim_export int aim_im_sendch2_geticqaway(aim_session_t *sess, const char *sn, int type);
-/* 0x0006 */ faim_export int aim_im_sendch4(aim_session_t *sess, char *sn, fu16_t type, fu8_t *message);
-/* 0x0008 */ faim_export int aim_im_warn(aim_session_t *sess, aim_conn_t *conn, const char *destsn, fu32_t flags);
-/* 0x000b */ faim_export int aim_im_denytransfer(aim_session_t *sess, const char *sender, const char *cookie, fu16_t code);
-/* 0x0014 */ faim_export int aim_im_sendmtn(aim_session_t *sess, fu16_t type1, const char *sn, fu16_t type2);
-
-
-
-/* ft.c */
-struct aim_fileheader_t {
-#if 0
-	char magic[4];		/* 0 */
-	fu16_t hdrlen;		/* 4 */
-	fu16_t hdrtype;		/* 6 */
-#endif
-	char bcookie[8];	/* 8 */
-	fu16_t encrypt;		/* 16 */
-	fu16_t compress;	/* 18 */
-	fu16_t totfiles;	/* 20 */
-	fu16_t filesleft;	/* 22 */
-	fu16_t totparts;	/* 24 */
-	fu16_t partsleft;	/* 26 */
-	fu32_t totsize;		/* 28 */
-	fu32_t size;		/* 32 */
-	fu32_t modtime;		/* 36 */
-	fu32_t checksum;	/* 40 */
-	fu32_t rfrcsum;		/* 44 */
-	fu32_t rfsize;		/* 48 */
-	fu32_t cretime;		/* 52 */
-	fu32_t rfcsum;		/* 56 */
-	fu32_t nrecvd;		/* 60 */
-	fu32_t recvcsum;	/* 64 */
-	fu8_t idstring[32];	/* 68 */
-	fu8_t flags;		/* 100 */
-	fu8_t lnameoffset;	/* 101 */
-	fu8_t lsizeoffset;	/* 102 */
-	char dummy[69];		/* 103 */
-	char macfileinfo[16];	/* 172 */
-	fu16_t nencode;		/* 188 */
-	fu16_t nlanguage;	/* 190 */
-	char name[64];		/* 192 */
-				/* 256 */
-};
-
-struct aim_oft_info {
-	char cookie[8];
-	char *sn;
-	char *proxyip;
-	char *clientip;
-	char *verifiedip;
-	fu16_t port;
-	aim_conn_t *conn;
-	aim_session_t *sess;
-	struct aim_fileheader_t fh;
-	struct aim_oft_info *next;
-};
-
-faim_export fu32_t aim_oft_checksum_chunk(const fu8_t *buffer, int bufferlen, fu32_t prevcheck);
-faim_export fu32_t aim_oft_checksum_file(char *filename);
-faim_export int aim_handlerendconnect(aim_session_t *sess, aim_conn_t *cur);
-faim_export int aim_odc_send_typing(aim_session_t *sess, aim_conn_t *conn, int typing);
-faim_export int aim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *msg, int len, int encoding, int isawaymsg);
-faim_export const char *aim_odc_getsn(aim_conn_t *conn);
-faim_export aim_conn_t *aim_odc_getconn(aim_session_t *sess, const char *sn);
-faim_export aim_conn_t *aim_odc_initiate(aim_session_t *sess, const char *sn);
-faim_export aim_conn_t *aim_odc_connect(aim_session_t *sess, const char *sn, const char *addr, const fu8_t *cookie);
-
-faim_export struct aim_oft_info *aim_oft_createinfo(aim_session_t *sess, const fu8_t *cookie, const char *sn, const char *ip, fu16_t port, fu32_t size, fu32_t modtime, char *filename);
-faim_export int aim_oft_destroyinfo(struct aim_oft_info *oft_info);
-faim_export int aim_sendfile_listen(aim_session_t *sess, struct aim_oft_info *oft_info);
-faim_export int aim_oft_sendheader(aim_session_t *sess, fu16_t type, struct aim_oft_info *oft_info);
-
-
-
-/* 0x0002 - locate.c */
-/*
- * AIM User Info, Standard Form.
- */
-#define AIM_FLAG_UNCONFIRMED	0x0001 /* "damned transients" */
-#define AIM_FLAG_ADMINISTRATOR	0x0002
-#define AIM_FLAG_AOL			0x0004
-#define AIM_FLAG_OSCAR_PAY		0x0008
-#define AIM_FLAG_FREE 			0x0010
-#define AIM_FLAG_AWAY			0x0020
-#define AIM_FLAG_ICQ			0x0040
-#define AIM_FLAG_WIRELESS		0x0080
-#define AIM_FLAG_UNKNOWN100		0x0100
-#define AIM_FLAG_UNKNOWN200		0x0200
-#define AIM_FLAG_ACTIVEBUDDY	0x0400
-#define AIM_FLAG_UNKNOWN800		0x0800
-#define AIM_FLAG_ABINTERNAL		0x1000
-#define AIM_FLAG_ALLUSERS		0x001f
-
-#define AIM_USERINFO_PRESENT_FLAGS        0x00000001
-#define AIM_USERINFO_PRESENT_MEMBERSINCE  0x00000002
-#define AIM_USERINFO_PRESENT_ONLINESINCE  0x00000004
-#define AIM_USERINFO_PRESENT_IDLE         0x00000008
-#define AIM_USERINFO_PRESENT_ICQEXTSTATUS 0x00000010
-#define AIM_USERINFO_PRESENT_ICQIPADDR    0x00000020
-#define AIM_USERINFO_PRESENT_ICQDATA      0x00000040
-#define AIM_USERINFO_PRESENT_CAPABILITIES 0x00000080
-#define AIM_USERINFO_PRESENT_SESSIONLEN   0x00000100
-#define AIM_USERINFO_PRESENT_CREATETIME   0x00000200
-
-struct userinfo_node {
-	char *sn;
-	struct userinfo_node *next;
-};
-
-typedef struct aim_userinfo_s {
-	char *sn;
-	fu16_t warnlevel; /* evil percent * 10 (999 = 99.9%) */
-	fu16_t idletime; /* in seconds */
-	fu16_t flags;
-	fu32_t createtime; /* time_t */
-	fu32_t membersince; /* time_t */
-	fu32_t onlinesince; /* time_t */
-	fu32_t sessionlen;  /* in seconds */
-	fu32_t capabilities;
-	struct {
-		fu32_t status;
-		fu32_t ipaddr;
-		fu8_t crap[0x25]; /* until we figure it out... */
-	} icqinfo;
-	fu32_t present;
-
-	fu16_t iconcsumlen;
-	fu8_t *iconcsum;
-
-	char *info;
-	char *info_encoding;
-	fu16_t info_len;
-
-	char *avail;
-	char *avail_encoding;
-	fu16_t avail_len;
-
-	char *away;
-	char *away_encoding;
-	fu16_t away_len;
-
-	struct aim_userinfo_s *next;
-} aim_userinfo_t;
-
-#define AIM_CAPS_BUDDYICON		0x00000001
-#define AIM_CAPS_VOICE			0x00000002
-#define AIM_CAPS_DIRECTIM		0x00000004
-#define AIM_CAPS_CHAT			0x00000008
-#define AIM_CAPS_GETFILE		0x00000010
-#define AIM_CAPS_SENDFILE		0x00000020
-#define AIM_CAPS_GAMES			0x00000040
-#define AIM_CAPS_SAVESTOCKS		0x00000080
-#define AIM_CAPS_SENDBUDDYLIST	0x00000100
-#define AIM_CAPS_GAMES2			0x00000200
-#define AIM_CAPS_ICQ_DIRECT		0x00000400
-#define AIM_CAPS_APINFO			0x00000800
-#define AIM_CAPS_ICQRTF			0x00001000
-#define AIM_CAPS_EMPTY			0x00002000
-#define AIM_CAPS_ICQSERVERRELAY	0x00004000
-#define AIM_CAPS_ICQUTF8OLD		0x00008000
-#define AIM_CAPS_TRILLIANCRYPT	0x00010000
-#define AIM_CAPS_ICQUTF8		0x00020000
-#define AIM_CAPS_INTEROPERATE	0x00040000
-#define AIM_CAPS_ICHAT			0x00080000
-#define AIM_CAPS_HIPTOP			0x00100000
-#define AIM_CAPS_SECUREIM		0x00200000
-#define AIM_CAPS_SMS			0x00400000
-#define AIM_CAPS_GENERICUNKNOWN	0x00800000
-#define AIM_CAPS_VIDEO			0x01000000
-#define AIM_CAPS_LAST			0x02000000
-
-#define AIM_SENDMEMBLOCK_FLAG_ISREQUEST  0
-#define AIM_SENDMEMBLOCK_FLAG_ISHASH     1
-
-faim_export int aim_sendmemblock(aim_session_t *sess, aim_conn_t *conn, fu32_t offset, fu32_t len, const fu8_t *buf, fu8_t flag);
-
-struct aim_invite_priv {
-	char *sn;
-	char *roomname;
-	fu16_t exchange;
-	fu16_t instance;
-};
-
-#define AIM_COOKIETYPE_UNKNOWN  0x00
-#define AIM_COOKIETYPE_ICBM     0x01
-#define AIM_COOKIETYPE_ADS      0x02
-#define AIM_COOKIETYPE_BOS      0x03
-#define AIM_COOKIETYPE_IM       0x04
-#define AIM_COOKIETYPE_CHAT     0x05
-#define AIM_COOKIETYPE_CHATNAV  0x06
-#define AIM_COOKIETYPE_INVITE   0x07
-/* we'll move OFT up a bit to give breathing room.  not like it really
- * matters. */
-#define AIM_COOKIETYPE_OFTIM    0x10
-#define AIM_COOKIETYPE_OFTGET   0x11
-#define AIM_COOKIETYPE_OFTSEND  0x12
-#define AIM_COOKIETYPE_OFTVOICE 0x13
-#define AIM_COOKIETYPE_OFTIMAGE 0x14
-#define AIM_COOKIETYPE_OFTICON  0x15
-
-faim_export aim_userinfo_t *aim_locate_finduserinfo(aim_session_t *sess, const char *sn);
-
-/* 0x0002 */ faim_export int aim_locate_reqrights(aim_session_t *sess);
-/* 0x0004 */ faim_export int aim_locate_setprofile(aim_session_t *sess, const char *profile_encoding, const char *profile, const int profile_len, const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len);
-/* 0x0004 */ faim_export int aim_locate_setcaps(aim_session_t *sess, fu32_t caps);
-/* 0x0005 */ faim_export int aim_locate_getinfo(aim_session_t *sess, const char *, fu16_t);
-/* 0x0009 */ faim_export int aim_locate_setdirinfo(aim_session_t *sess, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, fu16_t privacy);
-/* 0x000b */ faim_export int aim_locate_000b(aim_session_t *sess, const char *sn);
-/* 0x000f */ faim_export int aim_locate_setinterests(aim_session_t *sess, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, fu16_t privacy);
-/* 0x0015 */ faim_export int aim_locate_getinfoshort(aim_session_t *sess, const char *sn, fu32_t flags);
-
-
-
-/* 0x0003 - buddylist.c */
-/* 0x0002 */ faim_export int aim_buddylist_reqrights(aim_session_t *, aim_conn_t *);
-/* 0x0004 */ faim_export int aim_buddylist_set(aim_session_t *, aim_conn_t *, const char *);
-/* 0x0004 */ faim_export int aim_buddylist_addbuddy(aim_session_t *, aim_conn_t *, const char *);
-/* 0x0005 */ faim_export int aim_buddylist_removebuddy(aim_session_t *, aim_conn_t *, const char *);
-/* 0x000b */ faim_export int aim_buddylist_oncoming(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *info);
-/* 0x000c */ faim_export int aim_buddylist_offgoing(aim_session_t *sess, aim_conn_t *conn, const char *sn);
-
-
-
-/* 0x000a - search.c */
-faim_export int aim_search_address(aim_session_t *, aim_conn_t *, const char *);
-
-
-
-/* 0x000d - chatnav.c */
-/* 0x000e - chat.c */
-/* These apply to exchanges as well. */
-#define AIM_CHATROOM_FLAG_EVILABLE 0x0001
-#define AIM_CHATROOM_FLAG_NAV_ONLY 0x0002
-#define AIM_CHATROOM_FLAG_INSTANCING_ALLOWED 0x0004
-#define AIM_CHATROOM_FLAG_OCCUPANT_PEEK_ALLOWED 0x0008
-
-struct aim_chat_exchangeinfo {
-	fu16_t number;
-	fu16_t flags;
-	char *name;
-	char *charset1;
-	char *lang1;
-	char *charset2;
-	char *lang2;
-};
-
-#define AIM_CHATFLAGS_NOREFLECT 0x0001
-#define AIM_CHATFLAGS_AWAY      0x0002
-faim_export int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, fu16_t flags, const char *msg, int msglen);
-faim_export int aim_chat_join(aim_session_t *sess, aim_conn_t *conn, fu16_t exchange, const char *roomname, fu16_t instance);
-faim_export int aim_chat_attachname(aim_conn_t *conn, fu16_t exchange, const char *roomname, fu16_t instance);
-faim_export char *aim_chat_getname(aim_conn_t *conn);
-faim_export aim_conn_t *aim_chat_getconn(aim_session_t *, const char *name);
-
-faim_export int aim_chatnav_reqrights(aim_session_t *sess, aim_conn_t *conn);
-
-faim_export int aim_chat_invite(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *msg, fu16_t exchange, const char *roomname, fu16_t instance);
-
-faim_export int aim_chatnav_createroom(aim_session_t *sess, aim_conn_t *conn, const char *name, fu16_t exchange);
-faim_export int aim_chat_leaveroom(aim_session_t *sess, const char *name);
-
-
-
-/* 0x000f - odir.c */
-struct aim_odir {
-	char *first;
-	char *last;
-	char *middle;
-	char *maiden;
-	char *email;
-	char *country;
-	char *state;
-	char *city;
-	char *sn;
-	char *interest;
-	char *nick;
-	char *zip;
-	char *region;
-	char *address;
-	struct aim_odir *next;
-};
-
-faim_export int aim_odir_email(aim_session_t *, const char *, const char *);
-faim_export int aim_odir_name(aim_session_t *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *, const char *);
-faim_export int aim_odir_interest(aim_session_t *, const char *, const char *);
-
-
-
-/* 0x0010 - icon.c */
-faim_export int aim_bart_upload(aim_session_t *sess, const fu8_t *icon, fu16_t iconlen);
-faim_export int aim_bart_request(aim_session_t *sess, const char *sn, const fu8_t *iconstr, fu16_t iconstrlen);
-
-
-
-/* 0x0013 - ssi.c */
-#define AIM_SSI_TYPE_BUDDY		0x0000
-#define AIM_SSI_TYPE_GROUP		0x0001
-#define AIM_SSI_TYPE_PERMIT		0x0002
-#define AIM_SSI_TYPE_DENY		0x0003
-#define AIM_SSI_TYPE_PDINFO		0x0004
-#define AIM_SSI_TYPE_PRESENCEPREFS	0x0005
-#define AIM_SSI_TYPE_ICONINFO		0x0014
-
-#define AIM_SSI_ACK_SUCCESS		0x0000
-#define AIM_SSI_ACK_ITEMNOTFOUND	0x0002
-#define AIM_SSI_ACK_IDNUMINUSE		0x000a
-#define AIM_SSI_ACK_ATMAX		0x000c
-#define AIM_SSI_ACK_INVALIDNAME		0x000d
-#define AIM_SSI_ACK_AUTHREQUIRED	0x000e
-
-struct aim_ssi_item {
-	char *name;
-	fu16_t gid;
-	fu16_t bid;
-	fu16_t type;
-	struct aim_tlvlist_s *data;
-	struct aim_ssi_item *next;
-};
-
-struct aim_ssi_tmp {
-	fu16_t action;
-	fu16_t ack;
-	char *name;
-	struct aim_ssi_item *item;
-	struct aim_ssi_tmp *next;
-};
-
-/* These build the actual SNACs and queue them to be sent */
-/* 0x0002 */ faim_export int aim_ssi_reqrights(aim_session_t *sess);
-/* 0x0004 */ faim_export int aim_ssi_reqdata(aim_session_t *sess);
-/* 0x0005 */ faim_export int aim_ssi_reqifchanged(aim_session_t *sess, time_t localstamp, fu16_t localrev);
-/* 0x0007 */ faim_export int aim_ssi_enable(aim_session_t *sess);
-/* 0x0008 */ faim_export int aim_ssi_addmoddel(aim_session_t *sess);
-/* 0x0011 */ faim_export int aim_ssi_modbegin(aim_session_t *sess);
-/* 0x0012 */ faim_export int aim_ssi_modend(aim_session_t *sess);
-/* 0x0014 */ faim_export int aim_ssi_sendauth(aim_session_t *sess, char *sn, char *msg);
-/* 0x0018 */ faim_export int aim_ssi_sendauthrequest(aim_session_t *sess, char *sn, char *msg);
-/* 0x001a */ faim_export int aim_ssi_sendauthreply(aim_session_t *sess, char *sn, fu8_t reply, char *msg);
-
-/* Client functions for retrieving SSI data */
-faim_export struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, fu16_t gid, fu16_t bid);
-faim_export struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *sn, fu16_t type);
-faim_export struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *sn);
-faim_export char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *sn);
-faim_export int aim_ssi_getpermdeny(struct aim_ssi_item *list);
-faim_export fu32_t aim_ssi_getpresence(struct aim_ssi_item *list);
-faim_export char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *sn);
-faim_export char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *sn);
-faim_export int aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *sn);
-
-/* Client functions for changing SSI data */
-faim_export int aim_ssi_addbuddy(aim_session_t *sess, const char *name, const char *group, const char *alias, const char *comment, const char *smsnum, int needauth);
-faim_export int aim_ssi_addpermit(aim_session_t *sess, const char *name);
-faim_export int aim_ssi_adddeny(aim_session_t *sess, const char *name);
-faim_export int aim_ssi_delbuddy(aim_session_t *sess, const char *name, const char *group);
-faim_export int aim_ssi_delpermit(aim_session_t *sess, const char *name);
-faim_export int aim_ssi_deldeny(aim_session_t *sess, const char *name);
-faim_export int aim_ssi_movebuddy(aim_session_t *sess, const char *oldgn, const char *newgn, const char *sn);
-faim_export int aim_ssi_aliasbuddy(aim_session_t *sess, const char *gn, const char *sn, const char *alias);
-faim_export int aim_ssi_editcomment(aim_session_t *sess, const char *gn, const char *sn, const char *alias);
-faim_export int aim_ssi_rename_group(aim_session_t *sess, const char *oldgn, const char *newgn);
-faim_export int aim_ssi_cleanlist(aim_session_t *sess);
-faim_export int aim_ssi_deletelist(aim_session_t *sess);
-faim_export int aim_ssi_setpermdeny(aim_session_t *sess, fu8_t permdeny, fu32_t vismask);
-faim_export int aim_ssi_setpresence(aim_session_t *sess, fu32_t presence);
-faim_export int aim_ssi_seticon(aim_session_t *sess, fu8_t *iconsum, fu16_t iconsumlen);
-faim_export int aim_ssi_delicon(aim_session_t *sess);
-
-
-
-/* 0x0015 - icq.c */
-#define AIM_ICQ_INFO_SIMPLE	0x001
-#define AIM_ICQ_INFO_SUMMARY	0x002
-#define AIM_ICQ_INFO_EMAIL	0x004
-#define AIM_ICQ_INFO_PERSONAL	0x008
-#define AIM_ICQ_INFO_ADDITIONAL	0x010
-#define AIM_ICQ_INFO_WORK	0x020
-#define AIM_ICQ_INFO_INTERESTS	0x040
-#define AIM_ICQ_INFO_ORGS	0x080
-#define AIM_ICQ_INFO_UNKNOWN	0x100
-#define AIM_ICQ_INFO_HAVEALL	0x1ff
-
-struct aim_icq_offlinemsg {
-	fu32_t sender;
-	fu16_t year;
-	fu8_t month, day, hour, minute;
-	fu8_t type;
-	fu8_t flags;
-	char *msg;
-	int msglen;
-};
-
-struct aim_icq_info {
-	fu16_t reqid;
-
-	/* simple */
-	fu32_t uin;
-
-	/* general and "home" information (0x00c8) */
-	char *nick;
-	char *first;
-	char *last;
-	char *email;
-	char *homecity;
-	char *homestate;
-	char *homephone;
-	char *homefax;
-	char *homeaddr;
-	char *mobile;
-	char *homezip;
-	fu16_t homecountry;
-/*	fu8_t timezone;
-	fu8_t hideemail; */
-
-	/* personal (0x00dc) */
-	fu8_t age;
-	fu8_t unknown;
-	fu8_t gender;
-	char *personalwebpage;
-	fu16_t birthyear;
-	fu8_t birthmonth;
-	fu8_t birthday;
-	fu8_t language1;
-	fu8_t language2;
-	fu8_t language3;
-
-	/* work (0x00d2) */
-	char *workcity;
-	char *workstate;
-	char *workphone;
-	char *workfax;
-	char *workaddr;
-	char *workzip;
-	fu16_t workcountry;
-	char *workcompany;
-	char *workdivision;
-	char *workposition;
-	char *workwebpage;
-
-	/* additional personal information (0x00e6) */
-	char *info;
-
-	/* email (0x00eb) */
-	fu16_t numaddresses;
-	char **email2;
-
-	/* we keep track of these in a linked list because we're 1337 */
-	struct aim_icq_info *next;
-};
-
-faim_export int aim_icq_reqofflinemsgs(aim_session_t *sess);
-faim_export int aim_icq_ackofflinemsgs(aim_session_t *sess);
-faim_export int aim_icq_hideip(aim_session_t *sess);
-faim_export int aim_icq_changepasswd(aim_session_t *sess, const char *passwd);
-faim_export int aim_icq_getsimpleinfo(aim_session_t *sess, const char *uin);
-faim_export int aim_icq_getalias(aim_session_t *sess, const char *uin);
-faim_export int aim_icq_getallinfo(aim_session_t *sess, const char *uin);
-
-
-
-/* 0x0017 - auth.c */
-faim_export int aim_sendcookie(aim_session_t *, aim_conn_t *, const fu16_t length, const fu8_t *);
-faim_export int aim_admin_changepasswd(aim_session_t *, aim_conn_t *, const char *newpw, const char *curpw);
-faim_export int aim_admin_reqconfirm(aim_session_t *sess, aim_conn_t *conn);
-faim_export int aim_admin_getinfo(aim_session_t *sess, aim_conn_t *conn, fu16_t info);
-faim_export int aim_admin_setemail(aim_session_t *sess, aim_conn_t *conn, const char *newemail);
-faim_export int aim_admin_setnick(aim_session_t *sess, aim_conn_t *conn, const char *newnick);
-
-
-
-/* 0x0018 - email.c */
-struct aim_emailinfo {
-	fu8_t *cookie16;
-	fu8_t *cookie8;
-	char *url;
-	fu16_t nummsgs;
-	fu8_t unread;
-	char *domain;
-	fu16_t flag;
-	struct aim_emailinfo *next;
-};
-
-faim_export int aim_email_sendcookies(aim_session_t *sess);
-faim_export int aim_email_activate(aim_session_t *sess);
-
-
-
-#if defined(FAIM_INTERNAL) || defined(FAIM_NEED_TLV)
-/* tlv.c - TLV handling */
-
-/* TLV structure */
-typedef struct aim_tlv_s {
-	fu16_t type;
-	fu16_t length;
-	fu8_t *value;
-} aim_tlv_t;
-
-/* TLV List structure */
-typedef struct aim_tlvlist_s {
-	aim_tlv_t *tlv;
-	struct aim_tlvlist_s *next;
-} aim_tlvlist_t;
-
-/* TLV handling functions */
-faim_internal aim_tlv_t *aim_tlv_gettlv(aim_tlvlist_t *list, fu16_t type, const int nth);
-faim_internal char *aim_tlv_getstr(aim_tlvlist_t *list, const fu16_t type, const int nth);
-faim_internal fu8_t aim_tlv_get8(aim_tlvlist_t *list, const fu16_t type, const int nth);
-faim_internal fu16_t aim_tlv_get16(aim_tlvlist_t *list, const fu16_t type, const int nth);
-faim_internal fu32_t aim_tlv_get32(aim_tlvlist_t *list, const fu16_t type, const int nth);
-
-/* TLV list handling functions */
-faim_internal aim_tlvlist_t *aim_tlvlist_read(aim_bstream_t *bs);
-faim_internal aim_tlvlist_t *aim_tlvlist_readnum(aim_bstream_t *bs, fu16_t num);
-faim_internal aim_tlvlist_t *aim_tlvlist_readlen(aim_bstream_t *bs, fu16_t len);
-faim_internal aim_tlvlist_t *aim_tlvlist_copy(aim_tlvlist_t *orig);
-
-faim_internal int aim_tlvlist_count(aim_tlvlist_t **list);
-faim_internal int aim_tlvlist_size(aim_tlvlist_t **list);
-faim_internal int aim_tlvlist_cmp(aim_tlvlist_t *one, aim_tlvlist_t *two);
-faim_internal int aim_tlvlist_write(aim_bstream_t *bs, aim_tlvlist_t **list);
-faim_internal void aim_tlvlist_free(aim_tlvlist_t **list);
-
-faim_internal int aim_tlvlist_add_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t length, const fu8_t *value);
-faim_internal int aim_tlvlist_add_noval(aim_tlvlist_t **list, const fu16_t type);
-faim_internal int aim_tlvlist_add_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value);
-faim_internal int aim_tlvlist_add_16(aim_tlvlist_t **list, const fu16_t type, const fu16_t value);
-faim_internal int aim_tlvlist_add_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value);
-faim_internal int aim_tlvlist_add_caps(aim_tlvlist_t **list, const fu16_t type, const fu32_t caps);
-faim_internal int aim_tlvlist_add_userinfo(aim_tlvlist_t **list, fu16_t type, aim_userinfo_t *userinfo);
-faim_internal int aim_tlvlist_add_frozentlvlist(aim_tlvlist_t **list, fu16_t type, aim_tlvlist_t **tl);
-
-faim_internal int aim_tlvlist_replace_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t lenth, const fu8_t *value);
-faim_internal int aim_tlvlist_replace_noval(aim_tlvlist_t **list, const fu16_t type);
-faim_internal int aim_tlvlist_replace_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value);
-faim_internal int aim_tlvlist_replace_16(aim_tlvlist_t **list, const fu16_t type, const fu16_t value);
-faim_internal int aim_tlvlist_replace_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value);
-
-faim_internal void aim_tlvlist_remove(aim_tlvlist_t **list, const fu16_t type);
-#endif /* FAIM_INTERNAL */
-
-
-
-/* util.c */
-/*
- * These are really ugly.  You'd think this was LISP.  I wish it was.
- *
- * XXX With the advent of bstream's, these should be removed to enforce
- * their use.
- *
- */
-#define aimutil_put8(buf, data) ((*(buf) = (fu8_t)(data)&0xff),1)
-#define aimutil_get8(buf) ((*(buf))&0xff)
-#define aimutil_put16(buf, data) ( \
-		(*(buf) = (fu8_t)((data)>>8)&0xff), \
-		(*((buf)+1) = (fu8_t)(data)&0xff),  \
-		2)
-#define aimutil_get16(buf) ((((*(buf))<<8)&0xff00) + ((*((buf)+1)) & 0xff))
-#define aimutil_put32(buf, data) ( \
-		(*((buf)) = (fu8_t)((data)>>24)&0xff), \
-		(*((buf)+1) = (fu8_t)((data)>>16)&0xff), \
-		(*((buf)+2) = (fu8_t)((data)>>8)&0xff), \
-		(*((buf)+3) = (fu8_t)(data)&0xff), \
-		4)
-#define aimutil_get32(buf) ((((*(buf))<<24)&0xff000000) + \
-		(((*((buf)+1))<<16)&0x00ff0000) + \
-		(((*((buf)+2))<< 8)&0x0000ff00) + \
-		(((*((buf)+3)    )&0x000000ff)))
-
-/* Little-endian versions (damn ICQ) */
-#define aimutil_putle8(buf, data) ( \
-		(*(buf) = (fu8_t)(data) & 0xff), \
-		1)
-#define aimutil_getle8(buf) ( \
-		(*(buf)) & 0xff \
-		)
-#define aimutil_putle16(buf, data) ( \
-		(*((buf)+0) = (fu8_t)((data) >> 0) & 0xff),  \
-		(*((buf)+1) = (fu8_t)((data) >> 8) & 0xff), \
-		2)
-#define aimutil_getle16(buf) ( \
-		(((*((buf)+0)) << 0) & 0x00ff) + \
-		(((*((buf)+1)) << 8) & 0xff00) \
-		)
-#define aimutil_putle32(buf, data) ( \
-		(*((buf)+0) = (fu8_t)((data) >>  0) & 0xff), \
-		(*((buf)+1) = (fu8_t)((data) >>  8) & 0xff), \
-		(*((buf)+2) = (fu8_t)((data) >> 16) & 0xff), \
-		(*((buf)+3) = (fu8_t)((data) >> 24) & 0xff), \
-		4)
-#define aimutil_getle32(buf) ( \
-		(((*((buf)+0)) <<  0) & 0x000000ff) + \
-		(((*((buf)+1)) <<  8) & 0x0000ff00) + \
-		(((*((buf)+2)) << 16) & 0x00ff0000) + \
-		(((*((buf)+3)) << 24) & 0xff000000))
-
-
-faim_export int aimutil_putstr(char *, const char *, int);
-faim_export fu16_t aimutil_iconsum(const fu8_t *buf, int buflen);
-faim_export int aim_util_getlocalip(fu8_t *ip);
-faim_export int aimutil_tokslen(char *toSearch, int theindex, char dl);
-faim_export int aimutil_itemcnt(char *toSearch, char dl);
-faim_export char *aimutil_itemindex(char *toSearch, int theindex, char dl);
-
-faim_export int aim_snlen(const char *sn);
-faim_export int aim_sncmp(const char *sn1, const char *sn2);
-
-#include <aim_internal.h>
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __AIM_H__ */
Index: bfaim/aim_cbtypes.h
===================================================================
--- libfaim/aim_cbtypes.h	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,310 +1,0 @@
-/*
- * AIM Callback Types
- *
- */
-#ifndef __AIM_CBTYPES_H__
-#define __AIM_CBTYPES_H__
-
-/*
- * SNAC Families.
- */
-#define AIM_CB_FAM_ACK 0x0000
-#define AIM_CB_FAM_GEN 0x0001
-#define AIM_CB_FAM_LOC 0x0002
-#define AIM_CB_FAM_BUD 0x0003
-#define AIM_CB_FAM_MSG 0x0004
-#define AIM_CB_FAM_ADS 0x0005
-#define AIM_CB_FAM_INV 0x0006
-#define AIM_CB_FAM_ADM 0x0007
-#define AIM_CB_FAM_POP 0x0008
-#define AIM_CB_FAM_BOS 0x0009
-#define AIM_CB_FAM_LOK 0x000a
-#define AIM_CB_FAM_STS 0x000b
-#define AIM_CB_FAM_TRN 0x000c
-#define AIM_CB_FAM_CTN 0x000d /* ChatNav */
-#define AIM_CB_FAM_CHT 0x000e /* Chat */
-#define AIM_CB_FAM_SCH 0x000f /* "New" search */
-#define AIM_CB_FAM_ICO 0x0010 /* Used for uploading buddy icons */
-#define AIM_CB_FAM_SSI 0x0013 /* Server stored information */
-#define AIM_CB_FAM_ICQ 0x0015
-#define AIM_CB_FAM_ATH 0x0017
-#define AIM_CB_FAM_EML 0x0018
-#define AIM_CB_FAM_OFT 0xfffe /* OFT/Rvous */
-#define AIM_CB_FAM_SPECIAL 0xffff /* Internal libfaim use */
-
-/*
- * SNAC Family: Ack.
- * 
- * Not really a family, but treating it as one really
- * helps it fit into the libfaim callback structure better.
- *
- */
-#define AIM_CB_ACK_ACK 0x0001
-
-/*
- * SNAC Family: General.
- */ 
-#define AIM_CB_GEN_ERROR 0x0001
-#define AIM_CB_GEN_CLIENTREADY 0x0002
-#define AIM_CB_GEN_SERVERREADY 0x0003
-#define AIM_CB_GEN_SERVICEREQ 0x0004
-#define AIM_CB_GEN_REDIRECT 0x0005
-#define AIM_CB_GEN_RATEINFOREQ 0x0006
-#define AIM_CB_GEN_RATEINFO 0x0007
-#define AIM_CB_GEN_RATEINFOACK 0x0008
-#define AIM_CB_GEN_RATECHANGE 0x000a
-#define AIM_CB_GEN_SERVERPAUSE 0x000b
-#define AIM_CB_GEN_SERVERRESUME 0x000d
-#define AIM_CB_GEN_REQSELFINFO 0x000e
-#define AIM_CB_GEN_SELFINFO 0x000f
-#define AIM_CB_GEN_EVIL 0x0010
-#define AIM_CB_GEN_SETIDLE 0x0011
-#define AIM_CB_GEN_MIGRATIONREQ 0x0012
-#define AIM_CB_GEN_MOTD 0x0013
-#define AIM_CB_GEN_SETPRIVFLAGS 0x0014
-#define AIM_CB_GEN_WELLKNOWNURL 0x0015
-#define AIM_CB_GEN_NOP 0x0016
-#define AIM_CB_GEN_DEFAULT 0xffff
-
-/*
- * SNAC Family: Location Services.
- */ 
-#define AIM_CB_LOC_ERROR 0x0001
-#define AIM_CB_LOC_REQRIGHTS 0x0002
-#define AIM_CB_LOC_RIGHTSINFO 0x0003
-#define AIM_CB_LOC_SETUSERINFO 0x0004
-#define AIM_CB_LOC_REQUSERINFO 0x0005
-#define AIM_CB_LOC_USERINFO 0x0006
-#define AIM_CB_LOC_WATCHERSUBREQ 0x0007
-#define AIM_CB_LOC_WATCHERNOT 0x0008
-#define AIM_CB_LOC_DEFAULT 0xffff
-
-/*
- * SNAC Family: Buddy List Management Services.
- */ 
-#define AIM_CB_BUD_ERROR 0x0001
-#define AIM_CB_BUD_REQRIGHTS 0x0002
-#define AIM_CB_BUD_RIGHTSINFO 0x0003
-#define AIM_CB_BUD_ADDBUDDY 0x0004
-#define AIM_CB_BUD_REMBUDDY 0x0005
-#define AIM_CB_BUD_REJECT 0x000a
-#define AIM_CB_BUD_ONCOMING 0x000b
-#define AIM_CB_BUD_OFFGOING 0x000c
-#define AIM_CB_BUD_DEFAULT 0xffff
-
-/*
- * SNAC Family: Messeging Services.
- */ 
-#define AIM_CB_MSG_ERROR 0x0001
-#define AIM_CB_MSG_PARAMINFO 0x0005
-#define AIM_CB_MSG_INCOMING 0x0007
-#define AIM_CB_MSG_EVIL 0x0009
-#define AIM_CB_MSG_MISSEDCALL 0x000a
-#define AIM_CB_MSG_CLIENTAUTORESP 0x000b
-#define AIM_CB_MSG_ACK 0x000c
-#define AIM_CB_MSG_MTN 0x0014
-#define AIM_CB_MSG_DEFAULT 0xffff
-
-/*
- * SNAC Family: Advertisement Services
- */ 
-#define AIM_CB_ADS_ERROR 0x0001
-#define AIM_CB_ADS_DEFAULT 0xffff
-
-/*
- * SNAC Family: Invitation Services.
- */ 
-#define AIM_CB_INV_ERROR 0x0001
-#define AIM_CB_INV_DEFAULT 0xffff
-
-/*
- * SNAC Family: Administrative Services.
- */ 
-#define AIM_CB_ADM_ERROR 0x0001
-#define AIM_CB_ADM_INFOCHANGE_REPLY 0x0005
-#define AIM_CB_ADM_DEFAULT 0xffff
-
-/*
- * SNAC Family: Popup Messages
- */ 
-#define AIM_CB_POP_ERROR 0x0001
-#define AIM_CB_POP_DEFAULT 0xffff
-
-/*
- * SNAC Family: Misc BOS Services.
- */ 
-#define AIM_CB_BOS_ERROR 0x0001
-#define AIM_CB_BOS_RIGHTSQUERY 0x0002
-#define AIM_CB_BOS_RIGHTS 0x0003
-#define AIM_CB_BOS_DEFAULT 0xffff
-
-/*
- * SNAC Family: User Lookup Services
- */ 
-#define AIM_CB_LOK_ERROR 0x0001
-#define AIM_CB_LOK_DEFAULT 0xffff
-
-/*
- * SNAC Family: User Status Services
- */ 
-#define AIM_CB_STS_ERROR 0x0001
-#define AIM_CB_STS_SETREPORTINTERVAL 0x0002
-#define AIM_CB_STS_REPORTACK 0x0004
-#define AIM_CB_STS_DEFAULT 0xffff
-
-/*
- * SNAC Family: Translation Services
- */ 
-#define AIM_CB_TRN_ERROR 0x0001
-#define AIM_CB_TRN_DEFAULT 0xffff
-
-/*
- * SNAC Family: Chat Navigation Services
- */ 
-#define AIM_CB_CTN_ERROR 0x0001
-#define AIM_CB_CTN_CREATE 0x0008
-#define AIM_CB_CTN_INFO 0x0009
-#define AIM_CB_CTN_DEFAULT 0xffff
-
-/*
- * SNAC Family: Chat Services
- */ 
-#define AIM_CB_CHT_ERROR 0x0001
-#define AIM_CB_CHT_ROOMINFOUPDATE 0x0002
-#define AIM_CB_CHT_USERJOIN 0x0003
-#define AIM_CB_CHT_USERLEAVE 0x0004
-#define AIM_CB_CHT_OUTGOINGMSG 0x0005
-#define AIM_CB_CHT_INCOMINGMSG 0x0006
-#define AIM_CB_CHT_DEFAULT 0xffff
-
-/*
- * SNAC Family: "New" Search
- */ 
-#define AIM_CB_SCH_ERROR 0x0001
-#define AIM_CB_SCH_SEARCH 0x0002
-#define AIM_CB_SCH_RESULTS 0x0003
-
-/*
- * SNAC Family: Buddy icons
- */ 
-#define AIM_CB_ICO_ERROR 0x0001
-#define AIM_CB_ICO_REQUEST 0x0004
-#define AIM_CB_ICO_RESPONSE 0x0005
-
-/*
- * SNAC Family: ICQ
- *
- * Most of these are actually special.
- */ 
-#define AIM_CB_ICQ_ERROR 0x0001
-#define AIM_CB_ICQ_OFFLINEMSG 0x00f0
-#define AIM_CB_ICQ_OFFLINEMSGCOMPLETE 0x00f1
-#define AIM_CB_ICQ_INFO 0x00f2
-#define AIM_CB_ICQ_ALIAS 0x00f3
-#define AIM_CB_ICQ_DEFAULT 0xffff
-
-/*
- * SNAC Family: Server-Stored Buddy Lists
- */
-#define AIM_CB_SSI_ERROR 0x0001
-#define AIM_CB_SSI_REQRIGHTS 0x0002
-#define AIM_CB_SSI_RIGHTSINFO 0x0003
-#define AIM_CB_SSI_REQDATA 0x0004
-#define AIM_CB_SSI_REQIFCHANGED 0x0005
-#define AIM_CB_SSI_LIST 0x0006
-#define AIM_CB_SSI_ACTIVATE 0x0007
-#define AIM_CB_SSI_ADD 0x0008
-#define AIM_CB_SSI_MOD 0x0009
-#define AIM_CB_SSI_DEL 0x000A
-#define AIM_CB_SSI_SRVACK 0x000E
-#define AIM_CB_SSI_NOLIST 0x000F
-#define AIM_CB_SSI_EDITSTART 0x0011
-#define AIM_CB_SSI_EDITSTOP 0x0012
-#define AIM_CB_SSI_SENDAUTH 0x0014
-#define AIM_CB_SSI_RECVAUTH 0x0015
-#define AIM_CB_SSI_SENDAUTHREQ 0x0018
-#define AIM_CB_SSI_RECVAUTHREQ 0x0019
-#define AIM_CB_SSI_SENDAUTHREP 0x001a
-#define AIM_CB_SSI_RECVAUTHREP 0x001b
-#define AIM_CB_SSI_ADDED 0x001c
-
-/*
- * SNAC Family: Authorizer
- *
- * Used only in protocol versions three and above.
- *
- */
-#define AIM_CB_ATH_ERROR 0x0001
-#define AIM_CB_ATH_LOGINREQEST 0x0002
-#define AIM_CB_ATH_LOGINRESPONSE 0x0003
-#define AIM_CB_ATH_AUTHREQ 0x0006
-#define AIM_CB_ATH_AUTHRESPONSE 0x0007
-
-/*
- * SNAC Family: Email
- *
- * Used for getting information on the email address
- * associated with your screen name.
- *
- */
-#define AIM_CB_EML_ERROR 0x0001
-#define AIM_CB_EML_SENDCOOKIES 0x0006
-#define AIM_CB_EML_MAILSTATUS 0x0007
-#define AIM_CB_EML_INIT 0x0016
-
-/*
- * OFT Services
- *
- * For all of the above #defines, the number is the subtype 
- * of the SNAC.  For OFT #defines, the number is the 
- * "hdrtype" which comes after the magic string and OFT 
- * packet length.
- *
- * I'm pretty sure the ODC ones are arbitrary right now, 
- * that should be changed.
- */
-#define AIM_CB_OFT_DIRECTIMCONNECTREQ 0x0001	/* connect request -- actually an OSCAR CAP */
-#define AIM_CB_OFT_DIRECTIMINCOMING 0x0002
-#define AIM_CB_OFT_DIRECTIMDISCONNECT 0x0003
-#define AIM_CB_OFT_DIRECTIMTYPING 0x0004
-#define AIM_CB_OFT_DIRECTIM_ESTABLISHED 0x0005
-
-#define AIM_CB_OFT_PROMPT 0x0101		/* "I am going to send you this file, is that ok?" */
-#define AIM_CB_OFT_RESUMESOMETHING 0x0106	/* I really don't know */
-#define AIM_CB_OFT_ACK 0x0202			/* "Yes, it is ok for you to send me that file" */
-#define AIM_CB_OFT_DONE 0x0204			/* "I received that file with no problems, thanks a bunch" */
-#define AIM_CB_OFT_RESUME 0x0205		/* Resume transferring, sent by whoever paused? */
-#define AIM_CB_OFT_RESUMEACK 0x0207		/* Not really sure */
-
-#define AIM_CB_OFT_GETFILE_REQUESTLISTING 0x1108 /* "I have a listing.txt file, do you want it?" */
-#define AIM_CB_OFT_GETFILE_RECEIVELISTING 0x1209 /* "Yes, please send me your listing.txt file" */
-#define AIM_CB_OFT_GETFILE_RECEIVEDLISTING 0x120a /* received corrupt listing.txt file? */ /* I'm just guessing about this one... */
-#define AIM_CB_OFT_GETFILE_ACKLISTING 0x120b	/* "I received the listing.txt file successfully" */
-#define AIM_CB_OFT_GETFILE_REQUESTFILE 0x120c	/* "Please send me this file" */
-
-#define AIM_CB_OFT_ESTABLISHED 0xFFFF		/* connection to buddy initiated */
-
-/*
- * SNAC Family: Internal Messages
- *
- * This isn't truely a SNAC family either, but using
- * these, we can integrated non-SNAC services into
- * the SNAC-centered libfaim callback structure.
- *
- */ 
-#define AIM_CB_SPECIAL_AUTHSUCCESS 0x0001
-#define AIM_CB_SPECIAL_AUTHOTHER 0x0002
-#define AIM_CB_SPECIAL_CONNERR 0x0003
-#define AIM_CB_SPECIAL_CONNCOMPLETE 0x0004
-#define AIM_CB_SPECIAL_FLAPVER 0x0005
-#define AIM_CB_SPECIAL_CONNINITDONE 0x0006
-#define AIM_CB_SPECIAL_IMAGETRANSFER 0x0007
-#define AIM_CB_SPECIAL_MSGTIMEOUT 0x0008
-#define AIM_CB_SPECIAL_CONNDEAD 0x0009
-#define AIM_CB_SPECIAL_UNKNOWN 0xffff
-#define AIM_CB_SPECIAL_DEFAULT AIM_CB_SPECIAL_UNKNOWN
-
-/* SNAC flags */
-#define AIM_SNACFLAGS_DESTRUCTOR 0x0001
-
-#endif/*__AIM_CBTYPES_H__ */
Index: bfaim/aim_internal.h
===================================================================
--- libfaim/aim_internal.h	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,226 +1,0 @@
-/*
- * aim_internal.h -- prototypes/structs for the guts of libfaim
- *
- */
-
-#ifdef FAIM_INTERNAL
-#ifndef __AIM_INTERNAL_H__
-#define __AIM_INTERNAL_H__ 1
-
-typedef struct {
-	fu16_t family;
-	fu16_t subtype;
-	fu16_t flags;
-	fu32_t id;
-} aim_modsnac_t;
-
-#define AIM_MODULENAME_MAXLEN 16
-#define AIM_MODFLAG_MULTIFAMILY 0x0001
-typedef struct aim_module_s {
-	fu16_t family;
-	fu16_t version;
-	fu16_t toolid;
-	fu16_t toolversion;
-	fu16_t flags;
-	char name[AIM_MODULENAME_MAXLEN+1];
-	int (*snachandler)(aim_session_t *sess, struct aim_module_s *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs);
-
-	void (*shutdown)(aim_session_t *sess, struct aim_module_s *mod);
-	void *priv;
-	struct aim_module_s *next;
-} aim_module_t;
-
-faim_internal int aim__registermodule(aim_session_t *sess, int (*modfirst)(aim_session_t *, aim_module_t *));
-faim_internal void aim__shutdownmodules(aim_session_t *sess);
-faim_internal aim_module_t *aim__findmodulebygroup(aim_session_t *sess, fu16_t group);
-faim_internal aim_module_t *aim__findmodule(aim_session_t *sess, const char *name);
-
-faim_internal int admin_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int buddylist_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int bos_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int search_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int stats_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int auth_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int msg_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int misc_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int chatnav_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int chat_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int locate_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int service_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int invite_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int translate_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int popups_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int adverts_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int odir_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int bart_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int ssi_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int icq_modfirst(aim_session_t *sess, aim_module_t *mod);
-faim_internal int email_modfirst(aim_session_t *sess, aim_module_t *mod);
-
-faim_internal int aim_genericreq_n(aim_session_t *, aim_conn_t *conn, fu16_t family, fu16_t subtype);
-faim_internal int aim_genericreq_n_snacid(aim_session_t *, aim_conn_t *conn, fu16_t family, fu16_t subtype);
-faim_internal int aim_genericreq_l(aim_session_t *, aim_conn_t *conn, fu16_t family, fu16_t subtype, fu32_t *);
-faim_internal int aim_genericreq_s(aim_session_t *, aim_conn_t *conn, fu16_t family, fu16_t subtype, fu16_t *);
-
-#define AIMBS_CURPOSPAIR(x) ((x)->data + (x)->offset), ((x)->len - (x)->offset)
-
-/* bstream.c */
-faim_internal int aim_bstream_init(aim_bstream_t *bs, fu8_t *data, int len);
-faim_internal int aim_bstream_empty(aim_bstream_t *bs);
-faim_internal int aim_bstream_curpos(aim_bstream_t *bs);
-faim_internal int aim_bstream_setpos(aim_bstream_t *bs, int off);
-faim_internal void aim_bstream_rewind(aim_bstream_t *bs);
-faim_internal int aim_bstream_advance(aim_bstream_t *bs, int n);
-faim_internal fu8_t aimbs_get8(aim_bstream_t *bs);
-faim_internal fu16_t aimbs_get16(aim_bstream_t *bs);
-faim_internal fu32_t aimbs_get32(aim_bstream_t *bs);
-faim_internal fu8_t aimbs_getle8(aim_bstream_t *bs);
-faim_internal fu16_t aimbs_getle16(aim_bstream_t *bs);
-faim_internal fu32_t aimbs_getle32(aim_bstream_t *bs);
-faim_internal int aimbs_put8(aim_bstream_t *bs, fu8_t v);
-faim_internal int aimbs_put16(aim_bstream_t *bs, fu16_t v);
-faim_internal int aimbs_put32(aim_bstream_t *bs, fu32_t v);
-faim_internal int aimbs_putle8(aim_bstream_t *bs, fu8_t v);
-faim_internal int aimbs_putle16(aim_bstream_t *bs, fu16_t v);
-faim_internal int aimbs_putle32(aim_bstream_t *bs, fu32_t v);
-faim_internal int aimbs_getrawbuf(aim_bstream_t *bs, fu8_t *buf, int len);
-faim_internal fu8_t *aimbs_getraw(aim_bstream_t *bs, int len);
-faim_internal char *aimbs_getstr(aim_bstream_t *bs, int len);
-faim_internal int aimbs_putraw(aim_bstream_t *bs, const fu8_t *v, int len);
-faim_internal int aimbs_putbs(aim_bstream_t *bs, aim_bstream_t *srcbs, int len);
-
-/* conn.c */
-faim_internal aim_conn_t *aim_cloneconn(aim_session_t *sess, aim_conn_t *src);
-
-/* ft.c */
-faim_internal int aim_rxdispatch_rendezvous(aim_session_t *sess, aim_frame_t *fr);
-
-/* rxhandlers.c */
-faim_internal aim_rxcallback_t aim_callhandler(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t type);
-faim_internal int aim_callhandler_noparam(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t type, aim_frame_t *ptr);
-faim_internal int aim_parse_unknown(aim_session_t *, aim_frame_t *, ...);
-faim_internal void aim_clonehandlers(aim_session_t *sess, aim_conn_t *dest, aim_conn_t *src);
-
-/* rxqueue.c */
-faim_internal int aim_recv(int fd, void *buf, size_t count);
-faim_internal int aim_bstream_recv(aim_bstream_t *bs, int fd, size_t count);
-faim_internal void aim_rxqueue_cleanbyconn(aim_session_t *sess, aim_conn_t *conn);
-faim_internal void aim_frame_destroy(aim_frame_t *);
-
-/* txqueue.c */
-faim_internal aim_frame_t *aim_tx_new(aim_session_t *sess, aim_conn_t *conn, fu8_t framing, fu16_t chan, int datalen);
-faim_internal int aim_tx_enqueue(aim_session_t *, aim_frame_t *);
-faim_internal flap_seqnum_t aim_get_next_txseqnum(aim_conn_t *);
-faim_internal int aim_tx_sendframe(aim_session_t *sess, aim_frame_t *cur);
-faim_internal void aim_tx_cleanqueue(aim_session_t *, aim_conn_t *);
-
-/* XXX - What is this?   faim_internal int aim_tx_printqueue(aim_session_t *); */
-
-/*
- * Generic SNAC structure.  Rarely if ever used.
- */
-typedef struct aim_snac_s {
-	aim_snacid_t id;
-	fu16_t family;
-	fu16_t type;
-	fu16_t flags;
-	void *data;
-	time_t issuetime;
-	struct aim_snac_s *next;
-} aim_snac_t;
-
-/* snac.c */
-faim_internal void aim_initsnachash(aim_session_t *sess);
-faim_internal aim_snacid_t aim_newsnac(aim_session_t *, aim_snac_t *newsnac);
-faim_internal aim_snacid_t aim_cachesnac(aim_session_t *sess, const fu16_t family, const fu16_t type, const fu16_t flags, const void *data, const int datalen);
-faim_internal aim_snac_t *aim_remsnac(aim_session_t *, aim_snacid_t id);
-faim_internal int aim_putsnac(aim_bstream_t *, fu16_t family, fu16_t type, fu16_t flags, aim_snacid_t id);
-
-/* Stored in ->priv of the service request SNAC for chats. */
-struct chatsnacinfo {
-	fu16_t exchange;
-	char name[128];
-	fu16_t instance;
-};
-
-/* 
- * In SNACland, the terms 'family' and 'group' are synonymous -- the former
- * is my term, the latter is AOL's.
- */
-struct snacgroup {
-	fu16_t group;
-	struct snacgroup *next;
-};
-
-#ifdef FAIM_NEED_CONN_INTERNAL
-struct snacpair {
-	fu16_t group;
-	fu16_t subtype;
-	struct snacpair *next;
-};
-
-struct rateclass {
-	fu16_t classid;
-	fu32_t windowsize;
-	fu32_t clear;
-	fu32_t alert;
-	fu32_t limit;
-	fu32_t disconnect;
-	fu32_t current;
-	fu32_t max;
-	fu8_t unknown[5]; /* only present in versions >= 3 */
-	struct snacpair *members;
-	struct rateclass *next;
-};
-#endif /* FAIM_NEED_CONN_INTERNAL */
-
-/*
- * This is inside every connection.  But it is a void * to anything
- * outside of libfaim.  It should remain that way.  It's called data
- * abstraction.  Maybe you've heard of it.  (Probably not if you're a 
- * libfaim user.)
- * 
- */
-typedef struct aim_conn_inside_s {
-	struct snacgroup *groups;
-	struct rateclass *rates;
-} aim_conn_inside_t;
-
-faim_internal void aim_conn_addgroup(aim_conn_t *conn, fu16_t group);
-
-faim_internal int aim_cachecookie(aim_session_t *sess, aim_msgcookie_t *cookie);
-faim_internal aim_msgcookie_t *aim_uncachecookie(aim_session_t *sess, fu8_t *cookie, int type);
-faim_internal aim_msgcookie_t *aim_mkcookie(fu8_t *, int, void *);
-faim_internal aim_msgcookie_t *aim_checkcookie(aim_session_t *, const unsigned char *, const int);
-faim_internal int aim_freecookie(aim_session_t *sess, aim_msgcookie_t *cookie);
-faim_internal int aim_msgcookie_gettype(int reqclass);
-faim_internal int aim_cookie_free(aim_session_t *sess, aim_msgcookie_t *cookie);
-
-/* 0x0002 - locate.c */
-faim_internal void aim_locate_requestuserinfo(aim_session_t *sess, const char *sn);
-faim_internal fu32_t aim_locate_getcaps(aim_session_t *sess, aim_bstream_t *bs, int len);
-faim_internal fu32_t aim_locate_getcaps_short(aim_session_t *sess, aim_bstream_t *bs, int len);
-faim_internal int aim_putcap(aim_bstream_t *bs, fu32_t caps);
-faim_internal void aim_info_free(aim_userinfo_t *);
-faim_internal int aim_info_extract(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *);
-faim_internal int aim_putuserinfo(aim_bstream_t *bs, aim_userinfo_t *info);
-
-faim_internal int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roominfo *outinfo);
-
-faim_internal void aim_conn_kill_chat(aim_session_t *sess, aim_conn_t *conn);
-
-/* These are all handled internally now. */
-faim_internal int aim_setversions(aim_session_t *sess, aim_conn_t *conn);
-faim_internal int aim_reqrates(aim_session_t *, aim_conn_t *);
-faim_internal int aim_rates_addparam(aim_session_t *, aim_conn_t *);
-faim_internal int aim_rates_delparam(aim_session_t *, aim_conn_t *);
-
-faim_internal void faimdprintf(aim_session_t *sess, int dlevel, const char *format, ...);
-
-#ifndef FAIM_INTERNAL_INSANE
-#define printf() printf called inside libfaim
-#define sprintf() unbounded sprintf used inside libfaim
-#endif
-
-#endif /* __AIM_INTERNAL_H__ */
-#endif /* FAIM_INTERNAL */
Index: bfaim/auth.c
===================================================================
--- libfaim/auth.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,558 +1,0 @@
-/*
- * Family 0x0017 - Authentication.
- *
- * Deals with the authorizer for SNAC-based login, and also old-style 
- * non-SNAC login.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-#include "md5.h"
-
-#include <ctype.h>
-
-/**
- * Encode a password using old XOR method
- *
- * This takes a const pointer to a (null terminated) string
- * containing the unencoded password.  It also gets passed
- * an already allocated buffer to store the encoded password.
- * This buffer should be the exact length of the password without
- * the null.  The encoded password buffer /is not %NULL terminated/.
- *
- * The encoding_table seems to be a fixed set of values.  We'll
- * hope it doesn't change over time!  
- *
- * This is only used for the XOR method, not the better MD5 method.
- *
- * @param password Incoming password.
- * @param encoded Buffer to put encoded password.
- */
-static int aim_encode_password(const char *password, fu8_t *encoded)
-{
-	fu8_t encoding_table[] = {
-#if 0 /* old v1 table */
-		0xf3, 0xb3, 0x6c, 0x99,
-		0x95, 0x3f, 0xac, 0xb6,
-		0xc5, 0xfa, 0x6b, 0x63,
-		0x69, 0x6c, 0xc3, 0x9f
-#else /* v2.1 table, also works for ICQ */
-		0xf3, 0x26, 0x81, 0xc4,
-		0x39, 0x86, 0xdb, 0x92,
-		0x71, 0xa3, 0xb9, 0xe6,
-		0x53, 0x7a, 0x95, 0x7c
-#endif
-	};
-	int i;
-
-	for (i = 0; i < strlen(password); i++)
-		encoded[i] = (password[i] ^ encoding_table[i]);
-
-	return 0;
-}
-
-#ifdef USE_OLD_MD5
-static int aim_encode_password_md5(const char *password, const char *key, fu8_t *digest)
-{
-	md5_state_t state;
-
-	md5_init(&state);	
-	md5_append(&state, (const md5_byte_t *)key, strlen(key));
-	md5_append(&state, (const md5_byte_t *)password, strlen(password));
-	md5_append(&state, (const md5_byte_t *)AIM_MD5_STRING, strlen(AIM_MD5_STRING));
-	md5_finish(&state, (md5_byte_t *)digest);
-
-	return 0;
-}
-#else
-static int aim_encode_password_md5(const char *password, const char *key, fu8_t *digest)
-{
-	md5_state_t state;
-	fu8_t passdigest[16];
-
-	md5_init(&state);
-	md5_append(&state, (const md5_byte_t *)password, strlen(password));
-	md5_finish(&state, (md5_byte_t *)&passdigest);
-
-	md5_init(&state);	
-	md5_append(&state, (const md5_byte_t *)key, strlen(key));
-	md5_append(&state, (const md5_byte_t *)&passdigest, 16);
-	md5_append(&state, (const md5_byte_t *)AIM_MD5_STRING, strlen(AIM_MD5_STRING));
-	md5_finish(&state, (md5_byte_t *)digest);
-
-	return 0;
-}
-#endif
-
-/*
- * The FLAP version is sent by itself at the beginning of authorization 
- * connections.  The FLAP version is also sent before the cookie when connecting 
- * for other services (BOS, chatnav, chat, etc.).
- */
-faim_export int aim_sendflapver(aim_session_t *sess, aim_conn_t *conn)
-{
-	aim_frame_t *fr;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x01, 4)))
-		return -ENOMEM;
-
-	aimbs_put32(&fr->data, 0x00000001);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * This just pushes the passed cookie onto the passed connection, without
- * the SNAC header or any of that.
- *
- * Very commonly used, as every connection except auth will require this to
- * be the first thing you send.
- *
- */
-faim_export int aim_sendcookie(aim_session_t *sess, aim_conn_t *conn, const fu16_t length, const fu8_t *chipsahoy)
-{
-	aim_frame_t *fr;
-	aim_tlvlist_t *tl = NULL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x0001, 4+2+2+length)))
-		return -ENOMEM;
-
-	aimbs_put32(&fr->data, 0x00000001);
-	aim_tlvlist_add_raw(&tl, 0x0006, length, chipsahoy);
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Part two of the ICQ hack.  Note the ignoring of the key.
- */
-static int goddamnicq2(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *password, struct client_info_s *ci)
-{
-	aim_frame_t *fr;
-	aim_tlvlist_t *tl = NULL;
-	int passwdlen;
-	fu8_t *password_encoded;
-
-	passwdlen = strlen(password);
-	if (!(password_encoded = (char *)malloc(passwdlen+1)))
-		return -ENOMEM;
-	if (passwdlen > MAXICQPASSLEN)
-		passwdlen = MAXICQPASSLEN;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x01, 1152))) {
-		free(password_encoded);
-		return -ENOMEM;
-	}
-
-	aim_encode_password(password, password_encoded);
-
-	aimbs_put32(&fr->data, 0x00000001); /* FLAP Version */
-	aim_tlvlist_add_raw(&tl, 0x0001, strlen(sn), sn);
-	aim_tlvlist_add_raw(&tl, 0x0002, passwdlen, password_encoded);
-
-	if (ci->clientstring)
-		aim_tlvlist_add_raw(&tl, 0x0003, strlen(ci->clientstring), ci->clientstring);
-	aim_tlvlist_add_16(&tl, 0x0016, (fu16_t)ci->clientid);
-	aim_tlvlist_add_16(&tl, 0x0017, (fu16_t)ci->major);
-	aim_tlvlist_add_16(&tl, 0x0018, (fu16_t)ci->minor);
-	aim_tlvlist_add_16(&tl, 0x0019, (fu16_t)ci->point);
-	aim_tlvlist_add_16(&tl, 0x001a, (fu16_t)ci->build);
-	aim_tlvlist_add_32(&tl, 0x0014, (fu32_t)ci->distrib); /* distribution chan */
-	aim_tlvlist_add_raw(&tl, 0x000f, strlen(ci->lang), ci->lang);
-	aim_tlvlist_add_raw(&tl, 0x000e, strlen(ci->country), ci->country);
-
-	aim_tlvlist_write(&fr->data, &tl);
-
-	free(password_encoded);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0002
- *
- * This is the initial login request packet.
- *
- * NOTE!! If you want/need to make use of the aim_sendmemblock() function,
- * then the client information you send here must exactly match the
- * executable that you're pulling the data from.
- *
- * Java AIM 1.1.19:
- *   clientstring = "AOL Instant Messenger (TM) version 1.1.19 for Java built 03/24/98, freeMem 215871 totalMem 1048567, i686, Linus, #2 SMP Sun Feb 11 03:41:17 UTC 2001 2.4.1-ac9, IBM Corporation, 1.1.8, 45.3, Tue Mar 27 12:09:17 PST 2001"
- *   clientid = 0x0001
- *   major  = 0x0001
- *   minor  = 0x0001
- *   point = (not sent)
- *   build  = 0x0013
- *   unknown= (not sent)
- *   
- * AIM for Linux 1.1.112:
- *   clientstring = "AOL Instant Messenger (SM)"
- *   clientid = 0x1d09
- *   major  = 0x0001
- *   minor  = 0x0001
- *   point = 0x0001
- *   build  = 0x0070
- *   unknown= 0x0000008b
- *   serverstore = 0x01
- *
- */
-faim_export int aim_send_login(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *password, struct client_info_s *ci, const char *key)
-{
-	aim_frame_t *fr;
-	aim_tlvlist_t *tl = NULL;
-	fu8_t digest[16];
-	aim_snacid_t snacid;
-
-	if (!ci || !sn || !password)
-		return -EINVAL;
-
-	/* If we're signing on an ICQ account then use the older, XOR login method */
-	if (isdigit(sn[0]))
-		return goddamnicq2(sess, conn, sn, password, ci);
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0017, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0017, 0x0002, 0x0000, snacid);
-
-	aim_tlvlist_add_raw(&tl, 0x0001, strlen(sn), sn);
-
-	aim_encode_password_md5(password, key, digest);
-	aim_tlvlist_add_raw(&tl, 0x0025, 16, digest);
-
-#ifndef USE_OLD_MD5
-	aim_tlvlist_add_noval(&tl, 0x004c);
-#endif
-
-	if (ci->clientstring)
-		aim_tlvlist_add_raw(&tl, 0x0003, strlen(ci->clientstring), ci->clientstring);
-	aim_tlvlist_add_16(&tl, 0x0016, (fu16_t)ci->clientid);
-	aim_tlvlist_add_16(&tl, 0x0017, (fu16_t)ci->major);
-	aim_tlvlist_add_16(&tl, 0x0018, (fu16_t)ci->minor);
-	aim_tlvlist_add_16(&tl, 0x0019, (fu16_t)ci->point);
-	aim_tlvlist_add_16(&tl, 0x001a, (fu16_t)ci->build);
-	aim_tlvlist_add_32(&tl, 0x0014, (fu32_t)ci->distrib);
-	aim_tlvlist_add_raw(&tl, 0x000f, strlen(ci->lang), ci->lang);
-	aim_tlvlist_add_raw(&tl, 0x000e, strlen(ci->country), ci->country);
-
-#ifndef NOSSI
-	/*
-	 * If set, old-fashioned buddy lists will not work. You will need
-	 * to use SSI.
-	 */
-	aim_tlvlist_add_8(&tl, 0x004a, 0x01);
-#endif
-
-	aim_tlvlist_write(&fr->data, &tl);
-
-	aim_tlvlist_free(&tl);
-	
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * This is sent back as a general response to the login command.
- * It can be either an error or a success, depending on the
- * precense of certain TLVs.  
- *
- * The client should check the value passed as errorcode. If
- * its nonzero, there was an error.
- */
-static int parse(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_tlvlist_t *tlvlist;
-	aim_rxcallback_t userfunc;
-	struct aim_authresp_info *info;
-	int ret = 0;
-
-	info = (struct aim_authresp_info *)malloc(sizeof(struct aim_authresp_info));
-	memset(info, 0, sizeof(struct aim_authresp_info));
-
-	/*
-	 * Read block of TLVs.  All further data is derived
-	 * from what is parsed here.
-	 */
-	tlvlist = aim_tlvlist_read(bs);
-
-	/*
-	 * No matter what, we should have a screen name.
-	 */
-	memset(sess->sn, 0, sizeof(sess->sn));
-	if (aim_tlv_gettlv(tlvlist, 0x0001, 1)) {
-		info->sn = aim_tlv_getstr(tlvlist, 0x0001, 1);
-		strncpy(sess->sn, info->sn, sizeof(sess->sn));
-	}
-
-	/*
-	 * Check for an error code.  If so, we should also
-	 * have an error url.
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x0008, 1)) 
-		info->errorcode = aim_tlv_get16(tlvlist, 0x0008, 1);
-	if (aim_tlv_gettlv(tlvlist, 0x0004, 1))
-		info->errorurl = aim_tlv_getstr(tlvlist, 0x0004, 1);
-
-	/*
-	 * BOS server address.
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x0005, 1))
-		info->bosip = aim_tlv_getstr(tlvlist, 0x0005, 1);
-
-	/*
-	 * Authorization cookie.
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x0006, 1)) {
-		aim_tlv_t *tmptlv;
-
-		tmptlv = aim_tlv_gettlv(tlvlist, 0x0006, 1);
-
-		info->cookielen = tmptlv->length;
-		info->cookie = tmptlv->value;
-	}
-
-	/*
-	 * The email address attached to this account
-	 *   Not available for ICQ or @mac.com logins.
-	 *   If you receive this TLV, then you are allowed to use 
-	 *   family 0x0018 to check the status of your email.
-	 * XXX - Not really true!
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x0011, 1))
-		info->email = aim_tlv_getstr(tlvlist, 0x0011, 1);
-
-	/*
-	 * The registration status.  (Not real sure what it means.)
-	 *   Not available for ICQ or @mac.com logins.
-	 *
-	 *   1 = No disclosure
-	 *   2 = Limited disclosure
-	 *   3 = Full disclosure
-	 *
-	 * This has to do with whether your email address is available
-	 * to other users or not.  AFAIK, this feature is no longer used.
-	 *
-	 * Means you can use the admin family? (0x0007)
-	 *
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x0013, 1))
-		info->regstatus = aim_tlv_get16(tlvlist, 0x0013, 1);
-
-	if (aim_tlv_gettlv(tlvlist, 0x0040, 1))
-		info->latestbeta.build = aim_tlv_get32(tlvlist, 0x0040, 1);
-	if (aim_tlv_gettlv(tlvlist, 0x0041, 1))
-		info->latestbeta.url = aim_tlv_getstr(tlvlist, 0x0041, 1);
-	if (aim_tlv_gettlv(tlvlist, 0x0042, 1))
-		info->latestbeta.info = aim_tlv_getstr(tlvlist, 0x0042, 1);
-	if (aim_tlv_gettlv(tlvlist, 0x0043, 1))
-		info->latestbeta.name = aim_tlv_getstr(tlvlist, 0x0043, 1);
-	if (aim_tlv_gettlv(tlvlist, 0x0048, 1))
-		; /* beta serial */
-
-	if (aim_tlv_gettlv(tlvlist, 0x0044, 1))
-		info->latestrelease.build = aim_tlv_get32(tlvlist, 0x0044, 1);
-	if (aim_tlv_gettlv(tlvlist, 0x0045, 1))
-		info->latestrelease.url = aim_tlv_getstr(tlvlist, 0x0045, 1);
-	if (aim_tlv_gettlv(tlvlist, 0x0046, 1))
-		info->latestrelease.info = aim_tlv_getstr(tlvlist, 0x0046, 1);
-	if (aim_tlv_gettlv(tlvlist, 0x0047, 1))
-		info->latestrelease.name = aim_tlv_getstr(tlvlist, 0x0047, 1);
-	if (aim_tlv_gettlv(tlvlist, 0x0049, 1))
-		; /* lastest release serial */
-
-	/*
-	 * URL to change password.
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x0054, 1))
-		info->chpassurl = aim_tlv_getstr(tlvlist, 0x0054, 1);
-
-	/*
-	 * Unknown.  Seen on an @mac.com screen name with value of 0x003f
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x0055, 1))
-		;
-
-	sess->authinfo = info;
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac ? snac->family : 0x0017, snac ? snac->subtype : 0x0003)))
-		ret = userfunc(sess, rx, info);
-
-	aim_tlvlist_free(&tlvlist);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0007 (kind of) - Send a fake type 0x0007 SNAC to the client
- *
- * This is a bit confusing.
- *
- * Normal SNAC login goes like this:
- *   - connect
- *   - server sends flap version
- *   - client sends flap version
- *   - client sends screen name (17/6)
- *   - server sends hash key (17/7)
- *   - client sends auth request (17/2 -- aim_send_login)
- *   - server yells
- *
- * XOR login (for ICQ) goes like this:
- *   - connect
- *   - server sends flap version
- *   - client sends auth request which contains flap version (aim_send_login)
- *   - server yells
- *
- * For the client API, we make them implement the most complicated version,
- * and for the simpler version, we fake it and make it look like the more
- * complicated process.
- *
- * This is done by giving the client a faked key, just so we can convince
- * them to call aim_send_login right away, which will detect the session
- * flag that says this is XOR login and ignore the key, sending an ICQ
- * login request instead of the normal SNAC one.
- *
- * As soon as AOL makes ICQ log in the same way as AIM, this is /gone/.
- *
- * XXX This may cause problems if the client relies on callbacks only
- * being called from the context of aim_rxdispatch()...
- *
- */
-static int goddamnicq(aim_session_t *sess, aim_conn_t *conn, const char *sn)
-{
-	aim_frame_t fr;
-	aim_rxcallback_t userfunc;
-	
-	fr.conn = conn;
-	
-	if ((userfunc = aim_callhandler(sess, conn, 0x0017, 0x0007)))
-		userfunc(sess, &fr, "");
-
-	return 0;
-}
-
-/*
- * Subtype 0x0006
- *
- * In AIM 3.5 protocol, the first stage of login is to request login from the 
- * Authorizer, passing it the screen name for verification.  If the name is 
- * invalid, a 0017/0003 is spit back, with the standard error contents.  If 
- * valid, a 0017/0007 comes back, which is the signal to send it the main 
- * login command (0017/0002). 
- *
- */
-faim_export int aim_request_login(aim_session_t *sess, aim_conn_t *conn, const char *sn)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-	
-	if (!sess || !conn || !sn)
-		return -EINVAL;
-
-	if (isdigit(sn[0]))
-		return goddamnicq(sess, conn, sn);
-
-	aim_sendflapver(sess, conn);
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+2+strlen(sn) /*+8*/ )))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0017, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0017, 0x0006, 0x0000, snacid);
-
-	aim_tlvlist_add_raw(&tl, 0x0001, strlen(sn), sn);
-/*	aim_tlvlist_add_noval(&tl, 0x004b);
-	aim_tlvlist_add_noval(&tl, 0x005a); */
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0007
- *
- * Middle handler for 0017/0007 SNACs.  Contains the auth key prefixed
- * by only its length in a two byte word.
- *
- * Calls the client, which should then use the value to call aim_send_login.
- *
- */
-static int keyparse(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int keylen, ret = 1;
-	aim_rxcallback_t userfunc;
-	char *keystr;
-
-	keylen = aimbs_get16(bs);
-	keystr = aimbs_getstr(bs, keylen);
-
-	/* XXX - When GiantGrayPanda signed on AIM I got a thing asking me to register 
-	 * for the netscape network.  This SNAC had a type 0x0058 TLV with length 10.  
-	 * Data is 0x0007 0004 3e19 ae1e 0006 0004 0000 0005 */
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, keystr);
-
-	free(keystr); 
-
-	return ret;
-}
-
-static void auth_shutdown(aim_session_t *sess, aim_module_t *mod)
-{
-	if (sess->authinfo) {
-		free(sess->authinfo->sn);
-		free(sess->authinfo->bosip);
-		free(sess->authinfo->errorurl);
-		free(sess->authinfo->email);
-		free(sess->authinfo->chpassurl);
-		free(sess->authinfo->latestrelease.name);
-		free(sess->authinfo->latestrelease.url);
-		free(sess->authinfo->latestrelease.info);
-		free(sess->authinfo->latestbeta.name);
-		free(sess->authinfo->latestbeta.url);
-		free(sess->authinfo->latestbeta.info);
-		free(sess->authinfo);
-	}
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0003)
-		return parse(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0007)
-		return keyparse(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int auth_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x0017;
-	mod->version = 0x0000;
-	mod->flags = 0;
-	strncpy(mod->name, "auth", sizeof(mod->name));
-	mod->snachandler = snachandler;
-	mod->shutdown = auth_shutdown;
-
-	return 0;
-}
Index: bfaim/bart.c
===================================================================
--- libfaim/bart.c	(revision 07ab1cb58191016aa991b7765fc82ce89bd078c3)
+++ 	(revision )
@@ -1,165 +1,0 @@
-/*
- * Family 0x0010 - Server stored buddy art
- *
- * Used for storing and retrieving your cute little buddy icon 
- * from the AIM servers.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-/**
- * Subtype 0x0002 - Upload your icon.
- *
- * @param sess The oscar session.
- * @param conn The icon connection for this session.
- * @param icon The raw data of the icon image file.
- * @param iconlen Length of the raw data of the icon image file.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_bart_upload(aim_session_t *sess, const fu8_t *icon, fu16_t iconlen)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0010)) || !icon || !iconlen)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 2 + 2+iconlen)))
-		return -ENOMEM;
-	snacid = aim_cachesnac(sess, 0x0010, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0010, 0x0002, 0x0000, snacid);
-
-	/* The reference number for the icon */
-	aimbs_put16(&fr->data, 1);
-
-	/* The icon */
-	aimbs_put16(&fr->data, iconlen);
-	aimbs_putraw(&fr->data, icon, iconlen);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Subtype 0x0003 - Acknowledgement for uploading a buddy icon.
- *
- * You get this honky after you upload a buddy icon.
- */
-static int uploadack(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t something, somethingelse;
-	fu8_t onemorething;
-
-	something = aimbs_get16(bs);
-	somethingelse = aimbs_get16(bs);
-	onemorething = aimbs_get8(bs);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx);
-
-	return ret;
-}
-
-/**
- * Subtype 0x0004 - Request someone's icon.
- *
- * @param sess The oscar session.
- * @param conn The icon connection for this session.
- * @param sn The screen name of the person who's icon you are requesting.
- * @param iconcsum The MD5 checksum of the icon you are requesting.
- * @param iconcsumlen Length of the MD5 checksum given above.  Should be 10 bytes.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_bart_request(aim_session_t *sess, const char *sn, const fu8_t *iconcsum, fu16_t iconcsumlen)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0010)) || !sn || !strlen(sn) || !iconcsum || !iconcsumlen)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 1+strlen(sn) + 4 + 1+iconcsumlen)))
-		return -ENOMEM;
-	snacid = aim_cachesnac(sess, 0x0010, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0010, 0x0004, 0x0000, snacid);
-
-	/* Screen name */
-	aimbs_put8(&fr->data, strlen(sn));
-	aimbs_putraw(&fr->data, sn, strlen(sn));
-
-	/* Some numbers.  You like numbers, right? */
-	aimbs_put8(&fr->data, 0x01);
-	aimbs_put16(&fr->data, 0x0001);
-	aimbs_put8(&fr->data, 0x01);
-
-	/* Icon string */
-	aimbs_put8(&fr->data, iconcsumlen);
-	aimbs_putraw(&fr->data, iconcsum, iconcsumlen);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Subtype 0x0005 - Receive a buddy icon.
- *
- * This is sent in response to a buddy icon request.
- */
-static int parseicon(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	char *sn;
-	fu16_t flags, iconlen;
-	fu8_t number, iconcsumlen, *iconcsum, *icon;
-
-	sn = aimbs_getstr(bs, aimbs_get8(bs));
-	flags = aimbs_get16(bs);
-	number = aimbs_get8(bs);
-	iconcsumlen = aimbs_get8(bs);
-	iconcsum = aimbs_getraw(bs, iconcsumlen);
-	iconlen = aimbs_get16(bs);
-	icon = aimbs_getraw(bs, iconlen);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, sn, iconcsum, iconcsumlen, icon, iconlen);
-
-	free(sn);
-	free(iconcsum);
-	free(icon);
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0003)
-		return uploadack(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0005)
-		return parseicon(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int bart_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x0010;
-	mod->version = 0x0001;
-	mod->toolid = 0x0010;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "bart", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/bos.c
===================================================================
--- libfaim/bos.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,167 +1,0 @@
-/*
- * Family 0x0009 - Basic Oscar Service.
- *
- * The functionality of this family has been replaced by SSI.
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-#include <string.h>
-
-/* Subtype 0x0002 - Request BOS rights. */
-faim_export int aim_bos_reqrights(aim_session_t *sess, aim_conn_t *conn)
-{
-	return aim_genericreq_n_snacid(sess, conn, 0x0009, 0x0002);
-}
-
-/* Subtype 0x0003 - BOS Rights. */
-static int rights(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_rxcallback_t userfunc;
-	aim_tlvlist_t *tlvlist;
-	fu16_t maxpermits = 0, maxdenies = 0;
-	int ret = 0;
-
-	/* 
-	 * TLVs follow 
-	 */
-	tlvlist = aim_tlvlist_read(bs);
-
-	/*
-	 * TLV type 0x0001: Maximum number of buddies on permit list.
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x0001, 1))
-		maxpermits = aim_tlv_get16(tlvlist, 0x0001, 1);
-
-	/*
-	 * TLV type 0x0002: Maximum number of buddies on deny list.
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x0002, 1)) 
-		maxdenies = aim_tlv_get16(tlvlist, 0x0002, 1);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, maxpermits, maxdenies);
-
-	aim_tlvlist_free(&tlvlist);
-
-	return ret;  
-}
-
-/* 
- * Subtype 0x0004 - Set group permisson mask.
- *
- * Normally 0x1f (all classes).
- *
- * The group permission mask allows you to keep users of a certain
- * class or classes from talking to you.  The mask should be
- * a bitwise OR of all the user classes you want to see you.
- *
- */
-faim_export int aim_bos_setgroupperm(aim_session_t *sess, aim_conn_t *conn, fu32_t mask)
-{
-	return aim_genericreq_l(sess, conn, 0x0009, 0x0004, &mask);
-}
-
-/*
- * Stubtypes 0x0005, 0x0006, 0x0007, and 0x0008 - Modify permit/deny lists.
- *
- * Changes your visibility depending on changetype:
- *
- *  AIM_VISIBILITYCHANGE_PERMITADD: Lets provided list of names see you
- *  AIM_VISIBILITYCHANGE_PERMIDREMOVE: Removes listed names from permit list
- *  AIM_VISIBILITYCHANGE_DENYADD: Hides you from provided list of names
- *  AIM_VISIBILITYCHANGE_DENYREMOVE: Lets list see you again
- *
- * list should be a list of 
- * screen names in the form "Screen Name One&ScreenNameTwo&" etc.
- *
- * Equivelents to options in WinAIM:
- *   - Allow all users to contact me: Send an AIM_VISIBILITYCHANGE_DENYADD
- *      with only your name on it.
- *   - Allow only users on my Buddy List: Send an 
- *      AIM_VISIBILITYCHANGE_PERMITADD with the list the same as your
- *      buddy list
- *   - Allow only the uesrs below: Send an AIM_VISIBILITYCHANGE_PERMITADD 
- *      with everyone listed that you want to see you.
- *   - Block all users: Send an AIM_VISIBILITYCHANGE_PERMITADD with only 
- *      yourself in the list
- *   - Block the users below: Send an AIM_VISIBILITYCHANGE_DENYADD with
- *      the list of users to be blocked
- *
- * XXX ye gods.
- */
-faim_export int aim_bos_changevisibility(aim_session_t *sess, aim_conn_t *conn, int changetype, const char *denylist)
-{
-	aim_frame_t *fr;
-	int packlen = 0;
-	fu16_t subtype;
-	char *localcpy = NULL, *tmpptr = NULL;
-	int i;
-	int listcount;
-	aim_snacid_t snacid;
-
-	if (!denylist)
-		return -EINVAL;
-
-	if (changetype == AIM_VISIBILITYCHANGE_PERMITADD)
-		subtype = 0x05;
-	else if (changetype == AIM_VISIBILITYCHANGE_PERMITREMOVE)
-		subtype = 0x06;
-	else if (changetype == AIM_VISIBILITYCHANGE_DENYADD)
-		subtype = 0x07;
-	else if (changetype == AIM_VISIBILITYCHANGE_DENYREMOVE)
-		subtype = 0x08;
-	else
-		return -EINVAL;
-
-	localcpy = strdup(denylist);
-
-	listcount = aimutil_itemcnt(localcpy, '&');
-	packlen = aimutil_tokslen(localcpy, 99, '&') + listcount + 9;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, packlen))) {
-		free(localcpy);
-		return -ENOMEM;
-	}
-
-	snacid = aim_cachesnac(sess, 0x0009, subtype, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0009, subtype, 0x00, snacid);
-
-	for (i = 0; (i < (listcount - 1)) && (i < 99); i++) {
-		tmpptr = aimutil_itemindex(localcpy, i, '&');
-
-		aimbs_put8(&fr->data, strlen(tmpptr));
-		aimbs_putraw(&fr->data, tmpptr, strlen(tmpptr));
-
-		free(tmpptr);
-	}
-	free(localcpy);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0003)
-		return rights(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int bos_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x0009;
-	mod->version = 0x0001;
-	mod->toolid = 0x0110;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "bos", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/bstream.c
===================================================================
--- libfaim/bstream.c	(revision e374dee70435f8c596358571092675644a9ba731)
+++ 	(revision )
@@ -1,265 +1,0 @@
-/*
- * bstream.c
- *
- * This file contains all functions needed to use bstreams.
- */
-
-#define FAIM_INTERNAL
-#include <aim.h> 
-
-faim_internal int aim_bstream_init(aim_bstream_t *bs, fu8_t *data, int len)
-{
-	
-	if (!bs)
-		return -1;
-
-	bs->data = data;
-	bs->len = len;
-	bs->offset = 0;
-
-	return 0;
-}
-
-faim_internal int aim_bstream_empty(aim_bstream_t *bs)
-{
-	return bs->len - bs->offset;
-}
-
-faim_internal int aim_bstream_curpos(aim_bstream_t *bs)
-{
-	return bs->offset;
-}
-
-faim_internal int aim_bstream_setpos(aim_bstream_t *bs, int off)
-{
-
-	if (off > bs->len)
-		return -1;
-
-	bs->offset = off;
-
-	return off;
-}
-
-faim_internal void aim_bstream_rewind(aim_bstream_t *bs)
-{
-
-	aim_bstream_setpos(bs, 0);
-
-	return;
-}
-
-faim_internal int aim_bstream_advance(aim_bstream_t *bs, int n)
-{
-
-	if (aim_bstream_empty(bs) < n)
-		return 0; /* XXX throw an exception */
-
-	bs->offset += n;
-
-	return n;
-}
-
-faim_internal fu8_t aimbs_get8(aim_bstream_t *bs)
-{
-	
-	if (aim_bstream_empty(bs) < 1)
-		return 0; /* XXX throw an exception */
-	
-	bs->offset++;
-	
-	return aimutil_get8(bs->data + bs->offset - 1);
-}
-
-faim_internal fu16_t aimbs_get16(aim_bstream_t *bs)
-{
-	
-	if (aim_bstream_empty(bs) < 2)
-		return 0; /* XXX throw an exception */
-	
-	bs->offset += 2;
-	
-	return aimutil_get16(bs->data + bs->offset - 2);
-}
-
-faim_internal fu32_t aimbs_get32(aim_bstream_t *bs)
-{
-	
-	if (aim_bstream_empty(bs) < 4)
-		return 0; /* XXX throw an exception */
-	
-	bs->offset += 4;
-	
-	return aimutil_get32(bs->data + bs->offset - 4);
-}
-
-faim_internal fu8_t aimbs_getle8(aim_bstream_t *bs)
-{
-	
-	if (aim_bstream_empty(bs) < 1)
-		return 0; /* XXX throw an exception */
-	
-	bs->offset++;
-	
-	return aimutil_getle8(bs->data + bs->offset - 1);
-}
-
-faim_internal fu16_t aimbs_getle16(aim_bstream_t *bs)
-{
-	
-	if (aim_bstream_empty(bs) < 2)
-		return 0; /* XXX throw an exception */
-	
-	bs->offset += 2;
-	
-	return aimutil_getle16(bs->data + bs->offset - 2);
-}
-
-faim_internal fu32_t aimbs_getle32(aim_bstream_t *bs)
-{
-	
-	if (aim_bstream_empty(bs) < 4)
-		return 0; /* XXX throw an exception */
-	
-	bs->offset += 4;
-	
-	return aimutil_getle32(bs->data + bs->offset - 4);
-}
-
-faim_internal int aimbs_put8(aim_bstream_t *bs, fu8_t v)
-{
-
-	if (aim_bstream_empty(bs) < 1)
-		return 0; /* XXX throw an exception */
-
-	bs->offset += aimutil_put8(bs->data + bs->offset, v);
-
-	return 1;
-}
-
-faim_internal int aimbs_put16(aim_bstream_t *bs, fu16_t v)
-{
-
-	if (aim_bstream_empty(bs) < 2)
-		return 0; /* XXX throw an exception */
-
-	bs->offset += aimutil_put16(bs->data + bs->offset, v);
-
-	return 2;
-}
-
-faim_internal int aimbs_put32(aim_bstream_t *bs, fu32_t v)
-{
-
-	if (aim_bstream_empty(bs) < 4)
-		return 0; /* XXX throw an exception */
-
-	bs->offset += aimutil_put32(bs->data + bs->offset, v);
-
-	return 1;
-}
-
-faim_internal int aimbs_putle8(aim_bstream_t *bs, fu8_t v)
-{
-
-	if (aim_bstream_empty(bs) < 1)
-		return 0; /* XXX throw an exception */
-
-	bs->offset += aimutil_putle8(bs->data + bs->offset, v);
-
-	return 1;
-}
-
-faim_internal int aimbs_putle16(aim_bstream_t *bs, fu16_t v)
-{
-
-	if (aim_bstream_empty(bs) < 2)
-		return 0; /* XXX throw an exception */
-
-	bs->offset += aimutil_putle16(bs->data + bs->offset, v);
-
-	return 2;
-}
-
-faim_internal int aimbs_putle32(aim_bstream_t *bs, fu32_t v)
-{
-
-	if (aim_bstream_empty(bs) < 4)
-		return 0; /* XXX throw an exception */
-
-	bs->offset += aimutil_putle32(bs->data + bs->offset, v);
-
-	return 1;
-}
-
-faim_internal int aimbs_getrawbuf(aim_bstream_t *bs, fu8_t *buf, int len)
-{
-
-	if (aim_bstream_empty(bs) < len)
-		return 0;
-
-	memcpy(buf, bs->data + bs->offset, len);
-	bs->offset += len;
-
-	return len;
-}
-
-faim_internal fu8_t *aimbs_getraw(aim_bstream_t *bs, int len)
-{
-	fu8_t *ob;
-
-	if (!(ob = malloc(len)))
-		return NULL;
-
-	if (aimbs_getrawbuf(bs, ob, len) < len) {
-		free(ob);
-		return NULL;
-	}
-
-	return ob;
-}
-
-faim_internal char *aimbs_getstr(aim_bstream_t *bs, int len)
-{
-	char *ob;
-
-	if (!(ob = malloc(len+1)))
-		return NULL;
-
-	if (aimbs_getrawbuf(bs, ob, len) < len) {
-		free(ob);
-		return NULL;
-	}
-
-	ob[len] = '\0';
-
-	return ob;
-}
-
-faim_internal int aimbs_putraw(aim_bstream_t *bs, const fu8_t *v, int len)
-{
-
-	if (aim_bstream_empty(bs) < len)
-		return 0; /* XXX throw an exception */
-
-	memcpy(bs->data + bs->offset, v, len);
-	bs->offset += len;
-
-	return len;
-}
-
-faim_internal int aimbs_putbs(aim_bstream_t *bs, aim_bstream_t *srcbs, int len)
-{
-
-	if (aim_bstream_empty(srcbs) < len)
-		return 0; /* XXX throw exception (underrun) */
-
-	if (aim_bstream_empty(bs) < len)
-		return 0; /* XXX throw exception (overflow) */
-
-	memcpy(bs->data + bs->offset, srcbs->data + srcbs->offset, len);
-	bs->offset += len;
-	srcbs->offset += len;
-
-	return len;
-}
Index: bfaim/buddylist.c
===================================================================
--- libfaim/buddylist.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,285 +1,0 @@
-/*
- * Family 0x0003 - Old-style Buddylist Management (non-SSI).
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-#include <string.h>
-
-/*
- * Subtype 0x0002 - Request rights.
- *
- * Request Buddy List rights.
- *
- */
-faim_export int aim_buddylist_reqrights(aim_session_t *sess, aim_conn_t *conn)
-{
-	return aim_genericreq_n_snacid(sess, conn, 0x0003, 0x0002);
-}
-
-/*
- * Subtype 0x0003 - Rights.
- *
- */
-static int rights(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_rxcallback_t userfunc;
-	aim_tlvlist_t *tlvlist;
-	fu16_t maxbuddies = 0, maxwatchers = 0;
-	int ret = 0;
-
-	/* 
-	 * TLVs follow 
-	 */
-	tlvlist = aim_tlvlist_read(bs);
-
-	/*
-	 * TLV type 0x0001: Maximum number of buddies.
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x0001, 1))
-		maxbuddies = aim_tlv_get16(tlvlist, 0x0001, 1);
-
-	/*
-	 * TLV type 0x0002: Maximum number of watchers.
-	 *
-	 * Watchers are other users who have you on their buddy
-	 * list.  (This is called the "reverse list" by a certain
-	 * other IM protocol.)
-	 * 
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x0002, 1))
-		maxwatchers = aim_tlv_get16(tlvlist, 0x0002, 1);
-
-	/*
-	 * TLV type 0x0003: Unknown.
-	 *
-	 * ICQ only?
-	 */
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, maxbuddies, maxwatchers);
-
-	aim_tlvlist_free(&tlvlist);
-
-	return ret;  
-}
-
-/*
- * Subtype 0x0004 - Add buddy to list.
- *
- * Adds a single buddy to your buddy list after login.
- * XXX This should just be an extension of setbuddylist()
- *
- */
-faim_export int aim_buddylist_addbuddy(aim_session_t *sess, aim_conn_t *conn, const char *sn)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sn || !strlen(sn))
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, sn, strlen(sn)+1);
-	aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid);
-
-	aimbs_put8(&fr->data, strlen(sn));
-	aimbs_putraw(&fr->data, sn, strlen(sn));
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0004 - Add multiple buddies to your buddy list.
- *
- * This just builds the "set buddy list" command then queues it.
- *
- * buddy_list = "Screen Name One&ScreenNameTwo&";
- *
- * XXX Clean this up.  
- *
- */
-faim_export int aim_buddylist_set(aim_session_t *sess, aim_conn_t *conn, const char *buddy_list)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int len = 0;
-	char *localcpy = NULL;
-	char *tmpptr = NULL;
-
-	if (!buddy_list || !(localcpy = strdup(buddy_list))) 
-		return -EINVAL;
-
-	for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {
-		faimdprintf(sess, 2, "---adding: %s (%d)\n", tmpptr, strlen(tmpptr));
-		len += 1 + strlen(tmpptr);
-		tmpptr = strtok(NULL, "&");
-	}
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+len)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0003, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0003, 0x0004, 0x0000, snacid);
-
-	strncpy(localcpy, buddy_list, strlen(buddy_list) + 1);
-
-	for (tmpptr = strtok(localcpy, "&"); tmpptr; ) {
-
-		faimdprintf(sess, 2, "---adding: %s (%d)\n", tmpptr, strlen(tmpptr));
-
-		aimbs_put8(&fr->data, strlen(tmpptr));
-		aimbs_putraw(&fr->data, tmpptr, strlen(tmpptr));
-		tmpptr = strtok(NULL, "&");
-	}
-
-	aim_tx_enqueue(sess, fr);
-
-	free(localcpy);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0005 - Remove buddy from list.
- *
- * XXX generalise to support removing multiple buddies (basically, its
- * the same as setbuddylist() but with a different snac subtype).
- *
- */
-faim_export int aim_buddylist_removebuddy(aim_session_t *sess, aim_conn_t *conn, const char *sn)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sn || !strlen(sn))
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0003, 0x0005, 0x0000, sn, strlen(sn)+1);
-	aim_putsnac(&fr->data, 0x0003, 0x0005, 0x0000, snacid);
-
-	aimbs_put8(&fr->data, strlen(sn));
-	aimbs_putraw(&fr->data, sn, strlen(sn));
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/* 
- * Subtype 0x000b
- *
- * XXX Why would we send this?
- *
- */
-faim_export int aim_buddylist_oncoming(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *info)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !conn || !info)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0003, 0x000b, 0x0000, NULL, 0);
-	
-	aim_putsnac(&fr->data, 0x0003, 0x000b, 0x0000, snacid);
-	aim_putuserinfo(&fr->data, info);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/* 
- * Subtype 0x000c
- *
- * XXX Why would we send this?
- *
- */
-faim_export int aim_buddylist_offgoing(aim_session_t *sess, aim_conn_t *conn, const char *sn)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !conn || !sn)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0003, 0x000c, 0x0000, NULL, 0);
-	
-	aim_putsnac(&fr->data, 0x0003, 0x000c, 0x0000, snacid);
-	aimbs_put8(&fr->data, strlen(sn));
-	aimbs_putraw(&fr->data, sn, strlen(sn));
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtypes 0x000b and 0x000c - Change in buddy status
- *
- * Oncoming Buddy notifications contain a subset of the
- * user information structure.  It's close enough to run
- * through aim_info_extract() however.
- *
- * Although the offgoing notification contains no information,
- * it is still in a format parsable by aim_info_extract().
- *
- */
-static int buddychange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_userinfo_t userinfo;
-	aim_rxcallback_t userfunc;
-
-	aim_info_extract(sess, bs, &userinfo);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, &userinfo);
-
-	if (snac->subtype == 0x000b)
-		aim_locate_requestuserinfo(sess, userinfo.sn);
-	aim_info_free(&userinfo);
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0003)
-		return rights(sess, mod, rx, snac, bs);
-	else if ((snac->subtype == 0x000b) || (snac->subtype == 0x000c))
-		return buddychange(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int buddylist_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x0003;
-	mod->version = 0x0001;
-	mod->toolid = 0x0110;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "buddylist", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/chat.c
===================================================================
--- libfaim/chat.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,702 +1,0 @@
-/*
- * Family 0x000e - Routines for the Chat service.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h> 
-
-#include <string.h>
-
-/* Stored in the ->priv of chat connections */
-struct chatconnpriv {
-	fu16_t exchange;
-	char *name;
-	fu16_t instance;
-};
-
-faim_internal void aim_conn_kill_chat(aim_session_t *sess, aim_conn_t *conn)
-{
-	struct chatconnpriv *ccp = (struct chatconnpriv *)conn->priv;
-
-	if (ccp)
-		free(ccp->name);
-	free(ccp);
-
-	return;
-}
-
-faim_export char *aim_chat_getname(aim_conn_t *conn)
-{
-	struct chatconnpriv *ccp;
-
-	if (!conn)
-		return NULL;
-
-	if (conn->type != AIM_CONN_TYPE_CHAT)
-		return NULL;
-
-	ccp = (struct chatconnpriv *)conn->priv;
-
-	return ccp->name;
-}
-
-/* XXX get this into conn.c -- evil!! */
-faim_export aim_conn_t *aim_chat_getconn(aim_session_t *sess, const char *name)
-{
-	aim_conn_t *cur;
-
-	for (cur = sess->connlist; cur; cur = cur->next) {
-		struct chatconnpriv *ccp = (struct chatconnpriv *)cur->priv;
-
-		if (cur->type != AIM_CONN_TYPE_CHAT)
-			continue;
-		if (!cur->priv) {
-			faimdprintf(sess, 0, "faim: chat: chat connection with no name! (fd = %d)\n", cur->fd);
-			continue;
-		}
-
-		if (strcmp(ccp->name, name) == 0)
-			break;
-	}
-
-	return cur;
-}
-
-faim_export int aim_chat_attachname(aim_conn_t *conn, fu16_t exchange, const char *roomname, fu16_t instance)
-{
-	struct chatconnpriv *ccp;
-
-	if (!conn || !roomname)
-		return -EINVAL;
-
-	if (conn->priv)
-		free(conn->priv);
-
-	if (!(ccp = malloc(sizeof(struct chatconnpriv))))
-		return -ENOMEM;
-
-	ccp->exchange = exchange;
-	ccp->name = strdup(roomname);
-	ccp->instance = instance;
-
-	conn->priv = (void *)ccp;
-
-	return 0;
-}
-
-static int aim_addtlvtochain_chatroom(aim_tlvlist_t **list, fu16_t type, fu16_t exchange, const char *roomname, fu16_t instance)
-{
-	fu8_t *buf;
-	int buflen;
-	aim_bstream_t bs;
-
-	buflen = 2 + 1 + strlen(roomname) + 2;
-	
-	if (!(buf = malloc(buflen)))
-		return 0;
-
-	aim_bstream_init(&bs, buf, buflen);
-
-	aimbs_put16(&bs, exchange);
-	aimbs_put8(&bs, strlen(roomname));
-	aimbs_putraw(&bs, roomname, strlen(roomname));
-	aimbs_put16(&bs, instance);
-
-	aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf);
-
-	free(buf);
-
-	return 0;
-}
-
-/*
- * Join a room of name roomname.  This is the first step to joining an 
- * already created room.  It's basically a Service Request for 
- * family 0x000e, with a little added on to specify the exchange and room 
- * name.
- */
-faim_export int aim_chat_join(aim_session_t *sess, aim_conn_t *conn, fu16_t exchange, const char *roomname, fu16_t instance)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-	struct chatsnacinfo csi;
-	
-	if (!sess || !conn || !roomname || !strlen(roomname))
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512)))
-		return -ENOMEM;
-
-	memset(&csi, 0, sizeof(csi));
-	csi.exchange = exchange;
-	strncpy(csi.name, roomname, sizeof(csi.name));
-	csi.instance = instance;
-
-	snacid = aim_cachesnac(sess, 0x0001, 0x0004, 0x0000, &csi, sizeof(csi));
-	aim_putsnac(&fr->data, 0x0001, 0x0004, 0x0000, snacid);
-
-	/*
-	 * Requesting service chat (0x000e)
-	 */
-	aimbs_put16(&fr->data, 0x000e);
-
-	aim_addtlvtochain_chatroom(&tl, 0x0001, exchange, roomname, instance);
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0; 
-}
-
-faim_internal int aim_chat_readroominfo(aim_bstream_t *bs, struct aim_chat_roominfo *outinfo)
-{
-	int namelen;
-
-	if (!bs || !outinfo)
-		return 0;
-
-	outinfo->exchange = aimbs_get16(bs);
-	namelen = aimbs_get8(bs);
-	outinfo->name = aimbs_getstr(bs, namelen);
-	outinfo->instance = aimbs_get16(bs);
-
-	return 0;
-}
-
-faim_export int aim_chat_leaveroom(aim_session_t *sess, const char *name)
-{
-	aim_conn_t *conn;
-
-	if (!(conn = aim_chat_getconn(sess, name)))
-		return -ENOENT;
-
-	aim_conn_close(conn);
-
-	return 0;
-}
-
-/*
- * conn must be a BOS connection!
- */
-faim_export int aim_chat_invite(aim_session_t *sess, aim_conn_t *conn, const char *sn, const char *msg, fu16_t exchange, const char *roomname, fu16_t instance)
-{
-	int i;
-	aim_frame_t *fr;
-	aim_msgcookie_t *cookie;
-	struct aim_invite_priv *priv;
-	fu8_t ckstr[8];
-	aim_snacid_t snacid;
-	aim_tlvlist_t *otl = NULL, *itl = NULL;
-	fu8_t *hdr;
-	int hdrlen;
-	aim_bstream_t hdrbs;
-	
-	if (!sess || !conn || !sn || !msg || !roomname)
-		return -EINVAL;
-
-	if (conn->type != AIM_CONN_TYPE_BOS)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152+strlen(sn)+strlen(roomname)+strlen(msg))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, sn, strlen(sn)+1);
-	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
-
-	/*
-	 * Cookie
-	 */
-	for (i = 0; i < 8; i++)
-		ckstr[i] = (fu8_t)rand();
-
-	/* XXX should be uncached by an unwritten 'invite accept' handler */
-	if ((priv = malloc(sizeof(struct aim_invite_priv)))) {
-		priv->sn = strdup(sn);
-		priv->roomname = strdup(roomname);
-		priv->exchange = exchange;
-		priv->instance = instance;
-	}
-
-	if ((cookie = aim_mkcookie(ckstr, AIM_COOKIETYPE_INVITE, priv)))
-		aim_cachecookie(sess, cookie);
-	else
-		free(priv);
-
-	/* ICBM Header */
-	aimbs_putraw(&fr->data, ckstr, 8); /* Cookie */
-	aimbs_put16(&fr->data, 0x0002); /* Channel */
-	aimbs_put8(&fr->data, strlen(sn)); /* Screename length */
-	aimbs_putraw(&fr->data, sn, strlen(sn)); /* Screenname */
-
-	/*
-	 * TLV t(0005)
-	 *
-	 * Everything else is inside this TLV.
-	 *
-	 * Sigh.  AOL was rather inconsistent right here.  So we have
-	 * to play some minor tricks.  Right inside the type 5 is some
-	 * raw data, followed by a series of TLVs.  
-	 *
-	 */
-	hdrlen = 2+8+16+6+4+4+strlen(msg)+4+2+1+strlen(roomname)+2;
-	hdr = malloc(hdrlen);
-	aim_bstream_init(&hdrbs, hdr, hdrlen);
-	
-	aimbs_put16(&hdrbs, 0x0000); /* Unknown! */
-	aimbs_putraw(&hdrbs, ckstr, sizeof(ckstr)); /* I think... */
-	aim_putcap(&hdrbs, AIM_CAPS_CHAT);
-
-	aim_tlvlist_add_16(&itl, 0x000a, 0x0001);
-	aim_tlvlist_add_noval(&itl, 0x000f);
-	aim_tlvlist_add_raw(&itl, 0x000c, strlen(msg), msg);
-	aim_addtlvtochain_chatroom(&itl, 0x2711, exchange, roomname, instance);
-	aim_tlvlist_write(&hdrbs, &itl);
-	
-	aim_tlvlist_add_raw(&otl, 0x0005, aim_bstream_curpos(&hdrbs), hdr);
-
-	aim_tlvlist_write(&fr->data, &otl);
-
-	free(hdr);
-	aim_tlvlist_free(&itl);
-	aim_tlvlist_free(&otl);
-	
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0002 - General room information.  Lots of stuff.
- *
- * Values I know are in here but I havent attached
- * them to any of the 'Unknown's:
- *	- Language (English)
- *
- */
-static int infoupdate(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_userinfo_t *userinfo = NULL;
-	aim_rxcallback_t userfunc;
-	int ret = 0;
-	int usercount = 0;
-	fu8_t detaillevel = 0;
-	char *roomname = NULL;
-	struct aim_chat_roominfo roominfo;
-	fu16_t tlvcount = 0;
-	aim_tlvlist_t *tlvlist;
-	char *roomdesc = NULL;
-	fu16_t flags = 0;
-	fu32_t creationtime = 0;
-	fu16_t maxmsglen = 0, maxvisiblemsglen = 0;
-	fu16_t unknown_d2 = 0, unknown_d5 = 0;
-
-	aim_chat_readroominfo(bs, &roominfo);
-
-	detaillevel = aimbs_get8(bs);
-
-	if (detaillevel != 0x02) {
-		faimdprintf(sess, 0, "faim: chat_roomupdateinfo: detail level %d not supported\n", detaillevel);
-		return 1;
-	}
-
-	tlvcount = aimbs_get16(bs);
-
-	/*
-	 * Everything else are TLVs.
-	 */ 
-	tlvlist = aim_tlvlist_read(bs);
-
-	/*
-	 * TLV type 0x006a is the room name in Human Readable Form.
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x006a, 1))
-		roomname = aim_tlv_getstr(tlvlist, 0x006a, 1);
-
-	/*
-	 * Type 0x006f: Number of occupants.
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x006f, 1))
-		usercount = aim_tlv_get16(tlvlist, 0x006f, 1);
-
-	/*
-	 * Type 0x0073:  Occupant list.
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x0073, 1)) {	
-		int curoccupant = 0;
-		aim_tlv_t *tmptlv;
-		aim_bstream_t occbs;
-
-		tmptlv = aim_tlv_gettlv(tlvlist, 0x0073, 1);
-
-		/* Allocate enough userinfo structs for all occupants */
-		userinfo = calloc(usercount, sizeof(aim_userinfo_t));
-
-		aim_bstream_init(&occbs, tmptlv->value, tmptlv->length);
-
-		while (curoccupant < usercount)
-			aim_info_extract(sess, &occbs, &userinfo[curoccupant++]);
-	}
-
-	/* 
-	 * Type 0x00c9: Flags. (AIM_CHATROOM_FLAG)
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x00c9, 1))
-		flags = aim_tlv_get16(tlvlist, 0x00c9, 1);
-
-	/* 
-	 * Type 0x00ca: Creation time (4 bytes)
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x00ca, 1))
-		creationtime = aim_tlv_get32(tlvlist, 0x00ca, 1);
-
-	/* 
-	 * Type 0x00d1: Maximum Message Length
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x00d1, 1))
-		maxmsglen = aim_tlv_get16(tlvlist, 0x00d1, 1);
-
-	/* 
-	 * Type 0x00d2: Unknown. (2 bytes)
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x00d2, 1))
-		unknown_d2 = aim_tlv_get16(tlvlist, 0x00d2, 1);
-
-	/* 
-	 * Type 0x00d3: Room Description
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x00d3, 1))
-		roomdesc = aim_tlv_getstr(tlvlist, 0x00d3, 1);
-
-	/*
-	 * Type 0x000d4: Unknown (flag only)
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x000d4, 1))
-		;
-
-	/* 
-	 * Type 0x00d5: Unknown. (1 byte)
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x00d5, 1))
-		unknown_d5 = aim_tlv_get8(tlvlist, 0x00d5, 1);
-
-
-	/*
-	 * Type 0x00d6: Encoding 1 ("us-ascii")
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x000d6, 1))
-		;
-	
-	/*
-	 * Type 0x00d7: Language 1 ("en")
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x000d7, 1))
-		;
-
-	/*
-	 * Type 0x00d8: Encoding 2 ("us-ascii")
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x000d8, 1))
-		;
-	
-	/*
-	 * Type 0x00d9: Language 2 ("en")
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x000d9, 1))
-		;
-
-	/*
-	 * Type 0x00da: Maximum visible message length
-	 */
-	if (aim_tlv_gettlv(tlvlist, 0x000da, 1))
-		maxvisiblemsglen = aim_tlv_get16(tlvlist, 0x00da, 1);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) {
-		ret = userfunc(sess,
-				rx,
-				&roominfo,
-				roomname,
-				usercount,
-				userinfo,
-				roomdesc,
-				flags,
-				creationtime,
-				maxmsglen,
-				unknown_d2,
-				unknown_d5,
-				maxvisiblemsglen);
-	}
-
-	free(roominfo.name);
-
-	while (usercount > 0)
-		aim_info_free(&userinfo[--usercount]);
-
-	free(userinfo);
-	free(roomname);
-	free(roomdesc);
-	aim_tlvlist_free(&tlvlist);
-
-	return ret;
-}
-
-/* Subtypes 0x0003 and 0x0004 */
-static int userlistchange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_userinfo_t *userinfo = NULL;
-	aim_rxcallback_t userfunc;
-	int curcount = 0, ret = 0;
-
-	while (aim_bstream_empty(bs)) {
-		curcount++;
-		userinfo = realloc(userinfo, curcount * sizeof(aim_userinfo_t));
-		aim_info_extract(sess, bs, &userinfo[curcount-1]);
-	}
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, curcount, userinfo);
-
-	aim_info_free(userinfo);
-	free(userinfo);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0005 - Send a Chat Message.
- *
- * Possible flags:
- *   AIM_CHATFLAGS_NOREFLECT   --  Unset the flag that requests messages
- *                                 should be sent to their sender.
- *   AIM_CHATFLAGS_AWAY        --  Mark the message as an autoresponse
- *                                 (Note that WinAIM does not honor this,
- *                                 and displays the message as normal.)
- *
- * XXX convert this to use tlvchains 
- */
-faim_export int aim_chat_send_im(aim_session_t *sess, aim_conn_t *conn, fu16_t flags, const char *msg, int msglen)
-{   
-	int i;
-	aim_frame_t *fr;
-	aim_msgcookie_t *cookie;
-	aim_snacid_t snacid;
-	fu8_t ckstr[8];
-	aim_tlvlist_t *otl = NULL, *itl = NULL;
-
-	if (!sess || !conn || !msg || (msglen <= 0))
-		return 0;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x000e, 0x0005, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x000e, 0x0005, 0x0000, snacid);
-
-	/*
-	 * Cookie
-	 *
-	 * XXX mkcookie should generate the cookie and cache it in one
-	 * operation to preserve uniqueness.
-	 */
-	for (i = 0; i < 8; i++)
-		ckstr[i] = (fu8_t)rand();
-
-	cookie = aim_mkcookie(ckstr, AIM_COOKIETYPE_CHAT, NULL);
-	cookie->data = NULL; /* XXX store something useful here */
-
-	aim_cachecookie(sess, cookie);
-
-	/* ICBM Header */
-	aimbs_putraw(&fr->data, ckstr, 8); /* Cookie */
-	aimbs_put16(&fr->data, 0x0003); /* Channel */
-
-	/*
-	 * Type 1: Flag meaning this message is destined to the room.
-	 */
-	aim_tlvlist_add_noval(&otl, 0x0001);
-
-	/*
-	 * Type 6: Reflect
-	 */
-	if (!(flags & AIM_CHATFLAGS_NOREFLECT))
-		aim_tlvlist_add_noval(&otl, 0x0006);
-
-	/*
-	 * Type 7: Autoresponse
-	 */
-	if (flags & AIM_CHATFLAGS_AWAY)
-		aim_tlvlist_add_noval(&otl, 0x0007);
-
-	/*
-	 * SubTLV: Type 1: Message
-	 */
-	aim_tlvlist_add_raw(&itl, 0x0001, msglen, msg);
-
-	/*
-	 * Type 5: Message block.  Contains more TLVs.
-	 *
-	 * This could include other information... We just
-	 * put in a message TLV however.  
-	 * 
-	 */
-	aim_tlvlist_add_frozentlvlist(&otl, 0x0005, &itl);
-
-	aim_tlvlist_write(&fr->data, &otl);
-	
-	aim_tlvlist_free(&itl);
-	aim_tlvlist_free(&otl);
-	
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0006
- *
- * We could probably include this in the normal ICBM parsing 
- * code as channel 0x0003, however, since only the start
- * would be the same, we might as well do it here.
- *
- * General outline of this SNAC:
- *   snac
- *   cookie
- *   channel id
- *   tlvlist
- *     unknown
- *     source user info
- *       name
- *       evility
- *       userinfo tlvs
- *         online time
- *         etc
- *     message metatlv
- *       message tlv
- *         message string
- *       possibly others
- *  
- */
-static int incomingmsg(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_userinfo_t userinfo;
-	aim_rxcallback_t userfunc;	
-	int ret = 0;
-	fu8_t *cookie;
-	fu16_t channel;
-	aim_tlvlist_t *otl;
-	char *msg = NULL;
-	aim_msgcookie_t *ck;
-
-	memset(&userinfo, 0, sizeof(aim_userinfo_t));
-
-	/*
-	 * ICBM Cookie.  Uncache it.
-	 */
-	cookie = aimbs_getraw(bs, 8);
-
-	if ((ck = aim_uncachecookie(sess, cookie, AIM_COOKIETYPE_CHAT))) {
-		free(ck->data);
-		free(ck);
-	}
-
-	/*
-	 * Channel ID
-	 *
-	 * Channels 1 and 2 are implemented in the normal ICBM
-	 * parser.
-	 *
-	 * We only do channel 3 here.
-	 *
-	 */
-	channel = aimbs_get16(bs);
-
-	if (channel != 0x0003) {
-		faimdprintf(sess, 0, "faim: chat_incoming: unknown channel! (0x%04x)\n", channel);
-		return 0;
-	}
-
-	/*
-	 * Start parsing TLVs right away. 
-	 */
-	otl = aim_tlvlist_read(bs);
-
-	/*
-	 * Type 0x0003: Source User Information
-	 */
-	if (aim_tlv_gettlv(otl, 0x0003, 1)) {
-		aim_tlv_t *userinfotlv;
-		aim_bstream_t tbs;
-
-		userinfotlv = aim_tlv_gettlv(otl, 0x0003, 1);
-
-		aim_bstream_init(&tbs, userinfotlv->value, userinfotlv->length);
-		aim_info_extract(sess, &tbs, &userinfo);
-	}
-
-	/*
-	 * Type 0x0001: If present, it means it was a message to the 
-	 * room (as opposed to a whisper).
-	 */
-	if (aim_tlv_gettlv(otl, 0x0001, 1))
-		;
-
-	/*
-	 * Type 0x0005: Message Block.  Conains more TLVs.
-	 */
-	if (aim_tlv_gettlv(otl, 0x0005, 1)) {
-		aim_tlvlist_t *itl;
-		aim_tlv_t *msgblock;
-		aim_bstream_t tbs;
-
-		msgblock = aim_tlv_gettlv(otl, 0x0005, 1);
-		aim_bstream_init(&tbs, msgblock->value, msgblock->length);
-		itl = aim_tlvlist_read(&tbs);
-
-		/* 
-		 * Type 0x0001: Message.
-		 */	
-		if (aim_tlv_gettlv(itl, 0x0001, 1))
-			msg = aim_tlv_getstr(itl, 0x0001, 1);
-
-		aim_tlvlist_free(&itl); 
-	}
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, &userinfo, msg);
-
-	aim_info_free(&userinfo);
-	free(cookie);
-	free(msg);
-	aim_tlvlist_free(&otl);
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0002)
-		return infoupdate(sess, mod, rx, snac, bs);
-	else if ((snac->subtype == 0x0003) || (snac->subtype == 0x0004))
-		return userlistchange(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0006)
-		return incomingmsg(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int chat_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x000e;
-	mod->version = 0x0001;
-	mod->toolid = 0x0010;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "chat", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/chatnav.c
===================================================================
--- libfaim/chatnav.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,434 +1,0 @@
-/*
- * Family 0x000d - Handle ChatNav.
- *
- * The ChatNav(igation) service does various things to keep chat
- * alive.  It provides room information, room searching and creating,
- * as well as giving users the right ("permission") to use chat.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-/*
- * Subtype 0x0002
- *
- * conn must be a chatnav connection!
- *
- */
-faim_export int aim_chatnav_reqrights(aim_session_t *sess, aim_conn_t *conn)
-{
-	return aim_genericreq_n_snacid(sess, conn, 0x000d, 0x0002);
-}
-
-/*
- * Subtype 0x0008
- */
-faim_export int aim_chatnav_createroom(aim_session_t *sess, aim_conn_t *conn, const char *name, fu16_t exchange)
-{
-	static const char ck[] = {"create"};
-	static const char lang[] = {"en"};
-	static const char charset[] = {"us-ascii"};
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x000d, 0x0008, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x000d, 0x0008, 0x0000, snacid);
-
-	/* exchange */
-	aimbs_put16(&fr->data, exchange);
-
-	/*
-	 * This looks to be a big hack.  You'll note that this entire
-	 * SNAC is just a room info structure, but the hard room name,
-	 * here, is set to "create".  
-	 *
-	 * Either this goes on the "list of questions concerning
-	 * why-the-hell-did-you-do-that", or this value is completly
-	 * ignored.  Without experimental evidence, but a good knowledge of
-	 * AOL style, I'm going to guess that it is the latter, and that
-	 * the value of the room name in create requests is ignored.
-	 */
-	aimbs_put8(&fr->data, strlen(ck));
-	aimbs_putraw(&fr->data, ck, strlen(ck));
-
-	/* 
-	 * instance
-	 * 
-	 * Setting this to 0xffff apparently assigns the last instance.
-	 *
-	 */
-	aimbs_put16(&fr->data, 0xffff);
-
-	/* detail level */
-	aimbs_put8(&fr->data, 0x01);
-
-	aim_tlvlist_add_raw(&tl, 0x00d3, strlen(name), name);
-	aim_tlvlist_add_raw(&tl, 0x00d6, strlen(charset), charset);
-	aim_tlvlist_add_raw(&tl, 0x00d7, strlen(lang), lang);
-
-	/* tlvcount */
-	aimbs_put16(&fr->data, aim_tlvlist_count(&tl));
-	aim_tlvlist_write(&fr->data, &tl);
-
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-static int parseinfo_perms(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs, aim_snac_t *snac2)
-{
-	aim_rxcallback_t userfunc;
-	int ret = 0;
-	struct aim_chat_exchangeinfo *exchanges = NULL;
-	int curexchange;
-	aim_tlv_t *exchangetlv;
-	fu8_t maxrooms = 0;
-	aim_tlvlist_t *tlvlist, *innerlist;
-
-	tlvlist = aim_tlvlist_read(bs);
-
-	/* 
-	 * Type 0x0002: Maximum concurrent rooms.
-	 */ 
-	if (aim_tlv_gettlv(tlvlist, 0x0002, 1))
-		maxrooms = aim_tlv_get8(tlvlist, 0x0002, 1);
-
-	/* 
-	 * Type 0x0003: Exchange information
-	 *
-	 * There can be any number of these, each one
-	 * representing another exchange.  
-	 * 
-	 */
-	for (curexchange = 0; ((exchangetlv = aim_tlv_gettlv(tlvlist, 0x0003, curexchange+1))); ) {
-		aim_bstream_t tbs;
-
-		aim_bstream_init(&tbs, exchangetlv->value, exchangetlv->length);
-
-		curexchange++;
-
-		exchanges = realloc(exchanges, curexchange * sizeof(struct aim_chat_exchangeinfo));
-
-		/* exchange number */
-		exchanges[curexchange-1].number = aimbs_get16(&tbs);
-		innerlist = aim_tlvlist_read(&tbs);
-
-		/* 
-		 * Type 0x000a: Unknown.
-		 *
-		 * Usually three bytes: 0x0114 (exchange 1) or 0x010f (others).
-		 *
-		 */
-		if (aim_tlv_gettlv(innerlist, 0x000a, 1))
-			;
-
-		/* 
-		 * Type 0x000d: Unknown.
-		 */
-		if (aim_tlv_gettlv(innerlist, 0x000d, 1))
-			;
-
-		/* 
-		 * Type 0x0004: Unknown
-		 */
-		if (aim_tlv_gettlv(innerlist, 0x0004, 1))
-			;
-
-		/* 
-		 * Type 0x0002: Unknown
-		 */
-		if (aim_tlv_gettlv(innerlist, 0x0002, 1)) {
-			fu16_t classperms;
-
-			classperms = aim_tlv_get16(innerlist, 0x0002, 1);
-			
-			faimdprintf(sess, 1, "faim: class permissions %x\n", classperms);
-		}
-
-		/*
-		 * Type 0x00c9: Flags
-		 *
-		 * 1 Evilable
-		 * 2 Nav Only
-		 * 4 Instancing Allowed
-		 * 8 Occupant Peek Allowed
-		 *
-		 */ 
-		if (aim_tlv_gettlv(innerlist, 0x00c9, 1))
-			exchanges[curexchange-1].flags = aim_tlv_get16(innerlist, 0x00c9, 1);
-		      
-		/*
-		 * Type 0x00ca: Creation Date 
-		 */
-		if (aim_tlv_gettlv(innerlist, 0x00ca, 1))
-			;
-		      
-		/*
-		 * Type 0x00d0: Mandatory Channels?
-		 */
-		if (aim_tlv_gettlv(innerlist, 0x00d0, 1))
-			;
-
-		/*
-		 * Type 0x00d1: Maximum Message length
-		 */
-		if (aim_tlv_gettlv(innerlist, 0x00d1, 1))
-			;
-
-		/*
-		 * Type 0x00d2: Maximum Occupancy?
-		 */
-		if (aim_tlv_gettlv(innerlist, 0x00d2, 1))	
-			;
-
-		/*
-		 * Type 0x00d3: Exchange Description
-		 */
-		if (aim_tlv_gettlv(innerlist, 0x00d3, 1))	
-			exchanges[curexchange-1].name = aim_tlv_getstr(innerlist, 0x00d3, 1);
-		else
-			exchanges[curexchange-1].name = NULL;
-
-		/*
-		 * Type 0x00d4: Exchange Description URL
-		 */
-		if (aim_tlv_gettlv(innerlist, 0x00d4, 1))	
-			;
-
-		/*
-		 * Type 0x00d5: Creation Permissions
-		 *
-		 * 0  Creation not allowed
-		 * 1  Room creation allowed
-		 * 2  Exchange creation allowed
-		 * 
-		 */
-		if (aim_tlv_gettlv(innerlist, 0x00d5, 1)) {
-			fu8_t createperms;
-
-			createperms = aim_tlv_get8(innerlist, 0x00d5, 1);
-		}
-
-		/*
-		 * Type 0x00d6: Character Set (First Time)
-		 */	      
-		if (aim_tlv_gettlv(innerlist, 0x00d6, 1))	
-			exchanges[curexchange-1].charset1 = aim_tlv_getstr(innerlist, 0x00d6, 1);
-		else
-			exchanges[curexchange-1].charset1 = NULL;
-		      
-		/*
-		 * Type 0x00d7: Language (First Time)
-		 */	      
-		if (aim_tlv_gettlv(innerlist, 0x00d7, 1))	
-			exchanges[curexchange-1].lang1 = aim_tlv_getstr(innerlist, 0x00d7, 1);
-		else
-			exchanges[curexchange-1].lang1 = NULL;
-
-		/*
-		 * Type 0x00d8: Character Set (Second Time)
-		 */	      
-		if (aim_tlv_gettlv(innerlist, 0x00d8, 1))	
-			exchanges[curexchange-1].charset2 = aim_tlv_getstr(innerlist, 0x00d8, 1);
-		else
-			exchanges[curexchange-1].charset2 = NULL;
-
-		/*
-		 * Type 0x00d9: Language (Second Time)
-		 */	      
-		if (aim_tlv_gettlv(innerlist, 0x00d9, 1))	
-			exchanges[curexchange-1].lang2 = aim_tlv_getstr(innerlist, 0x00d9, 1);
-		else
-			exchanges[curexchange-1].lang2 = NULL;
-		      
-		/*
-		 * Type 0x00da: Unknown
-		 */
-		if (aim_tlv_gettlv(innerlist, 0x00da, 1))	
-			;
-
-		aim_tlvlist_free(&innerlist);
-	}
-
-	/*
-	 * Call client.
-	 */
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, snac2->type, maxrooms, curexchange, exchanges);
-
-	for (curexchange--; curexchange >= 0; curexchange--) {
-		free(exchanges[curexchange].name);
-		free(exchanges[curexchange].charset1);
-		free(exchanges[curexchange].lang1);
-		free(exchanges[curexchange].charset2);
-		free(exchanges[curexchange].lang2);
-	}
-	free(exchanges);
-	aim_tlvlist_free(&tlvlist);
-
-	return ret;
-}
-
-static int parseinfo_create(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs, aim_snac_t *snac2)
-{
-	aim_rxcallback_t userfunc;
-	aim_tlvlist_t *tlvlist, *innerlist;
-	char *ck = NULL, *fqcn = NULL, *name = NULL;
-	fu16_t exchange = 0, instance = 0, unknown = 0, flags = 0, maxmsglen = 0, maxoccupancy = 0;
-	fu32_t createtime = 0;
-	fu8_t createperms = 0, detaillevel;
-	int cklen;
-	aim_tlv_t *bigblock;
-	int ret = 0;
-	aim_bstream_t bbbs;
-
-	tlvlist = aim_tlvlist_read(bs);
-
-	if (!(bigblock = aim_tlv_gettlv(tlvlist, 0x0004, 1))) {
-		faimdprintf(sess, 0, "no bigblock in top tlv in create room response\n");
-		aim_tlvlist_free(&tlvlist);
-		return 0;
-	}
-
-	aim_bstream_init(&bbbs, bigblock->value, bigblock->length);
-
-	exchange = aimbs_get16(&bbbs);
-	cklen = aimbs_get8(&bbbs);
-	ck = aimbs_getstr(&bbbs, cklen);
-	instance = aimbs_get16(&bbbs);
-	detaillevel = aimbs_get8(&bbbs);
-
-	if (detaillevel != 0x02) {
-		faimdprintf(sess, 0, "unknown detaillevel in create room response (0x%02x)\n", detaillevel);
-		aim_tlvlist_free(&tlvlist);
-		free(ck);
-		return 0;
-	}
-
-	unknown = aimbs_get16(&bbbs);
-
-	innerlist = aim_tlvlist_read(&bbbs);
-
-	if (aim_tlv_gettlv(innerlist, 0x006a, 1))
-		fqcn = aim_tlv_getstr(innerlist, 0x006a, 1);
-
-	if (aim_tlv_gettlv(innerlist, 0x00c9, 1))
-		flags = aim_tlv_get16(innerlist, 0x00c9, 1);
-
-	if (aim_tlv_gettlv(innerlist, 0x00ca, 1))
-		createtime = aim_tlv_get32(innerlist, 0x00ca, 1);
-
-	if (aim_tlv_gettlv(innerlist, 0x00d1, 1))
-		maxmsglen = aim_tlv_get16(innerlist, 0x00d1, 1);
-
-	if (aim_tlv_gettlv(innerlist, 0x00d2, 1))
-		maxoccupancy = aim_tlv_get16(innerlist, 0x00d2, 1);
-
-	if (aim_tlv_gettlv(innerlist, 0x00d3, 1))
-		name = aim_tlv_getstr(innerlist, 0x00d3, 1);
-
-	if (aim_tlv_gettlv(innerlist, 0x00d5, 1))
-		createperms = aim_tlv_get8(innerlist, 0x00d5, 1);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) {
-		ret = userfunc(sess, rx, snac2->type, fqcn, instance, exchange, flags, createtime, maxmsglen, maxoccupancy, createperms, unknown, name, ck);
-	}
-
-	free(ck);
-	free(name);
-	free(fqcn);
-	aim_tlvlist_free(&innerlist);
-	aim_tlvlist_free(&tlvlist);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0009
- *
- * Since multiple things can trigger this callback, we must lookup the 
- * snacid to determine the original snac subtype that was called.
- *
- * XXX This isn't really how this works.  But this is:  Every d/9 response
- * has a 16bit value at the beginning. That matches to:
- *    Short Desc = 1
- *    Full Desc = 2
- *    Instance Info = 4
- *    Nav Short Desc = 8
- *    Nav Instance Info = 16
- * And then everything is really asynchronous.  There is no specific 
- * attachment of a response to a create room request, for example.  Creating
- * the room yields no different a response than requesting the room's info.
- *
- */
-static int parseinfo(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_snac_t *snac2;
-	int ret = 0;
-
-	if (!(snac2 = aim_remsnac(sess, snac->id))) {
-		faimdprintf(sess, 0, "faim: chatnav_parse_info: received response to unknown request! (%08lx)\n", snac->id);
-		return 0;
-	}
-
-	if (snac2->family != 0x000d) {
-		faimdprintf(sess, 0, "faim: chatnav_parse_info: recieved response that maps to corrupt request! (fam=%04x)\n", snac2->family);
-		return 0;
-	}
-
-	/*
-	 * We now know what the original SNAC subtype was.
-	 */
-	if (snac2->type == 0x0002) /* request chat rights */
-		ret = parseinfo_perms(sess, mod, rx, snac, bs, snac2);
-	else if (snac2->type == 0x0003) /* request exchange info */
-		faimdprintf(sess, 0, "chatnav_parse_info: resposne to exchange info\n");
-	else if (snac2->type == 0x0004) /* request room info */
-		faimdprintf(sess, 0, "chatnav_parse_info: response to room info\n");
-	else if (snac2->type == 0x0005) /* request more room info */
-		faimdprintf(sess, 0, "chatnav_parse_info: response to more room info\n");
-	else if (snac2->type == 0x0006) /* request occupant list */
-		faimdprintf(sess, 0, "chatnav_parse_info: response to occupant info\n");
-	else if (snac2->type == 0x0007) /* search for a room */
-		faimdprintf(sess, 0, "chatnav_parse_info: search results\n");
-	else if (snac2->type == 0x0008) /* create room */
-		ret = parseinfo_create(sess, mod, rx, snac, bs, snac2);
-	else
-		faimdprintf(sess, 0, "chatnav_parse_info: unknown request subtype (%04x)\n", snac2->type);
-
-	if (snac2)
-		free(snac2->data);
-	free(snac2);
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0009)
-		return parseinfo(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int chatnav_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x000d;
-	mod->version = 0x0001;
-	mod->toolid = 0x0010;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "chatnav", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/config.h.in
===================================================================
--- libfaim/config.h.in	(revision 5e53c4a15eca8b264df0aedf726d4545bc5b4b46)
+++ 	(revision )
@@ -1,83 +1,0 @@
-/* include/config.h.in.  Generated automatically from configure.in by autoheader.  */
-
-/* Define to empty if the keyword does not work.  */
-#undef const
-
-/* Define if you don't have vprintf but do have _doprnt.  */
-#undef HAVE_DOPRNT
-
-/* Define if you have the strftime function.  */
-#undef HAVE_STRFTIME
-
-/* Define if you have <sys/wait.h> that is POSIX.1 compatible.  */
-#undef HAVE_SYS_WAIT_H
-
-/* Define if you have the vprintf function.  */
-#undef HAVE_VPRINTF
-
-/* Define as __inline if that's what the C compiler calls it.  */
-#undef inline
-
-/* Define to `int' if <sys/types.h> doesn't define.  */
-#undef pid_t
-
-/* Define as the return type of signal handlers (int or void).  */
-#undef RETSIGTYPE
-
-/* Define to `unsigned' if <sys/types.h> doesn't define.  */
-#undef size_t
-
-/* Define if you have the ANSI C header files.  */
-#undef STDC_HEADERS
-
-/* Define if you can safely include both <sys/time.h> and <time.h>.  */
-#undef TIME_WITH_SYS_TIME
-
-/* Define if your <sys/time.h> declares struct tm.  */
-#undef TM_IN_SYS_TIME
-
-/* Define if you have the getaddrinfo function.  */
-#undef HAVE_GETADDRINFO
-
-/* Define if you have the gethostname function.  */
-#undef HAVE_GETHOSTNAME
-
-/* Define if you have the gettimeofday function.  */
-#undef HAVE_GETTIMEOFDAY
-
-/* Define if you have the select function.  */
-#undef HAVE_SELECT
-
-/* Define if you have the socket function.  */
-#undef HAVE_SOCKET
-
-/* Define if you have the strdup function.  */
-#undef HAVE_STRDUP
-
-/* Define if you have the strstr function.  */
-#undef HAVE_STRSTR
-
-/* Define if you have the strtol function.  */
-#undef HAVE_STRTOL
-
-/* Define if you have the uname function.  */
-#undef HAVE_UNAME
-
-/* Define if you have the <fcntl.h> header file.  */
-#undef HAVE_FCNTL_H
-
-/* Define if you have the <sys/time.h> header file.  */
-#undef HAVE_SYS_TIME_H
-
-/* Define if you have the <unistd.h> header file.  */
-#undef HAVE_UNISTD_H
-
-/* Define if you have the faim library (-lfaim).  */
-#undef HAVE_LIBFAIM
-
-/* Name of package */
-#undef PACKAGE
-
-/* Version number of package */
-#undef VERSION
-
Index: bfaim/configure
===================================================================
--- libfaim/configure	(revision 1ef65fbc93f88230a95c10105937627bdfe6708d)
+++ 	(revision )
@@ -1,3170 +1,0 @@
-#! /bin/sh
-# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59.
-#
-# Copyright (C) 2003 Free Software Foundation, Inc.
-# This configure script is free software; the Free Software Foundation
-# gives unlimited permission to copy, distribute and modify it.
-## --------------------- ##
-## M4sh Initialization.  ##
-## --------------------- ##
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
-  set -o posix
-fi
-DUALCASE=1; export DUALCASE # for MKS sh
-
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
-  as_unset=unset
-else
-  as_unset=false
-fi
-
-
-# Work around bugs in pre-3.0 UWIN ksh.
-$as_unset ENV MAIL MAILPATH
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
-  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
-  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
-  LC_TELEPHONE LC_TIME
-do
-  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
-    eval $as_var=C; export $as_var
-  else
-    $as_unset $as_var
-  fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
-  as_basename=basename
-else
-  as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)$' \| \
-	 .     : '\(.\)' 2>/dev/null ||
-echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
-  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\/\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-
-
-# PATH needs CR, and LINENO needs CR and PATH.
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-
-
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
-  # Find who we are.  Look in the path if we contain no path at all
-  # relative or not.
-  case $0 in
-    *[\\/]* ) as_myself=$0 ;;
-    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-
-       ;;
-  esac
-  # We did not find ourselves, most probably we were run as `sh COMMAND'
-  # in which case we are not to be found in the path.
-  if test "x$as_myself" = x; then
-    as_myself=$0
-  fi
-  if test ! -f "$as_myself"; then
-    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
-   { (exit 1); exit 1; }; }
-  fi
-  case $CONFIG_SHELL in
-  '')
-    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for as_base in sh bash ksh sh5; do
-	 case $as_dir in
-	 /*)
-	   if ("$as_dir/$as_base" -c '
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
-	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
-	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
-	     CONFIG_SHELL=$as_dir/$as_base
-	     export CONFIG_SHELL
-	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
-	   fi;;
-	 esac
-       done
-done
-;;
-  esac
-
-  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
-  # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line before each line; the second 'sed' does the real
-  # work.  The second script uses 'N' to pair each line-number line
-  # with the numbered line, and appends trailing '-' during
-  # substitution so that $LINENO is not a special case at line end.
-  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
-  sed '=' <$as_myself |
-    sed '
-      N
-      s,$,-,
-      : loop
-      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
-      t loop
-      s,-$,,
-      s,^['$as_cr_digits']*\n,,
-    ' >$as_me.lineno &&
-  chmod +x $as_me.lineno ||
-    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
-   { (exit 1); exit 1; }; }
-
-  # Don't try to exec as it changes $[0], causing all sort of problems
-  # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensible to this).
-  . ./$as_me.lineno
-  # Exit status is that of the last command.
-  exit
-}
-
-
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
-  *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T='	' ;;
-  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
-  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
-esac
-
-if expr a : '\(a\)' >/dev/null 2>&1; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
-  # We could just check for DJGPP; but this test a) works b) is more generic
-  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
-  if test -f conf$$.exe; then
-    # Don't use ln at all; we don't have any links
-    as_ln_s='cp -p'
-  else
-    as_ln_s='ln -s'
-  fi
-elif ln conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s=ln
-else
-  as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.file
-
-if mkdir -p . 2>/dev/null; then
-  as_mkdir_p=:
-else
-  test -d ./-p && rmdir ./-p
-  as_mkdir_p=false
-fi
-
-as_executable_p="test -f"
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" 	$as_nl"
-
-# CDPATH.
-$as_unset CDPATH
-
-
-# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-exec 6>&1
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_config_libobj_dir=.
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-# Maximum number of lines to put in a shell here document.
-# This variable seems obsolete.  It should probably be removed, and
-# only ac_max_sed_lines should be used.
-: ${ac_max_here_lines=38}
-
-# Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
-
-ac_unique_file="bos.c"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT RANLIB ac_ct_RANLIB LIBOBJS LTLIBOBJS'
-ac_subst_files=''
-
-# Initialize some variables set by options.
-ac_init_help=
-ac_init_version=false
-# The variables have the same names as the options, with
-# dashes changed to underlines.
-cache_file=/dev/null
-exec_prefix=NONE
-no_create=
-no_recursion=
-prefix=NONE
-program_prefix=NONE
-program_suffix=NONE
-program_transform_name=s,x,x,
-silent=
-site=
-srcdir=
-verbose=
-x_includes=NONE
-x_libraries=NONE
-
-# Installation directory options.
-# These are left unexpanded so users can "make install exec_prefix=/foo"
-# and all the variables that are supposed to be based on exec_prefix
-# by default will actually change.
-# Use braces instead of parens because sh, perl, etc. also accept them.
-bindir='${exec_prefix}/bin'
-sbindir='${exec_prefix}/sbin'
-libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
-sysconfdir='${prefix}/etc'
-sharedstatedir='${prefix}/com'
-localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
-includedir='${prefix}/include'
-oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
-
-ac_prev=
-for ac_option
-do
-  # If the previous option needs an argument, assign it.
-  if test -n "$ac_prev"; then
-    eval "$ac_prev=\$ac_option"
-    ac_prev=
-    continue
-  fi
-
-  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
-
-  # Accept the important Cygnus configure options, so we can diagnose typos.
-
-  case $ac_option in
-
-  -bindir | --bindir | --bindi | --bind | --bin | --bi)
-    ac_prev=bindir ;;
-  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
-    bindir=$ac_optarg ;;
-
-  -build | --build | --buil | --bui | --bu)
-    ac_prev=build_alias ;;
-  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
-    build_alias=$ac_optarg ;;
-
-  -cache-file | --cache-file | --cache-fil | --cache-fi \
-  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
-    ac_prev=cache_file ;;
-  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
-  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
-    cache_file=$ac_optarg ;;
-
-  --config-cache | -C)
-    cache_file=config.cache ;;
-
-  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
-    ac_prev=datadir ;;
-  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
-  | --da=*)
-    datadir=$ac_optarg ;;
-
-  -disable-* | --disable-*)
-    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
-   { (exit 1); exit 1; }; }
-    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
-    eval "enable_$ac_feature=no" ;;
-
-  -enable-* | --enable-*)
-    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
-   { (exit 1); exit 1; }; }
-    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
-    case $ac_option in
-      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
-      *) ac_optarg=yes ;;
-    esac
-    eval "enable_$ac_feature='$ac_optarg'" ;;
-
-  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
-  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
-  | --exec | --exe | --ex)
-    ac_prev=exec_prefix ;;
-  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
-  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
-  | --exec=* | --exe=* | --ex=*)
-    exec_prefix=$ac_optarg ;;
-
-  -gas | --gas | --ga | --g)
-    # Obsolete; use --with-gas.
-    with_gas=yes ;;
-
-  -help | --help | --hel | --he | -h)
-    ac_init_help=long ;;
-  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
-    ac_init_help=recursive ;;
-  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
-    ac_init_help=short ;;
-
-  -host | --host | --hos | --ho)
-    ac_prev=host_alias ;;
-  -host=* | --host=* | --hos=* | --ho=*)
-    host_alias=$ac_optarg ;;
-
-  -includedir | --includedir | --includedi | --included | --include \
-  | --includ | --inclu | --incl | --inc)
-    ac_prev=includedir ;;
-  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
-  | --includ=* | --inclu=* | --incl=* | --inc=*)
-    includedir=$ac_optarg ;;
-
-  -infodir | --infodir | --infodi | --infod | --info | --inf)
-    ac_prev=infodir ;;
-  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
-    infodir=$ac_optarg ;;
-
-  -libdir | --libdir | --libdi | --libd)
-    ac_prev=libdir ;;
-  -libdir=* | --libdir=* | --libdi=* | --libd=*)
-    libdir=$ac_optarg ;;
-
-  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
-  | --libexe | --libex | --libe)
-    ac_prev=libexecdir ;;
-  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
-  | --libexe=* | --libex=* | --libe=*)
-    libexecdir=$ac_optarg ;;
-
-  -localstatedir | --localstatedir | --localstatedi | --localstated \
-  | --localstate | --localstat | --localsta | --localst \
-  | --locals | --local | --loca | --loc | --lo)
-    ac_prev=localstatedir ;;
-  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
-  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
-  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
-    localstatedir=$ac_optarg ;;
-
-  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
-    ac_prev=mandir ;;
-  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
-    mandir=$ac_optarg ;;
-
-  -nfp | --nfp | --nf)
-    # Obsolete; use --without-fp.
-    with_fp=no ;;
-
-  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
-  | --no-cr | --no-c | -n)
-    no_create=yes ;;
-
-  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
-  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
-    no_recursion=yes ;;
-
-  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
-  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
-  | --oldin | --oldi | --old | --ol | --o)
-    ac_prev=oldincludedir ;;
-  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
-  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
-  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
-    oldincludedir=$ac_optarg ;;
-
-  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
-    ac_prev=prefix ;;
-  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
-    prefix=$ac_optarg ;;
-
-  -program-prefix | --program-prefix | --program-prefi | --program-pref \
-  | --program-pre | --program-pr | --program-p)
-    ac_prev=program_prefix ;;
-  -program-prefix=* | --program-prefix=* | --program-prefi=* \
-  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
-    program_prefix=$ac_optarg ;;
-
-  -program-suffix | --program-suffix | --program-suffi | --program-suff \
-  | --program-suf | --program-su | --program-s)
-    ac_prev=program_suffix ;;
-  -program-suffix=* | --program-suffix=* | --program-suffi=* \
-  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
-    program_suffix=$ac_optarg ;;
-
-  -program-transform-name | --program-transform-name \
-  | --program-transform-nam | --program-transform-na \
-  | --program-transform-n | --program-transform- \
-  | --program-transform | --program-transfor \
-  | --program-transfo | --program-transf \
-  | --program-trans | --program-tran \
-  | --progr-tra | --program-tr | --program-t)
-    ac_prev=program_transform_name ;;
-  -program-transform-name=* | --program-transform-name=* \
-  | --program-transform-nam=* | --program-transform-na=* \
-  | --program-transform-n=* | --program-transform-=* \
-  | --program-transform=* | --program-transfor=* \
-  | --program-transfo=* | --program-transf=* \
-  | --program-trans=* | --program-tran=* \
-  | --progr-tra=* | --program-tr=* | --program-t=*)
-    program_transform_name=$ac_optarg ;;
-
-  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-  | -silent | --silent | --silen | --sile | --sil)
-    silent=yes ;;
-
-  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
-    ac_prev=sbindir ;;
-  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
-  | --sbi=* | --sb=*)
-    sbindir=$ac_optarg ;;
-
-  -sharedstatedir | --sharedstatedir | --sharedstatedi \
-  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
-  | --sharedst | --shareds | --shared | --share | --shar \
-  | --sha | --sh)
-    ac_prev=sharedstatedir ;;
-  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
-  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
-  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
-  | --sha=* | --sh=*)
-    sharedstatedir=$ac_optarg ;;
-
-  -site | --site | --sit)
-    ac_prev=site ;;
-  -site=* | --site=* | --sit=*)
-    site=$ac_optarg ;;
-
-  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
-    ac_prev=srcdir ;;
-  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
-    srcdir=$ac_optarg ;;
-
-  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
-  | --syscon | --sysco | --sysc | --sys | --sy)
-    ac_prev=sysconfdir ;;
-  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
-  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
-    sysconfdir=$ac_optarg ;;
-
-  -target | --target | --targe | --targ | --tar | --ta | --t)
-    ac_prev=target_alias ;;
-  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
-    target_alias=$ac_optarg ;;
-
-  -v | -verbose | --verbose | --verbos | --verbo | --verb)
-    verbose=yes ;;
-
-  -version | --version | --versio | --versi | --vers | -V)
-    ac_init_version=: ;;
-
-  -with-* | --with-*)
-    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid package name: $ac_package" >&2
-   { (exit 1); exit 1; }; }
-    ac_package=`echo $ac_package| sed 's/-/_/g'`
-    case $ac_option in
-      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
-      *) ac_optarg=yes ;;
-    esac
-    eval "with_$ac_package='$ac_optarg'" ;;
-
-  -without-* | --without-*)
-    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid package name: $ac_package" >&2
-   { (exit 1); exit 1; }; }
-    ac_package=`echo $ac_package | sed 's/-/_/g'`
-    eval "with_$ac_package=no" ;;
-
-  --x)
-    # Obsolete; use --with-x.
-    with_x=yes ;;
-
-  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
-  | --x-incl | --x-inc | --x-in | --x-i)
-    ac_prev=x_includes ;;
-  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
-  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
-    x_includes=$ac_optarg ;;
-
-  -x-libraries | --x-libraries | --x-librarie | --x-librari \
-  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
-    ac_prev=x_libraries ;;
-  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
-  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
-    x_libraries=$ac_optarg ;;
-
-  -*) { echo "$as_me: error: unrecognized option: $ac_option
-Try \`$0 --help' for more information." >&2
-   { (exit 1); exit 1; }; }
-    ;;
-
-  *=*)
-    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
-    # Reject names that are not valid shell variable names.
-    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
-   { (exit 1); exit 1; }; }
-    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
-    eval "$ac_envvar='$ac_optarg'"
-    export $ac_envvar ;;
-
-  *)
-    # FIXME: should be removed in autoconf 3.0.
-    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
-    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
-    ;;
-
-  esac
-done
-
-if test -n "$ac_prev"; then
-  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  { echo "$as_me: error: missing argument to $ac_option" >&2
-   { (exit 1); exit 1; }; }
-fi
-
-# Be sure to have absolute paths.
-for ac_var in exec_prefix prefix
-do
-  eval ac_val=$`echo $ac_var`
-  case $ac_val in
-    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
-    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
-   { (exit 1); exit 1; }; };;
-  esac
-done
-
-# Be sure to have absolute paths.
-for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
-	      localstatedir libdir includedir oldincludedir infodir mandir
-do
-  eval ac_val=$`echo $ac_var`
-  case $ac_val in
-    [\\/$]* | ?:[\\/]* ) ;;
-    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
-   { (exit 1); exit 1; }; };;
-  esac
-done
-
-# There might be people who depend on the old broken behavior: `$host'
-# used to hold the argument of --host etc.
-# FIXME: To remove some day.
-build=$build_alias
-host=$host_alias
-target=$target_alias
-
-# FIXME: To remove some day.
-if test "x$host_alias" != x; then
-  if test "x$build_alias" = x; then
-    cross_compiling=maybe
-    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
-    If a cross compiler is detected then cross compile mode will be used." >&2
-  elif test "x$build_alias" != "x$host_alias"; then
-    cross_compiling=yes
-  fi
-fi
-
-ac_tool_prefix=
-test -n "$host_alias" && ac_tool_prefix=$host_alias-
-
-test "$silent" = yes && exec 6>/dev/null
-
-
-# Find the source files, if location was not specified.
-if test -z "$srcdir"; then
-  ac_srcdir_defaulted=yes
-  # Try the directory containing this script, then its parent.
-  ac_confdir=`(dirname "$0") 2>/dev/null ||
-$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$0" : 'X\(//\)[^/]' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
-echo X"$0" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-  srcdir=$ac_confdir
-  if test ! -r $srcdir/$ac_unique_file; then
-    srcdir=..
-  fi
-else
-  ac_srcdir_defaulted=no
-fi
-if test ! -r $srcdir/$ac_unique_file; then
-  if test "$ac_srcdir_defaulted" = yes; then
-    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
-   { (exit 1); exit 1; }; }
-  else
-    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
-   { (exit 1); exit 1; }; }
-  fi
-fi
-(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
-  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
-   { (exit 1); exit 1; }; }
-srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
-ac_env_build_alias_set=${build_alias+set}
-ac_env_build_alias_value=$build_alias
-ac_cv_env_build_alias_set=${build_alias+set}
-ac_cv_env_build_alias_value=$build_alias
-ac_env_host_alias_set=${host_alias+set}
-ac_env_host_alias_value=$host_alias
-ac_cv_env_host_alias_set=${host_alias+set}
-ac_cv_env_host_alias_value=$host_alias
-ac_env_target_alias_set=${target_alias+set}
-ac_env_target_alias_value=$target_alias
-ac_cv_env_target_alias_set=${target_alias+set}
-ac_cv_env_target_alias_value=$target_alias
-ac_env_CC_set=${CC+set}
-ac_env_CC_value=$CC
-ac_cv_env_CC_set=${CC+set}
-ac_cv_env_CC_value=$CC
-ac_env_CFLAGS_set=${CFLAGS+set}
-ac_env_CFLAGS_value=$CFLAGS
-ac_cv_env_CFLAGS_set=${CFLAGS+set}
-ac_cv_env_CFLAGS_value=$CFLAGS
-ac_env_LDFLAGS_set=${LDFLAGS+set}
-ac_env_LDFLAGS_value=$LDFLAGS
-ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
-ac_cv_env_LDFLAGS_value=$LDFLAGS
-ac_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_env_CPPFLAGS_value=$CPPFLAGS
-ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_cv_env_CPPFLAGS_value=$CPPFLAGS
-
-#
-# Report the --help message.
-#
-if test "$ac_init_help" = "long"; then
-  # Omit some internal or obsolete options to make the list less imposing.
-  # This message is too long to be a string in the A/UX 3.1 sh.
-  cat <<_ACEOF
-\`configure' configures this package to adapt to many kinds of systems.
-
-Usage: $0 [OPTION]... [VAR=VALUE]...
-
-To assign environment variables (e.g., CC, CFLAGS...), specify them as
-VAR=VALUE.  See below for descriptions of some of the useful variables.
-
-Defaults for the options are specified in brackets.
-
-Configuration:
-  -h, --help              display this help and exit
-      --help=short        display options specific to this package
-      --help=recursive    display the short help of all the included packages
-  -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking...' messages
-      --cache-file=FILE   cache test results in FILE [disabled]
-  -C, --config-cache      alias for \`--cache-file=config.cache'
-  -n, --no-create         do not create output files
-      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
-
-_ACEOF
-
-  cat <<_ACEOF
-Installation directories:
-  --prefix=PREFIX         install architecture-independent files in PREFIX
-			  [$ac_default_prefix]
-  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
-			  [PREFIX]
-
-By default, \`make install' will install all the files in
-\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
-an installation prefix other than \`$ac_default_prefix' using \`--prefix',
-for instance \`--prefix=\$HOME'.
-
-For better control, use the options below.
-
-Fine tuning of the installation directories:
-  --bindir=DIR           user executables [EPREFIX/bin]
-  --sbindir=DIR          system admin executables [EPREFIX/sbin]
-  --libexecdir=DIR       program executables [EPREFIX/libexec]
-  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
-  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
-  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
-  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
-  --libdir=DIR           object code libraries [EPREFIX/lib]
-  --includedir=DIR       C header files [PREFIX/include]
-  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
-  --infodir=DIR          info documentation [PREFIX/info]
-  --mandir=DIR           man documentation [PREFIX/man]
-_ACEOF
-
-  cat <<\_ACEOF
-_ACEOF
-fi
-
-if test -n "$ac_init_help"; then
-
-  cat <<\_ACEOF
-
-Some influential environment variables:
-  CC          C compiler command
-  CFLAGS      C compiler flags
-  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
-              nonstandard directory <lib dir>
-  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
-              headers in a nonstandard directory <include dir>
-
-Use these variables to override the choices made by `configure' or to help
-it to find libraries and programs with nonstandard names/locations.
-
-_ACEOF
-fi
-
-if test "$ac_init_help" = "recursive"; then
-  # If there are subdirs, report their specific --help.
-  ac_popdir=`pwd`
-  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
-    test -d $ac_dir || continue
-    ac_builddir=.
-
-if test "$ac_dir" != .; then
-  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A "../" for each directory in $ac_dir_suffix.
-  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
-  ac_dir_suffix= ac_top_builddir=
-fi
-
-case $srcdir in
-  .)  # No --srcdir option.  We are building in place.
-    ac_srcdir=.
-    if test -z "$ac_top_builddir"; then
-       ac_top_srcdir=.
-    else
-       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
-    fi ;;
-  [\\/]* | ?:[\\/]* )  # Absolute path.
-    ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir ;;
-  *) # Relative path.
-    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_builddir$srcdir ;;
-esac
-
-# Do not use `cd foo && pwd` to compute absolute paths, because
-# the directories may not exist.
-case `pwd` in
-.) ac_abs_builddir="$ac_dir";;
-*)
-  case "$ac_dir" in
-  .) ac_abs_builddir=`pwd`;;
-  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
-  *) ac_abs_builddir=`pwd`/"$ac_dir";;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_builddir=${ac_top_builddir}.;;
-*)
-  case ${ac_top_builddir}. in
-  .) ac_abs_top_builddir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
-  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_srcdir=$ac_srcdir;;
-*)
-  case $ac_srcdir in
-  .) ac_abs_srcdir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
-  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_srcdir=$ac_top_srcdir;;
-*)
-  case $ac_top_srcdir in
-  .) ac_abs_top_srcdir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
-  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
-  esac;;
-esac
-
-    cd $ac_dir
-    # Check for guested configure; otherwise get Cygnus style configure.
-    if test -f $ac_srcdir/configure.gnu; then
-      echo
-      $SHELL $ac_srcdir/configure.gnu  --help=recursive
-    elif test -f $ac_srcdir/configure; then
-      echo
-      $SHELL $ac_srcdir/configure  --help=recursive
-    elif test -f $ac_srcdir/configure.ac ||
-	   test -f $ac_srcdir/configure.in; then
-      echo
-      $ac_configure --help
-    else
-      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
-    fi
-    cd $ac_popdir
-  done
-fi
-
-test -n "$ac_init_help" && exit 0
-if $ac_init_version; then
-  cat <<\_ACEOF
-
-Copyright (C) 2003 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
-_ACEOF
-  exit 0
-fi
-exec 5>config.log
-cat >&5 <<_ACEOF
-This file contains any messages produced by compilers while
-running configure, to aid debugging if configure makes a mistake.
-
-It was created by $as_me, which was
-generated by GNU Autoconf 2.59.  Invocation command line was
-
-  $ $0 $@
-
-_ACEOF
-{
-cat <<_ASUNAME
-## --------- ##
-## Platform. ##
-## --------- ##
-
-hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
-/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
-
-/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
-/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
-/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
-/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
-/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
-
-_ASUNAME
-
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  echo "PATH: $as_dir"
-done
-
-} >&5
-
-cat >&5 <<_ACEOF
-
-
-## ----------- ##
-## Core tests. ##
-## ----------- ##
-
-_ACEOF
-
-
-# Keep a trace of the command line.
-# Strip out --no-create and --no-recursion so they do not pile up.
-# Strip out --silent because we don't want to record it for future runs.
-# Also quote any args containing shell meta-characters.
-# Make two passes to allow for proper duplicate-argument suppression.
-ac_configure_args=
-ac_configure_args0=
-ac_configure_args1=
-ac_sep=
-ac_must_keep_next=false
-for ac_pass in 1 2
-do
-  for ac_arg
-  do
-    case $ac_arg in
-    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
-    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-    | -silent | --silent | --silen | --sile | --sil)
-      continue ;;
-    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
-      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
-    esac
-    case $ac_pass in
-    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
-    2)
-      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
-      if test $ac_must_keep_next = true; then
-	ac_must_keep_next=false # Got value, back to normal.
-      else
-	case $ac_arg in
-	  *=* | --config-cache | -C | -disable-* | --disable-* \
-	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
-	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
-	  | -with-* | --with-* | -without-* | --without-* | --x)
-	    case "$ac_configure_args0 " in
-	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
-	    esac
-	    ;;
-	  -* ) ac_must_keep_next=true ;;
-	esac
-      fi
-      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
-      # Get rid of the leading space.
-      ac_sep=" "
-      ;;
-    esac
-  done
-done
-$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
-$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
-
-# When interrupted or exit'd, cleanup temporary files, and complete
-# config.log.  We remove comments because anyway the quotes in there
-# would cause problems or look ugly.
-# WARNING: Be sure not to use single quotes in there, as some shells,
-# such as our DU 5.0 friend, will then `close' the trap.
-trap 'exit_status=$?
-  # Save into config.log some information that might help in debugging.
-  {
-    echo
-
-    cat <<\_ASBOX
-## ---------------- ##
-## Cache variables. ##
-## ---------------- ##
-_ASBOX
-    echo
-    # The following way of writing the cache mishandles newlines in values,
-{
-  (set) 2>&1 |
-    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
-    *ac_space=\ *)
-      sed -n \
-	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
-	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
-      ;;
-    *)
-      sed -n \
-	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
-      ;;
-    esac;
-}
-    echo
-
-    cat <<\_ASBOX
-## ----------------- ##
-## Output variables. ##
-## ----------------- ##
-_ASBOX
-    echo
-    for ac_var in $ac_subst_vars
-    do
-      eval ac_val=$`echo $ac_var`
-      echo "$ac_var='"'"'$ac_val'"'"'"
-    done | sort
-    echo
-
-    if test -n "$ac_subst_files"; then
-      cat <<\_ASBOX
-## ------------- ##
-## Output files. ##
-## ------------- ##
-_ASBOX
-      echo
-      for ac_var in $ac_subst_files
-      do
-	eval ac_val=$`echo $ac_var`
-	echo "$ac_var='"'"'$ac_val'"'"'"
-      done | sort
-      echo
-    fi
-
-    if test -s confdefs.h; then
-      cat <<\_ASBOX
-## ----------- ##
-## confdefs.h. ##
-## ----------- ##
-_ASBOX
-      echo
-      sed "/^$/d" confdefs.h | sort
-      echo
-    fi
-    test "$ac_signal" != 0 &&
-      echo "$as_me: caught signal $ac_signal"
-    echo "$as_me: exit $exit_status"
-  } >&5
-  rm -f core *.core &&
-  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
-    exit $exit_status
-     ' 0
-for ac_signal in 1 2 13 15; do
-  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
-done
-ac_signal=0
-
-# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo >confdefs.h
-
-# Predefined preprocessor variables.
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
-
-
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
-
-
-# Let the site file select an alternate cache file if it wants to.
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
-  if test "x$prefix" != xNONE; then
-    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
-  else
-    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
-  fi
-fi
-for ac_site_file in $CONFIG_SITE; do
-  if test -r "$ac_site_file"; then
-    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
-echo "$as_me: loading site script $ac_site_file" >&6;}
-    sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file"
-  fi
-done
-
-if test -r "$cache_file"; then
-  # Some versions of bash will fail to source /dev/null (special
-  # files actually), so we avoid doing that.
-  if test -f "$cache_file"; then
-    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
-echo "$as_me: loading cache $cache_file" >&6;}
-    case $cache_file in
-      [\\/]* | ?:[\\/]* ) . $cache_file;;
-      *)                      . ./$cache_file;;
-    esac
-  fi
-else
-  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
-echo "$as_me: creating cache $cache_file" >&6;}
-  >$cache_file
-fi
-
-# Check that the precious variables saved in the cache have kept the same
-# value.
-ac_cache_corrupted=false
-for ac_var in `(set) 2>&1 |
-	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
-  eval ac_old_set=\$ac_cv_env_${ac_var}_set
-  eval ac_new_set=\$ac_env_${ac_var}_set
-  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
-  eval ac_new_val="\$ac_env_${ac_var}_value"
-  case $ac_old_set,$ac_new_set in
-    set,)
-      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,set)
-      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
-      ac_cache_corrupted=: ;;
-    ,);;
-    *)
-      if test "x$ac_old_val" != "x$ac_new_val"; then
-	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
-echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
-	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
-echo "$as_me:   former value:  $ac_old_val" >&2;}
-	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
-echo "$as_me:   current value: $ac_new_val" >&2;}
-	ac_cache_corrupted=:
-      fi;;
-  esac
-  # Pass precious variables to config.status.
-  if test "$ac_new_set" = set; then
-    case $ac_new_val in
-    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
-      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
-    *) ac_arg=$ac_var=$ac_new_val ;;
-    esac
-    case " $ac_configure_args " in
-      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
-      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
-    esac
-  fi
-done
-if $ac_cache_corrupted; then
-  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
-echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
-echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "gcc", so it can be a program name with args.
-set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  CC=$ac_ct_CC
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
-set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="${ac_tool_prefix}cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_CC"; then
-  ac_ct_CC=$CC
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  CC=$ac_ct_CC
-else
-  CC="$ac_cv_prog_CC"
-fi
-
-fi
-if test -z "$CC"; then
-  # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-  ac_prog_rejected=no
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
-       ac_prog_rejected=yes
-       continue
-     fi
-    ac_cv_prog_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-if test $ac_prog_rejected = yes; then
-  # We found a bogon in the path, so make sure we never use it.
-  set dummy $ac_cv_prog_CC
-  shift
-  if test $# != 0; then
-    # We chose a different compiler from the bogus one.
-    # However, it has the same basename, so the bogon will be chosen
-    # first if we set CC to just the basename; use the full file name.
-    shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
-  fi
-fi
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$CC"; then
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in cl
-  do
-    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
-set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$CC"; then
-  ac_cv_prog_CC="$CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-CC=$ac_cv_prog_CC
-if test -n "$CC"; then
-  echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-    test -n "$CC" && break
-  done
-fi
-if test -z "$CC"; then
-  ac_ct_CC=$CC
-  for ac_prog in cl
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_CC"; then
-  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_CC="$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
-  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  test -n "$ac_ct_CC" && break
-done
-
-  CC=$ac_ct_CC
-fi
-
-fi
-
-
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-
-# Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
-     "checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
-  (eval $ac_compiler --version </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
-  (eval $ac_compiler -v </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
-  (eval $ac_compiler -V </dev/null >&5) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
-  (eval $ac_link_default) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # Find the output, starting from the most likely.  This scheme is
-# not robust to junk in `.', hence go to wildcards (a.*) only as a last
-# resort.
-
-# Be careful to initialize this variable, since it used to be cached.
-# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
-ac_cv_exeext=
-# b.out is created by i960 compilers.
-for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
-do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
-	;;
-    conftest.$ac_ext )
-	# This is the source file.
-	;;
-    [ab].out )
-	# We found the default executable, but exeext='' is most
-	# certainly right.
-	break;;
-    *.* )
-	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-	# FIXME: I believe we export ac_cv_exeext for Libtool,
-	# but it would be cool to find out if it's true.  Does anybody
-	# maintain Libtool? --akim.
-	export ac_cv_exeext
-	break;;
-    * )
-	break;;
-  esac
-done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
-fi
-
-ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6
-
-# Check the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
-  if { ac_try='./$ac_file'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-	cross_compiling=yes
-    else
-	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-    fi
-  fi
-fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
-ac_clean_files=$ac_clean_files_save
-# Check the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6
-
-echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
-  (eval $ac_link) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
-  test -f "$ac_file" || continue
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
-    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
-	  export ac_cv_exeext
-	  break;;
-    * ) break;;
-  esac
-done
-else
-  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
-if test "${ac_cv_objext+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
-  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
-  case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
-    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
-       break;;
-  esac
-done
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-#ifndef __GNUC__
-       choke me
-#endif
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_compiler_gnu=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_compiler_gnu=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_cv_c_compiler_gnu=$ac_compiler_gnu
-
-fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
-GCC=`test $ac_compiler_gnu = yes && echo yes`
-ac_test_CFLAGS=${CFLAGS+set}
-ac_save_CFLAGS=$CFLAGS
-CFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_g+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_prog_cc_g=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
-if test "$ac_test_CFLAGS" = set; then
-  CFLAGS=$ac_save_CFLAGS
-elif test $ac_cv_prog_cc_g = yes; then
-  if test "$GCC" = yes; then
-    CFLAGS="-g -O2"
-  else
-    CFLAGS="-g"
-  fi
-else
-  if test "$GCC" = yes; then
-    CFLAGS="-O2"
-  else
-    CFLAGS=
-  fi
-fi
-echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
-echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_stdc+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  ac_cv_prog_cc_stdc=no
-ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std1 is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std1.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
-_ACEOF
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX			-qlanglvl=ansi
-# Ultrix and OSF/1	-std1
-# HP-UX 10.20 and later	-Ae
-# HP-UX older versions	-Aa -D_HPUX_SOURCE
-# SVR4			-Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
-do
-  CC="$ac_save_CC $ac_arg"
-  rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_prog_cc_stdc=$ac_arg
-break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext
-done
-rm -f conftest.$ac_ext conftest.$ac_objext
-CC=$ac_save_CC
-
-fi
-
-case "x$ac_cv_prog_cc_stdc" in
-  x|xno)
-    echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6 ;;
-  *)
-    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
-    CC="$CC $ac_cv_prog_cc_stdc" ;;
-esac
-
-# Some people use a C++ compiler to compile C.  Since we use `exit',
-# in C++ we need to declare it.  In case someone uses the same compiler
-# for both compiling C and C++ we need to have the C++ compiler decide
-# the declaration of exit, since it's the most demanding environment.
-cat >conftest.$ac_ext <<_ACEOF
-#ifndef __cplusplus
-  choke me
-#endif
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  for ac_declaration in \
-   '' \
-   'extern "C" void std::exit (int) throw (); using std::exit;' \
-   'extern "C" void std::exit (int); using std::exit;' \
-   'extern "C" void exit (int) throw ();' \
-   'extern "C" void exit (int);' \
-   'void exit (int);'
-do
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_declaration
-#include <stdlib.h>
-int
-main ()
-{
-exit (42);
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-continue
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_declaration
-int
-main ()
-{
-exit (42);
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
-  (eval $ac_compile) 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } &&
-	 { ac_try='test -z "$ac_c_werror_flag"
-			 || test ! -s conftest.err'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; } &&
-	 { ac_try='test -s conftest.$ac_objext'
-  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  break
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
-  echo '#ifdef __cplusplus' >>confdefs.h
-  echo $ac_declaration      >>confdefs.h
-  echo '#endif'             >>confdefs.h
-fi
-
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-if test "$GCC" = yes; then
-   CFLAGS="$CFLAGS -Wall -g";
-fi
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_RANLIB+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$RANLIB"; then
-  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-fi
-fi
-RANLIB=$ac_cv_prog_RANLIB
-if test -n "$RANLIB"; then
-  echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_RANLIB"; then
-  ac_ct_RANLIB=$RANLIB
-  # Extract the first word of "ranlib", so it can be a program name with args.
-set dummy ranlib; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$ac_ct_RANLIB"; then
-  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ac_ct_RANLIB="ranlib"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-
-  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
-fi
-fi
-ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
-if test -n "$ac_ct_RANLIB"; then
-  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
-echo "${ECHO_T}$ac_ct_RANLIB" >&6
-else
-  echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-  RANLIB=$ac_ct_RANLIB
-else
-  RANLIB="$ac_cv_prog_RANLIB"
-fi
-
-
-
-          ac_config_files="$ac_config_files Makefile"
-cat >confcache <<\_ACEOF
-# This file is a shell script that caches the results of configure
-# tests run on this system so they can be shared between configure
-# scripts and configure runs, see configure's option --config-cache.
-# It is not useful on other systems.  If it contains results you don't
-# want to keep, you may remove or edit it.
-#
-# config.status only pays attention to the cache file if you give it
-# the --recheck option to rerun configure.
-#
-# `ac_cv_env_foo' variables (set or unset) will be overridden when
-# loading this file, other *unset* `ac_cv_foo' will be assigned the
-# following values.
-
-_ACEOF
-
-# The following way of writing the cache mishandles newlines in values,
-# but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
-# Ultrix sh set writes to stderr and can't be redirected directly,
-# and sets the high bit in the cache file unless we assign to the vars.
-{
-  (set) 2>&1 |
-    case `(ac_space=' '; set | grep ac_space) 2>&1` in
-    *ac_space=\ *)
-      # `set' does not quote correctly, so add quotes (double-quote
-      # substitution turns \\\\ into \\, and sed turns \\ into \).
-      sed -n \
-	"s/'/'\\\\''/g;
-	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
-      ;;
-    *)
-      # `set' quotes correctly as required by POSIX, so do not add quotes.
-      sed -n \
-	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
-      ;;
-    esac;
-} |
-  sed '
-     t clear
-     : clear
-     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
-     t end
-     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
-     : end' >>confcache
-if diff $cache_file confcache >/dev/null 2>&1; then :; else
-  if test -w $cache_file; then
-    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
-    cat confcache >$cache_file
-  else
-    echo "not updating unwritable cache $cache_file"
-  fi
-fi
-rm -f confcache
-
-test "x$prefix" = xNONE && prefix=$ac_default_prefix
-# Let make expand exec_prefix.
-test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
-  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
-s/:*\$(srcdir):*/:/;
-s/:*\${srcdir}:*/:/;
-s/:*@srcdir@:*/:/;
-s/^\([^=]*=[	 ]*\):*/\1/;
-s/:*$//;
-s/^[^=]*=[	 ]*$//;
-}'
-fi
-
-# Transform confdefs.h into DEFS.
-# Protect against shell expansion while executing Makefile rules.
-# Protect against Makefile macro expansion.
-#
-# If the first sed substitution is executed (which looks for macros that
-# take arguments), then we branch to the quote section.  Otherwise,
-# look for a macro that doesn't take arguments.
-cat >confdef2opt.sed <<\_ACEOF
-t clear
-: clear
-s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\),-D\1=\2,g
-t quote
-s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\),-D\1=\2,g
-t quote
-d
-: quote
-s,[	 `~#$^&*(){}\\|;'"<>?],\\&,g
-s,\[,\\&,g
-s,\],\\&,g
-s,\$,$$,g
-p
-_ACEOF
-# We use echo to avoid assuming a particular line-breaking character.
-# The extra dot is to prevent the shell from consuming trailing
-# line-breaks from the sub-command output.  A line-break within
-# single-quotes doesn't work because, if this script is created in a
-# platform that uses two characters for line-breaks (e.g., DOS), tr
-# would break.
-ac_LF_and_DOT=`echo; echo .`
-DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
-rm -f confdef2opt.sed
-
-
-ac_libobjs=
-ac_ltlibobjs=
-for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
-  # 1. Remove the extension, and $U if already installed.
-  ac_i=`echo "$ac_i" |
-	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
-  # 2. Add them.
-  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
-  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
-done
-LIBOBJS=$ac_libobjs
-
-LTLIBOBJS=$ac_ltlibobjs
-
-
-
-: ${CONFIG_STATUS=./config.status}
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
-echo "$as_me: creating $CONFIG_STATUS" >&6;}
-cat >$CONFIG_STATUS <<_ACEOF
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate the current configuration.
-# Compiler output produced by configure, useful for debugging
-# configure, is in config.log if it exists.
-
-debug=false
-ac_cs_recheck=false
-ac_cs_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-## --------------------- ##
-## M4sh Initialization.  ##
-## --------------------- ##
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
-  set -o posix
-fi
-DUALCASE=1; export DUALCASE # for MKS sh
-
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
-  as_unset=unset
-else
-  as_unset=false
-fi
-
-
-# Work around bugs in pre-3.0 UWIN ksh.
-$as_unset ENV MAIL MAILPATH
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-for as_var in \
-  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
-  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
-  LC_TELEPHONE LC_TIME
-do
-  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
-    eval $as_var=C; export $as_var
-  else
-    $as_unset $as_var
-  fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
-  as_basename=basename
-else
-  as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)$' \| \
-	 .     : '\(.\)' 2>/dev/null ||
-echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
-  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\/\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-
-
-# PATH needs CR, and LINENO needs CR and PATH.
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
-  else
-    PATH_SEPARATOR=:
-  fi
-  rm -f conf$$.sh
-fi
-
-
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
-  # Find who we are.  Look in the path if we contain no path at all
-  # relative or not.
-  case $0 in
-    *[\\/]* ) as_myself=$0 ;;
-    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-
-       ;;
-  esac
-  # We did not find ourselves, most probably we were run as `sh COMMAND'
-  # in which case we are not to be found in the path.
-  if test "x$as_myself" = x; then
-    as_myself=$0
-  fi
-  if test ! -f "$as_myself"; then
-    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
-echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
-   { (exit 1); exit 1; }; }
-  fi
-  case $CONFIG_SHELL in
-  '')
-    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for as_base in sh bash ksh sh5; do
-	 case $as_dir in
-	 /*)
-	   if ("$as_dir/$as_base" -c '
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
-	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
-	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
-	     CONFIG_SHELL=$as_dir/$as_base
-	     export CONFIG_SHELL
-	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
-	   fi;;
-	 esac
-       done
-done
-;;
-  esac
-
-  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
-  # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line before each line; the second 'sed' does the real
-  # work.  The second script uses 'N' to pair each line-number line
-  # with the numbered line, and appends trailing '-' during
-  # substitution so that $LINENO is not a special case at line end.
-  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
-  sed '=' <$as_myself |
-    sed '
-      N
-      s,$,-,
-      : loop
-      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
-      t loop
-      s,-$,,
-      s,^['$as_cr_digits']*\n,,
-    ' >$as_me.lineno &&
-  chmod +x $as_me.lineno ||
-    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
-echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
-   { (exit 1); exit 1; }; }
-
-  # Don't try to exec as it changes $[0], causing all sort of problems
-  # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensible to this).
-  . ./$as_me.lineno
-  # Exit status is that of the last command.
-  exit
-}
-
-
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
-  *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T='	' ;;
-  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
-  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
-esac
-
-if expr a : '\(a\)' >/dev/null 2>&1; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
-  # We could just check for DJGPP; but this test a) works b) is more generic
-  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
-  if test -f conf$$.exe; then
-    # Don't use ln at all; we don't have any links
-    as_ln_s='cp -p'
-  else
-    as_ln_s='ln -s'
-  fi
-elif ln conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s=ln
-else
-  as_ln_s='cp -p'
-fi
-rm -f conf$$ conf$$.exe conf$$.file
-
-if mkdir -p . 2>/dev/null; then
-  as_mkdir_p=:
-else
-  test -d ./-p && rmdir ./-p
-  as_mkdir_p=false
-fi
-
-as_executable_p="test -f"
-
-# Sed expression to map a string onto a valid CPP name.
-as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
-
-# Sed expression to map a string onto a valid variable name.
-as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-
-
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" 	$as_nl"
-
-# CDPATH.
-$as_unset CDPATH
-
-exec 6>&1
-
-# Open the log real soon, to keep \$[0] and so on meaningful, and to
-# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling.  Logging --version etc. is OK.
-exec 5>>config.log
-{
-  echo
-  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
-} >&5
-cat >&5 <<_CSEOF
-
-This file was extended by $as_me, which was
-generated by GNU Autoconf 2.59.  Invocation command line was
-
-  CONFIG_FILES    = $CONFIG_FILES
-  CONFIG_HEADERS  = $CONFIG_HEADERS
-  CONFIG_LINKS    = $CONFIG_LINKS
-  CONFIG_COMMANDS = $CONFIG_COMMANDS
-  $ $0 $@
-
-_CSEOF
-echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
-echo >&5
-_ACEOF
-
-# Files that config.status was made for.
-if test -n "$ac_config_files"; then
-  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
-fi
-
-if test -n "$ac_config_headers"; then
-  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
-fi
-
-if test -n "$ac_config_links"; then
-  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
-fi
-
-if test -n "$ac_config_commands"; then
-  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
-fi
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-
-ac_cs_usage="\
-\`$as_me' instantiates files from templates according to the
-current configuration.
-
-Usage: $0 [OPTIONS] [FILE]...
-
-  -h, --help       print this help, then exit
-  -V, --version    print version number, then exit
-  -q, --quiet      do not print progress messages
-  -d, --debug      don't remove temporary files
-      --recheck    update $as_me by reconfiguring in the same conditions
-  --file=FILE[:TEMPLATE]
-		   instantiate the configuration file FILE
-
-Configuration files:
-$config_files
-
-Report bugs to <bug-autoconf@gnu.org>."
-_ACEOF
-
-cat >>$CONFIG_STATUS <<_ACEOF
-ac_cs_version="\\
-config.status
-configured by $0, generated by GNU Autoconf 2.59,
-  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
-
-Copyright (C) 2003 Free Software Foundation, Inc.
-This config.status script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it."
-srcdir=$srcdir
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If no file are specified by the user, then we need to provide default
-# value.  By we need to know if files were specified by the user.
-ac_need_defaults=:
-while test $# != 0
-do
-  case $1 in
-  --*=*)
-    ac_option=`expr "x$1" : 'x\([^=]*\)='`
-    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
-    ac_shift=:
-    ;;
-  -*)
-    ac_option=$1
-    ac_optarg=$2
-    ac_shift=shift
-    ;;
-  *) # This is not an option, so the user has probably given explicit
-     # arguments.
-     ac_option=$1
-     ac_need_defaults=false;;
-  esac
-
-  case $ac_option in
-  # Handling of the options.
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
-    ac_cs_recheck=: ;;
-  --version | --vers* | -V )
-    echo "$ac_cs_version"; exit 0 ;;
-  --he | --h)
-    # Conflict between --help and --header
-    { { echo "$as_me:$LINENO: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&5
-echo "$as_me: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&2;}
-   { (exit 1); exit 1; }; };;
-  --help | --hel | -h )
-    echo "$ac_cs_usage"; exit 0 ;;
-  --debug | --d* | -d )
-    debug=: ;;
-  --file | --fil | --fi | --f )
-    $ac_shift
-    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
-    ac_need_defaults=false;;
-  --header | --heade | --head | --hea )
-    $ac_shift
-    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
-    ac_need_defaults=false;;
-  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
-  | -silent | --silent | --silen | --sile | --sil | --si | --s)
-    ac_cs_silent=: ;;
-
-  # This is an error.
-  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&5
-echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2;}
-   { (exit 1); exit 1; }; } ;;
-
-  *) ac_config_targets="$ac_config_targets $1" ;;
-
-  esac
-  shift
-done
-
-ac_configure_extra_args=
-
-if $ac_cs_silent; then
-  exec 6>/dev/null
-  ac_configure_extra_args="$ac_configure_extra_args --silent"
-fi
-
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-if \$ac_cs_recheck; then
-  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
-  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
-fi
-
-_ACEOF
-
-
-
-
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-for ac_config_target in $ac_config_targets
-do
-  case "$ac_config_target" in
-  # Handling of arguments.
-  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
-  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
-echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
-   { (exit 1); exit 1; }; };;
-  esac
-done
-
-# If the user did not use the arguments to specify the items to instantiate,
-# then the envvar interface is used.  Set only those that are not.
-# We use the long form for the default assignment because of an extremely
-# bizarre bug on SunOS 4.1.3.
-if $ac_need_defaults; then
-  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
-fi
-
-# Have a temporary directory for convenience.  Make it in the build tree
-# simply because there is no reason to put it here, and in addition,
-# creating and moving files from /tmp can sometimes cause problems.
-# Create a temporary directory, and hook for its removal unless debugging.
-$debug ||
-{
-  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
-  trap '{ (exit 1); exit 1; }' 1 2 13 15
-}
-
-# Create a (secure) tmp directory for tmp files.
-
-{
-  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
-  test -n "$tmp" && test -d "$tmp"
-}  ||
-{
-  tmp=./confstat$$-$RANDOM
-  (umask 077 && mkdir $tmp)
-} ||
-{
-   echo "$me: cannot create a temporary directory in ." >&2
-   { (exit 1); exit 1; }
-}
-
-_ACEOF
-
-cat >>$CONFIG_STATUS <<_ACEOF
-
-#
-# CONFIG_FILES section.
-#
-
-# No need to generate the scripts if there are no CONFIG_FILES.
-# This happens for instance when ./config.status config.h
-if test -n "\$CONFIG_FILES"; then
-  # Protect against being on the right side of a sed subst in config.status.
-  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
-   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
-s,@SHELL@,$SHELL,;t t
-s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
-s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
-s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
-s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
-s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
-s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
-s,@exec_prefix@,$exec_prefix,;t t
-s,@prefix@,$prefix,;t t
-s,@program_transform_name@,$program_transform_name,;t t
-s,@bindir@,$bindir,;t t
-s,@sbindir@,$sbindir,;t t
-s,@libexecdir@,$libexecdir,;t t
-s,@datadir@,$datadir,;t t
-s,@sysconfdir@,$sysconfdir,;t t
-s,@sharedstatedir@,$sharedstatedir,;t t
-s,@localstatedir@,$localstatedir,;t t
-s,@libdir@,$libdir,;t t
-s,@includedir@,$includedir,;t t
-s,@oldincludedir@,$oldincludedir,;t t
-s,@infodir@,$infodir,;t t
-s,@mandir@,$mandir,;t t
-s,@build_alias@,$build_alias,;t t
-s,@host_alias@,$host_alias,;t t
-s,@target_alias@,$target_alias,;t t
-s,@DEFS@,$DEFS,;t t
-s,@ECHO_C@,$ECHO_C,;t t
-s,@ECHO_N@,$ECHO_N,;t t
-s,@ECHO_T@,$ECHO_T,;t t
-s,@LIBS@,$LIBS,;t t
-s,@CC@,$CC,;t t
-s,@CFLAGS@,$CFLAGS,;t t
-s,@LDFLAGS@,$LDFLAGS,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@ac_ct_CC@,$ac_ct_CC,;t t
-s,@EXEEXT@,$EXEEXT,;t t
-s,@OBJEXT@,$OBJEXT,;t t
-s,@RANLIB@,$RANLIB,;t t
-s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
-s,@LIBOBJS@,$LIBOBJS,;t t
-s,@LTLIBOBJS@,$LTLIBOBJS,;t t
-CEOF
-
-_ACEOF
-
-  cat >>$CONFIG_STATUS <<\_ACEOF
-  # Split the substitutions into bite-sized pieces for seds with
-  # small command number limits, like on Digital OSF/1 and HP-UX.
-  ac_max_sed_lines=48
-  ac_sed_frag=1 # Number of current file.
-  ac_beg=1 # First line for current file.
-  ac_end=$ac_max_sed_lines # Line after last line for current file.
-  ac_more_lines=:
-  ac_sed_cmds=
-  while $ac_more_lines; do
-    if test $ac_beg -gt 1; then
-      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
-    else
-      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
-    fi
-    if test ! -s $tmp/subs.frag; then
-      ac_more_lines=false
-    else
-      # The purpose of the label and of the branching condition is to
-      # speed up the sed processing (if there are no `@' at all, there
-      # is no need to browse any of the substitutions).
-      # These are the two extra sed commands mentioned above.
-      (echo ':t
-  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
-      if test -z "$ac_sed_cmds"; then
-	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
-      else
-	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
-      fi
-      ac_sed_frag=`expr $ac_sed_frag + 1`
-      ac_beg=$ac_end
-      ac_end=`expr $ac_end + $ac_max_sed_lines`
-    fi
-  done
-  if test -z "$ac_sed_cmds"; then
-    ac_sed_cmds=cat
-  fi
-fi # test -n "$CONFIG_FILES"
-
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
-  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
-  case $ac_file in
-  - | *:- | *:-:* ) # input from stdin
-	cat >$tmp/stdin
-	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
-  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
-	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
-  * )   ac_file_in=$ac_file.in ;;
-  esac
-
-  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
-  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
-$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$ac_file" : 'X\(//\)[^/]' \| \
-	 X"$ac_file" : 'X\(//\)$' \| \
-	 X"$ac_file" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
-echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-  { if $as_mkdir_p; then
-    mkdir -p "$ac_dir"
-  else
-    as_dir="$ac_dir"
-    as_dirs=
-    while test ! -d "$as_dir"; do
-      as_dirs="$as_dir $as_dirs"
-      as_dir=`(dirname "$as_dir") 2>/dev/null ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_dir" : 'X\(//\)[^/]' \| \
-	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| \
-	 .     : '\(.\)' 2>/dev/null ||
-echo X"$as_dir" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
-  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
-  	  /^X\(\/\/\)$/{ s//\1/; q; }
-  	  /^X\(\/\).*/{ s//\1/; q; }
-  	  s/.*/./; q'`
-    done
-    test ! -n "$as_dirs" || mkdir $as_dirs
-  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
-echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
-   { (exit 1); exit 1; }; }; }
-
-  ac_builddir=.
-
-if test "$ac_dir" != .; then
-  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
-  # A "../" for each directory in $ac_dir_suffix.
-  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
-  ac_dir_suffix= ac_top_builddir=
-fi
-
-case $srcdir in
-  .)  # No --srcdir option.  We are building in place.
-    ac_srcdir=.
-    if test -z "$ac_top_builddir"; then
-       ac_top_srcdir=.
-    else
-       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
-    fi ;;
-  [\\/]* | ?:[\\/]* )  # Absolute path.
-    ac_srcdir=$srcdir$ac_dir_suffix;
-    ac_top_srcdir=$srcdir ;;
-  *) # Relative path.
-    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
-    ac_top_srcdir=$ac_top_builddir$srcdir ;;
-esac
-
-# Do not use `cd foo && pwd` to compute absolute paths, because
-# the directories may not exist.
-case `pwd` in
-.) ac_abs_builddir="$ac_dir";;
-*)
-  case "$ac_dir" in
-  .) ac_abs_builddir=`pwd`;;
-  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
-  *) ac_abs_builddir=`pwd`/"$ac_dir";;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_builddir=${ac_top_builddir}.;;
-*)
-  case ${ac_top_builddir}. in
-  .) ac_abs_top_builddir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
-  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_srcdir=$ac_srcdir;;
-*)
-  case $ac_srcdir in
-  .) ac_abs_srcdir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
-  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
-  esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_srcdir=$ac_top_srcdir;;
-*)
-  case $ac_top_srcdir in
-  .) ac_abs_top_srcdir=$ac_abs_builddir;;
-  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
-  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
-  esac;;
-esac
-
-
-
-  if test x"$ac_file" != x-; then
-    { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
-    rm -f "$ac_file"
-  fi
-  # Let's still pretend it is `configure' which instantiates (i.e., don't
-  # use $as_me), people would be surprised to read:
-  #    /* config.h.  Generated by config.status.  */
-  if test x"$ac_file" = x-; then
-    configure_input=
-  else
-    configure_input="$ac_file.  "
-  fi
-  configure_input=$configure_input"Generated from `echo $ac_file_in |
-				     sed 's,.*/,,'` by configure."
-
-  # First look for the input files in the build tree, otherwise in the
-  # src tree.
-  ac_file_inputs=`IFS=:
-    for f in $ac_file_in; do
-      case $f in
-      -) echo $tmp/stdin ;;
-      [\\/$]*)
-	 # Absolute (can't be DOS-style, as IFS=:)
-	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
-   { (exit 1); exit 1; }; }
-	 echo "$f";;
-      *) # Relative
-	 if test -f "$f"; then
-	   # Build tree
-	   echo "$f"
-	 elif test -f "$srcdir/$f"; then
-	   # Source tree
-	   echo "$srcdir/$f"
-	 else
-	   # /dev/null tree
-	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
-   { (exit 1); exit 1; }; }
-	 fi;;
-      esac
-    done` || { (exit 1); exit 1; }
-_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
-  sed "$ac_vpsub
-$extrasub
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-:t
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s,@configure_input@,$configure_input,;t t
-s,@srcdir@,$ac_srcdir,;t t
-s,@abs_srcdir@,$ac_abs_srcdir,;t t
-s,@top_srcdir@,$ac_top_srcdir,;t t
-s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
-s,@builddir@,$ac_builddir,;t t
-s,@abs_builddir@,$ac_abs_builddir,;t t
-s,@top_builddir@,$ac_top_builddir,;t t
-s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
-" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
-  rm -f $tmp/stdin
-  if test x"$ac_file" != x-; then
-    mv $tmp/out $ac_file
-  else
-    cat $tmp/out
-    rm -f $tmp/out
-  fi
-
-done
-_ACEOF
-
-cat >>$CONFIG_STATUS <<\_ACEOF
-
-{ (exit 0); exit 0; }
-_ACEOF
-chmod +x $CONFIG_STATUS
-ac_clean_files=$ac_clean_files_save
-
-
-# configure is writing to config.log, and then calls config.status.
-# config.status does its own redirection, appending to config.log.
-# Unfortunately, on DOS this fails, as config.log is still kept open
-# by configure, so config.status won't be able to write to it; its
-# output is simply discarded.  So we exec the FD to /dev/null,
-# effectively closing config.log, so it can be properly (re)opened and
-# appended to by config.status.  When coming back to configure, we
-# need to make the FD available again.
-if test "$no_create" != yes; then
-  ac_cs_success=:
-  ac_config_status_args=
-  test "$silent" = yes &&
-    ac_config_status_args="$ac_config_status_args --quiet"
-  exec 5>/dev/null
-  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
-  exec 5>>config.log
-  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
-  # would make configure fail if this is the last instruction.
-  $ac_cs_success || { (exit 1); exit 1; }
-fi
-
Index: bfaim/configure.in
===================================================================
--- libfaim/configure.in	(revision e374dee70435f8c596358571092675644a9ba731)
+++ 	(revision )
@@ -1,13 +1,0 @@
-AC_INIT(bos.c)
-
-dnl AC_CONFIG_HEADER(config.h)
-
-AC_PROG_CC
-dnl we're using GCC, enable all warnings
-if test "$GCC" = yes; then
-   CFLAGS="$CFLAGS -Wall -g";
-fi
-AC_PROG_RANLIB
-
-
-AC_OUTPUT(Makefile)
Index: bfaim/conn.c
===================================================================
--- libfaim/conn.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,1053 +1,0 @@
-/*
- * conn.c
- *
- * Does all this gloriously nifty connection handling stuff...
- *
- */
-
-#define FAIM_INTERNAL
-#define FAIM_NEED_CONN_INTERNAL
-#include <aim.h> 
-
-#ifndef _WIN32
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif
-
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
-
-/*
- * In OSCAR, every connection has a set of SNAC groups associated
- * with it.  These are the groups that you can send over this connection
- * without being guarenteed a "Not supported" SNAC error.  
- *
- * The grand theory of things says that these associations transcend 
- * what libfaim calls "connection types" (conn->type).  You can probably
- * see the elegance here, but since I want to revel in it for a bit, you 
- * get to hear it all spelled out.
- *
- * So let us say that you have your core BOS connection running.  One
- * of your modules has just given you a SNAC of the group 0x0004 to send
- * you.  Maybe an IM destined for some twit in Greenland.  So you start
- * at the top of your connection list, looking for a connection that 
- * claims to support group 0x0004.  You find one.  Why, that neat BOS
- * connection of yours can do that.  So you send it on its way.
- *
- * Now, say, that fellow from Greenland has friends and they all want to
- * meet up with you in a lame chat room.  This has landed you a SNAC
- * in the family 0x000e and you have to admit you're a bit lost.  You've
- * searched your connection list for someone who wants to make your life
- * easy and deliver this SNAC for you, but there isn't one there.
- *
- * Here comes the good bit.  Without even letting anyone know, particularly
- * the module that decided to send this SNAC, and definitly not that twit
- * in Greenland, you send out a service request.  In this request, you have
- * marked the need for a connection supporting group 0x000e.  A few seconds
- * later, you receive a service redirect with an IP address and a cookie in
- * it.  Great, you say.  Now I have something to do.  Off you go, making
- * that connection.  One of the first things you get from this new server
- * is a message saying that indeed it does support the group you were looking
- * for.  So you continue and send rate confirmation and all that.  
- * 
- * Then you remember you had that SNAC to send, and now you have a means to
- * do it, and you do, and everyone is happy.  Except the Greenlander, who is
- * still stuck in the bitter cold.
- *
- * Oh, and this is useful for building the Migration SNACs, too.  In the
- * future, this may help convince me to implement rate limit mitigation
- * for real.  We'll see.
- *
- * Just to make me look better, I'll say that I've known about this great
- * scheme for quite some time now.  But I still haven't convinced myself
- * to make libfaim work that way.  It would take a fair amount of effort,
- * and probably some client API changes as well.  (Whenever I don't want
- * to do something, I just say it would change the client API.  Then I 
- * instantly have a couple of supporters of not doing it.)
- *
- * Generally, addgroup is only called by the internal handling of the
- * server ready SNAC.  So if you want to do something before that, you'll
- * have to be more creative.  That is done rather early, though, so I don't
- * think you have to worry about it.  Unless you're me.  I care deeply
- * about such inane things.
- *
- */
-faim_internal void aim_conn_addgroup(aim_conn_t *conn, fu16_t group)
-{
-	aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;
-	struct snacgroup *sg;
-
-	if (!(sg = malloc(sizeof(struct snacgroup))))
-		return;
-
-	faimdprintf(aim_conn_getsess(conn), 1, "adding group 0x%04x\n", group);
-	sg->group = group;
-
-	sg->next = ins->groups;
-	ins->groups = sg;
-
-	return;
-}
-
-faim_export aim_conn_t *aim_conn_findbygroup(aim_session_t *sess, fu16_t group)
-{
-	aim_conn_t *cur;
-
-	for (cur = sess->connlist; cur; cur = cur->next) {
-		aim_conn_inside_t *ins = (aim_conn_inside_t *)cur->inside;
-		struct snacgroup *sg;
-
-		for (sg = ins->groups; sg; sg = sg->next) {
-			if (sg->group == group)
-				return cur;
-		}
-	}
-
-	return NULL;
-}
-
-static void connkill_snacgroups(struct snacgroup **head)
-{
-	struct snacgroup *sg;
-
-	for (sg = *head; sg; ) {
-		struct snacgroup *tmp;
-
-		tmp = sg->next;
-		free(sg);
-		sg = tmp;
-	}
-
-	*head = NULL;
-
-	return;
-}
-
-static void connkill_rates(struct rateclass **head)
-{
-	struct rateclass *rc;
-
-	for (rc = *head; rc; ) {
-		struct rateclass *tmp;
-		struct snacpair *sp;
-
-		tmp = rc->next;
-
-		for (sp = rc->members; sp; ) {
-			struct snacpair *tmpsp;
-
-			tmpsp = sp->next;
-			free(sp);
-			sp = tmpsp;
-		}
-		free(rc);
-
-		rc = tmp;
-	}
-
-	*head = NULL;
-
-	return;
-}
-
-static void connkill_real(aim_session_t *sess, aim_conn_t **deadconn)
-{
-
-	aim_rxqueue_cleanbyconn(sess, *deadconn);
-	aim_tx_cleanqueue(sess, *deadconn);
-
-	if ((*deadconn)->fd != -1) 
-		aim_conn_close(*deadconn);
-
-	/*
-	 * XXX ->priv should never be touched by the library. I know
-	 * it used to be, but I'm getting rid of all that.  Use
-	 * ->internal instead.
-	 */
-	if ((*deadconn)->priv)
-		free((*deadconn)->priv);
-
-	/*
-	 * This will free ->internal if it necessary...
-	 */
-	if ((*deadconn)->type == AIM_CONN_TYPE_CHAT)
-		aim_conn_kill_chat(sess, *deadconn);
-
-	if ((*deadconn)->inside) {
-		aim_conn_inside_t *inside = (aim_conn_inside_t *)(*deadconn)->inside;
-
-		connkill_snacgroups(&inside->groups);
-		connkill_rates(&inside->rates);
-
-		free(inside);
-	}
-
-	free(*deadconn);
-	*deadconn = NULL;
-
-	return;
-}
-
-/**
- * Clears out connection list, killing remaining connections.
- *
- * @param sess Session to be cleared
- */
-static void aim_connrst(aim_session_t *sess)
-{
-
-	if (sess->connlist) {
-		aim_conn_t *cur = sess->connlist, *tmp;
-
-		while (cur) {
-			tmp = cur->next;
-			aim_conn_close(cur);
-			connkill_real(sess, &cur);
-			cur = tmp;
-		}
-	}
-
-	sess->connlist = NULL;
-
-	return;
-}
-
-/**
- * Reset a connection to default values.
- * Initializes and/or resets a connection structure.
- *
- * @param deadconn Connection to be reset
- */
-static void aim_conn_init(aim_conn_t *deadconn)
-{
-
-	if (!deadconn)
-		return;
-
-	deadconn->fd = -1;
-	deadconn->subtype = -1;
-	deadconn->type = -1;
-	deadconn->seqnum = 0;
-	deadconn->lastactivity = 0;
-	deadconn->forcedlatency = 0;
-	deadconn->handlerlist = NULL;
-	deadconn->priv = NULL;
-	memset(deadconn->inside, 0, sizeof(aim_conn_inside_t));
-
-	return;
-}
-
-/**
- * aim_conn_getnext - Gets a new connection structure.
- * @sess: Session
- *
- * Allocate a new empty connection structure.
- *
- */
-static aim_conn_t *aim_conn_getnext(aim_session_t *sess)
-{
-	aim_conn_t *newconn;
-
-	if (!(newconn = malloc(sizeof(aim_conn_t)))) 	
-		return NULL;
-	memset(newconn, 0, sizeof(aim_conn_t));
-
-	if (!(newconn->inside = malloc(sizeof(aim_conn_inside_t)))) {
-		free(newconn);
-		return NULL;
-	}
-	memset(newconn->inside, 0, sizeof(aim_conn_inside_t));
-
-	aim_conn_init(newconn);
-
-	newconn->next = sess->connlist;
-	sess->connlist = newconn;
-
-	return newconn;
-}
-
-/**
- * aim_conn_kill - Close and free a connection.
- * @sess: Session for the connection
- * @deadconn: Connection to be freed
- *
- * Close, clear, and free a connection structure. Should never be
- * called from within libfaim.
- *
- */
-faim_export void aim_conn_kill(aim_session_t *sess, aim_conn_t **deadconn)
-{
-	aim_conn_t *cur, **prev;
-
-	if (!deadconn || !*deadconn)	
-		return;
-
-	for (prev = &sess->connlist; (cur = *prev); ) {
-		if (cur == *deadconn) {
-			*prev = cur->next;
-			break;
-		}
-		prev = &cur->next;
-	}
-
-	if (!cur)
-		return; /* oops */
-
-	connkill_real(sess, &cur);
-
-	return;
-}
-
-/**
- * aim_conn_close - Close a connection
- * @deadconn: Connection to close
- *
- * Close (but not free) a connection.
- *
- * This leaves everything untouched except for clearing the 
- * handler list and setting the fd to -1 (used to recognize
- * dead connections).  It will also remove cookies if necessary.
- *
- */
-faim_export void aim_conn_close(aim_conn_t *deadconn)
-{
-	aim_rxcallback_t userfunc;
-
-	if (deadconn->fd >= 3)
-		close(deadconn->fd);
-
-	deadconn->fd = -1;
-
-	if ((userfunc = aim_callhandler(deadconn->sessv, deadconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNDEAD)))
-		userfunc(deadconn->sessv, NULL, deadconn);
-
-	if (deadconn->handlerlist)
-		aim_clearhandlers(deadconn);
-
-	return;
-}
-
-/**
- * aim_getconn_type - Find a connection of a specific type
- * @sess: Session to search
- * @type: Type of connection to look for
- *
- * Searches for a connection of the specified type in the 
- * specified session.  Returns the first connection of that
- * type found.
- *
- * XXX except for RENDEZVOUS, all uses of this should be removed and
- * use aim_conn_findbygroup() instead.
- */
-faim_export aim_conn_t *aim_getconn_type(aim_session_t *sess, int type)
-{
-	aim_conn_t *cur;
-
-	for (cur = sess->connlist; cur; cur = cur->next) {
-		if ((cur->type == type) && 
-				!(cur->status & AIM_CONN_STATUS_INPROGRESS))
-			break;
-	}
-
-	return cur;
-}
-
-faim_export aim_conn_t *aim_getconn_type_all(aim_session_t *sess, int type)
-{
-	aim_conn_t *cur;
-
-	for (cur = sess->connlist; cur; cur = cur->next) {
-		if (cur->type == type)
-			break;
-	}
-
-	return cur;
-}
-
-/* If you pass -1 for the fd, you'll get what you ask for.  Gibberish. */
-faim_export aim_conn_t *aim_getconn_fd(aim_session_t *sess, int fd)
-{
-	aim_conn_t *cur;
-
-	for (cur = sess->connlist; cur; cur = cur->next) {
-		if (cur->fd == fd)
-			break;
-	}
-
-	return cur;
-}
-
-/**
- * aim_proxyconnect - An extrememly quick and dirty SOCKS5 interface. 
- * @sess: Session to connect
- * @host: Host to connect to
- * @port: Port to connect to
- * @statusret: Return value of the connection
- *
- * Attempts to connect to the specified host via the configured
- * proxy settings, if present.  If no proxy is configured for
- * this session, the connection is done directly.
- *
- * XXX this is really awful.
- *
- */
-static int aim_proxyconnect(aim_session_t *sess, const char *host, fu16_t port, fu32_t *statusret)
-{
-	int fd = -1;
-
-	if (strlen(sess->socksproxy.server)) { /* connecting via proxy */
-		int i;
-		unsigned char buf[512];
-		struct sockaddr_in sa;
-		struct hostent *hp;
-		char *proxy;
-		unsigned short proxyport = 1080;
-
-		for(i=0;i<(int)strlen(sess->socksproxy.server);i++) {
-			if (sess->socksproxy.server[i] == ':') {
-				proxyport = atoi(&(sess->socksproxy.server[i+1]));
-				break;
-			}
-		}
-
-		proxy = (char *)malloc(i+1);
-		strncpy(proxy, sess->socksproxy.server, i);
-		proxy[i] = '\0';
-
-		if (!(hp = gethostbyname(proxy))) {
-			faimdprintf(sess, 0, "proxyconnect: unable to resolve proxy name\n");
-			*statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR);
-			return -1;
-		}
-		free(proxy);
-
-		memset(&sa.sin_zero, 0, 8);
-		sa.sin_port = htons(proxyport);
-		memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
-		sa.sin_family = hp->h_addrtype;
-
-		fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
-		if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
-			faimdprintf(sess, 0, "proxyconnect: unable to connect to proxy\n");
-			close(fd);
-			return -1;
-		}
-
-		i = 0;
-		buf[0] = 0x05; /* SOCKS version 5 */
-		if (strlen(sess->socksproxy.username)) {
-			buf[1] = 0x02; /* two methods */
-			buf[2] = 0x00; /* no authentication */
-			buf[3] = 0x02; /* username/password authentication */
-			i = 4;
-		} else {
-			buf[1] = 0x01;
-			buf[2] = 0x00;
-			i = 3;
-		}
-		if (write(fd, buf, i) < i) {
-			*statusret = errno;
-			close(fd);
-			return -1;
-		}
-		if (read(fd, buf, 2) < 2) {
-			*statusret = errno;
-			close(fd);
-			return -1;
-		}
-
-		if ((buf[0] != 0x05) || (buf[1] == 0xff)) {
-			*statusret = EINVAL;
-			close(fd);
-			return -1;
-		}
-
-		/* check if we're doing username authentication */
-		if (buf[1] == 0x02) {
-			i  = aimutil_put8(buf, 0x01); /* version 1 */
-			i += aimutil_put8(buf+i, strlen(sess->socksproxy.username));
-			i += aimutil_putstr(buf+i, sess->socksproxy.username, strlen(sess->socksproxy.username));
-			i += aimutil_put8(buf+i, strlen(sess->socksproxy.password));
-			i += aimutil_putstr(buf+i, sess->socksproxy.password, strlen(sess->socksproxy.password));
-			if (write(fd, buf, i) < i) {
-				*statusret = errno;
-				close(fd);
-				return -1;
-			}
-			if (read(fd, buf, 2) < 2) {
-				*statusret = errno;
-				close(fd);
-				return -1;
-			}
-			if ((buf[0] != 0x01) || (buf[1] != 0x00)) {
-				*statusret = EINVAL;
-				close(fd);
-				return -1;
-			}
-		}
-
-		i  = aimutil_put8(buf, 0x05);
-		i += aimutil_put8(buf+i, 0x01); /* CONNECT */
-		i += aimutil_put8(buf+i, 0x00); /* reserved */
-		i += aimutil_put8(buf+i, 0x03); /* address type: host name */
-		i += aimutil_put8(buf+i, strlen(host));
-		i += aimutil_putstr(buf+i, host, strlen(host));
-		i += aimutil_put16(buf+i, port);
-
-		if (write(fd, buf, i) < i) {
-			*statusret = errno;
-			close(fd);
-			return -1;
-		}
-
-		if (read(fd, buf, 10) < 10) {
-			*statusret = errno;
-			close(fd);
-			return -1;
-		}
-		if ((buf[0] != 0x05) || (buf[1] != 0x00)) {
-			*statusret = EINVAL;
-			close(fd);
-			return -1;
-		}
-
-	} else { /* connecting directly */
-		struct sockaddr_in sa;
-		struct hostent *hp;
-
-		if (!(hp = gethostbyname(host))) {
-			*statusret = (h_errno | AIM_CONN_STATUS_RESOLVERR);
-			return -1;
-		}
-
-		memset(&sa, 0, sizeof(struct sockaddr_in));
-		sa.sin_port = htons(port);
-		memcpy(&sa.sin_addr, hp->h_addr, hp->h_length);
-		sa.sin_family = hp->h_addrtype;
-
-		fd = socket(hp->h_addrtype, SOCK_STREAM, 0);
-
-		if (sess->nonblocking)
-			fcntl(fd, F_SETFL, O_NONBLOCK); /* XXX save flags */
-
-		if (connect(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)) < 0) {
-			if (sess->nonblocking) {
-				if ((errno == EINPROGRESS) || (errno == EINTR)) {
-					if (statusret)
-						*statusret |= AIM_CONN_STATUS_INPROGRESS;
-					return fd;
-				}
-			}
-			close(fd);
-			fd = -1;
-		}
-	}
-	return fd;
-}
-
-/**
- * aim_cloneconn - clone an aim_conn_t
- * @sess: session containing parent
- * @src: connection to clone
- *
- * A new connection is allocated, and the values are filled in
- * appropriately. Note that this function sets the new connnection's
- * ->priv pointer to be equal to that of its parent: only the pointer
- * is copied, not the data it points to.
- *
- * This function returns a pointer to the new aim_conn_t, or %NULL on
- * error
- */
-faim_internal aim_conn_t *aim_cloneconn(aim_session_t *sess, aim_conn_t *src)
-{
-	aim_conn_t *conn;
-
-	if (!(conn = aim_conn_getnext(sess)))
-		return NULL;
-
-	conn->fd = src->fd;
-	conn->type = src->type;
-	conn->subtype = src->subtype;
-	conn->seqnum = src->seqnum;
-	conn->priv = src->priv;
-	conn->internal = src->internal;
-	conn->lastactivity = src->lastactivity;
-	conn->forcedlatency = src->forcedlatency;
-	conn->sessv = src->sessv;
-	aim_clonehandlers(sess, conn, src);
-
-	if (src->inside) {
-		/*
-		 * XXX should clone this section as well, but since currently
-		 * this function only gets called for some of that rendezvous
-		 * crap, and not on SNAC connections, its probably okay for
-		 * now. 
-		 *
-		 */
-	}
-
-	return conn;
-}
-
-/**
- * aim_newconn - Open a new connection
- * @sess: Session to create connection in
- * @type: Type of connection to create
- * @dest: Host to connect to (in "host:port" syntax)
- *
- * Opens a new connection to the specified dest host of specified
- * type, using the proxy settings if available.  If @host is %NULL,
- * the connection is allocated and returned, but no connection 
- * is made.
- *
- * FIXME: Return errors in a more sane way.
- *
- */
-faim_export aim_conn_t *aim_newconn(aim_session_t *sess, int type, const char *dest)
-{
-	aim_conn_t *connstruct;
-	fu16_t port = FAIM_LOGIN_PORT;
-	char *host;
-	int i, ret;
-
-	if (!(connstruct = aim_conn_getnext(sess)))
-		return NULL;
-
-	connstruct->sessv = (void *)sess;
-	connstruct->type = type;
-
-	if (!dest) { /* just allocate a struct */
-		connstruct->fd = -1;
-		connstruct->status = 0;
-		return connstruct;
-	}
-
-	/* 
-	 * As of 23 Jul 1999, AOL now sends the port number, preceded by a 
-	 * colon, in the BOS redirect.  This fatally breaks all previous 
-	 * libfaims.  Bad, bad AOL.
-	 *
-	 * We put this here to catch every case. 
-	 *
-	 */
-
-	for(i = 0; i < (int)strlen(dest); i++) {
-		if (dest[i] == ':') {
-			port = atoi(&(dest[i+1]));
-			break;
-		}
-	}
-
-	host = (char *)malloc(i+1);
-	strncpy(host, dest, i);
-	host[i] = '\0';
-
-	if ((ret = aim_proxyconnect(sess, host, port, &connstruct->status)) < 0) {
-		connstruct->fd = -1;
-		connstruct->status = (errno | AIM_CONN_STATUS_CONNERR);
-		free(host);
-		return connstruct;
-	} else
-		connstruct->fd = ret;
-
-	free(host);
-
-	return connstruct;
-}
-
-/**
- * aim_conngetmaxfd - Return the highest valued file discriptor in session
- * @sess: Session to search
- *
- * Returns the highest valued filed descriptor of all open 
- * connections in @sess.
- *
- */
-faim_export int aim_conngetmaxfd(aim_session_t *sess)
-{
-	int j;
-	aim_conn_t *cur;
-
-	for (cur = sess->connlist, j = 0; cur; cur = cur->next) {
-		if (cur->fd > j)
-			j = cur->fd;
-	}
-
-	return j;
-}
-
-/**
- * aim_conn_in_sess - Predicate to test the precense of a connection in a sess
- * @sess: Session to look in
- * @conn: Connection to look for
- *
- * Searches @sess for the passed connection.  Returns 1 if its present,
- * zero otherwise.
- *
- */
-faim_export int aim_conn_in_sess(aim_session_t *sess, aim_conn_t *conn)
-{
-	aim_conn_t *cur;
-
-	for (cur = sess->connlist; cur; cur = cur->next) {
-		if (cur == conn)
-			return 1;
-	}
-
-	return 0;
-}
-
-/**
- * aim_select - Wait for a socket with data or timeout
- * @sess: Session to wait on
- * @timeout: How long to wait
- * @status: Return status
- *
- * Waits for a socket with data or for timeout, whichever comes first.
- * See select(2).
- * 
- * Return codes in *status:
- *   -1  error in select() (%NULL returned)
- *    0  no events pending (%NULL returned)
- *    1  outgoing data pending (%NULL returned)
- *    2  incoming data pending (connection with pending data returned)
- *
- */ 
-faim_export aim_conn_t *aim_select(aim_session_t *sess, struct timeval *timeout, int *status)
-{
-	aim_conn_t *cur;
-	fd_set fds, wfds;
-	int maxfd, i, haveconnecting = 0;
-
-	if (!sess->connlist) {
-		*status = -1;
-		return NULL;
-	}
-
-	FD_ZERO(&fds);
-	FD_ZERO(&wfds);
-
-	for (cur = sess->connlist, maxfd = 0; cur; cur = cur->next) {
-		if (cur->fd == -1) {
-			/* don't let invalid/dead connections sit around */
-			*status = 2;
-			return cur;
-		} else if (cur->status & AIM_CONN_STATUS_INPROGRESS) {
-			FD_SET(cur->fd, &wfds);
-
-			haveconnecting++;
-		}
-		FD_SET(cur->fd, &fds);
-		if (cur->fd > maxfd)
-			maxfd = cur->fd;
-	}
-
-	/* 
-	 * If we have data waiting to be sent, return
-	 *
-	 * We have to not do this if theres at least one
-	 * connection thats still connecting, since that connection
-	 * may have queued data and this return would prevent
-	 * the connection from ever completing!  This is a major
-	 * inadequacy of the libfaim way of doing things.  It means
-	 * that nothing can transmit as long as there's connecting
-	 * sockets. Evil.
-	 *
-	 * But its still better than having blocking connects.
-	 *
-	 */
-	if (!haveconnecting && sess->queue_outgoing) {
-		*status = 1;
-		return NULL;
-	} 
-
-	if ((i = select(maxfd+1, &fds, &wfds, NULL, timeout))>=1) {
-		for (cur = sess->connlist; cur; cur = cur->next) {
-			if ((FD_ISSET(cur->fd, &fds)) || 
-					((cur->status & AIM_CONN_STATUS_INPROGRESS) && 
-					FD_ISSET(cur->fd, &wfds))) {
-				*status = 2;
-				return cur;
-			}
-		}
-		*status = 0; /* shouldn't happen */
-	} else if ((i == -1) && (errno == EINTR)) /* treat interrupts as a timeout */
-		*status = 0;
-	else
-		*status = i; /* can be 0 or -1 */
-
-	return NULL;  /* no waiting or error, return */
-}
-
-/**
- * aim_conn_setlatency - Set a forced latency value for connection
- * @conn: Conn to set latency for
- * @newval: Number of seconds to force between transmits
- *
- * Causes @newval seconds to be spent between transmits on a connection.
- *
- * This is my lame attempt at overcoming not understanding the rate
- * limiting. 
- *
- * XXX: This should really be replaced with something that scales and
- * backs off like the real rate limiting does.
- *
- */
-faim_export int aim_conn_setlatency(aim_conn_t *conn, int newval)
-{
-
-	if (!conn)
-		return -1;
-
-	conn->forcedlatency = newval;
-	conn->lastactivity = 0; /* reset this just to make sure */
-
-	return 0;
-}
-
-/**
- * aim_setupproxy - Configure a proxy for this session
- * @sess: Session to set proxy for
- * @server: SOCKS server
- * @username: SOCKS username
- * @password: SOCKS password
- *
- * Call this with your SOCKS5 proxy server parameters before
- * the first call to aim_newconn().  If called with all %NULL
- * args, it will clear out a previously set proxy.  
- *
- * Set username and password to %NULL if not applicable.
- *
- */
-faim_export void aim_setupproxy(aim_session_t *sess, const char *server, const char *username, const char *password)
-{
-	/* clear out the proxy info */
-	if (!server || !strlen(server)) {
-		memset(sess->socksproxy.server, 0, sizeof(sess->socksproxy.server));
-		memset(sess->socksproxy.username, 0, sizeof(sess->socksproxy.username));
-		memset(sess->socksproxy.password, 0, sizeof(sess->socksproxy.password));
-		return;
-	}
-
-	strncpy(sess->socksproxy.server, server, sizeof(sess->socksproxy.server));
-	if (username && strlen(username)) 
-		strncpy(sess->socksproxy.username, username, sizeof(sess->socksproxy.username));
-	if (password && strlen(password))
-		strncpy(sess->socksproxy.password, password, sizeof(sess->socksproxy.password));
-
-	return;
-}
-
-static void defaultdebugcb(aim_session_t *sess, int level, const char *format, va_list va)
-{
-
-	vfprintf(stderr, format, va);
-
-	return;
-}
-
-/**
- * Initializes a session structure by setting the initial values 
- * stuff in the aim_session_t struct.
- *
- * @param sess Session to initialize.
- * @param nonblocking Set to true if you want connections to be non-blocking.
- * @param debuglevel Level of debugging output (zero is least).
- */
-faim_export void aim_session_init(aim_session_t *sess, bool nonblocking, int debuglevel)
-{
-
-	if (!sess)
-		return;
-
-	memset(sess, 0, sizeof(aim_session_t));
-	aim_connrst(sess);
-	sess->queue_outgoing = NULL;
-	sess->queue_incoming = NULL;
-	aim_initsnachash(sess);
-	sess->msgcookies = NULL;
-	sess->nonblocking = nonblocking;
-	sess->debug = debuglevel;
-	sess->debugcb = defaultdebugcb;
-	sess->modlistv = NULL;
-	sess->snacid_next = 0x00000001;
-
-	sess->locate.userinfo = NULL;
-	sess->locate.torequest = NULL;
-	sess->locate.requested = NULL;
-	sess->locate.waiting_for_response = FALSE;
-	sess->ssi.received_data = 0;
-	sess->ssi.numitems = 0;
-	sess->ssi.official = NULL;
-	sess->ssi.local = NULL;
-	sess->ssi.pending = NULL;
-	sess->ssi.timestamp = (time_t)0;
-	sess->ssi.waiting_for_ack = 0;
-	sess->icq_info = NULL;
-	sess->authinfo = NULL;
-	sess->emailinfo = NULL;
-	sess->oft_info = NULL;
-
-	/*
-	 * This must always be set.  Default to the queue-based
-	 * version for back-compatibility.  
-	 */
-	aim_tx_setenqueue(sess, AIM_TX_QUEUED, NULL);
-
-	/*
-	 * Register all the modules for this session...
-	 */
-	aim__registermodule(sess, misc_modfirst); /* load the catch-all first */
-	aim__registermodule(sess, service_modfirst);
-	aim__registermodule(sess, locate_modfirst);
-	aim__registermodule(sess, buddylist_modfirst);
-	aim__registermodule(sess, msg_modfirst);
-	aim__registermodule(sess, adverts_modfirst);
-	aim__registermodule(sess, invite_modfirst);
-	aim__registermodule(sess, admin_modfirst);
-	aim__registermodule(sess, popups_modfirst);
-	aim__registermodule(sess, bos_modfirst);
-	aim__registermodule(sess, search_modfirst);
-	aim__registermodule(sess, stats_modfirst);
-	aim__registermodule(sess, translate_modfirst);
-	aim__registermodule(sess, chatnav_modfirst);
-	aim__registermodule(sess, chat_modfirst);
-	aim__registermodule(sess, odir_modfirst);
-	aim__registermodule(sess, bart_modfirst);
-	/* missing 0x11 - 0x12 */
-	aim__registermodule(sess, ssi_modfirst);
-	/* missing 0x14 */
-	aim__registermodule(sess, icq_modfirst); /* XXX - Make sure this isn't sent for AIM */
-	/* missing 0x16 */
-	aim__registermodule(sess, auth_modfirst);
-	aim__registermodule(sess, email_modfirst);
-
-	return;
-}
-
-/**
- * aim_session_kill - Deallocate a session
- * @sess: Session to kill
- *
- */
-faim_export void aim_session_kill(aim_session_t *sess)
-{
-	aim_cleansnacs(sess, -1);
-
-	aim_logoff(sess);
-
-	aim__shutdownmodules(sess);
-
-	return;
-}
-
-/**
- * aim_setdebuggingcb - Set the function to call when outputting debugging info
- * @sess: Session to change
- * @cb: Function to call
- *
- * The function specified is called whenever faimdprintf() is used within
- * libfaim, and the session's debugging level is greater tha nor equal to
- * the value faimdprintf was called with.
- *
- */
-faim_export int aim_setdebuggingcb(aim_session_t *sess, faim_debugging_callback_t cb)
-{
-
-	if (!sess)
-		return -1;
-
-	sess->debugcb = cb;
-
-	return 0;
-}
-
-/**
- * aim_conn_isconnecting - Determine if a connection is connecting
- * @conn: Connection to examine
- *
- * Returns nonzero if the connection is in the process of
- * connecting (or if it just completed and aim_conn_completeconnect()
- * has yet to be called on it).
- *
- */
-faim_export int aim_conn_isconnecting(aim_conn_t *conn)
-{
-
-	if (!conn)
-		return 0;
-
-	return !!(conn->status & AIM_CONN_STATUS_INPROGRESS);
-}
-
-/*
- * XXX this is nearly as ugly as proxyconnect().
- */
-faim_export int aim_conn_completeconnect(aim_session_t *sess, aim_conn_t *conn)
-{
-	aim_rxcallback_t userfunc;
-
-	if (!conn || (conn->fd == -1))
-		return -1;
-
-	if (!(conn->status & AIM_CONN_STATUS_INPROGRESS))
-		return -1;
-
-	fcntl(conn->fd, F_SETFL, 0);
-
-	conn->status &= ~AIM_CONN_STATUS_INPROGRESS;
-
-	if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNCOMPLETE)))
-		userfunc(sess, NULL, conn);
-
-	/* Flush out the queues if there was something waiting for this conn  */
-	aim_tx_flushqueue(sess);
-
-	return 0;
-}
-
-faim_export aim_session_t *aim_conn_getsess(aim_conn_t *conn)
-{
-
-	if (!conn)
-		return NULL;
-
-	return (aim_session_t *)conn->sessv;
-}
-
-/*
- * aim_logoff()
- *
- * Closes -ALL- open connections.
- *
- */
-faim_export int aim_logoff(aim_session_t *sess)
-{
-
-	aim_connrst(sess);  /* in case we want to connect again */
-
-	return 0;
-}
-
-/*
- * aim_flap_nop()
- *
- * No-op.  WinAIM 4.x sends these _every minute_ to keep
- * the connection alive.
- */
-faim_export int aim_flap_nop(aim_session_t *sess, aim_conn_t *conn)
-{
-	aim_frame_t *fr;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x05, 0)))
-		return -ENOMEM;
-
-	aim_tx_enqueue(sess, fr);
-
-	/* clean out SNACs over 60sec old */
-	aim_cleansnacs(sess, 60);
-
-	return 0;
-}
Index: bfaim/email.c
===================================================================
--- libfaim/email.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,216 +1,0 @@
-/*
- * Family 0x0018 - Email notification
- *
- * Used for being alerted when the email address(es) associated with 
- * your screen name get new electronic-m.  For normal AIM accounts, you 
- * get the email address screenname@netscape.net.  AOL accounts have 
- * screenname@aol.com, and can also activate a netscape.net account.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-/**
- * Subtype 0x0006 - Request information about your email account
- *
- * @param sess The oscar session.
- * @param conn The email connection for this session.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_email_sendcookies(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_EML)))
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+16+16)))
-		return -ENOMEM;
-	snacid = aim_cachesnac(sess, 0x0018, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0018, 0x0006, 0x0000, snacid);
-
-	/* Number of cookies to follow */
-	aimbs_put16(&fr->data, 0x0002);
-
-	/* Cookie */
-	aimbs_put16(&fr->data, 0x5d5e);
-	aimbs_put16(&fr->data, 0x1708);
-	aimbs_put16(&fr->data, 0x55aa);
-	aimbs_put16(&fr->data, 0x11d3);
-	aimbs_put16(&fr->data, 0xb143);
-	aimbs_put16(&fr->data, 0x0060);
-	aimbs_put16(&fr->data, 0xb0fb);
-	aimbs_put16(&fr->data, 0x1ecb);
-
-	/* Cookie */
-	aimbs_put16(&fr->data, 0xb380);
-	aimbs_put16(&fr->data, 0x9ad8);
-	aimbs_put16(&fr->data, 0x0dba);
-	aimbs_put16(&fr->data, 0x11d5);
-	aimbs_put16(&fr->data, 0x9f8a);
-	aimbs_put16(&fr->data, 0x0060);
-	aimbs_put16(&fr->data, 0xb0ee);
-	aimbs_put16(&fr->data, 0x0631);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-
-/**
- * Subtype 0x0007 - Receive information about your email account
- *
- * So I don't even know if you can have multiple 16 byte keys, 
- * but this is coded so it will handle that, and handle it well.
- * This tells you if you have unread mail or not, the URL you 
- * should use to access that mail, and the domain name for the 
- * email account (screenname@domainname.com).  If this is the 
- * first 0x0007 SNAC you've received since you signed on, or if 
- * this is just a periodic status update, this will also contain 
- * the number of unread emails that you have.
- */
-static int parseinfo(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	struct aim_emailinfo *new;
-	aim_tlvlist_t *tlvlist;
-	fu8_t *cookie8, *cookie16;
-	int tmp, havenewmail = 0; /* Used to tell the client we have _new_ mail */
-
-	char *alertitle = NULL, *alerturl = NULL;
-
-	cookie8 = aimbs_getraw(bs, 8); /* Possibly the code used to log you in to mail? */
-	cookie16 = aimbs_getraw(bs, 16); /* Mail cookie sent above */
-
-	/* See if we already have some info associated with this cookie */
-	for (new=sess->emailinfo; (new && strncmp(cookie16, new->cookie16, 16)); new=new->next);
-	if (new) {
-		/* Free some of the old info, if existant */
-		free(new->cookie8);
-		free(new->cookie16);
-		free(new->url);
-		free(new->domain);
-	} else {
-		/* We don't already have info, so create a new struct for it */
-		if (!(new = malloc(sizeof(struct aim_emailinfo))))
-			return -ENOMEM;
-		memset(new, 0, sizeof(struct aim_emailinfo));
-		new->next = sess->emailinfo;
-		sess->emailinfo = new;
-	}
-
-	new->cookie8 = cookie8;
-	new->cookie16 = cookie16;
-
-	tlvlist = aim_tlvlist_readnum(bs, aimbs_get16(bs));
-
-	tmp = aim_tlv_get16(tlvlist, 0x0080, 1);
-	if (tmp) {
-		if (new->nummsgs < tmp)
-			havenewmail = 1;
-		new->nummsgs = tmp;
-	} else {
-		/* If they don't send a 0x0080 TLV, it means we definately have new mail */
-		/* (ie. this is not just another status update) */
-		havenewmail = 1;
-		new->nummsgs++; /* We know we have at least 1 new email */
-	}
-	new->url = aim_tlv_getstr(tlvlist, 0x0007, 1);
-	if (!(new->unread = aim_tlv_get8(tlvlist, 0x0081, 1))) {
-		havenewmail = 0;
-		new->nummsgs = 0;
-	}
-	new->domain = aim_tlv_getstr(tlvlist, 0x0082, 1);
-	new->flag = aim_tlv_get16(tlvlist, 0x0084, 1);
-
-	alertitle = aim_tlv_getstr(tlvlist, 0x0005, 1);
-	alerturl  = aim_tlv_getstr(tlvlist, 0x000d, 1);
-	
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, new, havenewmail, alertitle, (alerturl ? alerturl + 2 : NULL));
-
-	aim_tlvlist_free(&tlvlist);
-
-	free(alertitle);
-	free(alerturl);
-
-	return ret;
-}
-
-/**
- * Subtype 0x0016 - Send something or other
- *
- * @param sess The oscar session.
- * @param conn The email connection for this session.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_email_activate(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_EML)))
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+16)))
-		return -ENOMEM;
-	snacid = aim_cachesnac(sess, 0x0018, 0x0016, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0018, 0x0016, 0x0000, snacid);
-
-	/* I would guess this tells AIM that you want updates for your mail accounts */
-	/* ...but I really have no idea */
-	aimbs_put8(&fr->data, 0x02);
-	aimbs_put32(&fr->data, 0x04000000);
-	aimbs_put32(&fr->data, 0x04000000);
-	aimbs_put32(&fr->data, 0x04000000);
-	aimbs_put32(&fr->data, 0x00000000);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0007)
-		return parseinfo(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-static void email_shutdown(aim_session_t *sess, aim_module_t *mod)
-{
-	while (sess->emailinfo) {
-		struct aim_emailinfo *tmp = sess->emailinfo;
-		sess->emailinfo = sess->emailinfo->next;
-		free(tmp->cookie16);
-		free(tmp->cookie8);
-		free(tmp->url);
-		free(tmp->domain);
-		free(tmp);
-	}
-
-	return;
-}
-
-faim_internal int email_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x0018;
-	mod->version = 0x0001;
-	mod->toolid = 0x0010;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "email", sizeof(mod->name));
-	mod->snachandler = snachandler;
-	mod->shutdown = email_shutdown;
-
-	return 0;
-}
Index: bfaim/faimconfig.h
===================================================================
--- libfaim/faimconfig.h	(revision 5e53c4a15eca8b264df0aedf726d4545bc5b4b46)
+++ 	(revision )
@@ -1,59 +1,0 @@
-/*
- *  faimconfig.h
- *
- * Contains various compile-time options that apply _only_ to libfaim.
- *
- */
-
-#ifndef __FAIMCONFIG_H__
-#define __FAIMCONFIG_H__
-
-/*
- * USE_SNAC_FOR_IMS is an old feature that allowed better
- * tracking of error messages by caching SNAC IDs of outgoing
- * ICBMs and comparing them to incoming errors.  However,
- * its a helluvalot of overhead for something that should
- * rarely happen.  
- *
- * Default: defined.  This is now defined by default
- * because it should be stable and its not too bad.  
- * And Josh wanted it.
- *
- */
-#define USE_SNAC_FOR_IMS
-
-/*
- * Default Authorizer server name and TCP port for the OSCAR farm.  
- *
- * You shouldn't need to change this unless you're writing
- * your own server. 
- *
- * Note that only one server is needed to start the whole
- * AIM process.  The later server addresses come from
- * the authorizer service.
- *
- * This is only here for convenience.  Its still up to
- * the client to connect to it.
- *
- */
-#define FAIM_LOGIN_SERVER "login.oscar.aol.com"
-#define FAIM_LOGIN_PORT 5190
-
-/*
- * Size of the SNAC caching hash.
- *
- * Default: 16
- *
- */
-#define FAIM_SNAC_HASH_SIZE 16
-
-/*
- * If building on Win32, define WIN32_STATIC if you don't want
- * to compile libfaim as a DLL (and instead link it right into
- * your app).
- */
-#define WIN32_STATIC
-
-#endif /* __FAIMCONFIG_H__ */
-
-
Index: bfaim/ft.c
===================================================================
--- libfaim/ft.c	(revision dd0edbf4e5ea467a25debc666f9fadc1317b7f0c)
+++ 	(revision )
@@ -1,993 +1,0 @@
-/*
- * Oscar File transfer (OFT) and Oscar Direct Connect (ODC).
- * (ODC is also referred to as DirectIM and IM Image.)
- *
- * There are a few static helper functions at the top, then 
- * ODC stuff, then ft stuff.
- *
- * I feel like this is a good place to explain OFT, so I'm going to 
- * do just that.  Each OFT packet has a header type.  I guess this 
- * is pretty similar to the subtype of a SNAC packet.  The type 
- * basically tells the other client the meaning of the OFT packet.  
- * There are two distinct types of file transfer, which I usually 
- * call "sendfile" and "getfile."  Sendfile is when you send a file 
- * to another AIM user.  Getfile is when you share a group of files, 
- * and other users request that you send them the files.
- *
- * A typical sendfile file transfer goes like this:
- *   1) Sender sends a channel 2 ICBM telling the other user that 
- *      we want to send them a file.  At the same time, we open a 
- *      listener socket (this should be done before sending the 
- *      ICBM) on some port, and wait for them to connect to us.  
- *      The ICBM we sent should contain our IP address and the port 
- *      number that we're listening on.
- *   2) The receiver connects to the sender on the given IP address 
- *      and port.  After the connection is established, the receiver 
- *      sends an ICBM signifying that we are ready and waiting.
- *   3) The sender sends an OFT PROMPT message over the OFT 
- *      connection.
- *   4) The receiver of the file sends back an exact copy of this 
- *      OFT packet, except the cookie is filled in with the cookie 
- *      from the ICBM.  I think this might be an attempt to verify 
- *      that the user that is connected is actually the guy that 
- *      we sent the ICBM to.  Oh, I've been calling this the ACK.
- *   5) The sender starts sending raw data across the connection 
- *      until the entire file has been sent.
- *   6) The receiver knows the file is finished because the sender 
- *      sent the file size in an earlier OFT packet.  So then the 
- *      receiver sends the DONE thingy (after filling in the 
- *      "received" checksum and size) and closes the connection.
- */
-
-#define FAIM_INTERNAL
-#ifdef HAVE_CONFIG_H
-#include  <config.h>
-#endif
-
-#include <aim.h>
-
-#ifndef _WIN32
-#include <stdio.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <sys/utsname.h> /* for aim_odc_initiate */
-#include <arpa/inet.h> /* for inet_ntoa */
-#define G_DIR_SEPARATOR '/'
-#endif
-
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
-
-#ifndef socklen_t
-#define socklen_t int
-#endif
-
-struct aim_odc_intdata {
-	fu8_t cookie[8];
-	char sn[MAXSNLEN+1];
-	char ip[22];
-};
-
-/**
- * Convert the directory separator from / (0x2f) to ^A (0x01)
- *
- * @param name The filename to convert.
- */
-static void aim_oft_dirconvert_tostupid(char *name)
-{
-	while (name[0]) {
-		if (name[0] == 0x01)
-			name[0] = G_DIR_SEPARATOR;
-		name++;
-	}
-}
-
-/**
- * Convert the directory separator from ^A (0x01) to / (0x2f)
- *
- * @param name The filename to convert.
- */
-static void aim_oft_dirconvert_fromstupid(char *name)
-{
-	while (name[0]) {
-		if (name[0] == G_DIR_SEPARATOR)
-			name[0] = 0x01;
-		name++;
-	}
-}
-
-/**
- * Calculate oft checksum of buffer
- *
- * Prevcheck should be 0xFFFF0000 when starting a checksum of a file.  The 
- * checksum is kind of a rolling checksum thing, so each time you get bytes 
- * of a file you just call this puppy and it updates the checksum.  You can 
- * calculate the checksum of an entire file by calling this in a while or a 
- * for loop, or something.
- *
- * Thanks to Graham Booker for providing this improved checksum routine, 
- * which is simpler and should be more accurate than Josh Myer's original 
- * code. -- wtm
- *
- * This algorithim works every time I have tried it.  The other fails 
- * sometimes.  So, AOL who thought this up?  It has got to be the weirdest 
- * checksum I have ever seen.
- *
- * @param buffer Buffer of data to checksum.  Man I'd like to buff her...
- * @param bufsize Size of buffer.
- * @param prevcheck Previous checksum.
- */
-faim_export fu32_t aim_oft_checksum_chunk(const fu8_t *buffer, int bufferlen, fu32_t prevcheck)
-{
-	fu32_t check = (prevcheck >> 16) & 0xffff, oldcheck;
-	int i;
-	unsigned short val;
-
-	for (i=0; i<bufferlen; i++) {
-		oldcheck = check;
-		if (i&1)
-			val = buffer[i];
-		else
-			val = buffer[i] << 8;
-		check -= val;
-		/*
-		 * The following appears to be necessary.... It happens 
-		 * every once in a while and the checksum doesn't fail.
-		 */
-		if (check > oldcheck)
-			check--;
-	}
-	check = ((check & 0x0000ffff) + (check >> 16));
-	check = ((check & 0x0000ffff) + (check >> 16));
-	return check << 16;
-}
-
-faim_export fu32_t aim_oft_checksum_file(char *filename) {
-	FILE *fd;
-	fu32_t checksum = 0xffff0000;
-
-	if ((fd = fopen(filename, "rb"))) {
-		int bytes;
-		fu8_t buffer[1024];
-
-		while ((bytes = fread(buffer, 1, 1024, fd)))
-			checksum = aim_oft_checksum_chunk(buffer, bytes, checksum);
-		fclose(fd);
-	}
-
-	return checksum;
-}
-
-/**
- * Create a listening socket on a given port.
- *
- * XXX - Give the client author the responsibility of setting up a 
- *       listener, then we no longer have a libfaim problem with broken 
- *       solaris *innocent smile* -- jbm
- *
- * @param portnum The port number to bind to.
- * @return The file descriptor of the listening socket.
- */
-static int listenestablish(fu16_t portnum)
-{
-#if HAVE_GETADDRINFO
-	int listenfd;
-	const int on = 1;
-	struct addrinfo hints, *res, *ressave;
-	char serv[5];
-
-	snprintf(serv, sizeof(serv), "%d", portnum);
-	memset(&hints, 0, sizeof(struct addrinfo));
-	hints.ai_flags = AI_PASSIVE;
-	hints.ai_family = AF_UNSPEC;
-	hints.ai_socktype = SOCK_STREAM;
-	if (getaddrinfo(NULL /* any IP */, serv, &hints, &res) != 0) {
-		perror("getaddrinfo");
-		return -1;
-	} 
-	ressave = res;
-	do { 
-		listenfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
-		if (listenfd < 0)
-			continue;
-		setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
-		if (bind(listenfd, res->ai_addr, res->ai_addrlen) == 0)
-			break; /* success */
-		close(listenfd);
-	} while ( (res = res->ai_next) );
-
-	if (!res)
-		return -1;
-
-	freeaddrinfo(ressave);
-#else
-	int listenfd;
-	const int on = 1;
-	struct sockaddr_in sockin;
-
-	if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-		perror("socket");
-		return -1;
-	}
-
-	if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) != 0) {
-		perror("setsockopt");
-		close(listenfd);
-		return -1;
-	}
-
-	memset(&sockin, 0, sizeof(struct sockaddr_in));
-	sockin.sin_family = AF_INET;
-	sockin.sin_port = htons(portnum);
-
-	if (bind(listenfd, (struct sockaddr *)&sockin, sizeof(struct sockaddr_in)) != 0) {
-		perror("bind");
-		close(listenfd);
-		return -1;
-	}
-#endif
-
-	if (listen(listenfd, 4) != 0) {
-		perror("listen");
-		close(listenfd);
-		return -1;
-	}
-	fcntl(listenfd, F_SETFL, O_NONBLOCK);
-
-	return listenfd;
-}
-
-/**
- * After establishing a listening socket, this is called to accept a connection.  It
- * clones the conn used by the listener, and passes both of these to a signal handler.
- * The signal handler should close the listener conn and keep track of the new conn,
- * since this is what is used for file transfers and what not.
- *
- * @param sess The session.
- * @param cur The conn the incoming connection is on.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_handlerendconnect(aim_session_t *sess, aim_conn_t *cur)
-{
-	int acceptfd = 0;
-	struct sockaddr addr;
-	socklen_t addrlen = sizeof(addr);
-	int ret = 0;
-	aim_conn_t *newconn;
-	char ip[20];
-	int port;
-
-	if ((acceptfd = accept(cur->fd, &addr, &addrlen)) == -1)
-		return 0; /* not an error */
-
-	if ((addr.sa_family != AF_INET) && (addr.sa_family != AF_INET6)) { /* just in case IPv6 really is happening */
-		close(acceptfd);
-		aim_conn_close(cur);
-		return -1;
-	}
-
-	strncpy(ip, inet_ntoa(((struct sockaddr_in *)&addr)->sin_addr), sizeof(ip));
-	port = ntohs(((struct sockaddr_in *)&addr)->sin_port);
-
-	if (!(newconn = aim_cloneconn(sess, cur))) {
-		close(acceptfd);
-		aim_conn_close(cur);
-		return -ENOMEM;
-	}
-
-	newconn->type = AIM_CONN_TYPE_RENDEZVOUS;
-	newconn->fd = acceptfd;
-
-	if (newconn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) {
-		aim_rxcallback_t userfunc;
-		struct aim_odc_intdata *priv;
-
-		priv = (struct aim_odc_intdata *)(newconn->internal = cur->internal);
-		cur->internal = NULL;
-		snprintf(priv->ip, sizeof(priv->ip), "%s:%u", ip, port);
-
-		if ((userfunc = aim_callhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIM_ESTABLISHED)))
-			ret = userfunc(sess, NULL, newconn, cur);
-
-	} else if (newconn->subtype == AIM_CONN_SUBTYPE_OFT_GETFILE) {
-	} else if (newconn->subtype == AIM_CONN_SUBTYPE_OFT_SENDFILE) {
-		aim_rxcallback_t userfunc;
-
-		if ((userfunc = aim_callhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_ESTABLISHED)))
-			ret = userfunc(sess, NULL, newconn, cur);
-
-	} else {
-		faimdprintf(sess, 1,"Got a connection on a listener that's not rendezvous.  Closing connection.\n");
-		aim_conn_close(newconn);
-		ret = -1;
-	}
-
-	return ret;
-}
-
-/**
- * Send client-to-client typing notification over an established direct connection.
- *
- * @param sess The session.
- * @param conn The already-connected ODC connection.
- * @param typing If 0x0002, sends a "typing" message, 0x0001 sends "typed," and 
- *        0x0000 sends "stopped."
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_odc_send_typing(aim_session_t *sess, aim_conn_t *conn, int typing)
-{
-	struct aim_odc_intdata *intdata = (struct aim_odc_intdata *)conn->internal;
-	aim_frame_t *fr;
-	aim_bstream_t *hdrbs;
-	fu8_t *hdr;
-	int hdrlen = 0x44;
-
-	if (!sess || !conn || (conn->type != AIM_CONN_TYPE_RENDEZVOUS))
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x0001, 0)))
-		return -ENOMEM;
-	memcpy(fr->hdr.rend.magic, "ODC2", 4);
-	fr->hdr.rend.hdrlen = hdrlen;
-
-	if (!(hdr = calloc(1, hdrlen))) {
-		aim_frame_destroy(fr);
-		return -ENOMEM;
-	}
-
-	hdrbs = &(fr->data);
-	aim_bstream_init(hdrbs, hdr, hdrlen);
-
-	aimbs_put16(hdrbs, 0x0006);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_putraw(hdrbs, intdata->cookie, 8);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put32(hdrbs, 0x00000000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-
-	if (typing == 0x0002)
-		aimbs_put16(hdrbs, 0x0002 | 0x0008);
-	else if (typing == 0x0001)
-		aimbs_put16(hdrbs, 0x0002 | 0x0004);
-	else
-		aimbs_put16(hdrbs, 0x0002);
-
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_putraw(hdrbs, sess->sn, strlen(sess->sn));
-
-	aim_bstream_setpos(hdrbs, 52); /* bleeehh */
-
-	aimbs_put8(hdrbs, 0x00);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put8(hdrbs, 0x00);
-
-	/* end of hdr */
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Send client-to-client IM over an established direct connection.
- * Call this just like you would aim_send_im, to send a directim.
- * 
- * @param sess The session.
- * @param conn The already-connected ODC connection.
- * @param msg Null-terminated string to send.
- * @param len The length of the message to send, including binary data.
- * @param encoding 0 for ascii, 2 for Unicode, 3 for ISO 8859-1.
- * @param isawaymsg 0 if this is not an auto-response, 1 if it is.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *msg, int len, int encoding, int isawaymsg)
-{
-	aim_frame_t *fr;
-	aim_bstream_t *hdrbs;
-	struct aim_odc_intdata *intdata = (struct aim_odc_intdata *)conn->internal;
-	int hdrlen = 0x44;
-	fu8_t *hdr;
-
-	if (!sess || !conn || (conn->type != AIM_CONN_TYPE_RENDEZVOUS) || !msg)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_OFT, 0x01, 0)))
-		return -ENOMEM;
-
-	memcpy(fr->hdr.rend.magic, "ODC2", 4);
-	fr->hdr.rend.hdrlen = hdrlen;
-
-	if (!(hdr = calloc(1, hdrlen + len))) {
-		aim_frame_destroy(fr);
-		return -ENOMEM;
-	}
-
-	hdrbs = &(fr->data);
-	aim_bstream_init(hdrbs, hdr, hdrlen + len);
-
-	aimbs_put16(hdrbs, 0x0006);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_putraw(hdrbs, intdata->cookie, 8);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put32(hdrbs, len);
-	aimbs_put16(hdrbs, encoding);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-
-	/* flags - used for typing notification and to mark if this is an away message */
-	aimbs_put16(hdrbs, 0x0000 | isawaymsg);
-
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_putraw(hdrbs, sess->sn, strlen(sess->sn));
-
-	aim_bstream_setpos(hdrbs, 52); /* bleeehh */
-
-	aimbs_put8(hdrbs, 0x00);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put8(hdrbs, 0x00);
-
-	/* end of hdr2 */
-
-#if 0 /* XXX - this is how you send buddy icon info... */	
-	aimbs_put16(hdrbs, 0x0008);
-	aimbs_put16(hdrbs, 0x000c);
-	aimbs_put16(hdrbs, 0x0000);
-	aimbs_put16(hdrbs, 0x1466);
-	aimbs_put16(hdrbs, 0x0001);
-	aimbs_put16(hdrbs, 0x2e0f);
-	aimbs_put16(hdrbs, 0x393e);
-	aimbs_put16(hdrbs, 0xcac8);
-#endif
-	aimbs_putraw(hdrbs, msg, len);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Get the screen name of the peer of a direct connection.
- * 
- * @param conn The ODC connection.
- * @return The screen name of the dude, or NULL if there was an anomaly.
- */
-faim_export const char *aim_odc_getsn(aim_conn_t *conn)
-{
-	struct aim_odc_intdata *intdata;
-
-	if (!conn || !conn->internal)
-		return NULL;
-
-	if ((conn->type != AIM_CONN_TYPE_RENDEZVOUS) || 
-			(conn->subtype != AIM_CONN_SUBTYPE_OFT_DIRECTIM))
-		return NULL;
-
-	intdata = (struct aim_odc_intdata *)conn->internal;
-
-	return intdata->sn;
-}
-
-/**
- * Find the conn of a direct connection with the given buddy.
- *
- * @param sess The session.
- * @param sn The screen name of the buddy whose direct connection you want to find.
- * @return The conn for the direct connection with the given buddy, or NULL if no 
- *         connection was found.
- */
-faim_export aim_conn_t *aim_odc_getconn(aim_session_t *sess, const char *sn)
-{
-	aim_conn_t *cur;
-	struct aim_odc_intdata *intdata;
-
-	if (!sess || !sn || !strlen(sn))
-		return NULL;
-
-	for (cur = sess->connlist; cur; cur = cur->next) {
-		if ((cur->type == AIM_CONN_TYPE_RENDEZVOUS) && (cur->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM)) {
-			intdata = cur->internal;
-			if (!aim_sncmp(intdata->sn, sn))
-				return cur;
-		}
-	}
-
-	return NULL;
-}
-
-/**
- * For those times when we want to open up the direct connection channel ourselves.
- *
- * You'll want to set up some kind of watcher on this socket.  
- * When the state changes, call aim_handlerendconnection with 
- * the connection returned by this.  aim_handlerendconnection 
- * will accept the pending connection and stop listening.
- *
- * @param sess The session
- * @param sn The screen name to connect to.
- * @return The new connection.
- */
-faim_export aim_conn_t *aim_odc_initiate(aim_session_t *sess, const char *sn)
-{
-	aim_conn_t *newconn;
-	aim_msgcookie_t *cookie;
-	struct aim_odc_intdata *priv;
-	int listenfd;
-	fu16_t port = 4443;
-	fu8_t localip[4];
-	fu8_t ck[8];
-
-	if (aim_util_getlocalip(localip) == -1)
-		return NULL;
-
-	if ((listenfd = listenestablish(port)) == -1)
-		return NULL;
-
-	aim_im_sendch2_odcrequest(sess, ck, sn, localip, port);
-
-	cookie = (aim_msgcookie_t *)calloc(1, sizeof(aim_msgcookie_t));
-	memcpy(cookie->cookie, ck, 8);
-	cookie->type = AIM_COOKIETYPE_OFTIM;
-
-	/* this one is for the cookie */
-	priv = (struct aim_odc_intdata *)calloc(1, sizeof(struct aim_odc_intdata));
-
-	memcpy(priv->cookie, ck, 8);
-	strncpy(priv->sn, sn, sizeof(priv->sn));
-	cookie->data = priv;
-	aim_cachecookie(sess, cookie);
-
-	/* XXX - switch to aim_cloneconn()? */
-	if (!(newconn = aim_newconn(sess, AIM_CONN_TYPE_LISTENER, NULL))) {
-		close(listenfd);
-		return NULL;
-	}
-
-	/* this one is for the conn */
-	priv = (struct aim_odc_intdata *)calloc(1, sizeof(struct aim_odc_intdata));
-
-	memcpy(priv->cookie, ck, 8);
-	strncpy(priv->sn, sn, sizeof(priv->sn));
-
-	newconn->fd = listenfd;
-	newconn->subtype = AIM_CONN_SUBTYPE_OFT_DIRECTIM;
-	newconn->internal = priv;
-	newconn->lastactivity = time(NULL);
-
-	return newconn;
-}
-
-/**
- * Connect directly to the given buddy for directim.
- *
- * This is a wrapper for aim_newconn.
- *
- * If addr is NULL, the socket is not created, but the connection is 
- * allocated and setup to connect.
- *
- * @param sess The Godly session.
- * @param sn The screen name we're connecting to.  I hope it's a girl...
- * @param addr Address to connect to.
- * @return The new connection.
- */
-faim_export aim_conn_t *aim_odc_connect(aim_session_t *sess, const char *sn, const char *addr, const fu8_t *cookie)
-{
-	aim_conn_t *newconn;
-	struct aim_odc_intdata *intdata;
-
-	if (!sess || !sn)
-		return NULL;
-
-	if (!(intdata = calloc(1, sizeof(struct aim_odc_intdata))))
-		return NULL;
-	memcpy(intdata->cookie, cookie, 8);
-	strncpy(intdata->sn, sn, sizeof(intdata->sn));
-	if (addr)
-		strncpy(intdata->ip, addr, sizeof(intdata->ip));
-
-	/* XXX - verify that non-blocking connects actually work */
-	if (!(newconn = aim_newconn(sess, AIM_CONN_TYPE_RENDEZVOUS, addr))) {
-		free(intdata);
-		return NULL;
-	}
-
-	newconn->internal = intdata;
-	newconn->subtype = AIM_CONN_SUBTYPE_OFT_DIRECTIM;
-
-	return newconn;
-}
-
-/**
- * Sometimes you just don't know with these kinds of people.
- *
- * @param sess The session.
- * @param conn The ODC connection of the incoming data.
- * @param frr The frame allocated for the incoming data.
- * @param bs It stands for "bologna sandwich."
- * @return Return 0 if no errors, otherwise return the error number.
- */
-static int handlehdr_odc(aim_session_t *sess, aim_conn_t *conn, aim_frame_t *frr, aim_bstream_t *bs)
-{
-	aim_frame_t fr;
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu32_t payloadlength;
-	fu16_t flags, encoding;
-	char *snptr = NULL;
-
-	fr.conn = conn;
-
-	/* AAA - ugly */
-	aim_bstream_setpos(bs, 20);
-	payloadlength = aimbs_get32(bs);
-
-	aim_bstream_setpos(bs, 24);
-	encoding = aimbs_get16(bs);
-
-	aim_bstream_setpos(bs, 30);
-	flags = aimbs_get16(bs);
-
-	aim_bstream_setpos(bs, 36);
-	/* XXX - create an aimbs_getnullstr function? */
-	snptr = aimbs_getstr(bs, 32); /* Next 32 bytes contain the sn, padded with null chars */
-
-	faimdprintf(sess, 2, "faim: OFT frame: handlehdr_odc: %04x / %04x / %s\n", payloadlength, flags, snptr);
-
-	if (flags & 0x0008) {
-		if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING)))
-			ret = userfunc(sess, &fr, snptr, 2);
-	} else if (flags & 0x0004) {
-		if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING)))
-			ret = userfunc(sess, &fr, snptr, 1);
-	} else {
-		if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING)))
-			ret = userfunc(sess, &fr, snptr, 0);
-	}
-
-	if (payloadlength) {
-		char *msg;
-		int recvd = 0;
-		int i, isawaymsg;
-
-		isawaymsg = flags & 0x0001;
-
-		if (!(msg = calloc(1, payloadlength+1))) {
-			free(snptr);
-			return -ENOMEM;
-		}
-
-		while (payloadlength - recvd) {
-			if (payloadlength - recvd >= 1024)
-				i = aim_recv(conn->fd, &msg[recvd], 1024);
-			else 
-				i = aim_recv(conn->fd, &msg[recvd], payloadlength - recvd);
-			if (i <= 0) {
-				free(msg);
-				free(snptr);
-				return -1;
-			}
-			recvd = recvd + i;
-			if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER)))
-				ret = userfunc(sess, &fr, snptr, (double)recvd / payloadlength);
-		}
-		
-		if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING)))
-			ret = userfunc(sess, &fr, snptr, msg, payloadlength, encoding, isawaymsg);
-
-		free(msg);
-	}
-
-	free(snptr);
-
-	return ret;
-}
-
-faim_export struct aim_oft_info *aim_oft_createinfo(aim_session_t *sess, const fu8_t *cookie, const char *sn, const char *ip, fu16_t port, fu32_t size, fu32_t modtime, char *filename)
-{
-	struct aim_oft_info *new;
-
-	if (!sess)
-		return NULL;
-
-	if (!(new = (struct aim_oft_info *)calloc(1, sizeof(struct aim_oft_info))))
-		return NULL;
-
-	new->sess = sess;
-	if (cookie)
-		memcpy(new->cookie, cookie, 8);
-	if (ip)
-		new->clientip = strdup(ip);
-	if (sn)
-		new->sn = strdup(sn);
-	new->port = port;
-	new->fh.totfiles = 1;
-	new->fh.filesleft = 1;
-	new->fh.totparts = 1;
-	new->fh.partsleft = 1;
-	new->fh.totsize = size;
-	new->fh.size = size;
-	new->fh.modtime = modtime;
-	new->fh.checksum = 0xffff0000;
-	new->fh.rfrcsum = 0xffff0000;
-	new->fh.rfcsum = 0xffff0000;
-	new->fh.recvcsum = 0xffff0000;
-	strncpy(new->fh.idstring, "OFT_Windows ICBMFT V1.1 32", 31);
-	if (filename)
-		strncpy(new->fh.name, filename, 63);
-
-	new->next = sess->oft_info;
-	sess->oft_info = new;
-
-	return new;
-}
-
-/**
- * Remove the given oft_info struct from the oft_info linked list, and 
- * then free its memory.
- *
- * @param sess The session.
- * @param oft_info The aim_oft_info struct that we're destroying.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_oft_destroyinfo(struct aim_oft_info *oft_info)
-{
-	aim_session_t *sess;
-
-	if (!oft_info || !(sess = oft_info->sess))
-		return -EINVAL;
-
-	if (sess->oft_info && (sess->oft_info == oft_info)) {
-		sess->oft_info = sess->oft_info->next;
-	} else {
-		struct aim_oft_info *cur;
-		for (cur=sess->oft_info; (cur->next && (cur->next!=oft_info)); cur=cur->next);
-		if (cur->next)
-			cur->next = cur->next->next;
-	}
-
-	free(oft_info->sn);
-	free(oft_info->proxyip);
-	free(oft_info->clientip);
-	free(oft_info->verifiedip);
-	free(oft_info);
-
-	return 0;
-}
-
-/**
- * Creates a listener socket so the other dude can connect to us.
- *
- * You'll want to set up some kind of watcher on this socket.  
- * When the state changes, call aim_handlerendconnection with 
- * the connection returned by this.  aim_handlerendconnection 
- * will accept the pending connection and stop listening.
- *
- * @param sess The session.
- * @param oft_info File transfer information associated with this 
- *        connection.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_sendfile_listen(aim_session_t *sess, struct aim_oft_info *oft_info)
-{
-	int listenfd;
-
-	if (!oft_info)
-		return -EINVAL;
-
-	if ((listenfd = listenestablish(oft_info->port)) == -1)
-		return 1;
-
-	if (!(oft_info->conn = aim_newconn(sess, AIM_CONN_TYPE_LISTENER, NULL))) {
-		close(listenfd);
-		return -ENOMEM;
-	}
-
-	oft_info->conn->fd = listenfd;
-	oft_info->conn->subtype = AIM_CONN_SUBTYPE_OFT_SENDFILE;
-	oft_info->conn->lastactivity = time(NULL);
-
-	return 0;
-}
-
-/**
- * Extract an &aim_fileheader_t from the given buffer.
- *
- * @param bs The should be from an incoming rendezvous packet.
- * @return A pointer to new struct on success, or NULL on error.
- */
-static struct aim_fileheader_t *aim_oft_getheader(aim_bstream_t *bs)
-{
-	struct aim_fileheader_t *fh;
-
-	if (!(fh = calloc(1, sizeof(struct aim_fileheader_t))))
-		return NULL;
-
-	/* The bstream should be positioned after the hdrtype. */
-	aimbs_getrawbuf(bs, fh->bcookie, 8);
-	fh->encrypt = aimbs_get16(bs);
-	fh->compress = aimbs_get16(bs);
-	fh->totfiles = aimbs_get16(bs);
-	fh->filesleft = aimbs_get16(bs);
-	fh->totparts = aimbs_get16(bs);
-	fh->partsleft = aimbs_get16(bs);
-	fh->totsize = aimbs_get32(bs);
-	fh->size = aimbs_get32(bs);
-	fh->modtime = aimbs_get32(bs);
-	fh->checksum = aimbs_get32(bs);
-	fh->rfrcsum = aimbs_get32(bs);
-	fh->rfsize = aimbs_get32(bs);
-	fh->cretime = aimbs_get32(bs);
-	fh->rfcsum = aimbs_get32(bs);
-	fh->nrecvd = aimbs_get32(bs);
-	fh->recvcsum = aimbs_get32(bs);
-	aimbs_getrawbuf(bs, fh->idstring, 32);
-	fh->flags = aimbs_get8(bs);
-	fh->lnameoffset = aimbs_get8(bs);
-	fh->lsizeoffset = aimbs_get8(bs);
-	aimbs_getrawbuf(bs, fh->dummy, 69);
-	aimbs_getrawbuf(bs, fh->macfileinfo, 16);
-	fh->nencode = aimbs_get16(bs);
-	fh->nlanguage = aimbs_get16(bs);
-	aimbs_getrawbuf(bs, fh->name, 64); /* XXX - filenames longer than 64B */
-
-	return fh;
-} 
-
-/**
- * Fills a buffer with network-order fh data
- *
- * @param bs A bstream to fill -- automatically initialized
- * @param fh A struct aim_fileheader_t to get data from.
- * @return Return non-zero on error.
- */
-static int aim_oft_buildheader(aim_bstream_t *bs, struct aim_fileheader_t *fh)
-{ 
-	fu8_t *hdr;
-
-	if (!bs || !fh)
-		return -EINVAL;
-
-	if (!(hdr = (unsigned char *)calloc(1, 0x100 - 8)))
-		return -ENOMEM;
-
-	aim_bstream_init(bs, hdr, 0x100 - 8);
-	aimbs_putraw(bs, fh->bcookie, 8);
-	aimbs_put16(bs, fh->encrypt);
-	aimbs_put16(bs, fh->compress);
-	aimbs_put16(bs, fh->totfiles);
-	aimbs_put16(bs, fh->filesleft);
-	aimbs_put16(bs, fh->totparts);
-	aimbs_put16(bs, fh->partsleft);
-	aimbs_put32(bs, fh->totsize);
-	aimbs_put32(bs, fh->size);
-	aimbs_put32(bs, fh->modtime);
-	aimbs_put32(bs, fh->checksum);
-	aimbs_put32(bs, fh->rfrcsum);
-	aimbs_put32(bs, fh->rfsize);
-	aimbs_put32(bs, fh->cretime);
-	aimbs_put32(bs, fh->rfcsum);
-	aimbs_put32(bs, fh->nrecvd);
-	aimbs_put32(bs, fh->recvcsum);
-	aimbs_putraw(bs, fh->idstring, 32);
-	aimbs_put8(bs, fh->flags);
-	aimbs_put8(bs, fh->lnameoffset);
-	aimbs_put8(bs, fh->lsizeoffset);
-	aimbs_putraw(bs, fh->dummy, 69);
-	aimbs_putraw(bs, fh->macfileinfo, 16);
-	aimbs_put16(bs, fh->nencode);
-	aimbs_put16(bs, fh->nlanguage);
-	aimbs_putraw(bs, fh->name, 64);	/* XXX - filenames longer than 64B */
-
-	return 0;
-}
-
-/**
- * Create an OFT packet based on the given information, and send it on its merry way.
- *
- * @param sess The session.
- * @param type The subtype of the OFT packet we're sending.
- * @param oft_info The aim_oft_info struct with the connection and OFT 
- *        info we're sending.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_oft_sendheader(aim_session_t *sess, fu16_t type, struct aim_oft_info *oft_info)
-{
-	aim_frame_t *fr;
-
-	if (!sess || !oft_info || !oft_info->conn || (oft_info->conn->type != AIM_CONN_TYPE_RENDEZVOUS))
-		return -EINVAL;
-
-#if 0
-	/*
-	 * If you are receiving a file, the cookie should be null, if you are sending a 
-	 * file, the cookie should be the same as the one used in the ICBM negotiation 
-	 * SNACs.
-	 */
-	fh->lnameoffset = 0x1a;
-	fh->lsizeoffset = 0x10;
-
-	/* apparently 0 is ASCII, 2 is UCS-2 */
-	/* it is likely that 3 is ISO 8859-1 */
-	/* I think "nlanguage" might be the same thing as "subenc" in im.c */
-	fh->nencode = 0x0000;
-	fh->nlanguage = 0x0000;
-#endif
-
-	aim_oft_dirconvert_tostupid(oft_info->fh.name);
-
-	if (!(fr = aim_tx_new(sess, oft_info->conn, AIM_FRAMETYPE_OFT, type, 0)))
-		return -ENOMEM;
-
-	if (aim_oft_buildheader(&fr->data, &oft_info->fh) == -1) {
-		aim_frame_destroy(fr);
-		return -ENOMEM;
-	}
-
-	memcpy(fr->hdr.rend.magic, "OFT2", 4);
-	fr->hdr.rend.hdrlen = aim_bstream_curpos(&fr->data);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Handle incoming data on a rendezvous connection.  This is analogous to the 
- * consumesnac function in rxhandlers.c, and I really think this should probably 
- * be in rxhandlers.c as well, but I haven't finished cleaning everything up yet.
- *
- * @param sess The session.
- * @param fr The frame allocated for the incoming data.
- * @return Return 0 if the packet was handled correctly, otherwise return the 
- *         error number.
- */
-faim_internal int aim_rxdispatch_rendezvous(aim_session_t *sess, aim_frame_t *fr)
-{
-	aim_conn_t *conn = fr->conn;
-	int ret = 1;
-
-	if (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM) {
-		if (fr->hdr.rend.type == 0x0001)
-			ret = handlehdr_odc(sess, conn, fr, &fr->data);
-		else
-			faimdprintf(sess, 0, "faim: ODC directim frame unknown, type is %04x\n", fr->hdr.rend.type);
-
-	} else {
-		aim_rxcallback_t userfunc;
-		struct aim_fileheader_t *header = aim_oft_getheader(&fr->data);
-		aim_oft_dirconvert_fromstupid(header->name); /* XXX - This should be client-side */
-
-		if ((userfunc = aim_callhandler(sess, conn, AIM_CB_FAM_OFT, fr->hdr.rend.type)))
-			ret = userfunc(sess, fr, conn, header->bcookie, header);
-
-		free(header);
-	}
-
-	if (ret == -1)
-		aim_conn_close(conn);
-
-	return ret;
-}
Index: bfaim/icq.c
===================================================================
--- libfaim/icq.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,684 +1,0 @@
-/*
- * Family 0x0015 - Encapsulated ICQ.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-faim_export int aim_icq_reqofflinemsgs(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int bslen;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
-		return -EINVAL;
-
-	bslen = 2 + 4 + 2 + 2;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
-
-	/* For simplicity, don't bother using a tlvlist */
-	aimbs_put16(&fr->data, 0x0001);
-	aimbs_put16(&fr->data, bslen);
-
-	aimbs_putle16(&fr->data, bslen - 2);
-	aimbs_putle32(&fr->data, atoi(sess->sn));
-	aimbs_putle16(&fr->data, 0x003c); /* I command thee. */
-	aimbs_putle16(&fr->data, snacid); /* eh. */
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-faim_export int aim_icq_ackofflinemsgs(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int bslen;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
-		return -EINVAL;
-
-	bslen = 2 + 4 + 2 + 2;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
-
-	/* For simplicity, don't bother using a tlvlist */
-	aimbs_put16(&fr->data, 0x0001);
-	aimbs_put16(&fr->data, bslen);
-
-	aimbs_putle16(&fr->data, bslen - 2);
-	aimbs_putle32(&fr->data, atoi(sess->sn));
-	aimbs_putle16(&fr->data, 0x003e); /* I command thee. */
-	aimbs_putle16(&fr->data, snacid); /* eh. */
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-faim_export int aim_icq_hideip(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int bslen;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
-		return -EINVAL;
-
-	bslen = 2+4+2+2+2+4;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
-
-	/* For simplicity, don't bother using a tlvlist */
-	aimbs_put16(&fr->data, 0x0001);
-	aimbs_put16(&fr->data, bslen);
-
-	aimbs_putle16(&fr->data, bslen - 2);
-	aimbs_putle32(&fr->data, atoi(sess->sn));
-	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
-	aimbs_putle16(&fr->data, snacid); /* eh. */
-	aimbs_putle16(&fr->data, 0x0424); /* shrug. */
-	aimbs_putle16(&fr->data, 0x0001);
-	aimbs_putle16(&fr->data, 0x0001);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Change your ICQ password.
- *
- * @param sess The oscar session
- * @param passwd The new password.  If this is longer than 8 characters it 
- *        will be truncated.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_icq_changepasswd(aim_session_t *sess, const char *passwd)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int bslen, passwdlen;
-
-	if (!passwd)
-		return -EINVAL;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
-		return -EINVAL;
-
-	passwdlen = strlen(passwd);
-	if (passwdlen > MAXICQPASSLEN)
-		passwdlen = MAXICQPASSLEN;
-	bslen = 2+4+2+2+2+2+passwdlen+1;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
-
-	/* For simplicity, don't bother using a tlvlist */
-	aimbs_put16(&fr->data, 0x0001);
-	aimbs_put16(&fr->data, bslen);
-
-	aimbs_putle16(&fr->data, bslen - 2);
-	aimbs_putle32(&fr->data, atoi(sess->sn));
-	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
-	aimbs_putle16(&fr->data, snacid); /* eh. */
-	aimbs_putle16(&fr->data, 0x042e); /* shrug. */
-	aimbs_putle16(&fr->data, passwdlen+1);
-	aimbs_putraw(&fr->data, passwd, passwdlen);
-	aimbs_putle8(&fr->data, '\0');
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-faim_export int aim_icq_getallinfo(aim_session_t *sess, const char *uin)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int bslen;
-	struct aim_icq_info *info;
-
-	if (!uin || uin[0] < '0' || uin[0] > '9')
-		return -EINVAL;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
-		return -EINVAL;
-
-	bslen = 2 + 4 + 2 + 2 + 2 + 4;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
-
-	/* For simplicity, don't bother using a tlvlist */
-	aimbs_put16(&fr->data, 0x0001);
-	aimbs_put16(&fr->data, bslen);
-
-	aimbs_putle16(&fr->data, bslen - 2);
-	aimbs_putle32(&fr->data, atoi(sess->sn));
-	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
-	aimbs_putle16(&fr->data, snacid); /* eh. */
-	aimbs_putle16(&fr->data, 0x04b2); /* shrug. */
-	aimbs_putle32(&fr->data, atoi(uin));
-
-	aim_tx_enqueue(sess, fr);
-
-	/* Keep track of this request and the ICQ number and request ID */
-	info = (struct aim_icq_info *)calloc(1, sizeof(struct aim_icq_info));
-	info->reqid = snacid;
-	info->uin = atoi(uin);
-	info->next = sess->icq_info;
-	sess->icq_info = info;
-
-	return 0;
-}
-
-faim_export int aim_icq_getalias(aim_session_t *sess, const char *uin)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int bslen;
-	struct aim_icq_info *info;
-
-	if (!uin || uin[0] < '0' || uin[0] > '9')
-		return -EINVAL;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
-		return -EINVAL;
-
-	bslen = 2 + 4 + 2 + 2 + 2 + 4;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
-
-	/* For simplicity, don't bother using a tlvlist */
-	aimbs_put16(&fr->data, 0x0001);
-	aimbs_put16(&fr->data, bslen);
-
-	aimbs_putle16(&fr->data, bslen - 2);
-	aimbs_putle32(&fr->data, atoi(sess->sn));
-	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
-	aimbs_putle16(&fr->data, snacid); /* eh. */
-	aimbs_putle16(&fr->data, 0x04ba); /* shrug. */
-	aimbs_putle32(&fr->data, atoi(uin));
-
-	aim_tx_enqueue(sess, fr);
-
-	/* Keep track of this request and the ICQ number and request ID */
-	info = (struct aim_icq_info *)calloc(1, sizeof(struct aim_icq_info));
-	info->reqid = snacid;
-	info->uin = atoi(uin);
-	info->next = sess->icq_info;
-	sess->icq_info = info;
-
-	return 0;
-}
-
-faim_export int aim_icq_getsimpleinfo(aim_session_t *sess, const char *uin)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int bslen;
-
-	if (!uin || uin[0] < '0' || uin[0] > '9')
-		return -EINVAL;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
-		return -EINVAL;
-
-	bslen = 2 + 4 + 2 + 2 + 2 + 4;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
-
-	/* For simplicity, don't bother using a tlvlist */
-	aimbs_put16(&fr->data, 0x0001);
-	aimbs_put16(&fr->data, bslen);
-
-	aimbs_putle16(&fr->data, bslen - 2);
-	aimbs_putle32(&fr->data, atoi(sess->sn));
-	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
-	aimbs_putle16(&fr->data, snacid); /* eh. */
-	aimbs_putle16(&fr->data, 0x051f); /* shrug. */
-	aimbs_putle32(&fr->data, atoi(uin));
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-faim_export int aim_icq_sendxmlreq(aim_session_t *sess, const char *xml)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int bslen;
-
-	if (!xml || !strlen(xml))
-		return -EINVAL;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
-		return -EINVAL;
-
-	bslen = 2 + 10 + 2 + strlen(xml) + 1;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
-
-	/* For simplicity, don't bother using a tlvlist */
-	aimbs_put16(&fr->data, 0x0001);
-	aimbs_put16(&fr->data, bslen);
-
-	aimbs_putle16(&fr->data, bslen - 2);
-	aimbs_putle32(&fr->data, atoi(sess->sn));
-	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
-	aimbs_putle16(&fr->data, snacid); /* eh. */
-	aimbs_putle16(&fr->data, 0x0998); /* shrug. */
-	aimbs_putle16(&fr->data, strlen(xml) + 1);
-	aimbs_putraw(&fr->data, xml, strlen(xml) + 1);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Send an SMS message.  This is the non-US way.  The US-way is to IM 
- * their cell phone number (+19195551234).
- *
- * We basically construct and send an XML message.  The format is:
- * <icq_sms_message>
- *   <destination>full_phone_without_leading_+</destination>
- *   <text>message</text>
- *   <codepage>1252</codepage>
- *   <senders_UIN>self_uin</senders_UIN>
- *   <senders_name>self_name</senders_name>
- *   <delivery_receipt>Yes|No</delivery_receipt>
- *   <time>Wkd, DD Mmm YYYY HH:MM:SS TMZ</time>
- * </icq_sms_message>
- *
- * Yeah hi Peter, whaaaat's happening.  If there's any way to use 
- * a codepage other than 1252 that would be great.  Thaaaanks.
- */
-faim_export int aim_icq_sendsms(aim_session_t *sess, const char *name, const char *msg, const char *alias)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int bslen, xmllen;
-	char *xml, timestr[30];
-	time_t t;
-	struct tm *tm;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0015)))
-		return -EINVAL;
-
-	if (!name || !msg || !alias)
-		return -EINVAL;
-
-	time(&t);
-	tm = gmtime(&t);
-	strftime(timestr, 30, "%a, %d %b %Y %T %Z", tm);
-
-	/* The length of xml included the null terminating character */
-	xmllen = 225 + strlen(name) + strlen(msg) + strlen(sess->sn) + strlen(alias) + strlen(timestr) + 1;
-
-	if (!(xml = (char *)malloc(xmllen*sizeof(char))))
-		return -ENOMEM;
-	snprintf(xml, xmllen, "<icq_sms_message>\n"
-		"\t<destination>%s</destination>\n"
-		"\t<text>%s</text>\n"
-		"\t<codepage>1252</codepage>\n"
-		"\t<senders_UIN>%s</senders_UIN>\n"
-		"\t<senders_name>%s</senders_name>\n"
-		"\t<delivery_receipt>Yes</delivery_receipt>\n"
-		"\t<time>%s</time>\n"
-		"</icq_sms_message>\n",
-		name, msg, sess->sn, alias, timestr);
-
-	bslen = 37 + xmllen;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + bslen))) {
-		free(xml);
-		return -ENOMEM;
-	}
-
-	snacid = aim_cachesnac(sess, 0x0015, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0015, 0x0002, 0x0000, snacid);
-
-	/* For simplicity, don't bother using a tlvlist */
-	aimbs_put16(&fr->data, 0x0001);
-	aimbs_put16(&fr->data, bslen);
-
-	aimbs_putle16(&fr->data, bslen - 2);
-	aimbs_putle32(&fr->data, atoi(sess->sn));
-	aimbs_putle16(&fr->data, 0x07d0); /* I command thee. */
-	aimbs_putle16(&fr->data, snacid); /* eh. */
-
-	/* From libicq200-0.3.2/src/SNAC-SRV.cpp */
-	aimbs_putle16(&fr->data, 0x8214);
-	aimbs_put16(&fr->data, 0x0001);
-	aimbs_put16(&fr->data, 0x0016);
-	aimbs_put32(&fr->data, 0x00000000);
-	aimbs_put32(&fr->data, 0x00000000);
-	aimbs_put32(&fr->data, 0x00000000);
-	aimbs_put32(&fr->data, 0x00000000);
-
-	aimbs_put16(&fr->data, 0x0000);
-	aimbs_put16(&fr->data, xmllen);
-	aimbs_putraw(&fr->data, xml, xmllen);
-
-	aim_tx_enqueue(sess, fr);
-
-	free(xml);
-
-	return 0;
-}
-
-static void aim_icq_freeinfo(struct aim_icq_info *info) {
-	int i;
-
-	if (!info)
-		return;
-	free(info->nick);
-	free(info->first);
-	free(info->last);
-	free(info->email);
-	free(info->homecity);
-	free(info->homestate);
-	free(info->homephone);
-	free(info->homefax);
-	free(info->homeaddr);
-	free(info->mobile);
-	free(info->homezip);
-	free(info->personalwebpage);
-	if (info->email2)
-		for (i = 0; i < info->numaddresses; i++)
-			free(info->email2[i]);
-	free(info->email2);
-	free(info->workcity);
-	free(info->workstate);
-	free(info->workphone);
-	free(info->workfax);
-	free(info->workaddr);
-	free(info->workzip);
-	free(info->workcompany);
-	free(info->workdivision);
-	free(info->workposition);
-	free(info->workwebpage);
-	free(info->info);
-	free(info);
-}
-
-/**
- * Subtype 0x0003 - Response to 0x0015/0x002, contains an ICQesque packet.
- */
-static int icqresponse(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_tlvlist_t *tl;
-	aim_tlv_t *datatlv;
-	aim_bstream_t qbs;
-	fu32_t ouruin;
-	fu16_t cmdlen, cmd, reqid;
-
-	if (!(tl = aim_tlvlist_read(bs)) || !(datatlv = aim_tlv_gettlv(tl, 0x0001, 1))) {
-		aim_tlvlist_free(&tl);
-		faimdprintf(sess, 0, "corrupt ICQ response\n");
-		return 0;
-	}
-
-	aim_bstream_init(&qbs, datatlv->value, datatlv->length);
-
-	cmdlen = aimbs_getle16(&qbs);
-	ouruin = aimbs_getle32(&qbs);
-	cmd = aimbs_getle16(&qbs);
-	reqid = aimbs_getle16(&qbs);
-
-	faimdprintf(sess, 1, "icq response: %d bytes, %ld, 0x%04x, 0x%04x\n", cmdlen, ouruin, cmd, reqid);
-
-	if (cmd == 0x0041) { /* offline message */
-		struct aim_icq_offlinemsg msg;
-		aim_rxcallback_t userfunc;
-
-		memset(&msg, 0, sizeof(msg));
-
-		msg.sender = aimbs_getle32(&qbs);
-		msg.year = aimbs_getle16(&qbs);
-		msg.month = aimbs_getle8(&qbs);
-		msg.day = aimbs_getle8(&qbs);
-		msg.hour = aimbs_getle8(&qbs);
-		msg.minute = aimbs_getle8(&qbs);
-		msg.type = aimbs_getle8(&qbs);
-		msg.flags = aimbs_getle8(&qbs);
-		msg.msglen = aimbs_getle16(&qbs);
-		msg.msg = aimbs_getstr(&qbs, msg.msglen);
-
-		if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG)))
-			ret = userfunc(sess, rx, &msg);
-
-		free(msg.msg);
-
-	} else if (cmd == 0x0042) {
-		aim_rxcallback_t userfunc;
-
-		if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSGCOMPLETE)))
-			ret = userfunc(sess, rx);
-
-	} else if (cmd == 0x07da) { /* information */
-		fu16_t subtype;
-		struct aim_icq_info *info;
-		aim_rxcallback_t userfunc;
-
-		subtype = aimbs_getle16(&qbs);
-		aim_bstream_advance(&qbs, 1); /* 0x0a */
-
-		/* find other data from the same request */
-		for (info = sess->icq_info; info && (info->reqid != reqid); info = info->next);
-		if (!info) {
-			info = (struct aim_icq_info *)calloc(1, sizeof(struct aim_icq_info));
-			info->reqid = reqid;
-			info->next = sess->icq_info;
-			sess->icq_info = info;
-		}
-
-		switch (subtype) {
-		case 0x00a0: { /* hide ip status */
-			/* nothing */
-		} break;
-
-		case 0x00aa: { /* password change status */
-			/* nothing */
-		} break;
-
-		case 0x00c8: { /* general and "home" information */
-			info->nick = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->first = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->last = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->email = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->homecity = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->homestate = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->homephone = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->homefax = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->homeaddr = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->mobile = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->homezip = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->homecountry = aimbs_getle16(&qbs);
-			/* 0x0a 00 02 00 */
-			/* 1 byte timezone? */
-			/* 1 byte hide email flag? */
-		} break;
-
-		case 0x00dc: { /* personal information */
-			info->age = aimbs_getle8(&qbs);
-			info->unknown = aimbs_getle8(&qbs);
-			info->gender = aimbs_getle8(&qbs);
-			info->personalwebpage = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->birthyear = aimbs_getle16(&qbs);
-			info->birthmonth = aimbs_getle8(&qbs);
-			info->birthday = aimbs_getle8(&qbs);
-			info->language1 = aimbs_getle8(&qbs);
-			info->language2 = aimbs_getle8(&qbs);
-			info->language3 = aimbs_getle8(&qbs);
-			/* 0x00 00 01 00 00 01 00 00 00 00 00 */
-		} break;
-
-		case 0x00d2: { /* work information */
-			info->workcity = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->workstate = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->workphone = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->workfax = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->workaddr = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->workzip = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->workcountry = aimbs_getle16(&qbs);
-			info->workcompany = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->workdivision = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->workposition = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			aim_bstream_advance(&qbs, 2); /* 0x01 00 */
-			info->workwebpage = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-		} break;
-
-		case 0x00e6: { /* additional personal information */
-			info->info = aimbs_getstr(&qbs, aimbs_getle16(&qbs)-1);
-		} break;
-
-		case 0x00eb: { /* email address(es) */
-			int i;
-			info->numaddresses = aimbs_getle16(&qbs);
-			info->email2 = (char **)calloc(info->numaddresses, sizeof(char *));
-			for (i = 0; i < info->numaddresses; i++) {
-				info->email2[i] = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-				if (i+1 != info->numaddresses)
-					aim_bstream_advance(&qbs, 1); /* 0x00 */
-			}
-		} break;
-
-		case 0x00f0: { /* personal interests */
-		} break;
-
-		case 0x00fa: { /* past background and current organizations */
-		} break;
-
-		case 0x0104: { /* alias info */
-			info->nick = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->first = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->last = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			aim_bstream_advance(&qbs, aimbs_getle16(&qbs)); /* email address? */
-			/* Then 0x00 02 00 */
-		} break;
-
-		case 0x010e: { /* unknown */
-			/* 0x00 00 */
-		} break;
-
-		case 0x019a: { /* simple info */
-			aim_bstream_advance(&qbs, 2);
-			info->uin = aimbs_getle32(&qbs);
-			info->nick = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->first = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->last = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			info->email = aimbs_getstr(&qbs, aimbs_getle16(&qbs));
-			/* Then 0x00 02 00 00 00 00 00 */
-		} break;
-		} /* End switch statement */
-
-		if (!(snac->flags & 0x0001)) {
-			if (subtype != 0x0104)
-				if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_INFO)))
-					ret = userfunc(sess, rx, info);
-
-			if (info->uin && info->nick)
-				if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_ALIAS)))
-					ret = userfunc(sess, rx, info);
-
-			if (sess->icq_info == info) {
-				sess->icq_info = info->next;
-			} else {
-				struct aim_icq_info *cur;
-				for (cur=sess->icq_info; (cur->next && (cur->next!=info)); cur=cur->next);
-				if (cur->next)
-					cur->next = cur->next->next;
-			}
-			aim_icq_freeinfo(info);
-		}
-	}
-
-	aim_tlvlist_free(&tl);
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0003)
-		return icqresponse(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-static void icq_shutdown(aim_session_t *sess, aim_module_t *mod)
-{
-	struct aim_icq_info *del;
-
-	while (sess->icq_info) {
-		del = sess->icq_info;
-		sess->icq_info = sess->icq_info->next;
-		aim_icq_freeinfo(del);
-	}
-
-	return;
-}
-
-faim_internal int icq_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x0015;
-	mod->version = 0x0001;
-	mod->toolid = 0x0110;
-	mod->toolversion = 0x047c;
-	mod->flags = 0;
-	strncpy(mod->name, "icq", sizeof(mod->name));
-	mod->snachandler = snachandler;
-	mod->shutdown = icq_shutdown;
-
-	return 0;
-}
Index: bfaim/im.c
===================================================================
--- libfaim/im.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,2298 +1,0 @@
-/*
- * Family 0x0004 - Routines for sending/receiving Instant Messages.
- *
- * Note the term ICBM (Inter-Client Basic Message) which blankets
- * all types of genericly routed through-server messages.  Within
- * the ICBM types (family 4), a channel is defined.  Each channel
- * represents a different type of message.  Channel 1 is used for
- * what would commonly be called an "instant message".  Channel 2
- * is used for negotiating "rendezvous".  These transactions end in
- * something more complex happening, such as a chat invitation, or
- * a file transfer.  Channel 3 is used for chat messages (not in 
- * the same family as these channels).  Channel 4 is used for 
- * various ICQ messages.  Examples are normal messages, URLs, and 
- * old-style authorization.
- *
- * In addition to the channel, every ICBM contains a cookie.  For
- * standard IMs, these are only used for error messages.  However,
- * the more complex rendezvous messages make suitably more complex
- * use of this field.
- *
- * TODO: Split this up into an im.c file an an icbm.c file.  It 
- *       will be beautiful, you'll see.
- *
- *       Need to rename all the mpmsg messages to aim_im_bleh.
- *
- *       Make sure aim_conn_findbygroup is used by all functions.
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
-
-/**
- * Add a standard ICBM header to the given bstream with the given 
- * information.
- *
- * @param bs The bstream to write the ICBM header to.
- * @param c c is for cookie, and cookie is for me.
- * @param ch The ICBM channel (1 through 4).
- * @param sn Null-terminated scrizeen nizame.
- * @return The number of bytes written.  It's really not useful.
- */
-static int aim_im_puticbm(aim_bstream_t *bs, const fu8_t *c, fu16_t ch, const char *sn)
-{
-	aimbs_putraw(bs, c, 8);
-	aimbs_put16(bs, ch);
-	aimbs_put8(bs, strlen(sn));
-	aimbs_putraw(bs, sn, strlen(sn));
-	return 8+2+1+strlen(sn);
-}
-
-/*
- * Takes a msghdr (and a length) and returns a client type
- * code.  Note that this is *only a guess* and has a low likelihood
- * of actually being accurate.
- *
- * Its based on experimental data, with the help of Eric Warmenhoven
- * who seems to have collected a wide variety of different AIM clients.
- *
- *
- * Heres the current collection:
- *  0501 0003 0101 0101 01		AOL Mobile Communicator, WinAIM 1.0.414
- *  0501 0003 0101 0201 01		WinAIM 2.0.847, 2.1.1187, 3.0.1464, 
- *					4.3.2229, 4.4.2286
- *  0501 0004 0101 0102 0101		WinAIM 4.1.2010, libfaim (right here)
- *  0501 0003 0101 02			WinAIM 5
- *  0501 0001 01			iChat x.x, mobile buddies
- *  0501 0001 0101 01			AOL v6.0, CompuServe 2000 v6.0, any TOC client
- *  0501 0002 0106			WinICQ 5.45.1.3777.85
- *
- * Note that in this function, only the feature bytes are tested, since
- * the rest will always be the same.
- *
- */
-faim_export fu16_t aim_im_fingerprint(const fu8_t *msghdr, int len)
-{
-	static const struct {
-		fu16_t clientid;
-		int len;
-		fu8_t data[10];
-	} fingerprints[] = {
-		/* AOL Mobile Communicator, WinAIM 1.0.414 */
-		{ AIM_CLIENTTYPE_MC, 
-		  3, {0x01, 0x01, 0x01}},
-
-		/* WinAIM 2.0.847, 2.1.1187, 3.0.1464, 4.3.2229, 4.4.2286 */
-		{ AIM_CLIENTTYPE_WINAIM, 
-		  3, {0x01, 0x01, 0x02}},
-
-		/* WinAIM 4.1.2010, libfaim */
-		{ AIM_CLIENTTYPE_WINAIM41,
-		  4, {0x01, 0x01, 0x01, 0x02}},
-
-		/* AOL v6.0, CompuServe 2000 v6.0, any TOC client */
-		{ AIM_CLIENTTYPE_AOL_TOC,
-		  1, {0x01}},
-
-		{ 0, 0}
-	};
-	int i;
-
-	if (!msghdr || (len <= 0))
-		return AIM_CLIENTTYPE_UNKNOWN;
-
-	for (i = 0; fingerprints[i].len; i++) {
-		if (fingerprints[i].len != len)
-			continue;
-		if (memcmp(fingerprints[i].data, msghdr, fingerprints[i].len) == 0)
-			return fingerprints[i].clientid;
-	}
-
-	return AIM_CLIENTTYPE_UNKNOWN;
-}
-
-/** 
- * Subtype 0x0002 - Set ICBM parameters.
- *
- * I definitly recommend sending this.  If you don't, you'll be stuck
- * with the rather unreasonable defaults.
- * 
- */
-faim_export int aim_im_setparams(aim_session_t *sess, struct aim_icbmparameters *params)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
-		return -EINVAL;
-
-	if (!params)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+16)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0004, 0x0002, 0x0000, snacid);
-
-	/* This is read-only (see Parameter Reply). Must be set to zero here. */
-	aimbs_put16(&fr->data, 0x0000);
-
-	/* These are all read-write */
-	aimbs_put32(&fr->data, params->flags); 
-	aimbs_put16(&fr->data, params->maxmsglen);
-	aimbs_put16(&fr->data, params->maxsenderwarn); 
-	aimbs_put16(&fr->data, params->maxrecverwarn); 
-	aimbs_put32(&fr->data, params->minmsginterval);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Subtype 0x0004 - Request ICBM parameter information.
- *
- */
-faim_export int aim_im_reqparams(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
-		return -EINVAL;
-
-	return aim_genericreq_n_snacid(sess, conn, 0x0004, 0x0004);
-}
-
-/**
- * Subtype 0x0005 - Receive parameter information.
- *
- */
-static int aim_im_paraminfo(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_rxcallback_t userfunc;
-	struct aim_icbmparameters params;
-
-	params.maxchan = aimbs_get16(bs);
-	params.flags = aimbs_get32(bs);
-	params.maxmsglen = aimbs_get16(bs);
-	params.maxsenderwarn = aimbs_get16(bs);
-	params.maxrecverwarn = aimbs_get16(bs);
-	params.minmsginterval = aimbs_get32(bs);
-	
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		return userfunc(sess, rx, &params);
-
-	return 0;
-}
-
-/**
- * Subtype 0x0006 - Send an ICBM (instant message).  
- *
- *
- * Possible flags:
- *   AIM_IMFLAGS_AWAY  -- Marks the message as an autoresponse
- *   AIM_IMFLAGS_ACK   -- Requests that the server send an ack
- *                        when the message is received (of type 0x0004/0x000c)
- *   AIM_IMFLAGS_OFFLINE--If destination is offline, store it until they are
- *                        online (probably ICQ only).
- *   AIM_IMFLAGS_UNICODE--Instead of ASCII7, the passed message is
- *                        made up of UNICODE duples.  If you set
- *                        this, you'd better be damn sure you know
- *                        what you're doing.
- *   AIM_IMFLAGS_ISO_8859_1 -- The message contains the ASCII8 subset
- *                        known as ISO-8859-1.  
- *
- * Generally, you should use the lowest encoding possible to send
- * your message.  If you only use basic punctuation and the generic
- * Latin alphabet, use ASCII7 (no flags).  If you happen to use non-ASCII7
- * characters, but they are all clearly defined in ISO-8859-1, then 
- * use that.  Keep in mind that not all characters in the PC ASCII8
- * character set are defined in the ISO standard. For those cases (most
- * notably when the (r) symbol is used), you must use the full UNICODE
- * encoding for your message.  In UNICODE mode, _all_ characters must
- * occupy 16bits, including ones that are not special.  (Remember that
- * the first 128 UNICODE symbols are equivelent to ASCII7, however they
- * must be prefixed with a zero high order byte.)
- *
- * I strongly discourage the use of UNICODE mode, mainly because none
- * of the clients I use can parse those messages (and besides that,
- * wchars are difficult and non-portable to handle in most UNIX environments).
- * If you really need to include special characters, use the HTML UNICODE 
- * entities.  These are of the form &#2026; where 2026 is the hex 
- * representation of the UNICODE index (in this case, UNICODE 
- * "Horizontal Ellipsis", or 133 in in ASCII8).
- *
- * Implementation note:  Since this is one of the most-used functions
- * in all of libfaim, it is written with performance in mind.  As such,
- * it is not as clear as it could be in respect to how this message is
- * supposed to be layed out. Most obviously, tlvlists should be used 
- * instead of writing out the bytes manually. 
- *
- * XXX - more precise verification that we never send SNACs larger than 8192
- * XXX - check SNAC size for multipart
- *
- */
-faim_export int aim_im_sendch1_ext(aim_session_t *sess, struct aim_sendimext_args *args)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	fu8_t ck[8];
-	int i, msgtlvlen;
-	static const fu8_t deffeatures[] = { 0x01, 0x01, 0x01, 0x02 };
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
-		return -EINVAL;
-
-	if (!args)
-		return -EINVAL;
-
-	if (args->flags & AIM_IMFLAGS_MULTIPART) {
-		if (args->mpmsg->numparts <= 0)
-			return -EINVAL;
-	} else {
-		if (!args->msg || (args->msglen <= 0))
-			return -EINVAL;
-
-		if (args->msglen >= MAXMSGLEN)
-			return -E2BIG;
-	}
-
-	/* Painfully calculate the size of the message TLV */
-	msgtlvlen = 1 + 1; /* 0501 */
-
-	if (args->flags & AIM_IMFLAGS_CUSTOMFEATURES)
-		msgtlvlen += 2 + args->featureslen;
-	else
-		msgtlvlen += 2 + sizeof(deffeatures);
-
-	if (args->flags & AIM_IMFLAGS_MULTIPART) {
-		aim_mpmsg_section_t *sec;
-
-		for (sec = args->mpmsg->parts; sec; sec = sec->next) {
-			msgtlvlen += 2 /* 0101 */ + 2 /* block len */;
-			msgtlvlen += 4 /* charset */ + sec->datalen;
-		}
-
-	} else {
-		msgtlvlen += 2 /* 0101 */ + 2 /* block len */;
-		msgtlvlen += 4 /* charset */ + args->msglen;
-	}
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, msgtlvlen+128)))
-		return -ENOMEM;
-
-	/* XXX - should be optional */	
-	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, args->destsn, strlen(args->destsn)+1);
-	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
-
-	/* 
-	 * Generate a random message cookie
-	 *
-	 * We could cache these like we do SNAC IDs.  (In fact, it 
-	 * might be a good idea.)  In the message error functions, 
-	 * the 8byte message cookie is returned as well as the 
-	 * SNAC ID.
-	 *
-	 */
-	for (i = 0; i < 8; i++)
-		ck[i] = (fu8_t)rand();
-
-	/* ICBM header */
-	aim_im_puticbm(&fr->data, ck, 0x0001, args->destsn);
-
-	/* Message TLV (type 0x0002) */
-	aimbs_put16(&fr->data, 0x0002);
-	aimbs_put16(&fr->data, msgtlvlen);
-
-	/* Features TLV (type 0x0501) */
-	aimbs_put16(&fr->data, 0x0501);
-	if (args->flags & AIM_IMFLAGS_CUSTOMFEATURES) {
-		aimbs_put16(&fr->data, args->featureslen);
-		aimbs_putraw(&fr->data, args->features, args->featureslen);
-	} else {
-		aimbs_put16(&fr->data, sizeof(deffeatures));
-		aimbs_putraw(&fr->data, deffeatures, sizeof(deffeatures));
-	}
-
-	if (args->flags & AIM_IMFLAGS_MULTIPART) {
-		aim_mpmsg_section_t *sec;
-
-		/* Insert each message part in a TLV (type 0x0101) */
-		for (sec = args->mpmsg->parts; sec; sec = sec->next) {
-			aimbs_put16(&fr->data, 0x0101);
-			aimbs_put16(&fr->data, sec->datalen + 4);
-			aimbs_put16(&fr->data, sec->charset);
-			aimbs_put16(&fr->data, sec->charsubset);
-			aimbs_putraw(&fr->data, sec->data, sec->datalen);
-		}
-
-	} else {
-
-		/* Insert message text in a TLV (type 0x0101) */
-		aimbs_put16(&fr->data, 0x0101);
-
-		/* Message block length */
-		aimbs_put16(&fr->data, args->msglen + 0x04);
-
-		/* Character set */
-		aimbs_put16(&fr->data, args->charset);
-		aimbs_put16(&fr->data, args->charsubset);
-
-		/* Message.  Not terminated */
-		aimbs_putraw(&fr->data, args->msg, args->msglen);
-	}
-
-	/* Set the Autoresponse flag */
-	if (args->flags & AIM_IMFLAGS_AWAY) {
-		aimbs_put16(&fr->data, 0x0004);
-		aimbs_put16(&fr->data, 0x0000);
-	} else if (args->flags & AIM_IMFLAGS_ACK) {
-		/* Set the Request Acknowledge flag */
-		aimbs_put16(&fr->data, 0x0003);
-		aimbs_put16(&fr->data, 0x0000);
-	}
-
-	if (args->flags & AIM_IMFLAGS_OFFLINE) {
-		aimbs_put16(&fr->data, 0x0006);
-		aimbs_put16(&fr->data, 0x0000);
-	}
-
-	/*
-	 * Set the I HAVE A REALLY PURTY ICON flag.
-	 * XXX - This should really only be sent on initial 
-	 * IMs and when you change your icon.
-	 */
-	if (args->flags & AIM_IMFLAGS_HASICON) {
-		aimbs_put16(&fr->data, 0x0008);
-		aimbs_put16(&fr->data, 0x000c);
-		aimbs_put32(&fr->data, args->iconlen);
-		aimbs_put16(&fr->data, 0x0001);
-		aimbs_put16(&fr->data, args->iconsum);
-		aimbs_put32(&fr->data, args->iconstamp);
-	}
-
-	/*
-	 * Set the Buddy Icon Requested flag.
-	 * XXX - Everytime?  Surely not...
-	 */
-	if (args->flags & AIM_IMFLAGS_BUDDYREQ) {
-		aimbs_put16(&fr->data, 0x0009);
-		aimbs_put16(&fr->data, 0x0000);
-	}
-
-	aim_tx_enqueue(sess, fr);
-
-	/* clean out SNACs over 60sec old */
-	aim_cleansnacs(sess, 60);
-
-	return 0;
-}
-
-/*
- * Simple wrapper for aim_im_sendch1_ext() 
- *
- * You cannot use aim_send_im if you need the HASICON flag.  You must
- * use aim_im_sendch1_ext directly for that.
- *
- * aim_send_im also cannot be used if you require UNICODE messages, because
- * that requires an explicit message length.  Use aim_im_sendch1_ext().
- *
- */
-faim_export int aim_im_sendch1(aim_session_t *sess, const char *sn, fu16_t flags, const char *msg)
-{
-	struct aim_sendimext_args args;
-
-	args.destsn = sn;
-	args.flags = flags;
-	args.msg = msg;
-	args.msglen = strlen(msg);
-	args.charset = 0x0000;
-	args.charsubset = 0x0000;
-
-	/* Make these don't get set by accident -- they need aim_im_sendch1_ext */
-	args.flags &= ~(AIM_IMFLAGS_CUSTOMFEATURES | AIM_IMFLAGS_HASICON | AIM_IMFLAGS_MULTIPART);
-
-	return aim_im_sendch1_ext(sess, &args);
-}
-
-/**
- * Subtype 0x0006 - Send your icon to a given user.
- *
- * This is also performance sensitive. (If you can believe it...)
- *
- */
-faim_export int aim_im_sendch2_icon(aim_session_t *sess, const char *sn, const fu8_t *icon, int iconlen, time_t stamp, fu16_t iconsum)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	fu8_t ck[8];
-	int i;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
-		return -EINVAL;
-
-	if (!sn || !icon || (iconlen <= 0) || (iconlen >= MAXICONLEN))
-		return -EINVAL;
-
-	for (i = 0; i < 8; i++)
-		ck[i] = (fu8_t)rand();
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+2+1+strlen(sn)+2+2+2+8+16+2+2+2+2+2+2+2+4+4+4+iconlen+strlen(AIM_ICONIDENT)+2+2)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
-
-	/* ICBM header */
-	aim_im_puticbm(&fr->data, ck, 0x0002, sn);
-
-	/*
-	 * TLV t(0005)
-	 *
-	 * Encompasses everything below.
-	 */
-	aimbs_put16(&fr->data, 0x0005);
-	aimbs_put16(&fr->data, 2+8+16+6+4+4+iconlen+4+4+4+strlen(AIM_ICONIDENT));
-
-	aimbs_put16(&fr->data, 0x0000);
-	aimbs_putraw(&fr->data, ck, 8);
-	aim_putcap(&fr->data, AIM_CAPS_BUDDYICON);
-
-	/* TLV t(000a) */
-	aimbs_put16(&fr->data, 0x000a);
-	aimbs_put16(&fr->data, 0x0002);
-	aimbs_put16(&fr->data, 0x0001);
-
-	/* TLV t(000f) */
-	aimbs_put16(&fr->data, 0x000f);
-	aimbs_put16(&fr->data, 0x0000);
-
-	/* TLV t(2711) */
-	aimbs_put16(&fr->data, 0x2711);
-	aimbs_put16(&fr->data, 4+4+4+iconlen+strlen(AIM_ICONIDENT));
-	aimbs_put16(&fr->data, 0x0000);
-	aimbs_put16(&fr->data, iconsum);
-	aimbs_put32(&fr->data, iconlen);
-	aimbs_put32(&fr->data, stamp);
-	aimbs_putraw(&fr->data, icon, iconlen);
-	aimbs_putraw(&fr->data, AIM_ICONIDENT, strlen(AIM_ICONIDENT));
-
-	/* TLV t(0003) */
-	aimbs_put16(&fr->data, 0x0003);
-	aimbs_put16(&fr->data, 0x0000);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0006 - Send a rich text message.
- *
- * This only works for ICQ 2001b (thats 2001 not 2000).  Better, only
- * send it to clients advertising the RTF capability.  In fact, if you send
- * it to a client that doesn't support that capability, the server will gladly
- * bounce it back to you.
- *
- * You'd think this would be in icq.c, but, well, I'm trying to stick with
- * the one-group-per-file scheme as much as possible.  This could easily
- * be an exception, since Rendezvous IMs are external of the Oscar core, 
- * and therefore are undefined.  Really I just need to think of a good way to
- * make an interface similar to what AOL actually uses.  But I'm not using COM.
- *
- */
-faim_export int aim_im_sendch2_rtfmsg(aim_session_t *sess, struct aim_sendrtfmsg_args *args)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	fu8_t ck[8];
-	const char rtfcap[] = {"{97B12751-243C-4334-AD22-D6ABF73F1492}"}; /* AIM_CAPS_ICQRTF capability in string form */
-	int i, servdatalen;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
-		return -EINVAL;
-
-	if (!args || !args->destsn || !args->rtfmsg)
-		return -EINVAL;
-
-	servdatalen = 2+2+16+2+4+1+2  +  2+2+4+4+4  +  2+4+2+strlen(args->rtfmsg)+1  +  4+4+4+strlen(rtfcap)+1;
-
-	for (i = 0; i < 8; i++)
-		ck[i] = (fu8_t)rand();
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+128+servdatalen)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
-
-	/* ICBM header */
-	aim_im_puticbm(&fr->data, ck, 0x0002, args->destsn);
-
-	/* TLV t(0005) - Encompasses everything below. */
-	aimbs_put16(&fr->data, 0x0005);
-	aimbs_put16(&fr->data, 2+8+16  +  2+2+2  +  2+2  +  2+2+servdatalen);
-
-	aimbs_put16(&fr->data, 0x0000);
-	aimbs_putraw(&fr->data, ck, 8);
-	aim_putcap(&fr->data, AIM_CAPS_ICQSERVERRELAY);
-
-	/* t(000a) l(0002) v(0001) */
-	aimbs_put16(&fr->data, 0x000a);
-	aimbs_put16(&fr->data, 0x0002);
-	aimbs_put16(&fr->data, 0x0001);
-
-	/* t(000f) l(0000) v() */
-	aimbs_put16(&fr->data, 0x000f);
-	aimbs_put16(&fr->data, 0x0000);
-
-	/* Service Data TLV */
-	aimbs_put16(&fr->data, 0x2711);
-	aimbs_put16(&fr->data, servdatalen);
-
-	aimbs_putle16(&fr->data, 11 + 16 /* 11 + (sizeof CLSID) */);
-	aimbs_putle16(&fr->data, 9);
-	aim_putcap(&fr->data, AIM_CAPS_EMPTY);
-	aimbs_putle16(&fr->data, 0);
-	aimbs_putle32(&fr->data, 0);
-	aimbs_putle8(&fr->data, 0);
-	aimbs_putle16(&fr->data, 0x03ea); /* trid1 */
-
-	aimbs_putle16(&fr->data, 14);
-	aimbs_putle16(&fr->data, 0x03eb); /* trid2 */
-	aimbs_putle32(&fr->data, 0);
-	aimbs_putle32(&fr->data, 0);
-	aimbs_putle32(&fr->data, 0);
-
-	aimbs_putle16(&fr->data, 0x0001);
-	aimbs_putle32(&fr->data, 0);
-	aimbs_putle16(&fr->data, strlen(args->rtfmsg)+1);
-	aimbs_putraw(&fr->data, args->rtfmsg, strlen(args->rtfmsg)+1);
-
-	aimbs_putle32(&fr->data, args->fgcolor);
-	aimbs_putle32(&fr->data, args->bgcolor);
-	aimbs_putle32(&fr->data, strlen(rtfcap)+1);
-	aimbs_putraw(&fr->data, rtfcap, strlen(rtfcap)+1);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Subtype 0x0006 - Send an "I want to directly connect to you" message
- *
- */
-faim_export int aim_im_sendch2_odcrequest(aim_session_t *sess, fu8_t *cookie, const char *sn, const fu8_t *ip, fu16_t port)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	fu8_t ck[8];
-	aim_tlvlist_t *tl = NULL, *itl = NULL;
-	int hdrlen, i;
-	fu8_t *hdr;
-	aim_bstream_t hdrbs;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 256+strlen(sn))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
-
-	/* 
-	 * Generate a random message cookie 
-	 *
-	 * This cookie needs to be alphanumeric and NULL-terminated to be 
-	 * TOC-compatible.
-	 *
-	 * XXX - have I mentioned these should be generated in msgcookie.c?
-	 *
-	 */
-	for (i = 0; i < 7; i++)
-	       	ck[i] = 0x30 + ((fu8_t) rand() % 10);
-	ck[7] = '\0';
-
-	if (cookie)
-		memcpy(cookie, ck, 8);
-
-	/* ICBM header */
-	aim_im_puticbm(&fr->data, ck, 0x0002, sn);
-
-	aim_tlvlist_add_noval(&tl, 0x0003);
-
-	hdrlen = 2+8+16+6+8+6+4;
-	hdr = malloc(hdrlen);
-	aim_bstream_init(&hdrbs, hdr, hdrlen);
-
-	aimbs_put16(&hdrbs, 0x0000);
-	aimbs_putraw(&hdrbs, ck, 8);
-	aim_putcap(&hdrbs, AIM_CAPS_DIRECTIM);
-
-	aim_tlvlist_add_16(&itl, 0x000a, 0x0001);
-	aim_tlvlist_add_raw(&itl, 0x0003, 4, ip);
-	aim_tlvlist_add_16(&itl, 0x0005, port);
-	aim_tlvlist_add_noval(&itl, 0x000f);
-	
-	aim_tlvlist_write(&hdrbs, &itl);
-
-	aim_tlvlist_add_raw(&tl, 0x0005, aim_bstream_curpos(&hdrbs), hdr);
-
-	aim_tlvlist_write(&fr->data, &tl);
-
-	free(hdr);
-	aim_tlvlist_free(&itl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Subtype 0x0006 - Send an "I want to send you this file" message
- *
- */
-faim_export int aim_im_sendch2_sendfile_ask(aim_session_t *sess, struct aim_oft_info *oft_info)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl=NULL, *subtl=NULL;
-	int i;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)) || !oft_info)
-		return -EINVAL;
-
-	/* XXX - Should be like "21CBF95" and null terminated */
-	for (i = 0; i < 7; i++)
-		oft_info->cookie[i] = 0x30 + ((fu8_t)rand() % 10);
-	oft_info->cookie[7] = '\0';
-
-	{ /* Create the subTLV chain */
-		fu8_t *buf;
-		int buflen;
-		aim_bstream_t bs;
-
-		aim_tlvlist_add_16(&subtl, 0x000a, 0x0001);
-		aim_tlvlist_add_noval(&subtl, 0x000f);
-/*		aim_tlvlist_add_raw(&subtl, 0x000e, 2, "en");
-		aim_tlvlist_add_raw(&subtl, 0x000d, 8, "us-ascii");
-		aim_tlvlist_add_raw(&subtl, 0x000c, 24, "Please accept this file."); */
-		if (oft_info->clientip) {
-			fu8_t ip[4];
-			char *nexttoken;
-			int i = 0;
-			nexttoken = strtok(oft_info->clientip, ".");
-			while (nexttoken && i<4) {
-				ip[i] = atoi(nexttoken);
-				nexttoken = strtok(NULL, ".");
-				i++;
-			}
-			aim_tlvlist_add_raw(&subtl, 0x0003, 4, ip);
-		}
-		aim_tlvlist_add_16(&subtl, 0x0005, oft_info->port);
-
-		/* TLV t(2711) */
-		buflen = 2+2+4+strlen(oft_info->fh.name)+1;
-		buf = malloc(buflen);
-		aim_bstream_init(&bs, buf, buflen);
-		aimbs_put16(&bs, (oft_info->fh.totfiles > 1) ? 0x0002 : 0x0001);
-		aimbs_put16(&bs, oft_info->fh.totfiles);
-		aimbs_put32(&bs, oft_info->fh.totsize);
-
-		/* Filename - NULL terminated, for some odd reason */
-		aimbs_putraw(&bs, oft_info->fh.name, strlen(oft_info->fh.name));
-		aimbs_put8(&bs, 0x00);
-
-		aim_tlvlist_add_raw(&subtl, 0x2711, bs.len, bs.data);
-		free(buf);
-	}
-
-	{ /* Create the main TLV chain */
-		fu8_t *buf;
-		int buflen;
-		aim_bstream_t bs;
-
-		/* TLV t(0005) - Encompasses everything from above. Gee. */
-		buflen = 2+8+16+aim_tlvlist_size(&subtl);
-		buf = malloc(buflen);
-		aim_bstream_init(&bs, buf, buflen);
-		aimbs_put16(&bs, AIM_RENDEZVOUS_PROPOSE);
-		aimbs_putraw(&bs, oft_info->cookie, 8);
-		aim_putcap(&bs, AIM_CAPS_SENDFILE);
-		aim_tlvlist_write(&bs, &subtl);
-		aim_tlvlist_free(&subtl);
-		aim_tlvlist_add_raw(&tl, 0x0005, bs.len, bs.data);
-		free(buf);
-
-		/* TLV t(0003) - Request an ack */
-		aim_tlvlist_add_noval(&tl, 0x0003);
-	}
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 11+strlen(oft_info->sn) + aim_tlvlist_size(&tl))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0006, AIM_SNACFLAGS_DESTRUCTOR, oft_info->cookie, sizeof(oft_info->cookie));
-	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
-
-	/* ICBM header */
-	aim_im_puticbm(&fr->data, oft_info->cookie, 0x0002, oft_info->sn);
-
-	/* All that crap from above (the 0x0005 TLV and the 0x0003 TLV) */
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Subtype 0x0006 - Send an "I will accept this file" message?
- *
- * @param rendid Capability type (AIM_CAPS_GETFILE or AIM_CAPS_SENDFILE)
- */
-faim_export int aim_im_sendch2_sendfile_accept(aim_session_t *sess, struct aim_oft_info *oft_info)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)) || !oft_info)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 11+strlen(oft_info->sn) + 4+2+8+16)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
-
-	/* ICBM header */
-	aim_im_puticbm(&fr->data, oft_info->cookie, 0x0002, oft_info->sn);
-
-	aimbs_put16(&fr->data, 0x0005);
-	aimbs_put16(&fr->data, 0x001a);
-	aimbs_put16(&fr->data, AIM_RENDEZVOUS_ACCEPT);
-	aimbs_putraw(&fr->data, oft_info->cookie, 8);
-	aim_putcap(&fr->data, AIM_CAPS_SENDFILE);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Subtype 0x0006 - Send a "cancel this file transfer" message?
- *
- */
-faim_export int aim_im_sendch2_sendfile_cancel(aim_session_t *sess, struct aim_oft_info *oft_info)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)) || !oft_info)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 11+strlen(oft_info->sn) + 4+2+8+16)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
-
-	/* ICBM header */
-	aim_im_puticbm(&fr->data, oft_info->cookie, 0x0002, oft_info->sn);
-
-	aimbs_put16(&fr->data, 0x0005);
-	aimbs_put16(&fr->data, 0x001a);
-	aimbs_put16(&fr->data, AIM_RENDEZVOUS_CANCEL);
-	aimbs_putraw(&fr->data, oft_info->cookie, 8);
-	aim_putcap(&fr->data, AIM_CAPS_SENDFILE);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Subtype 0x0006 - Request the status message of the given ICQ user.
- *
- * @param sess The oscar session.
- * @param sn The UIN of the user of whom you wish to request info.
- * @param type The type of info you wish to request.  This should be the current 
- *        state of the user, as one of the AIM_ICQ_STATE_* defines.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_im_sendch2_geticqaway(aim_session_t *sess, const char *sn, int type)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int i;
-	fu8_t ck[8];
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)) || !sn)
-		return -EINVAL;
-
-	for (i = 0; i < 8; i++)
-		ck[i] = (fu8_t)rand();
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+2+1+strlen(sn) + 4+0x5e + 4)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
-
-	/* ICBM header */
-	aim_im_puticbm(&fr->data, ck, 0x0002, sn);
-
-	/* TLV t(0005) - Encompasses almost everything below. */
-	aimbs_put16(&fr->data, 0x0005); /* T */
-	aimbs_put16(&fr->data, 0x005e); /* L */
-	{ /* V */
-		aimbs_put16(&fr->data, 0x0000);
-
-		/* Cookie */
-		aimbs_putraw(&fr->data, ck, 8);
-
-		/* Put the 16 byte server relay capability */
-		aim_putcap(&fr->data, AIM_CAPS_ICQSERVERRELAY);
-
-		/* TLV t(000a) */
-		aimbs_put16(&fr->data, 0x000a);
-		aimbs_put16(&fr->data, 0x0002);
-		aimbs_put16(&fr->data, 0x0001);
-
-		/* TLV t(000f) */
-		aimbs_put16(&fr->data, 0x000f);
-		aimbs_put16(&fr->data, 0x0000);
-
-		/* TLV t(2711) */
-		aimbs_put16(&fr->data, 0x2711);
-		aimbs_put16(&fr->data, 0x0036);
-		{ /* V */
-			aimbs_putle16(&fr->data, 0x001b); /* L */
-			aimbs_putle16(&fr->data, 0x0008); /* XXX - Protocol version */
-			aim_putcap(&fr->data, AIM_CAPS_EMPTY);
-			aimbs_putle16(&fr->data, 0x0000); /* Unknown */
-			aimbs_putle16(&fr->data, 0x0003); /* Client features? */
-			aimbs_putle16(&fr->data, 0x0000); /* Unknown */
-			aimbs_putle8(&fr->data, 0x00); /* Unkizown */
-			aimbs_putle16(&fr->data, 0xffff); /* Sequence number?  XXX - This should decrement by 1 with each request */
-
-			aimbs_putle16(&fr->data, 0x000e); /* L */
-			aimbs_putle16(&fr->data, 0xffff); /* Sequence number?  XXX - This should decrement by 1 with each request */
-			aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
-			aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
-			aimbs_putle32(&fr->data, 0x00000000); /* Unknown */
-
-			/* The type of status message being requested */
-			if (type & AIM_ICQ_STATE_CHAT)
-				aimbs_putle16(&fr->data, 0x03ec);
-			else if(type & AIM_ICQ_STATE_DND)
-				aimbs_putle16(&fr->data, 0x03eb);
-			else if(type & AIM_ICQ_STATE_OUT)
-				aimbs_putle16(&fr->data, 0x03ea);
-			else if(type & AIM_ICQ_STATE_BUSY)
-				aimbs_putle16(&fr->data, 0x03e9);
-			else if(type & AIM_ICQ_STATE_AWAY)
-				aimbs_putle16(&fr->data, 0x03e8);
-
-			aimbs_putle16(&fr->data, 0x0000); /* Status? */
-			aimbs_putle16(&fr->data, 0x0001); /* Priority of this message? */
-			aimbs_putle16(&fr->data, 0x0001); /* L */
-			aimbs_putle8(&fr->data, 0x00); /* String of length L */
-		} /* End TLV t(2711) */
-	} /* End TLV t(0005) */
-
-	/* TLV t(0003) */
-	aimbs_put16(&fr->data, 0x0003);
-	aimbs_put16(&fr->data, 0x0000);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/**
- * Subtype 0x0006 - Send an ICQ-esque ICBM.
- *
- * This can be used to send an ICQ authorization reply (deny or grant).  It is the "old way."  
- * The new way is to use SSI.  I like the new way a lot better.  This seems like such a hack, 
- * mostly because it's in network byte order.  Figuring this stuff out sometimes takes a while, 
- * but thats ok, because it gives me time to try to figure out what kind of drugs the AOL people 
- * were taking when they merged the two protocols.
- *
- * @param sn The destination screen name.
- * @param type The type of message.  0x0007 for authorization denied.  0x0008 for authorization granted.
- * @param message The message you want to send, it should be null terminated.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_im_sendch4(aim_session_t *sess, char *sn, fu16_t type, fu8_t *message)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int i;
-	char ck[8];
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0002)))
-		return -EINVAL;
-
-	if (!sn || !type || !message)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+3+strlen(sn)+12+strlen(message)+1+4)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0006, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0004, 0x0006, 0x0000, snacid);
-
-	/* Cookie */
-	for (i=0; i<8; i++)
-		ck[i] = (fu8_t)rand();
-
-	/* ICBM header */
-	aim_im_puticbm(&fr->data, ck, 0x0004, sn);
-
-	/*
-	 * TLV t(0005)
-	 *
-	 * ICQ data (the UIN and the message).
-	 */
-	aimbs_put16(&fr->data, 0x0005);
-	aimbs_put16(&fr->data, 4 + 2+2+strlen(message)+1);
-
-	/*
-	 * Your UIN
-	 */
-	aimbs_putle32(&fr->data, atoi(sess->sn));
-
-	/*
-	 * TLV t(type) l(strlen(message)+1) v(message+NULL)
-	 */
-	aimbs_putle16(&fr->data, type);
-	aimbs_putle16(&fr->data, strlen(message)+1);
-	aimbs_putraw(&fr->data, message, strlen(message)+1);
-
-	/*
-	 * TLV t(0006) l(0000) v()
-	 */
-	aimbs_put16(&fr->data, 0x0006);
-	aimbs_put16(&fr->data, 0x0000);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * XXX - I don't see when this would ever get called...
- */
-static int outgoingim(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int i, ret = 0;
-	aim_rxcallback_t userfunc;
-	fu8_t cookie[8];
-	fu16_t channel;
-	aim_tlvlist_t *tlvlist;
-	char *sn;
-	int snlen;
-	fu16_t icbmflags = 0;
-	fu8_t flag1 = 0, flag2 = 0;
-	fu8_t *msg = NULL;
-	aim_tlv_t *msgblock;
-
-	/* ICBM Cookie. */
-	for (i = 0; i < 8; i++)
-		cookie[i] = aimbs_get8(bs);
-
-	/* Channel ID */
-	channel = aimbs_get16(bs);
-
-	if (channel != 0x01) {
-		faimdprintf(sess, 0, "icbm: ICBM recieved on unsupported channel.  Ignoring. (chan = %04x)\n", channel);
-		return 0;
-	}
-
-	snlen = aimbs_get8(bs);
-	sn = aimbs_getstr(bs, snlen);
-
-	tlvlist = aim_tlvlist_read(bs);
-
-	if (aim_tlv_gettlv(tlvlist, 0x0003, 1))
-		icbmflags |= AIM_IMFLAGS_ACK;
-	if (aim_tlv_gettlv(tlvlist, 0x0004, 1))
-		icbmflags |= AIM_IMFLAGS_AWAY;
-
-	if ((msgblock = aim_tlv_gettlv(tlvlist, 0x0002, 1))) {
-		aim_bstream_t mbs;
-		int featurelen, msglen;
-
-		aim_bstream_init(&mbs, msgblock->value, msgblock->length);
-
-		aimbs_get8(&mbs);
-		aimbs_get8(&mbs);
-		for (featurelen = aimbs_get16(&mbs); featurelen; featurelen--)
-			aimbs_get8(&mbs);
-		aimbs_get8(&mbs);
-		aimbs_get8(&mbs);
-
-		msglen = aimbs_get16(&mbs) - 4; /* final block length */
-
-		flag1 = aimbs_get16(&mbs);
-		flag2 = aimbs_get16(&mbs);
-
-		msg = aimbs_getstr(&mbs, msglen);
-	}
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, channel, sn, msg, icbmflags, flag1, flag2);
-
-	free(sn);
-	aim_tlvlist_free(&tlvlist);
-
-	return ret;
-}
-
-/*
- * Ahh, the joys of nearly ridiculous over-engineering.
- *
- * Not only do AIM ICBM's support multiple channels.  Not only do they
- * support multiple character sets.  But they support multiple character 
- * sets / encodings within the same ICBM.
- *
- * These multipart messages allow for complex space savings techniques, which
- * seem utterly unnecessary by today's standards.  In fact, there is only
- * one client still in popular use that still uses this method: AOL for the
- * Macintosh, Version 5.0.  Obscure, yes, I know.  
- *
- * In modern (non-"legacy") clients, if the user tries to send a character
- * that is not ISO-8859-1 or ASCII, the client will send the entire message
- * as UNICODE, meaning that every character in the message will occupy the
- * full 16 bit UNICODE field, even if the high order byte would be zero.
- * Multipart messages prevent this wasted space by allowing the client to
- * only send the characters in UNICODE that need to be sent that way, and
- * the rest of the message can be sent in whatever the native character 
- * set is (probably ASCII).
- *
- * An important note is that sections will be displayed in the order that
- * they appear in the ICBM.  There is no facility for merging or rearranging
- * sections at run time.  So if you have, say, ASCII then UNICODE then ASCII,
- * you must supply two ASCII sections with a UNICODE in the middle, and incur
- * the associated overhead.
- *
- * Normally I would have laughed and given a firm 'no' to supporting this
- * seldom-used feature, but something is attracting me to it.  In the future,
- * it may be possible to abuse this to send mixed-media messages to other
- * open source clients (like encryption or something) -- see faimtest for
- * examples of how to do this.
- *
- * I would definitly recommend avoiding this feature unless you really
- * know what you are doing, and/or you have something neat to do with it.
- *
- */
-faim_export int aim_mpmsg_init(aim_session_t *sess, aim_mpmsg_t *mpm)
-{
-
-	memset(mpm, 0, sizeof(aim_mpmsg_t));
-
-	return 0;
-}
-
-static int mpmsg_addsection(aim_session_t *sess, aim_mpmsg_t *mpm, fu16_t charset, fu16_t charsubset, fu8_t *data, fu16_t datalen)
-{
-	aim_mpmsg_section_t *sec; 
-	
-	if (!(sec = malloc(sizeof(aim_mpmsg_section_t))))
-		return -1;
-
-	sec->charset = charset;
-	sec->charsubset = charsubset;
-	sec->data = data;
-	sec->datalen = datalen;
-	sec->next = NULL;
-
-	if (!mpm->parts)
-		mpm->parts = sec;
-	else {
-		aim_mpmsg_section_t *cur;
-
-		for (cur = mpm->parts; cur->next; cur = cur->next)
-			;
-		cur->next = sec;
-	}
-
-	mpm->numparts++;
-
-	return 0;
-}
-
-faim_export int aim_mpmsg_addraw(aim_session_t *sess, aim_mpmsg_t *mpm, fu16_t charset, fu16_t charsubset, const fu8_t *data, fu16_t datalen)
-{
-	fu8_t *dup;
-
-	if (!(dup = malloc(datalen)))
-		return -1;
-	memcpy(dup, data, datalen);
-
-	if (mpmsg_addsection(sess, mpm, charset, charsubset, dup, datalen) == -1) {
-		free(dup);
-		return -1;
-	}
-
-	return 0;
-}
-
-/* XXX - should provide a way of saying ISO-8859-1 specifically */
-faim_export int aim_mpmsg_addascii(aim_session_t *sess, aim_mpmsg_t *mpm, const char *ascii)
-{
-	fu8_t *dup;
-
-	if (!(dup = strdup(ascii))) 
-		return -1;
-
-	if (mpmsg_addsection(sess, mpm, 0x0000, 0x0000, dup, strlen(ascii)) == -1) {
-		free(dup);
-		return -1;
-	}
-
-	return 0;
-}
-
-faim_export int aim_mpmsg_addunicode(aim_session_t *sess, aim_mpmsg_t *mpm, const fu16_t *unicode, fu16_t unicodelen)
-{
-	fu8_t *buf;
-	aim_bstream_t bs;
-	int i;
-
-	if (!(buf = malloc(unicodelen * 2)))
-		return -1;
-
-	aim_bstream_init(&bs, buf, unicodelen * 2);
-
-	/* We assume unicode is in /host/ byte order -- convert to network */
-	for (i = 0; i < unicodelen; i++)
-		aimbs_put16(&bs, unicode[i]);
-
-	if (mpmsg_addsection(sess, mpm, 0x0002, 0x0000, buf, aim_bstream_curpos(&bs)) == -1) {
-		free(buf);
-		return -1;
-	}
-	
-	return 0;
-}
-
-faim_export void aim_mpmsg_free(aim_session_t *sess, aim_mpmsg_t *mpm)
-{
-	aim_mpmsg_section_t *cur;
-
-	for (cur = mpm->parts; cur; ) {
-		aim_mpmsg_section_t *tmp;
-		
-		tmp = cur->next;
-		free(cur->data);
-		free(cur);
-		cur = tmp;
-	}
-	
-	mpm->numparts = 0;
-	mpm->parts = NULL;
-
-	return;
-}
-
-/*
- * Start by building the multipart structures, then pick the first 
- * human-readable section and stuff it into args->msg so no one gets
- * suspicious.
- *
- */
-static int incomingim_ch1_parsemsgs(aim_session_t *sess, fu8_t *data, int len, struct aim_incomingim_ch1_args *args)
-{
-	static const fu16_t charsetpri[] = {
-		0x0000, /* ASCII first */
-		0x0003, /* then ISO-8859-1 */
-		0x0002, /* UNICODE as last resort */
-	};
-	static const int charsetpricount = 3;
-	int i;
-	aim_bstream_t mbs;
-	aim_mpmsg_section_t *sec;
-
-	aim_bstream_init(&mbs, data, len);
-
-	while (aim_bstream_empty(&mbs)) {
-		fu16_t msglen, flag1, flag2;
-		fu8_t *msgbuf;
-
-		aimbs_get8(&mbs); /* 01 */
-		aimbs_get8(&mbs); /* 01 */
-
-		/* Message string length, including character set info. */
-		msglen = aimbs_get16(&mbs);
-
-		/* Character set info */
-		flag1 = aimbs_get16(&mbs);
-		flag2 = aimbs_get16(&mbs);
-
-		/* Message. */
-		msglen -= 4;
-
-		/*
-		 * For now, we don't care what the encoding is.  Just copy
-		 * it into a multipart struct and deal with it later. However,
-		 * always pad the ending with a NULL.  This makes it easier
-		 * to treat ASCII sections as strings.  It won't matter for
-		 * UNICODE or binary data, as you should never read past
-		 * the specified data length, which will not include the pad.
-		 *
-		 * XXX - There's an API bug here.  For sending, the UNICODE is
-		 * given in host byte order (aim_mpmsg_addunicode), but here
-		 * the received messages are given in network byte order.
-		 *
-		 */
-		msgbuf = aimbs_getstr(&mbs, msglen);
-		mpmsg_addsection(sess, &args->mpmsg, flag1, flag2, msgbuf, msglen);
-
-	} /* while */
-
-	args->icbmflags |= AIM_IMFLAGS_MULTIPART; /* always set */
-
-	/*
-	 * Clients that support multiparts should never use args->msg, as it
-	 * will point to an arbitrary section.
-	 *
-	 * Here, we attempt to provide clients that do not support multipart
-	 * messages with something to look at -- hopefully a human-readable
-	 * string.  But, failing that, a UNICODE message, or nothing at all.
-	 *
-	 * Which means that even if args->msg is NULL, it does not mean the
-	 * message was blank.
-	 *
-	 */
-	for (i = 0; i < charsetpricount; i++) {
-		for (sec = args->mpmsg.parts; sec; sec = sec->next) {
-
-			if (sec->charset != charsetpri[i])
-				continue;
-
-			/* Great. We found one.  Fill it in. */
-			args->charset = sec->charset;
-			args->charsubset = sec->charsubset;
-
-			/* Set up the simple flags */
-			if (args->charset == 0x0000)
-				; /* ASCII */
-			else if (args->charset == 0x0002)
-				args->icbmflags |= AIM_IMFLAGS_UNICODE;
-			else if (args->charset == 0x0003)
-				args->icbmflags |= AIM_IMFLAGS_ISO_8859_1;
-			else if (args->charset == 0xffff)
-				; /* no encoding (yeep!) */
-
-			if (args->charsubset == 0x0000)
-				; /* standard subencoding? */
-			else if (args->charsubset == 0x000b)
-				args->icbmflags |= AIM_IMFLAGS_SUBENC_MACINTOSH;
-			else if (args->charsubset == 0xffff)
-				; /* no subencoding */
-
-			args->msg = sec->data;
-			args->msglen = sec->datalen;
-
-			return 0;
-		}
-	}
-
-	/* No human-readable sections found.  Oh well. */
-	args->charset = args->charsubset = 0xffff;
-	args->msg = NULL;
-	args->msglen = 0;
-
-	return 0;
-}
-
-static int incomingim_ch1(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, fu16_t channel, aim_userinfo_t *userinfo, aim_bstream_t *bs, fu8_t *cookie)
-{
-	fu16_t type, length;
-	aim_rxcallback_t userfunc;
-	int ret = 0;
-	struct aim_incomingim_ch1_args args;
-	int endpos;
-
-	memset(&args, 0, sizeof(args));
-
-	aim_mpmsg_init(sess, &args.mpmsg);
-
-	/*
-	 * This used to be done using tlvchains.  For performance reasons,
-	 * I've changed it to process the TLVs in-place.  This avoids lots
-	 * of per-IM memory allocations.
-	 */
-	while (aim_bstream_empty(bs)) {
-
-		type = aimbs_get16(bs);
-		length = aimbs_get16(bs);
-
-		endpos = aim_bstream_curpos(bs) + length;
-
-		if (type == 0x0002) { /* Message Block */
-
-			/*
-			 * This TLV consists of the following:
-			 *   - 0501 -- Unknown
-			 *   - Features: Don't know how to interpret these
-			 *   - 0101 -- Unknown
-			 *   - Message
-			 *
-			 */
-
-			aimbs_get8(bs); /* 05 */
-			aimbs_get8(bs); /* 01 */
-
-			args.featureslen = aimbs_get16(bs);
-			/* XXX XXX this is all evil! */
-			args.features = bs->data + bs->offset;
-			aim_bstream_advance(bs, args.featureslen);
-			args.icbmflags |= AIM_IMFLAGS_CUSTOMFEATURES;
-
-			/*
-			 * The rest of the TLV contains one or more message
-			 * blocks...
-			 */
-			incomingim_ch1_parsemsgs(sess, bs->data + bs->offset /* XXX evil!!! */, length - 2 - 2 - args.featureslen, &args);
-
-		} else if (type == 0x0003) { /* Server Ack Requested */
-
-			args.icbmflags |= AIM_IMFLAGS_ACK;
-
-		} else if (type == 0x0004) { /* Message is Auto Response */
-
-			args.icbmflags |= AIM_IMFLAGS_AWAY;
-
-		} else if (type == 0x0006) { /* Message was received offline. */
-
-			/* XXX - not sure if this actually gets sent. */
-			args.icbmflags |= AIM_IMFLAGS_OFFLINE;
-
-		} else if (type == 0x0008) { /* I-HAVE-A-REALLY-PURTY-ICON Flag */
-
-			args.iconlen = aimbs_get32(bs);
-			aimbs_get16(bs); /* 0x0001 */
-			args.iconsum = aimbs_get16(bs);
-			args.iconstamp = aimbs_get32(bs);
-
-			/*
-			 * This looks to be a client bug.  MacAIM 4.3 will
-			 * send this tag, but with all zero values, in the
-			 * first message of a conversation. This makes no
-			 * sense whatsoever, so I'm going to say its a bug.
-			 *
-			 * You really shouldn't advertise a zero-length icon
-			 * anyway.
-			 * 
-			 */
-			if (args.iconlen)
-				args.icbmflags |= AIM_IMFLAGS_HASICON;
-
-		} else if (type == 0x0009) {
-
-			args.icbmflags |= AIM_IMFLAGS_BUDDYREQ;
-
-		} else if (type == 0x000b) { /* Non-direct connect typing notification */
-
-			args.icbmflags |= AIM_IMFLAGS_TYPINGNOT;
-
-		} else if (type == 0x0017) {
-
-			args.extdatalen = length;
-			args.extdata = aimbs_getraw(bs, args.extdatalen);
-
-		} else {
-			faimdprintf(sess, 0, "incomingim_ch1: unknown TLV 0x%04x (len %d)\n", type, length);
-		}
-
-		/*
-		 * This is here to protect ourselves from ourselves.  That
-		 * is, if something above doesn't completly parse its value
-		 * section, or, worse, overparses it, this will set the
-		 * stream where it needs to be in order to land on the next
-		 * TLV when the loop continues.
-		 *
-		 */
-		aim_bstream_setpos(bs, endpos);
-	}
-
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, channel, userinfo, &args);
-
-	aim_mpmsg_free(sess, &args.mpmsg);
-	free(args.extdata);
-
-	return ret;
-}
-
-static void incomingim_ch2_buddylist(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args, aim_bstream_t *servdata)
-{
-
-	/*
-	 * This goes like this...
-	 *
-	 *   group name length
-	 *   group name
-	 *     num of buddies in group
-	 *     buddy name length
-	 *     buddy name
-	 *     buddy name length
-	 *     buddy name
-	 *     ...
-	 *   group name length
-	 *   group name
-	 *     num of buddies in group
-	 *     buddy name length
-	 *     buddy name
-	 *     ...
-	 *   ...
-	 */
-	while (servdata && aim_bstream_empty(servdata)) {
-		fu16_t gnlen, numb;
-		int i;
-		char *gn;
-
-		gnlen = aimbs_get16(servdata);
-		gn = aimbs_getstr(servdata, gnlen);
-		numb = aimbs_get16(servdata);
-
-		for (i = 0; i < numb; i++) {
-			fu16_t bnlen;
-			char *bn;
-
-			bnlen = aimbs_get16(servdata);
-			bn = aimbs_getstr(servdata, bnlen);
-
-			faimdprintf(sess, 0, "got a buddy list from %s: group %s, buddy %s\n", userinfo->sn, gn, bn);
-
-			free(bn);
-		}
-
-		free(gn);
-	}
-
-	return;
-}
-
-static void incomingim_ch2_buddyicon_free(aim_session_t *sess, struct aim_incomingim_ch2_args *args)
-{
-
-	free(args->info.icon.icon);
-
-	return;
-}
-
-static void incomingim_ch2_buddyicon(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args, aim_bstream_t *servdata)
-{
-
-	if (servdata) {
-		args->info.icon.checksum = aimbs_get32(servdata);
-		args->info.icon.length = aimbs_get32(servdata);
-		args->info.icon.timestamp = aimbs_get32(servdata);
-		args->info.icon.icon = aimbs_getraw(servdata, args->info.icon.length);
-	}
-
-	args->destructor = (void *)incomingim_ch2_buddyicon_free;
-
-	return;
-}
-
-static void incomingim_ch2_chat_free(aim_session_t *sess, struct aim_incomingim_ch2_args *args)
-{
-
-	/* XXX - aim_chat_roominfo_free() */
-	free(args->info.chat.roominfo.name);
-
-	return;
-}
-
-static void incomingim_ch2_chat(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args, aim_bstream_t *servdata)
-{
-
-	/*
-	 * Chat room info.
-	 */
-	if (servdata)
-		aim_chat_readroominfo(servdata, &args->info.chat.roominfo);
-
-	args->destructor = (void *)incomingim_ch2_chat_free;
-
-	return;
-}
-
-static void incomingim_ch2_icqserverrelay_free(aim_session_t *sess, struct aim_incomingim_ch2_args *args)
-{
-
-	free((char *)args->info.rtfmsg.rtfmsg);
-
-	return;
-}
-
-/*
- * The relationship between AIM_CAPS_ICQSERVERRELAY and AIM_CAPS_ICQRTF is 
- * kind of odd. This sends the client ICQRTF since that is all that I've seen
- * SERVERRELAY used for.
- *
- * Note that this is all little-endian.  Cringe.
- *
- */
-static void incomingim_ch2_icqserverrelay(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args, aim_bstream_t *servdata)
-{
-	fu16_t hdrlen, anslen, msglen;
-	fu16_t msgtype;
-
-	hdrlen = aimbs_getle16(servdata);
-	aim_bstream_advance(servdata, hdrlen);
-
-	hdrlen = aimbs_getle16(servdata);
-	aim_bstream_advance(servdata, hdrlen);
-
-	msgtype = aimbs_getle16(servdata);
-	
-	anslen = aimbs_getle32(servdata);
-	aim_bstream_advance(servdata, anslen);
-
-	msglen = aimbs_getle16(servdata);
-	args->info.rtfmsg.rtfmsg = aimbs_getstr(servdata, msglen);
-
-	args->info.rtfmsg.fgcolor = aimbs_getle32(servdata);
-	args->info.rtfmsg.bgcolor = aimbs_getle32(servdata);
-
-	hdrlen = aimbs_getle32(servdata);
-	aim_bstream_advance(servdata, hdrlen);
-
-	/* XXX - This is such a hack. */
-	args->reqclass = AIM_CAPS_ICQRTF;
-
-	args->destructor = (void *)incomingim_ch2_icqserverrelay_free;
-
-	return;
-}
-
-static void incomingim_ch2_sendfile_free(aim_session_t *sess, struct aim_incomingim_ch2_args *args)
-{
-	free(args->info.sendfile.filename);
-}
-
-static void incomingim_ch2_sendfile(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args, aim_bstream_t *servdata)
-{
-
-	args->destructor = (void *)incomingim_ch2_sendfile_free;
-
-	/* Maybe there is a better way to tell what kind of sendfile 
-	 * this is?  Maybe TLV t(000a)? */
-	if (servdata) { /* Someone is sending us a file */
-		int flen;
-
-		/* subtype is one of AIM_OFT_SUBTYPE_* */
-		args->info.sendfile.subtype = aimbs_get16(servdata);
-		args->info.sendfile.totfiles = aimbs_get16(servdata);
-		args->info.sendfile.totsize = aimbs_get32(servdata);
-
-		/*
-		 * I hope to God I'm right when I guess that there is a 
-		 * 32 char max filename length for single files.  I think 
-		 * OFT tends to do that.  Gotta love inconsistency.  I saw 
-		 * a 26 byte filename?
-		 */
-		/* AAA - create an aimbs_getnullstr function (don't anymore)(maybe) */
-		/* Use an inelegant way of getting the null-terminated filename, 
-		 * since there's no easy bstream routine. */
-		for (flen = 0; aimbs_get8(servdata); flen++);
-		aim_bstream_advance(servdata, -flen -1);
-		args->info.sendfile.filename = aimbs_getstr(servdata, flen);
-
-		/* There is sometimes more after the null-terminated filename, 
-		 * but I'm unsure of its format. */
-		/* I don't believe him. */
-	}
-
-	return;
-}
-
-typedef void (*ch2_args_destructor_t)(aim_session_t *sess, struct aim_incomingim_ch2_args *args);
-
-static int incomingim_ch2(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, fu16_t channel, aim_userinfo_t *userinfo, aim_tlvlist_t *tlvlist, fu8_t *cookie)
-{
-	aim_rxcallback_t userfunc;
-	aim_tlv_t *block1, *servdatatlv;
-	aim_tlvlist_t *list2;
-	struct aim_incomingim_ch2_args args;
-	aim_bstream_t bbs, sdbs, *sdbsptr = NULL;
-	fu8_t *cookie2;
-	int ret = 0;
-
-	char proxyip[30] = {""};
-	char clientip[30] = {""};
-	char verifiedip[30] = {""};
-
-	memset(&args, 0, sizeof(args));
-
-	/*
-	 * There's another block of TLVs embedded in the type 5 here. 
-	 */
-	block1 = aim_tlv_gettlv(tlvlist, 0x0005, 1);
-	aim_bstream_init(&bbs, block1->value, block1->length);
-
-	/*
-	 * First two bytes represent the status of the connection.
-	 *
-	 * 0 is a request, 1 is a cancel, 2 is an accept
-	 */ 
-	args.status = aimbs_get16(&bbs);
-
-	/*
-	 * Next comes the cookie.  Should match the ICBM cookie.
-	 */
-	cookie2 = aimbs_getraw(&bbs, 8);
-	if (memcmp(cookie, cookie2, 8) != 0) 
-		faimdprintf(sess, 0, "rend: warning cookies don't match!\n");
-	memcpy(args.cookie, cookie2, 8);
-	free(cookie2);
-
-	/*
-	 * The next 16bytes are a capability block so we can
-	 * identify what type of rendezvous this is.
-	 */
-	args.reqclass = aim_locate_getcaps(sess, &bbs, 0x10);
-
-	/* 
-	 * What follows may be TLVs or nothing, depending on the
-	 * purpose of the message.
-	 *
-	 * Ack packets for instance have nothing more to them.
-	 */
-	list2 = aim_tlvlist_read(&bbs);
-
-	/*
-	 * IP address to proxy the file transfer through.
-	 *
-	 * XXX - I don't like this.  Maybe just read in an int?  Or inet_ntoa...
-	 */
-	if (aim_tlv_gettlv(list2, 0x0002, 1)) {
-		aim_tlv_t *iptlv;
-
-		iptlv = aim_tlv_gettlv(list2, 0x0002, 1);
-		if (iptlv->length == 4)
-			snprintf(proxyip, sizeof(proxyip), "%hhu.%hhu.%hhu.%hhu",
-				iptlv->value[0], iptlv->value[1],
-				iptlv->value[2], iptlv->value[3]);
-	}
-
-	/*
-	 * IP address from the perspective of the client.
-	 */
-	if (aim_tlv_gettlv(list2, 0x0003, 1)) {
-		aim_tlv_t *iptlv;
-
-		iptlv = aim_tlv_gettlv(list2, 0x0003, 1);
-		if (iptlv->length == 4)
-			snprintf(clientip, sizeof(clientip), "%hhu.%hhu.%hhu.%hhu",
-				iptlv->value[0], iptlv->value[1],
-				iptlv->value[2], iptlv->value[3]);
-	}
-
-	/*
-	 * Verified IP address (from the perspective of Oscar).
-	 *
-	 * This is added by the server.
-	 */
-	if (aim_tlv_gettlv(list2, 0x0004, 1)) {
-		aim_tlv_t *iptlv;
-
-		iptlv = aim_tlv_gettlv(list2, 0x0004, 1);
-		if (iptlv->length == 4)
-			snprintf(verifiedip, sizeof(verifiedip), "%hhu.%hhu.%hhu.%hhu",
-				iptlv->value[0], iptlv->value[1],
-				iptlv->value[2], iptlv->value[3]);
-	}
-
-	/*
-	 * Port number for something.
-	 */
-	if (aim_tlv_gettlv(list2, 0x0005, 1))
-		args.port = aim_tlv_get16(list2, 0x0005, 1);
-
-	/*
-	 * Something to do with ft -- two bytes
-	 * 0x0001 - "I want to send you this file"
-	 * 0x0002 - "I will accept this file from you"
-	 */
-	if (aim_tlv_gettlv(list2, 0x000a, 1))
-		;
-
-	/*
-	 * Error code.
-	 */
-	if (aim_tlv_gettlv(list2, 0x000b, 1))
-		args.errorcode = aim_tlv_get16(list2, 0x000b, 1);
-
-	/*
-	 * Invitation message / chat description.
-	 */
-	if (aim_tlv_gettlv(list2, 0x000c, 1))
-		args.msg = aim_tlv_getstr(list2, 0x000c, 1);
-
-	/*
-	 * Character set.
-	 */
-	if (aim_tlv_gettlv(list2, 0x000d, 1))
-		args.encoding = aim_tlv_getstr(list2, 0x000d, 1);
-	
-	/*
-	 * Language.
-	 */
-	if (aim_tlv_gettlv(list2, 0x000e, 1))
-		args.language = aim_tlv_getstr(list2, 0x000e, 1);
-
-	/*
-	 * Unknown -- no value
-	 *
-	 * Maybe means we should connect directly to transfer the file?
-	 */
-	if (aim_tlv_gettlv(list2, 0x000f, 1))
-		;
-
-	/*
-	 * Unknown -- no value
-	 *
-	 * Maybe means we should proxy the file transfer through an AIM server?
-	 */
-	if (aim_tlv_gettlv(list2, 0x0010, 1))
-		;
-
-	if (strlen(proxyip))
-		args.proxyip = (char *)proxyip;
-	if (strlen(clientip))
-		args.clientip = (char *)clientip;
-	if (strlen(verifiedip))
-		args.verifiedip = (char *)verifiedip;
-
-	/*
-	 * This must be present in PROPOSALs, but will probably not
-	 * exist in CANCELs and ACCEPTs.
-	 *
-	 * Service Data blocks are module-specific in format.
-	 */
-	if ((servdatatlv = aim_tlv_gettlv(list2, 0x2711 /* 10001 */, 1))) {
-
-		aim_bstream_init(&sdbs, servdatatlv->value, servdatatlv->length);
-		sdbsptr = &sdbs;
-	}
-
-	/*
-	 * The rest of the handling depends on what type it is.
-	 *
-	 * Not all of them have special handling (yet).
-	 */
-	if (args.reqclass & AIM_CAPS_BUDDYICON)
-		incomingim_ch2_buddyicon(sess, mod, rx, snac, userinfo, &args, sdbsptr);
-	else if (args.reqclass & AIM_CAPS_SENDBUDDYLIST)
-		incomingim_ch2_buddylist(sess, mod, rx, snac, userinfo, &args, sdbsptr);
-	else if (args.reqclass & AIM_CAPS_CHAT)
-		incomingim_ch2_chat(sess, mod, rx, snac, userinfo, &args, sdbsptr);
-	else if (args.reqclass & AIM_CAPS_ICQSERVERRELAY)
-		incomingim_ch2_icqserverrelay(sess, mod, rx, snac, userinfo, &args, sdbsptr);
-	else if (args.reqclass & AIM_CAPS_SENDFILE)
-		incomingim_ch2_sendfile(sess, mod, rx, snac, userinfo, &args, sdbsptr);
-
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, channel, userinfo, &args);
-
-
-	if (args.destructor)
-		((ch2_args_destructor_t)args.destructor)(sess, &args);
-
-	free((char *)args.msg);
-	free((char *)args.encoding);
-	free((char *)args.language);
-
-	aim_tlvlist_free(&list2);
-
-	return ret;
-}
-
-static int incomingim_ch4(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, fu16_t channel, aim_userinfo_t *userinfo, aim_tlvlist_t *tlvlist, fu8_t *cookie)
-{
-	aim_bstream_t meat;
-	aim_rxcallback_t userfunc;
-	aim_tlv_t *block;
-	struct aim_incomingim_ch4_args args;
-	int ret = 0;
-
-	/*
-	 * Make a bstream for the meaty part.  Yum.  Meat.
-	 */
-	if (!(block = aim_tlv_gettlv(tlvlist, 0x0005, 1)))
-		return -1;
-	aim_bstream_init(&meat, block->value, block->length);
-
-	args.uin = aimbs_getle32(&meat);
-	args.type = aimbs_getle8(&meat);
-	args.flags = aimbs_getle8(&meat);
-	args.msglen = aimbs_getle16(&meat);
-	args.msg = aimbs_getraw(&meat, args.msglen);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, channel, userinfo, &args);
-
-	free(args.msg);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0007
- *
- * It can easily be said that parsing ICBMs is THE single
- * most difficult thing to do in the in AIM protocol.  In
- * fact, I think I just did say that.
- *
- * Below is the best damned solution I've come up with
- * over the past sixteen months of battling with it. This
- * can parse both away and normal messages from every client
- * I have access to.  Its not fast, its not clean.  But it works.
- *
- */
-static int incomingim(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int i, ret = 0;
-	fu8_t cookie[8];
-	fu16_t channel;
-	aim_userinfo_t userinfo;
-
-	memset(&userinfo, 0x00, sizeof(aim_userinfo_t));
-
-	/*
-	 * Read ICBM Cookie.  And throw away.
-	 */
-	for (i = 0; i < 8; i++)
-		cookie[i] = aimbs_get8(bs);
-
-	/*
-	 * Channel ID.
-	 *
-	 * Channel 0x0001 is the message channel.  It is 
-	 * used to send basic ICBMs.
-	 *
-	 * Channel 0x0002 is the Rendevous channel, which
-	 * is where Chat Invitiations and various client-client
-	 * connection negotiations come from.
-	 *
-	 * Channel 0x0003 is used for chat messages.
-	 *
-	 * Channel 0x0004 is used for ICQ authorization, or 
-	 * possibly any system notice.
-	 *
-	 */
-	channel = aimbs_get16(bs);
-
-	/*
-	 * Extract the standard user info block.
-	 *
-	 * Note that although this contains TLVs that appear contiguous
-	 * with the TLVs read below, they are two different pieces.  The
-	 * userinfo block contains the number of TLVs that contain user
-	 * information, the rest are not even though there is no seperation.
-	 * You can start reading the message TLVs after aim_info_extract() 
-	 * parses out the standard userinfo block.
-	 *
-	 * That also means that TLV types can be duplicated between the
-	 * userinfo block and the rest of the message, however there should
-	 * never be two TLVs of the same type in one block.
-	 * 
-	 */
-	aim_info_extract(sess, bs, &userinfo);
-
-	/*
-	 * From here on, its depends on what channel we're on.
-	 *
-	 * Technically all channels have a TLV list have this, however,
-	 * for the common channel 1 case, in-place parsing is used for
-	 * performance reasons (less memory allocation).
-	 */
-	if (channel == 1) {
-
-		ret = incomingim_ch1(sess, mod, rx, snac, channel, &userinfo, bs, cookie);
-
-	} else if (channel == 2) {
-		aim_tlvlist_t *tlvlist;
-
-		/*
-		 * Read block of TLVs (not including the userinfo data).  All 
-		 * further data is derived from what is parsed here.
-		 */
-		tlvlist = aim_tlvlist_read(bs);
-
-		ret = incomingim_ch2(sess, mod, rx, snac, channel, &userinfo, tlvlist, cookie);
-
-		aim_tlvlist_free(&tlvlist);
-
-	} else if (channel == 4) {
-		aim_tlvlist_t *tlvlist;
-
-		tlvlist = aim_tlvlist_read(bs);
-		ret = incomingim_ch4(sess, mod, rx, snac, channel, &userinfo, tlvlist, cookie);
-		aim_tlvlist_free(&tlvlist);
-
-	} else {
-		faimdprintf(sess, 0, "icbm: ICBM received on an unsupported channel.  Ignoring.  (chan = %04x)\n", channel);
-	}
-
-	aim_info_free(&userinfo);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0008 - Send a warning to sn.
- * 
- * Flags:
- *  AIM_WARN_ANON  Send as an anonymous (doesn't count as much)
- *
- * returns -1 on error (couldn't alloc packet), 0 on success. 
- *
- */
-faim_export int aim_im_warn(aim_session_t *sess, aim_conn_t *conn, const char *sn, fu32_t flags)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !conn || !sn)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, strlen(sn)+13)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0008, 0x0000, sn, strlen(sn)+1);
-	aim_putsnac(&fr->data, 0x0004, 0x0008, 0x0000, snacid);
-
-	aimbs_put16(&fr->data, (flags & AIM_WARN_ANON) ? 0x0001 : 0x0000); 
-	aimbs_put8(&fr->data, strlen(sn));
-	aimbs_putraw(&fr->data, sn, strlen(sn));
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/* Subtype 0x000a */
-static int missedcall(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t channel, nummissed, reason;
-	aim_userinfo_t userinfo;
-
-	while (aim_bstream_empty(bs)) {	
-
-		channel = aimbs_get16(bs);
-		aim_info_extract(sess, bs, &userinfo);
-		nummissed = aimbs_get16(bs);
-		reason = aimbs_get16(bs);
-
-		if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-			 ret = userfunc(sess, rx, channel, &userinfo, nummissed, reason);
-
-		aim_info_free(&userinfo);
-	}
-
-	return ret;
-}
-
-/*
- * Subtype 0x000b
- *
- * Possible codes:
- *    AIM_TRANSFER_DENY_NOTSUPPORTED -- "client does not support"
- *    AIM_TRANSFER_DENY_DECLINE -- "client has declined transfer"
- *    AIM_TRANSFER_DENY_NOTACCEPTING -- "client is not accepting transfers"
- * 
- */
-faim_export int aim_im_denytransfer(aim_session_t *sess, const char *sender, const char *cookie, fu16_t code)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-	
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+8+2+1+strlen(sender)+6)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x000b, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0004, 0x000b, 0x0000, snacid);
-	
-	aimbs_putraw(&fr->data, cookie, 8);
-
-	aimbs_put16(&fr->data, 0x0002); /* channel */
-	aimbs_put8(&fr->data, strlen(sender));
-	aimbs_putraw(&fr->data, sender, strlen(sender));
-
-	aim_tlvlist_add_16(&tl, 0x0003, code);
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x000b - Receive the response from an ICQ status message request.
- *
- * This contains the ICQ status message.  Go figure.
- *
- */
-static int clientautoresp(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t channel, reason;
-	char *sn;
-	fu8_t *ck, snlen;
-
-	ck = aimbs_getraw(bs, 8);
-	channel = aimbs_get16(bs);
-	snlen = aimbs_get8(bs);
-	sn = aimbs_getstr(bs, snlen);
-	reason = aimbs_get16(bs);
-
-	if (channel == 0x0002) { /* File transfer declined */
-		aimbs_get16(bs); /* Unknown */
-		aimbs_get16(bs); /* Unknown */
-		if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-			ret = userfunc(sess, rx, channel, sn, reason, ck);
-	} else if (channel == 0x0004) { /* ICQ message */
-		switch (reason) {
-			case 0x0003: { /* ICQ status message.  Maybe other stuff too, you never know with these people. */
-				fu8_t statusmsgtype, *msg;
-				fu16_t len;
-				fu32_t state;
-
-				len = aimbs_getle16(bs); /* Should be 0x001b */
-				aim_bstream_advance(bs, len); /* Unknown */
-
-				len = aimbs_getle16(bs); /* Should be 0x000e */
-				aim_bstream_advance(bs, len); /* Unknown */
-
-				statusmsgtype = aimbs_getle8(bs);
-				switch (statusmsgtype) {
-					case 0xe8:
-						state = AIM_ICQ_STATE_AWAY;
-						break;
-					case 0xe9:
-						state = AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY;
-						break;
-					case 0xea:
-						state = AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_OUT;
-						break;
-					case 0xeb:
-						state = AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY;
-						break;
-					case 0xec:
-						state = AIM_ICQ_STATE_CHAT;
-						break;
-					default:
-						state = 0;
-						break;
-				}
-
-				aimbs_getle8(bs); /* Unknown - 0x03 Maybe this means this is an auto-reply */
-				aimbs_getle16(bs); /* Unknown - 0x0000 */
-				aimbs_getle16(bs); /* Unknown - 0x0000 */
-
-				len = aimbs_getle16(bs);
-				msg = aimbs_getraw(bs, len);
-
-				if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-					ret = userfunc(sess, rx, channel, sn, reason, state, msg);
-
-				free(msg);
-			} break;
-
-			default: {
-				if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-					ret = userfunc(sess, rx, channel, sn, reason);
-			} break;
-		} /* end switch */
-	}
-
-	free(ck);
-	free(sn);
-
-	return ret;
-}
-
-/*
- * Subtype 0x000c - Receive an ack after sending an ICBM.
- *
- * You have to have send the message with the AIM_IMFLAGS_ACK flag set 
- * (TLV t(0003)).  The ack contains the ICBM header of the message you 
- * sent.
- *
- */
-static int msgack(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_rxcallback_t userfunc;
-	fu16_t ch;
-	fu8_t *ck;
-	char *sn;
-	int ret = 0;
-
-	ck = aimbs_getraw(bs, 8);
-	ch = aimbs_get16(bs);
-	sn = aimbs_getstr(bs, aimbs_get8(bs));
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, ch, sn);
-
-	free(sn);
-	free(ck);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0014 - Send a mini typing notification (mtn) packet.
- *
- * This is supported by winaim5 and newer, MacAIM bleh and newer, iChat bleh and newer, 
- * and Gaim 0.60 and newer.
- *
- */
-faim_export int aim_im_sendmtn(aim_session_t *sess, fu16_t type1, const char *sn, fu16_t type2)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0002)))
-		return -EINVAL;
-
-	if (!sn)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+11+strlen(sn)+2)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0004, 0x0014, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0004, 0x0014, 0x0000, snacid);
-
-	/*
-	 * 8 days of light
-	 * Er, that is to say, 8 bytes of 0's
-	 */
-	aimbs_put16(&fr->data, 0x0000);
-	aimbs_put16(&fr->data, 0x0000);
-	aimbs_put16(&fr->data, 0x0000);
-	aimbs_put16(&fr->data, 0x0000);
-
-	/*
-	 * Type 1 (should be 0x0001 for mtn)
-	 */
-	aimbs_put16(&fr->data, type1);
-
-	/*
-	 * Dest sn
-	 */
-	aimbs_put8(&fr->data, strlen(sn));
-	aimbs_putraw(&fr->data, sn, strlen(sn));
-
-	/*
-	 * Type 2 (should be 0x0000, 0x0001, or 0x0002 for mtn)
-	 */
-	aimbs_put16(&fr->data, type2);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0014 - Receive a mini typing notification (mtn) packet.
- *
- * This is supported by winaim5 and newer, MacAIM bleh and newer, iChat bleh and newer, 
- * and Gaim 0.60 and newer.
- *
- */
-static int mtn_receive(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	char *sn;
-	fu8_t snlen;
-	fu16_t type1, type2;
-
-	aim_bstream_advance(bs, 8); /* Unknown - All 0's */
-	type1 = aimbs_get16(bs);
-	snlen = aimbs_get8(bs);
-	sn = aimbs_getstr(bs, snlen);
-	type2 = aimbs_get16(bs);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, type1, sn, type2);
-
-	free(sn);
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0005)
-		return aim_im_paraminfo(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0006)
-		return outgoingim(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0007)
-		return incomingim(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x000a)
-		return missedcall(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x000b)
-		return clientautoresp(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x000c)
-		return msgack(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0014)
-		return mtn_receive(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int msg_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x0004;
-	mod->version = 0x0001;
-	mod->toolid = 0x0110;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "messaging", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/invite.c
===================================================================
--- libfaim/invite.c	(revision e374dee70435f8c596358571092675644a9ba731)
+++ 	(revision )
@@ -1,34 +1,0 @@
-/*
- * Family 0x0006 - This isn't really ever used by anyone anymore.
- *
- * Once upon a time, there used to be a menu item in AIM clients that
- * said something like "Invite a friend to use AIM..." and then it would
- * ask for an email address and it would sent a mail to them saying
- * how perfectly wonderful the AIM service is and why you should use it
- * and click here if you hate the person who sent this to you and want to
- * complain and yell at them in a small box with pretty fonts.
- *
- * I could've sworn libfaim had this implemented once, a long long time ago,
- * but I can't find it.
- *
- * I'm mainly adding this so that I can keep advertising that we support
- * group 6, even though we don't.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-faim_internal int invite_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x0006;
-	mod->version = 0x0001;
-	mod->toolid = 0x0110;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "invite", sizeof(mod->name));
-	mod->snachandler = NULL;
-
-	return 0;
-}
Index: bfaim/locate.c
===================================================================
--- libfaim/locate.c	(revision 6e3980ec43c1493159467eaaec6b67940a4ac6f0)
+++ 	(revision )
@@ -1,1319 +1,0 @@
-/*
- * Family 0x0002 - Locate.
- *
- * The functions here are responsible for requesting and parsing information-
- * gathering SNACs.  Or something like that.  This family contains the SNACs 
- * for getting and setting info, away messages, directory profile thingy, etc.
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
-
-/*
- * Capability blocks. 
- *
- * These are CLSIDs. They should actually be of the form:
- *
- * {0x0946134b, 0x4c7f, 0x11d1,
- *  {0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}},
- *
- * But, eh.
- */
-static const struct {
-	fu32_t flag;
-	fu8_t data[16];
-} aim_caps[] = {
-
-	/*
-	 * These are in ascending numerical order.
-	 */
-
-	/*
-	 * Perhaps better called AIM_CAPS_SHORTCAPS
-	 */
-	{AIM_CAPS_ICHAT,
-	 {0x09, 0x46, 0x00, 0x00, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_SECUREIM,
-	 {0x09, 0x46, 0x00, 0x01, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_VIDEO,
-	 {0x09, 0x46, 0x01, 0x00, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	/*
-	 * Not really sure about this one.  In an email from 
-	 * 26 Sep 2003, Matthew Sachs suggested that, "this 
-	 * is probably the capability for the SMS features."
-	 */
-	{AIM_CAPS_SMS,
-	 {0x09, 0x46, 0x01, 0xff, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_GENERICUNKNOWN,
-	 {0x09, 0x46, 0xf0, 0x03, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_GENERICUNKNOWN,
-	 {0x09, 0x46, 0xf0, 0x04, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_GENERICUNKNOWN,
-	 {0x09, 0x46, 0xf0, 0x05, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_HIPTOP,
-	 {0x09, 0x46, 0x13, 0x23, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_VOICE,
-	 {0x09, 0x46, 0x13, 0x41, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_SENDFILE,
-	 {0x09, 0x46, 0x13, 0x43, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_ICQ_DIRECT,
-	 {0x09, 0x46, 0x13, 0x44, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_DIRECTIM,
-	 {0x09, 0x46, 0x13, 0x45, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_BUDDYICON,
-	 {0x09, 0x46, 0x13, 0x46, 0x4c, 0x7f, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	/*
-	 * Windows AIM calls this "Add-ins," which is probably more accurate
-	 */
-	{AIM_CAPS_SAVESTOCKS,
-	 {0x09, 0x46, 0x13, 0x47, 0x4c, 0x7f, 0x11, 0xd1,
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_GETFILE,
-	 {0x09, 0x46, 0x13, 0x48, 0x4c, 0x7f, 0x11, 0xd1,
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_ICQSERVERRELAY,
-	 {0x09, 0x46, 0x13, 0x49, 0x4c, 0x7f, 0x11, 0xd1,
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	/*
-	 * Indeed, there are two of these.  The former appears to be correct, 
-	 * but in some versions of winaim, the second one is set.  Either they 
-	 * forgot to fix endianness, or they made a typo. It really doesn't 
-	 * matter which.
-	 */
-	{AIM_CAPS_GAMES,
-	 {0x09, 0x46, 0x13, 0x4a, 0x4c, 0x7f, 0x11, 0xd1,
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-	{AIM_CAPS_GAMES2,
-	 {0x09, 0x46, 0x13, 0x4a, 0x4c, 0x7f, 0x11, 0xd1,
-	  0x22, 0x82, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_SENDBUDDYLIST,
-	 {0x09, 0x46, 0x13, 0x4b, 0x4c, 0x7f, 0x11, 0xd1,
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	/*
-	 * Setting this lets AIM users receive messages from ICQ users, and ICQ 
-	 * users receive messages from AIM users.  It also lets ICQ users show 
-	 * up in buddy lists for AIM users, and AIM users show up in buddy lists 
-	 * for ICQ users.  And ICQ privacy/invisibility acts like AIM privacy, 
-	 * in that if you add a user to your deny list, you will not be able to 
-	 * see them as online (previous you could still see them, but they 
-	 * couldn't see you.
-	 */
-	{AIM_CAPS_INTEROPERATE,
-	 {0x09, 0x46, 0x13, 0x4d, 0x4c, 0x7f, 0x11, 0xd1,
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_ICQUTF8,
-	 {0x09, 0x46, 0x13, 0x4e, 0x4c, 0x7f, 0x11, 0xd1,
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	{AIM_CAPS_ICQUTF8OLD,
-	 {0x2e, 0x7a, 0x64, 0x75, 0xfa, 0xdf, 0x4d, 0xc8,
-	  0x88, 0x6f, 0xea, 0x35, 0x95, 0xfd, 0xb6, 0xdf}},
-
-	/*
-	 * Chat is oddball.
-	 */
-	{AIM_CAPS_CHAT,
-	 {0x74, 0x8f, 0x24, 0x20, 0x62, 0x87, 0x11, 0xd1, 
-	  0x82, 0x22, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}},
-
-	/*
-	{AIM_CAPS_ICQ2GO,
-	 {0x56, 0x3f, 0xc8, 0x09, 0x0b, 0x6f, 0x41, 0xbd,
-	  0x9f, 0x79, 0x42, 0x26, 0x09, 0xdf, 0xa2, 0xf3}},
-	*/
-
-	{AIM_CAPS_ICQRTF,
-	 {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34,
-	  0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x92}},
-
-	/* This is added by the servers and it only shows up for ourselves... */
-	{AIM_CAPS_GENERICUNKNOWN,
-	 {0x97, 0xb1, 0x27, 0x51, 0x24, 0x3c, 0x43, 0x34, 
-	  0xad, 0x22, 0xd6, 0xab, 0xf7, 0x3f, 0x14, 0x09}},
-
-	{AIM_CAPS_APINFO, 
-	 {0xaa, 0x4a, 0x32, 0xb5, 0xf8, 0x84, 0x48, 0xc6,
-	  0xa3, 0xd7, 0x8c, 0x50, 0x97, 0x19, 0xfd, 0x5b}},
-
-	{AIM_CAPS_TRILLIANCRYPT,
-	 {0xf2, 0xe7, 0xc7, 0xf4, 0xfe, 0xad, 0x4d, 0xfb,
-	  0xb2, 0x35, 0x36, 0x79, 0x8b, 0xdf, 0x00, 0x00}},
-
-	{AIM_CAPS_EMPTY,
-	 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-	  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
-
-	{AIM_CAPS_LAST}
-};
-
-/*
- * Add the userinfo to our linked list.  If we already have userinfo 
- * for this buddy, then just overwrite parts of the old data.
- * @param userinfo Contains the new information for the buddy.
- */
-static void aim_locate_adduserinfo(aim_session_t *sess, aim_userinfo_t *userinfo) {
-	aim_userinfo_t *cur;
-
-	cur = aim_locate_finduserinfo(sess, userinfo->sn);
-
-	if (cur == NULL) {
-		cur = (aim_userinfo_t *)calloc(1, sizeof(aim_userinfo_t));
-		cur->sn = strdup(userinfo->sn);
-		cur->next = sess->locate.userinfo;
-		sess->locate.userinfo = cur;
-	}
-
-	cur->warnlevel = userinfo->warnlevel;
-	cur->idletime = userinfo->idletime;
-	if (userinfo->flags != 0)
-		cur->flags = userinfo->flags;
-	if (userinfo->createtime != 0)
-		cur->createtime = userinfo->createtime;
-	if (userinfo->membersince != 0)
-		cur->membersince = userinfo->membersince;
-	if (userinfo->onlinesince != 0)
-		cur->onlinesince = userinfo->onlinesince;
-	if (userinfo->sessionlen != 0)
-		cur->sessionlen = userinfo->sessionlen;
-	if (userinfo->capabilities != 0)
-		cur->capabilities = userinfo->capabilities;
-	cur->present |= userinfo->present;
-
-	if (userinfo->iconcsumlen > 0) {
-		free(cur->iconcsum);
-		cur->iconcsum = (fu8_t *)malloc(userinfo->iconcsumlen);
-		memcpy(cur->iconcsum, userinfo->iconcsum, userinfo->iconcsumlen);
-		cur->iconcsumlen = userinfo->iconcsumlen;
-	}
-
-	if (userinfo->info != NULL) {
-		free(cur->info);
-		free(cur->info_encoding);
-		cur->info = (char *)malloc(userinfo->info_len);
-		memcpy(cur->info, userinfo->info, userinfo->info_len);
-		cur->info_encoding = strdup(userinfo->info_encoding);
-		cur->info_len = userinfo->info_len;
-	}
-
-	if (userinfo->away != NULL) {
-		free(cur->away);
-		free(cur->away_encoding);
-		cur->away = (char *)malloc(userinfo->away_len);
-		memcpy(cur->away, userinfo->away, userinfo->away_len);
-		cur->away_encoding = strdup(userinfo->away_encoding);
-		cur->away_len = userinfo->away_len;
-	}
-}
-
-static void aim_locate_dorequest(aim_session_t *sess) {
-	struct userinfo_node *cur = sess->locate.torequest;
-
-	if (cur == NULL)
-		return;
-
-	if (sess->locate.waiting_for_response == TRUE)
-		return;
-
-	sess->locate.waiting_for_response = TRUE;
-	aim_locate_getinfoshort(sess, cur->sn, 0x00000003);
-
-	/* Move this node to the "requested" queue */
-	sess->locate.torequest = cur->next;
-	cur->next = sess->locate.requested;
-	sess->locate.requested = cur;
-}
-
-/**
- * Remove this screen name from our queue.  If this info was resquested 
- * by our info request queue, then pop the next element off of the queue.
- *
- * @param sess The aim session.
- * @param sn Screen name of the info we just received.
- * @return True if the request was explicit (client requested the info), 
- *         false if the request was implicit (libfaim request the info).
- */
-static int aim_locate_gotuserinfo(aim_session_t *sess, const char *sn) {
-	struct userinfo_node *cur, *del;
-	int was_explicit = TRUE;
-
-	while ((sess->locate.requested != NULL) && (aim_sncmp(sn, sess->locate.requested->sn) == 0)) {
-		del = sess->locate.requested;
-		sess->locate.requested = del->next;
-		was_explicit = FALSE;
-		free(del->sn);
-		free(del);
-	}
-
-	cur = sess->locate.requested;
-	while ((cur != NULL) && (cur->next != NULL)) {
-		if (aim_sncmp(sn, cur->next->sn) == 0) {
-			del = cur->next;
-			cur->next = del->next;
-			was_explicit = FALSE;
-			free(del->sn);
-			free(del);
-		} else
-			cur = cur->next;
-	}
-
-	if (!was_explicit) {
-		sess->locate.waiting_for_response = FALSE;
-		aim_locate_dorequest(sess);
-	}
-
-	return was_explicit;
-}
-
-faim_internal void aim_locate_requestuserinfo(aim_session_t *sess, const char *sn) {
-	struct userinfo_node *cur;
-
-	/* Make sure we aren't already requesting info for this buddy */
-	cur = sess->locate.torequest;
-	while (cur != NULL) {
-		if (aim_sncmp(sn, cur->sn) == 0)
-			return;
-		cur = cur->next;
-	}
-
-	/* Add a new node to our request queue */
-	cur = (struct userinfo_node *)malloc(sizeof(struct userinfo_node));
-	cur->sn = strdup(sn);
-	cur->next = sess->locate.torequest;
-	sess->locate.torequest = cur;
-
-	/* Actually request some info up in this piece */
-	aim_locate_dorequest(sess);
-}
-
-faim_export aim_userinfo_t *aim_locate_finduserinfo(aim_session_t *sess, const char *sn) {
-	aim_userinfo_t *cur = sess->locate.userinfo;
-
-	while (cur != NULL) {
-		if (aim_sncmp(cur->sn, sn) == 0)
-			return cur;
-		cur = cur->next;
-	}
-
-	return NULL;
-}
-
-faim_internal fu32_t aim_locate_getcaps(aim_session_t *sess, aim_bstream_t *bs, int len)
-{
-	fu32_t flags = 0;
-	int offset;
-
-	for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x10) {
-		fu8_t *cap;
-		int i, identified;
-
-		cap = aimbs_getraw(bs, 0x10);
-
-		for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) {
-			if (memcmp(&aim_caps[i].data, cap, 0x10) == 0) {
-				flags |= aim_caps[i].flag;
-				identified++;
-				break; /* should only match once... */
-			}
-		}
-
-		if (!identified)
-			faimdprintf(sess, 0, "unknown capability: {%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x}\n",
-					cap[0], cap[1], cap[2], cap[3],
-					cap[4], cap[5],
-					cap[6], cap[7],
-					cap[8], cap[9],
-					cap[10], cap[11], cap[12], cap[13],
-					cap[14], cap[15]);
-
-		free(cap);
-	}
-
-	return flags;
-}
-
-faim_internal fu32_t aim_locate_getcaps_short(aim_session_t *sess, aim_bstream_t *bs, int len)
-{
-	fu32_t flags = 0;
-	int offset;
-
-	for (offset = 0; aim_bstream_empty(bs) && (offset < len); offset += 0x02) {
-		fu8_t *cap;
-		int i, identified;
-
-		cap = aimbs_getraw(bs, 0x02);
-
-		for (i = 0, identified = 0; !(aim_caps[i].flag & AIM_CAPS_LAST); i++) {
-			if (memcmp(&aim_caps[i].data[2], cap, 0x02) == 0) {
-				flags |= aim_caps[i].flag;
-				identified++;
-				break; /* should only match once... */
-			}
-		}
-
-		if (!identified)
-			faimdprintf(sess, 0, "unknown short capability: {%02x%02x}\n", cap[0], cap[1]);
-
-		free(cap);
-	}
-
-	return flags;
-}
-
-faim_internal int aim_putcap(aim_bstream_t *bs, fu32_t caps)
-{
-	int i;
-
-	if (!bs)
-		return -EINVAL;
-
-	for (i = 0; aim_bstream_empty(bs); i++) {
-
-		if (aim_caps[i].flag == AIM_CAPS_LAST)
-			break;
-
-		if (caps & aim_caps[i].flag)
-			aimbs_putraw(bs, aim_caps[i].data, 0x10);
-
-	}
-
-	return 0;
-}
-
-static void dumptlv(aim_session_t *sess, fu16_t type, aim_bstream_t *bs, fu8_t len)
-{
-	int i;
-
-	if (!sess || !bs || !len)
-		return;
-
-	faimdprintf(sess, 0, "userinfo:   type  =0x%04x\n", type);
-	faimdprintf(sess, 0, "userinfo:   length=0x%04x\n", len);
-	faimdprintf(sess, 0, "userinfo:   value:\n");
-
-	for (i = 0; i < len; i++) {
-		if ((i % 8) == 0)
-			faimdprintf(sess, 0, "\nuserinfo:        ");
-		faimdprintf(sess, 0, "0x%2x ", aimbs_get8(bs));
-	}
-
-	faimdprintf(sess, 0, "\n");
-
-	return;
-}
-
-faim_internal void aim_info_free(aim_userinfo_t *info)
-{
-	free(info->sn);
-	free(info->iconcsum);
-	free(info->info);
-	free(info->info_encoding);
-	free(info->avail);
-	free(info->avail_encoding);
-	free(info->away);
-	free(info->away_encoding);
-}
-
-/*
- * AIM is fairly regular about providing user info.  This is a generic 
- * routine to extract it in its standard form.
- */
-faim_internal int aim_info_extract(aim_session_t *sess, aim_bstream_t *bs, aim_userinfo_t *outinfo)
-{
-	int curtlv, tlvcnt;
-	fu8_t snlen;
-
-	if (!bs || !outinfo)
-		return -EINVAL;
-
-	/* Clear out old data first */
-	memset(outinfo, 0x00, sizeof(aim_userinfo_t));
-
-	/*
-	 * Screen name.  Stored as an unterminated string prepended with a 
-	 * byte containing its length.
-	 */
-	snlen = aimbs_get8(bs);
-	outinfo->sn = aimbs_getstr(bs, snlen);
-
-	/*
-	 * Warning Level.  Stored as an unsigned short.
-	 */
-	outinfo->warnlevel = aimbs_get16(bs);
-
-	/*
-	 * TLV Count. Unsigned short representing the number of 
-	 * Type-Length-Value triples that follow.
-	 */
-	tlvcnt = aimbs_get16(bs);
-
-	/* 
-	 * Parse out the Type-Length-Value triples as they're found.
-	 */
-	for (curtlv = 0; curtlv < tlvcnt; curtlv++) {
-		int endpos;
-		fu16_t type, length;
-
-		type = aimbs_get16(bs);
-		length = aimbs_get16(bs);
-
-		endpos = aim_bstream_curpos(bs) + length;
-
-		if (type == 0x0001) {
-			/*
-			 * Type = 0x0001: User flags
-			 * 
-			 * Specified as any of the following ORed together:
-			 *      0x0001  Trial (user less than 60days)
-			 *      0x0002  Unknown bit 2
-			 *      0x0004  AOL Main Service user
-			 *      0x0008  Unknown bit 4
-			 *      0x0010  Free (AIM) user 
-			 *      0x0020  Away
-			 *      0x0400  ActiveBuddy
-			 *
-			 */
-			outinfo->flags = aimbs_get16(bs);
-			outinfo->present |= AIM_USERINFO_PRESENT_FLAGS;
-
-		} else if (type == 0x0002) {
-			/*
-			 * Type = 0x0002: Account creation time. 
-			 *
-			 * The time/date that the user originally registered for
-			 * the service, stored in time_t format.
-			 *
-			 * I'm not sure how this differs from type 5 ("member
-			 * since").
-			 *
-			 * Note: This is the field formerly known as "member
-			 * since".  All these years and I finally found out
-			 * that I got the name wrong.
-			 */
-			outinfo->createtime = aimbs_get32(bs);
-			outinfo->present |= AIM_USERINFO_PRESENT_CREATETIME;
-
-		} else if (type == 0x0003) {
-			/*
-			 * Type = 0x0003: On-Since date.
-			 *
-			 * The time/date that the user started their current 
-			 * session, stored in time_t format.
-			 */
-			outinfo->onlinesince = aimbs_get32(bs);
-			outinfo->present |= AIM_USERINFO_PRESENT_ONLINESINCE;
-
-		} else if (type == 0x0004) {
-			/*
-			 * Type = 0x0004: Idle time.
-			 *
-			 * Number of minutes since the user actively used the 
-			 * service.
-			 *
-			 * Note that the client tells the server when to start
-			 * counting idle times, so this may or may not be 
-			 * related to reality.
-			 */
-			outinfo->idletime = aimbs_get16(bs);
-			outinfo->present |= AIM_USERINFO_PRESENT_IDLE;
-
-		} else if (type == 0x0005) {
-			/*
-			 * Type = 0x0005: Member since date. 
-			 *
-			 * The time/date that the user originally registered for
-			 * the service, stored in time_t format.
-			 *
-			 * This is sometimes sent instead of type 2 ("account
-			 * creation time"), particularly in the self-info.
-			 * And particularly for ICQ?
-			 */
-			outinfo->membersince = aimbs_get32(bs);
-			outinfo->present |= AIM_USERINFO_PRESENT_MEMBERSINCE;
-
-		} else if (type == 0x0006) {
-			/*
-			 * Type = 0x0006: ICQ Online Status
-			 *
-			 * ICQ's Away/DND/etc "enriched" status. Some decoding 
-			 * of values done by Scott <darkagl@pcnet.com>
-			 */
-			aimbs_get16(bs);
-			outinfo->icqinfo.status = aimbs_get16(bs);
-			outinfo->present |= AIM_USERINFO_PRESENT_ICQEXTSTATUS;
-
-		} else if (type == 0x0008) {
-			/*
-			 * Type = 0x0008
-			 *
-			 * Client type, or some such.
-			 */
-
-		} else if (type == 0x000a) {
-			/*
-			 * Type = 0x000a
-			 *
-			 * ICQ User IP Address.
-			 * Ahh, the joy of ICQ security.
-			 */
-			outinfo->icqinfo.ipaddr = aimbs_get32(bs);
-			outinfo->present |= AIM_USERINFO_PRESENT_ICQIPADDR;
-
-		} else if (type == 0x000c) {
-			/* 
-			 * Type = 0x000c
-			 *
-			 * random crap containing the IP address,
-			 * apparently a port number, and some Other Stuff.
-			 *
-			 * Format is:
-			 * 4 bytes - Our IP address, 0xc0 a8 01 2b for 192.168.1.43
-			 * 
-			 *
-			 */
-			aimbs_getrawbuf(bs, outinfo->icqinfo.crap, 0x25);
-			outinfo->present |= AIM_USERINFO_PRESENT_ICQDATA;
-
-		} else if (type == 0x000d) {
-			/*
-			 * Type = 0x000d
-			 *
-			 * OSCAR Capability information.
-			 *
-			 */
-			outinfo->capabilities |= aim_locate_getcaps(sess, bs, length);
-			outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES;
-
-		} else if (type == 0x000e) {
-			/*
-			 * Type = 0x000e
-			 *
-			 * AOL capability information.
-			 *
-			 */
-
-		} else if ((type == 0x000f) || (type == 0x0010)) {
-			/*
-			 * Type = 0x000f: Session Length. (AIM)
-			 * Type = 0x0010: Session Length. (AOL)
-			 *
-			 * The duration, in seconds, of the user's current 
-			 * session.
-			 *
-			 * Which TLV type this comes in depends on the
-			 * service the user is using (AIM or AOL).
-			 *
-			 */
-			outinfo->sessionlen = aimbs_get32(bs);
-			outinfo->present |= AIM_USERINFO_PRESENT_SESSIONLEN;
-
-		} else if (type == 0x0019) {
-			/*
-			 * Type = 0x0019
-			 *
-			 * OSCAR short capability information.  A shortened 
-			 * form of the normal capabilities.
-			 */
-			outinfo->capabilities |= aim_locate_getcaps_short(sess, bs, length);
-			outinfo->present |= AIM_USERINFO_PRESENT_CAPABILITIES;
-
-		} else if (type == 0x001b) {
-			/*
-			 * Type = 0x001a
-			 *
-			 * AOL short capability information.  A shortened 
-			 * form of the normal capabilities.
-			 */
-
-		} else if (type == 0x001b) {
-			/*
-			 * Type = 0x0019
-			 *
-			 * Encryption certification MD5 checksum.
-			 */
-
-		} else if (type == 0x001d) {
-			/*
-			 * Type = 0x001d
-			 *
-			 * Buddy icon information and available messages.
-			 *
-			 * This almost seems like the AIM protocol guys gave 
-			 * the iChat guys a Type, and the iChat guys tried to 
-			 * cram as much cool shit into it as possible.  Then 
-			 * the Windows AIM guys were like, "hey, that's 
-			 * pretty neat, let's copy those prawns."
-			 *
-			 * In that spirit, this can contain a custom message, 
-			 * kind of like an away message, but you're not away 
-			 * (it's called an "available" message).  Or it can 
-			 * contain information about the buddy icon the user 
-			 * has stored on the server.
-			 */
-			int type2, number, length2;
-
-			while (aim_bstream_curpos(bs) < endpos) {
-				type2 = aimbs_get16(bs);
-				number = aimbs_get8(bs);
-				length2 = aimbs_get8(bs);
-
-				switch (type2) {
-					case 0x0000: { /* This is an official buddy icon? */
-						/* This is always 5 bytes of "0x02 01 d2 04 72"? */
-						aim_bstream_advance(bs, length2);
-					} break;
-
-					case 0x0001: { /* A buddy icon checksum */
-						if ((length2 > 0) && (number == 0x01)) {
-							free(outinfo->iconcsum);
-							outinfo->iconcsum = aimbs_getraw(bs, length2);
-							outinfo->iconcsumlen = length2;
-						} else
-							aim_bstream_advance(bs, length2);
-					} break;
-
-					case 0x0002: { /* An available message */
-						if (length2 > 4) {
-							free(outinfo->avail);
-							outinfo->avail_len = aimbs_get16(bs);
-							outinfo->avail = aimbs_getstr(bs, outinfo->avail_len);
-							if (aimbs_get16(bs) == 0x0001) { /* We have an encoding */
-								aimbs_get16(bs);
-								outinfo->avail_encoding = aimbs_getstr(bs, aimbs_get16(bs));
-							} else {
-								/* No explicit encoding, client should use UTF-8 */
-								outinfo->avail_encoding = NULL;
-							}
-						} else
-							aim_bstream_advance(bs, length2);
-					} break;
-
-					default: {
-						aim_bstream_advance(bs, length2);
-					} break;
-				}
-			}
-
-		} else if (type == 0x001e) {
-			/*
-			 * Type 30: Unknown.
-			 *
-			 * Always four bytes, but it doesn't look like an int.
-			 */
-
-		} else if (type == 0x001f) {
-			/*
-			 * Type 31: Unknown.
-			 *
-			 * Seen on a buddy using DeadAIM.  Data was 4 bytes:
-			 * 0x00 00 00 10
-			 */
-
-		} else {
-
-			/*
-			 * Reaching here indicates that either AOL has
-			 * added yet another TLV for us to deal with, 
-			 * or the parsing has gone Terribly Wrong.
-			 *
-			 * Either way, inform the owner and attempt
-			 * recovery.
-			 *
-			 */
-			faimdprintf(sess, 0, "userinfo: **warning: unexpected TLV:\n");
-			faimdprintf(sess, 0, "userinfo:   sn    =%s\n", outinfo->sn);
-			dumptlv(sess, type, bs, length);
-		}
-
-		/* Save ourselves. */
-		aim_bstream_setpos(bs, endpos);
-	}
-
-	aim_locate_adduserinfo(sess, outinfo);
-
-	return 0;
-}
-
-/*
- * Inverse of aim_info_extract()
- */
-faim_internal int aim_putuserinfo(aim_bstream_t *bs, aim_userinfo_t *info)
-{
-	aim_tlvlist_t *tlvlist = NULL;
-
-	if (!bs || !info)
-		return -EINVAL;
-
-	aimbs_put8(bs, strlen(info->sn));
-	aimbs_putraw(bs, info->sn, strlen(info->sn));
-
-	aimbs_put16(bs, info->warnlevel);
-
-	if (info->present & AIM_USERINFO_PRESENT_FLAGS)
-		aim_tlvlist_add_16(&tlvlist, 0x0001, info->flags);
-	if (info->present & AIM_USERINFO_PRESENT_MEMBERSINCE)
-		aim_tlvlist_add_32(&tlvlist, 0x0002, info->membersince);
-	if (info->present & AIM_USERINFO_PRESENT_ONLINESINCE)
-		aim_tlvlist_add_32(&tlvlist, 0x0003, info->onlinesince);
-	if (info->present & AIM_USERINFO_PRESENT_IDLE)
-		aim_tlvlist_add_16(&tlvlist, 0x0004, info->idletime);
-
-/* XXX - So, ICQ_OSCAR_SUPPORT is never defined anywhere... */
-#if ICQ_OSCAR_SUPPORT
-	if (atoi(info->sn) != 0) {
-		if (info->present & AIM_USERINFO_PRESENT_ICQEXTSTATUS)
-			aim_tlvlist_add_16(&tlvlist, 0x0006, info->icqinfo.status);
-		if (info->present & AIM_USERINFO_PRESENT_ICQIPADDR)
-			aim_tlvlist_add_32(&tlvlist, 0x000a, info->icqinfo.ipaddr);
-	}
-#endif
-
-	if (info->present & AIM_USERINFO_PRESENT_CAPABILITIES)
-		aim_tlvlist_add_caps(&tlvlist, 0x000d, info->capabilities);
- 
-	if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN)
-		aim_tlvlist_add_32(&tlvlist, (fu16_t)((info->flags & AIM_FLAG_AOL) ? 0x0010 : 0x000f), info->sessionlen);
-
-	aimbs_put16(bs, aim_tlvlist_count(&tlvlist));
-	aim_tlvlist_write(bs, &tlvlist);
-	aim_tlvlist_free(&tlvlist);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0001
- */
-static int error(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	aim_snac_t *snac2;
-	fu16_t reason;
-	char *sn;
-	int was_explicit;
-
-	if (!(snac2 = aim_remsnac(sess, snac->id))) {
-		faimdprintf(sess, 0, "faim: locate.c, error(): received response from unknown request!\n");
-		return 0;
-	}
-
-	if ((snac2->family != 0x0002) && (snac2->type != 0x0015)) {
-		faimdprintf(sess, 0, "faim: locate.c, error(): received response from invalid request! %d\n", snac2->family);
-		return 0;
-	}
-
-	if (!(sn = snac2->data)) {
-		faimdprintf(sess, 0, "faim: locate.c, error(): received response from request without a screen name!\n");
-		return 0;
-	}
-
-	reason = aimbs_get16(bs);
-
-	/*
-	 * Remove this screen name from our queue.  If the client requested 
-	 * this buddy's info explicitly, then notify them that we do not have 
-	 * info for this buddy.
-	 */
-	was_explicit = aim_locate_gotuserinfo(sess, sn);
-	if (was_explicit == TRUE)
-		if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-			ret = userfunc(sess, rx, reason, sn);
-
-	if (snac2)
-		free(snac2->data);
-	free(snac2);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0002
- *
- * Request Location services rights.
- *
- */
-faim_export int aim_locate_reqrights(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)))
-		return -EINVAL;
-
-	return aim_genericreq_n_snacid(sess, conn, AIM_CB_FAM_LOC, AIM_CB_LOC_REQRIGHTS);
-}
-
-/*
- * Subtype 0x0003
- *
- * Normally contains:
- *   t(0001)  - short containing max profile length (value = 1024)
- *   t(0002)  - short - unknown (value = 16) [max MIME type length?]
- *   t(0003)  - short - unknown (value = 10)
- *   t(0004)  - short - unknown (value = 2048) [ICQ only?]
- */
-static int rights(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_tlvlist_t *tlvlist;
-	aim_rxcallback_t userfunc;
-	int ret = 0;
-	fu16_t maxsiglen = 0;
-
-	tlvlist = aim_tlvlist_read(bs);
-
-	if (aim_tlv_gettlv(tlvlist, 0x0001, 1))
-		maxsiglen = aim_tlv_get16(tlvlist, 0x0001, 1);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, maxsiglen);
-
-	aim_tlvlist_free(&tlvlist);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0004
- *
- * Gives BOS your profile.
- *
- * profile_encoding and awaymsg_encoding MUST be set if profile or
- * away are set, respectively, and their value may or may not be
- * restricted to a few choices.  I am currently aware of:
- * 
- * us-ascii		Just that
- * unicode-2-0		UCS2-BE
- * 
- * profile_len and awaymsg_len MUST be set similarly, and they MUST
- * be the length of their respective strings in bytes.
- *
- * To get the previous behavior of awaymsg == "" un-setting the away
- * message, set awaymsg non-NULL and awaymsg_len to 0 (this is the
- * obvious equivalent).
- * 
- */
-faim_export int aim_locate_setprofile(aim_session_t *sess,
-				  const char *profile_encoding, const char *profile, const int profile_len,
-				  const char *awaymsg_encoding, const char *awaymsg, const int awaymsg_len)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-	char *encoding;
-	static const char defencoding[] = {"text/aolrtf; charset=\"%s\""};
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)))
-		return -EINVAL;
-
-	if (!profile && !awaymsg)
-		return -EINVAL;
-
-	if ((profile && profile_encoding == NULL) || (awaymsg && awaymsg_len && awaymsg_encoding == NULL)) {
-		return -EINVAL;
-	}
-
-	/* Build the packet first to get real length */
-	if (profile) {
-		/* no + 1 here because of %s */
-		encoding = malloc(strlen(defencoding) + strlen(profile_encoding));
-		if (encoding == NULL) {
-			return -ENOMEM;
-		}
-		snprintf(encoding, strlen(defencoding) + strlen(profile_encoding), defencoding, profile_encoding);
-		aim_tlvlist_add_raw(&tl, 0x0001, strlen(encoding), encoding);
-		aim_tlvlist_add_raw(&tl, 0x0002, profile_len, profile);
-		free(encoding);
-	}
-
-	/*
-	 * So here's how this works:
-	 *   - You are away when you have a non-zero-length type 4 TLV stored.
-	 *   - You become unaway when you clear the TLV with a zero-length
-	 *       type 4 TLV.
-	 *   - If you do not send the type 4 TLV, your status does not change
-	 *       (that is, if you were away, you'll remain away).
-	 */
-	if (awaymsg) {
-		if (awaymsg_len) {
-			encoding = malloc(strlen(defencoding) + strlen(awaymsg_encoding));
-			if (encoding == NULL) {
-				return -ENOMEM;
-			}
-			snprintf(encoding, strlen(defencoding) + strlen(awaymsg_encoding), defencoding, awaymsg_encoding);
-			aim_tlvlist_add_raw(&tl, 0x0003, strlen(encoding), encoding);
-			aim_tlvlist_add_raw(&tl, 0x0004, awaymsg_len, awaymsg);
-			free(encoding);
-		} else
-			aim_tlvlist_add_noval(&tl, 0x0004);
-	}
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid);
-
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0004 - Set your client's capabilities.
- */
-faim_export int aim_locate_setcaps(aim_session_t *sess, fu32_t caps)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)))
-		return -EINVAL;
-
-	aim_tlvlist_add_caps(&tl, 0x0005, caps);
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + aim_tlvlist_size(&tl))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0002, 0x0004, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0002, 0x004, 0x0000, snacid);
-
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0005 - Request info of another AIM user.
- *
- * @param sn The screenname whose info you wish to request.
- * @param infotype The type of info you wish to request.
- *        0x0001 - Info/profile
- *        0x0003 - Away message
- *        0x0004 - Capabilities
- */
-faim_export int aim_locate_getinfo(aim_session_t *sess, const char *sn, fu16_t infotype)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)) || !sn)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 12+1+strlen(sn))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0002, 0x0005, 0x0000, NULL, 0);
-	
-	aim_putsnac(&fr->data, 0x0002, 0x0005, 0x0000, snacid);
-	aimbs_put16(&fr->data, infotype);
-	aimbs_put8(&fr->data, strlen(sn));
-	aimbs_putraw(&fr->data, sn, strlen(sn));
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/* Subtype 0x0006 */
-static int userinfo(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	aim_userinfo_t *userinfo, *userinfo2;
-	aim_tlvlist_t *tlvlist;
-	aim_tlv_t *tlv = NULL;
-	int was_explicit;
-
-	userinfo = (aim_userinfo_t *)malloc(sizeof(aim_userinfo_t));
-	aim_info_extract(sess, bs, userinfo);
-	tlvlist = aim_tlvlist_read(bs);
-
-	/* Profile will be 1 and 2 */
-	userinfo->info_encoding = aim_tlv_getstr(tlvlist, 0x0001, 1);
-	if ((tlv = aim_tlv_gettlv(tlvlist, 0x0002, 1))) {
-		userinfo->info = (char *)malloc(tlv->length);
-		memcpy(userinfo->info, tlv->value, tlv->length);
-		userinfo->info_len = tlv->length;
-	}
-
-	/* Away message will be 3 and 4 */
-	userinfo->away_encoding = aim_tlv_getstr(tlvlist, 0x0003, 1);
-	if ((tlv = aim_tlv_gettlv(tlvlist, 0x0004, 1))) {
-		userinfo->away = (char *)malloc(tlv->length);
-		memcpy(userinfo->away, tlv->value, tlv->length);
-		userinfo->away_len = tlv->length;
-	}
-
-	/* Caps will be 5 */
-	if ((tlv = aim_tlv_gettlv(tlvlist, 0x0005, 1))) {
-		aim_bstream_t cbs;
-		aim_bstream_init(&cbs, tlv->value, tlv->length);
-		userinfo->capabilities = aim_locate_getcaps(sess, &cbs, tlv->length);
-		userinfo->present = AIM_USERINFO_PRESENT_CAPABILITIES;
-	}
-	aim_tlvlist_free(&tlvlist);
-
-	aim_locate_adduserinfo(sess, userinfo);
-	userinfo2 = aim_locate_finduserinfo(sess, userinfo->sn);
-	aim_info_free(userinfo);
-	free(userinfo);
-
-	/*
-	 * Remove this screen name from our queue.  If the client requested 
-	 * this buddy's info explicitly, then notify them that we have info 
-	 * for this buddy.
-	 */
-	was_explicit = aim_locate_gotuserinfo(sess, userinfo2->sn);
-	if (was_explicit == TRUE)
-		if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-			ret = userfunc(sess, rx, userinfo2);
-
-	return ret;
-}
-
-/* 
- * Subtype 0x0009 - Set directory profile data.
- *
- * This is not the same as aim_location_setprofile!
- * privacy: 1 to allow searching, 0 to disallow.
- *
- */
-faim_export int aim_locate_setdirinfo(aim_session_t *sess, const char *first, const char *middle, const char *last, const char *maiden, const char *nickname, const char *street, const char *city, const char *state, const char *zip, int country, fu16_t privacy) 
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)))
-		return -EINVAL;
-
-	aim_tlvlist_add_16(&tl, 0x000a, privacy);
-
-	if (first)
-		aim_tlvlist_add_raw(&tl, 0x0001, strlen(first), first);
-	if (last)
-		aim_tlvlist_add_raw(&tl, 0x0002, strlen(last), last);
-	if (middle)
-		aim_tlvlist_add_raw(&tl, 0x0003, strlen(middle), middle);
-	if (maiden)
-		aim_tlvlist_add_raw(&tl, 0x0004, strlen(maiden), maiden);
-
-	if (state)
-		aim_tlvlist_add_raw(&tl, 0x0007, strlen(state), state);
-	if (city)
-		aim_tlvlist_add_raw(&tl, 0x0008, strlen(city), city);
-
-	if (nickname)
-		aim_tlvlist_add_raw(&tl, 0x000c, strlen(nickname), nickname);
-	if (zip)
-		aim_tlvlist_add_raw(&tl, 0x000d, strlen(zip), zip);
-
-	if (street)
-		aim_tlvlist_add_raw(&tl, 0x0021, strlen(street), street);
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_tlvlist_size(&tl))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0002, 0x0009, 0x0000, NULL, 0);
-
-	aim_putsnac(&fr->data, 0x0002, 0x0009, 0x0000, snacid);
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x000b - Huh? What is this?
- */
-faim_export int aim_locate_000b(aim_session_t *sess, const char *sn)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-		return -EINVAL;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)) || !sn)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0002, 0x000b, 0x0000, NULL, 0);
-	
-	aim_putsnac(&fr->data, 0x0002, 0x000b, 0x0000, snacid);
-	aimbs_put8(&fr->data, strlen(sn));
-	aimbs_putraw(&fr->data, sn, strlen(sn));
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x000f
- * 
- * XXX pass these in better
- *
- */
-faim_export int aim_locate_setinterests(aim_session_t *sess, const char *interest1, const char *interest2, const char *interest3, const char *interest4, const char *interest5, fu16_t privacy)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)))
-		return -EINVAL;
-
-	/* ?? privacy ?? */
-	aim_tlvlist_add_16(&tl, 0x000a, privacy);
-
-	if (interest1)
-		aim_tlvlist_add_raw(&tl, 0x0000b, strlen(interest1), interest1);
-	if (interest2)
-		aim_tlvlist_add_raw(&tl, 0x0000b, strlen(interest2), interest2);
-	if (interest3)
-		aim_tlvlist_add_raw(&tl, 0x0000b, strlen(interest3), interest3);
-	if (interest4)
-		aim_tlvlist_add_raw(&tl, 0x0000b, strlen(interest4), interest4);
-	if (interest5)
-		aim_tlvlist_add_raw(&tl, 0x0000b, strlen(interest5), interest5);
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_tlvlist_size(&tl))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0002, 0x000f, 0x0000, NULL, 0);
-
-	aim_putsnac(&fr->data, 0x0002, 0x000f, 0x0000, 0);
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0015 - Request the info a user using the short method.  This is 
- * what iChat uses.  It normally is VERY leniently rate limited.
- *
- * @param sn The screen name whose info you wish to request.
- * @param flags The bitmask which specifies the type of info you wish to request.
- *        0x00000001 - Info/profile.
- *        0x00000002 - Away message.
- *        0x00000004 - Capabilities.
- *        0x00000008 - Certification.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_locate_getinfoshort(aim_session_t *sess, const char *sn, fu32_t flags)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_LOC)) || !sn)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+1+strlen(sn))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0002, 0x0015, 0x0000, sn, strlen(sn)+1);
-
-	aim_putsnac(&fr->data, 0x0002, 0x0015, 0x0000, snacid);
-	aimbs_put32(&fr->data, flags);
-	aimbs_put8(&fr->data, strlen(sn));
-	aimbs_putraw(&fr->data, sn, strlen(sn));
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0001)
-		return error(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0003)
-		return rights(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0006)
-		return userinfo(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-static void locate_shutdown(aim_session_t *sess, aim_module_t *mod)
-{
-	aim_userinfo_t *del;
-
-	while (sess->locate.userinfo) {
-		del = sess->locate.userinfo;
-		sess->locate.userinfo = sess->locate.userinfo->next;
-		aim_info_free(del);
-		free(del);
-	}
-}
-
-faim_internal int locate_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = AIM_CB_FAM_LOC;
-	mod->version = 0x0001;
-	mod->toolid = 0x0110;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "locate", sizeof(mod->name));
-	mod->snachandler = snachandler;
-	mod->shutdown = locate_shutdown;
-
-	return 0;
-}
Index: bfaim/md5.c
===================================================================
--- libfaim/md5.c	(revision 5e53c4a15eca8b264df0aedf726d4545bc5b4b46)
+++ 	(revision )
@@ -1,392 +1,0 @@
-/*
-  Copyright (C) 1999 Aladdin Enterprises.  All rights reserved.
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  L. Peter Deutsch
-  ghost@aladdin.com
-
- */
-/*
-  Independent implementation of MD5 (RFC 1321).
-
-  This code implements the MD5 Algorithm defined in RFC 1321.
-  It is derived directly from the text of the RFC and not from the
-  reference implementation.
-
-  The original and principal author of md5.c is L. Peter Deutsch
-  <ghost@aladdin.com>.  Other authors are noted in the change history
-  that follows (in reverse chronological order):
-
-  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
-  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
-  1999-05-03 lpd Original version.
- */
-
-#include "md5.h"
-#include <string.h>
-
-#ifdef TEST
-/*
- * Compile with -DTEST to create a self-contained executable test program.
- * The test program should print out the same values as given in section
- * A.5 of RFC 1321, reproduced below.
- */
-#include <string.h>
-main()
-{
-    static const char *const test[7] = {
-	"", /*d41d8cd98f00b204e9800998ecf8427e*/
-	"945399884.61923487334tuvga", /*0cc175b9c0f1b6a831c399e269772661*/
-	"abc", /*900150983cd24fb0d6963f7d28e17f72*/
-	"message digest", /*f96b697d7cb7938d525a2f31aaf161d0*/
-	"abcdefghijklmnopqrstuvwxyz", /*c3fcd3d76192e4007dfb496cca67e13b*/
-	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
-				/*d174ab98d277d9f5a5611c2c9f419d9f*/
-	"12345678901234567890123456789012345678901234567890123456789012345678901234567890" /*57edf4a22be3c955ac49da2e2107b67a*/
-    };
-    int i;
-
-    for (i = 0; i < 7; ++i) {
-	md5_state_t state;
-	md5_byte_t digest[16];
-	int di;
-
-	md5_init(&state);
-	md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i]));
-	md5_finish(&state, digest);
-	printf("MD5 (\"%s\") = ", test[i]);
-	for (di = 0; di < 16; ++di)
-	    printf("%02x", digest[di]);
-	printf("\n");
-    }
-    return 0;
-}
-#endif /* TEST */
-
-
-/*
- * For reference, here is the program that computed the T values.
- */
-#if 0
-#include <math.h>
-main()
-{
-    int i;
-    for (i = 1; i <= 64; ++i) {
-	unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i)));
-	printf("#define T%d 0x%08lx\n", i, v);
-    }
-    return 0;
-}
-#endif
-/*
- * End of T computation program.
- */
-#define T1 0xd76aa478
-#define T2 0xe8c7b756
-#define T3 0x242070db
-#define T4 0xc1bdceee
-#define T5 0xf57c0faf
-#define T6 0x4787c62a
-#define T7 0xa8304613
-#define T8 0xfd469501
-#define T9 0x698098d8
-#define T10 0x8b44f7af
-#define T11 0xffff5bb1
-#define T12 0x895cd7be
-#define T13 0x6b901122
-#define T14 0xfd987193
-#define T15 0xa679438e
-#define T16 0x49b40821
-#define T17 0xf61e2562
-#define T18 0xc040b340
-#define T19 0x265e5a51
-#define T20 0xe9b6c7aa
-#define T21 0xd62f105d
-#define T22 0x02441453
-#define T23 0xd8a1e681
-#define T24 0xe7d3fbc8
-#define T25 0x21e1cde6
-#define T26 0xc33707d6
-#define T27 0xf4d50d87
-#define T28 0x455a14ed
-#define T29 0xa9e3e905
-#define T30 0xfcefa3f8
-#define T31 0x676f02d9
-#define T32 0x8d2a4c8a
-#define T33 0xfffa3942
-#define T34 0x8771f681
-#define T35 0x6d9d6122
-#define T36 0xfde5380c
-#define T37 0xa4beea44
-#define T38 0x4bdecfa9
-#define T39 0xf6bb4b60
-#define T40 0xbebfbc70
-#define T41 0x289b7ec6
-#define T42 0xeaa127fa
-#define T43 0xd4ef3085
-#define T44 0x04881d05
-#define T45 0xd9d4d039
-#define T46 0xe6db99e5
-#define T47 0x1fa27cf8
-#define T48 0xc4ac5665
-#define T49 0xf4292244
-#define T50 0x432aff97
-#define T51 0xab9423a7
-#define T52 0xfc93a039
-#define T53 0x655b59c3
-#define T54 0x8f0ccc92
-#define T55 0xffeff47d
-#define T56 0x85845dd1
-#define T57 0x6fa87e4f
-#define T58 0xfe2ce6e0
-#define T59 0xa3014314
-#define T60 0x4e0811a1
-#define T61 0xf7537e82
-#define T62 0xbd3af235
-#define T63 0x2ad7d2bb
-#define T64 0xeb86d391
-
-static void
-md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
-{
-    md5_word_t
-	a = pms->abcd[0], b = pms->abcd[1],
-	c = pms->abcd[2], d = pms->abcd[3];
-    md5_word_t t;
-
-#ifndef ARCH_IS_BIG_ENDIAN
-# define ARCH_IS_BIG_ENDIAN 1	/* slower, default implementation */
-#endif
-#if ARCH_IS_BIG_ENDIAN
-
-    /*
-     * On big-endian machines, we must arrange the bytes in the right
-     * order.  (This also works on machines of unknown byte order.)
-     */
-    md5_word_t X[16];
-    const md5_byte_t *xp = data;
-    int i;
-
-    for (i = 0; i < 16; ++i, xp += 4)
-	X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
-
-#else  /* !ARCH_IS_BIG_ENDIAN */
-
-    /*
-     * On little-endian machines, we can process properly aligned data
-     * without copying it.
-     */
-    md5_word_t xbuf[16];
-    const md5_word_t *X;
-
-    if (!((data - (const md5_byte_t *)0) & 3)) {
-	/* data are properly aligned */
-	X = (const md5_word_t *)data;
-    } else {
-	/* not aligned */
-	memcpy(xbuf, data, 64);
-	X = xbuf;
-    }
-#endif
-
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
-
-    /* Round 1. */
-    /* Let [abcd k s i] denote the operation
-       a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
-#define F(x, y, z) (((x) & (y)) | (~(x) & (z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + F(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-    /* Do the following 16 operations. */
-    SET(a, b, c, d,  0,  7,  T1);
-    SET(d, a, b, c,  1, 12,  T2);
-    SET(c, d, a, b,  2, 17,  T3);
-    SET(b, c, d, a,  3, 22,  T4);
-    SET(a, b, c, d,  4,  7,  T5);
-    SET(d, a, b, c,  5, 12,  T6);
-    SET(c, d, a, b,  6, 17,  T7);
-    SET(b, c, d, a,  7, 22,  T8);
-    SET(a, b, c, d,  8,  7,  T9);
-    SET(d, a, b, c,  9, 12, T10);
-    SET(c, d, a, b, 10, 17, T11);
-    SET(b, c, d, a, 11, 22, T12);
-    SET(a, b, c, d, 12,  7, T13);
-    SET(d, a, b, c, 13, 12, T14);
-    SET(c, d, a, b, 14, 17, T15);
-    SET(b, c, d, a, 15, 22, T16);
-#undef SET
-
-     /* Round 2. */
-     /* Let [abcd k s i] denote the operation
-          a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
-#define G(x, y, z) (((x) & (z)) | ((y) & ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + G(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-     /* Do the following 16 operations. */
-    SET(a, b, c, d,  1,  5, T17);
-    SET(d, a, b, c,  6,  9, T18);
-    SET(c, d, a, b, 11, 14, T19);
-    SET(b, c, d, a,  0, 20, T20);
-    SET(a, b, c, d,  5,  5, T21);
-    SET(d, a, b, c, 10,  9, T22);
-    SET(c, d, a, b, 15, 14, T23);
-    SET(b, c, d, a,  4, 20, T24);
-    SET(a, b, c, d,  9,  5, T25);
-    SET(d, a, b, c, 14,  9, T26);
-    SET(c, d, a, b,  3, 14, T27);
-    SET(b, c, d, a,  8, 20, T28);
-    SET(a, b, c, d, 13,  5, T29);
-    SET(d, a, b, c,  2,  9, T30);
-    SET(c, d, a, b,  7, 14, T31);
-    SET(b, c, d, a, 12, 20, T32);
-#undef SET
-
-     /* Round 3. */
-     /* Let [abcd k s t] denote the operation
-          a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + H(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-     /* Do the following 16 operations. */
-    SET(a, b, c, d,  5,  4, T33);
-    SET(d, a, b, c,  8, 11, T34);
-    SET(c, d, a, b, 11, 16, T35);
-    SET(b, c, d, a, 14, 23, T36);
-    SET(a, b, c, d,  1,  4, T37);
-    SET(d, a, b, c,  4, 11, T38);
-    SET(c, d, a, b,  7, 16, T39);
-    SET(b, c, d, a, 10, 23, T40);
-    SET(a, b, c, d, 13,  4, T41);
-    SET(d, a, b, c,  0, 11, T42);
-    SET(c, d, a, b,  3, 16, T43);
-    SET(b, c, d, a,  6, 23, T44);
-    SET(a, b, c, d,  9,  4, T45);
-    SET(d, a, b, c, 12, 11, T46);
-    SET(c, d, a, b, 15, 16, T47);
-    SET(b, c, d, a,  2, 23, T48);
-#undef SET
-
-     /* Round 4. */
-     /* Let [abcd k s t] denote the operation
-          a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
-#define I(x, y, z) ((y) ^ ((x) | ~(z)))
-#define SET(a, b, c, d, k, s, Ti)\
-  t = a + I(b,c,d) + X[k] + Ti;\
-  a = ROTATE_LEFT(t, s) + b
-     /* Do the following 16 operations. */
-    SET(a, b, c, d,  0,  6, T49);
-    SET(d, a, b, c,  7, 10, T50);
-    SET(c, d, a, b, 14, 15, T51);
-    SET(b, c, d, a,  5, 21, T52);
-    SET(a, b, c, d, 12,  6, T53);
-    SET(d, a, b, c,  3, 10, T54);
-    SET(c, d, a, b, 10, 15, T55);
-    SET(b, c, d, a,  1, 21, T56);
-    SET(a, b, c, d,  8,  6, T57);
-    SET(d, a, b, c, 15, 10, T58);
-    SET(c, d, a, b,  6, 15, T59);
-    SET(b, c, d, a, 13, 21, T60);
-    SET(a, b, c, d,  4,  6, T61);
-    SET(d, a, b, c, 11, 10, T62);
-    SET(c, d, a, b,  2, 15, T63);
-    SET(b, c, d, a,  9, 21, T64);
-#undef SET
-
-     /* Then perform the following additions. (That is increment each
-        of the four registers by the value it had before this block
-        was started.) */
-    pms->abcd[0] += a;
-    pms->abcd[1] += b;
-    pms->abcd[2] += c;
-    pms->abcd[3] += d;
-}
-
-void
-md5_init(md5_state_t *pms)
-{
-    pms->count[0] = pms->count[1] = 0;
-    pms->abcd[0] = 0x67452301;
-    pms->abcd[1] = 0xefcdab89;
-    pms->abcd[2] = 0x98badcfe;
-    pms->abcd[3] = 0x10325476;
-}
-
-void
-md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
-{
-    const md5_byte_t *p = data;
-    int left = nbytes;
-    int offset = (pms->count[0] >> 3) & 63;
-    md5_word_t nbits = (md5_word_t)(nbytes << 3);
-
-    if (nbytes <= 0)
-	return;
-
-    /* Update the message length. */
-    pms->count[1] += nbytes >> 29;
-    pms->count[0] += nbits;
-    if (pms->count[0] < nbits)
-	pms->count[1]++;
-
-    /* Process an initial partial block. */
-    if (offset) {
-	int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
-
-	memcpy(pms->buf + offset, p, copy);
-	if (offset + copy < 64)
-	    return;
-	p += copy;
-	left -= copy;
-	md5_process(pms, pms->buf);
-    }
-
-    /* Process full blocks. */
-    for (; left >= 64; p += 64, left -= 64)
-	md5_process(pms, p);
-
-    /* Process a final partial block. */
-    if (left)
-	memcpy(pms->buf, p, left);
-}
-
-void
-md5_finish(md5_state_t *pms, md5_byte_t digest[16])
-{
-    static const md5_byte_t pad[64] = {
-	0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-    };
-    md5_byte_t data[8];
-    int i;
-
-    /* Save the length before padding. */
-    for (i = 0; i < 8; ++i)
-	data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
-    /* Pad to 56 bytes mod 64. */
-    md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
-    /* Append the length. */
-    md5_append(pms, data, 8);
-    for (i = 0; i < 16; ++i)
-	digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
-}
Index: bfaim/md5.h
===================================================================
--- libfaim/md5.h	(revision 5e53c4a15eca8b264df0aedf726d4545bc5b4b46)
+++ 	(revision )
@@ -1,93 +1,0 @@
-/*
-  Copyright (C) 1999 Aladdin Enterprises.  All rights reserved.
-
-  This software is provided 'as-is', without any express or implied
-  warranty.  In no event will the authors be held liable for any damages
-  arising from the use of this software.
-
-  Permission is granted to anyone to use this software for any purpose,
-  including commercial applications, and to alter it and redistribute it
-  freely, subject to the following restrictions:
-
-  1. The origin of this software must not be misrepresented; you must not
-     claim that you wrote the original software. If you use this software
-     in a product, an acknowledgment in the product documentation would be
-     appreciated but is not required.
-  2. Altered source versions must be plainly marked as such, and must not be
-     misrepresented as being the original software.
-  3. This notice may not be removed or altered from any source distribution.
-
-  L. Peter Deutsch
-  ghost@aladdin.com
-
- */
-/*
-  Independent implementation of MD5 (RFC 1321).
-
-  This code implements the MD5 Algorithm defined in RFC 1321.
-  It is derived directly from the text of the RFC and not from the
-  reference implementation.
-
-  The original and principal author of md5.h is L. Peter Deutsch
-  <ghost@aladdin.com>.  Other authors are noted in the change history
-  that follows (in reverse chronological order):
-
-  1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
-  1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
-	added conditionalization for C++ compilation from Martin
-	Purschke <purschke@bnl.gov>.
-  1999-05-03 lpd Original version.
- */
-
-#ifndef md5_INCLUDED
-#  define md5_INCLUDED
-
-/*
- * This code has some adaptations for the Ghostscript environment, but it
- * will compile and run correctly in any environment with 8-bit chars and
- * 32-bit ints.  Specifically, it assumes that if the following are
- * defined, they have the same meaning as in Ghostscript: P1, P2, P3,
- * ARCH_IS_BIG_ENDIAN.
- */
-
-typedef unsigned char md5_byte_t; /* 8-bit byte */
-typedef unsigned int md5_word_t; /* 32-bit word */
-
-/* Define the state of the MD5 Algorithm. */
-typedef struct md5_state_s {
-    md5_word_t count[2];	/* message length in bits, lsw first */
-    md5_word_t abcd[4];		/* digest buffer */
-    md5_byte_t buf[64];		/* accumulate block */
-} md5_state_t;
-
-#ifdef __cplusplus
-extern "C" 
-{
-#endif
-
-/* Initialize the algorithm. */
-#ifdef P1
-void md5_init(P1(md5_state_t *pms));
-#else
-void md5_init(md5_state_t *pms);
-#endif
-
-/* Append a string to the message. */
-#ifdef P3
-void md5_append(P3(md5_state_t *pms, const md5_byte_t *data, int nbytes));
-#else
-void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes);
-#endif
-
-/* Finish the message and return the digest. */
-#ifdef P2
-void md5_finish(P2(md5_state_t *pms, md5_byte_t digest[16]));
-#else
-void md5_finish(md5_state_t *pms, md5_byte_t digest[16]);
-#endif
-
-#ifdef __cplusplus
-}  /* end extern "C" */
-#endif
-
-#endif /* md5_INCLUDED */
Index: bfaim/misc.c
===================================================================
--- libfaim/misc.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,147 +1,0 @@
-/*
- * misc.c
- *
- * Random stuff.  Basically just a few functions for sending 
- * simple SNACs, and then the generic error handler.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h> 
-
-/*
- * Generic routine for sending commands.
- *
- * I know I can do this in a smarter way...but I'm not thinking straight
- * right now...
- *
- * I had one big function that handled all three cases, but then it broke
- * and I split it up into three.  But then I fixed it.  I just never went
- * back to the single.  I don't see any advantage to doing it either way.
- *
- */
-faim_internal int aim_genericreq_n(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid = 0x00000000;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10)))
-		return -ENOMEM;
-
-	aim_putsnac(&fr->data, family, subtype, 0x0000, snacid);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-faim_internal int aim_genericreq_n_snacid(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, family, subtype, 0x0000, snacid);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-faim_internal int aim_genericreq_l(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype, fu32_t *longdata)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!longdata)
-		return aim_genericreq_n(sess, conn, family, subtype);
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4)))
-		return -ENOMEM; 
-
-	snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0);
-
-	aim_putsnac(&fr->data, family, subtype, 0x0000, snacid);
-	aimbs_put32(&fr->data, *longdata);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-faim_internal int aim_genericreq_s(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t subtype, fu16_t *shortdata)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!shortdata)
-		return aim_genericreq_n(sess, conn, family, subtype);
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2)))
-		return -ENOMEM; 
-
-	snacid = aim_cachesnac(sess, family, subtype, 0x0000, NULL, 0);
-
-	aim_putsnac(&fr->data, family, subtype, 0x0000, snacid);
-	aimbs_put16(&fr->data, *shortdata);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Should be generic enough to handle the errors for all groups.
- *
- */
-static int generror(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	int error = 0;
-	aim_rxcallback_t userfunc;
-	aim_snac_t *snac2;
-
-	snac2 = aim_remsnac(sess, snac->id);
-
-	if (aim_bstream_empty(bs))
-		error = aimbs_get16(bs);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, error, snac2 ? snac2->data : NULL);
-
-	if (snac2)
-		free(snac2->data);
-	free(snac2);
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0001)
-		return generror(sess, mod, rx, snac, bs);
-	else if ((snac->family == 0xffff) && (snac->subtype == 0xffff)) {
-		aim_rxcallback_t userfunc;
-
-		if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-			return userfunc(sess, rx);
-	}
-
-	return 0;
-}
-
-faim_internal int misc_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0xffff;
-	mod->version = 0x0000;
-	mod->flags = AIM_MODFLAG_MULTIFAMILY;
-	strncpy(mod->name, "misc", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/msgcookie.c
===================================================================
--- libfaim/msgcookie.c	(revision e374dee70435f8c596358571092675644a9ba731)
+++ 	(revision )
@@ -1,193 +1,0 @@
-/*
- * Cookie Caching stuff. Adam wrote this, apparently just some
- * derivatives of n's SNAC work. I cleaned it up, added comments.
- * 
- */
-
-/*
- * I'm assuming that cookies are type-specific. that is, we can have
- * "1234578" for type 1 and type 2 concurrently. if i'm wrong, then we
- * lose some error checking. if we assume cookies are not type-specific and are
- * wrong, we get quirky behavior when cookies step on each others' toes.
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-/**
- * aim_cachecookie - appends a cookie to the cookie list
- * @sess: session to add to
- * @cookie: pointer to struct to append
- *
- * if cookie->cookie for type cookie->type is found, updates the
- * ->addtime of the found structure; otherwise adds the given cookie
- * to the cache
- *
- * returns -1 on error, 0 on append, 1 on update.  the cookie you pass
- * in may be free'd, so don't count on its value after calling this!
- * 
- */
-faim_internal int aim_cachecookie(aim_session_t *sess, aim_msgcookie_t *cookie)
-{
-	aim_msgcookie_t *newcook;
-
-	if (!sess || !cookie)
-		return -EINVAL;
-
-	newcook = aim_checkcookie(sess, cookie->cookie, cookie->type);
-	
-	if (newcook == cookie) {
-		newcook->addtime = time(NULL);
-		return 1;
-	} else if (newcook)
-		aim_cookie_free(sess, newcook);
-
-	cookie->addtime = time(NULL);  
-
-	cookie->next = sess->msgcookies;
-	sess->msgcookies = cookie;
-
-	return 0;
-}
-
-/**
- * aim_uncachecookie - grabs a cookie from the cookie cache (removes it from the list)
- * @sess: session to grab cookie from
- * @cookie: cookie string to look for
- * @type: cookie type to look for
- *
- * takes a cookie string and a cookie type and finds the cookie struct associated with that duple, removing it from the cookie list ikn the process.
- *
- * if found, returns the struct; if none found (or on error), returns NULL:
- */
-faim_internal aim_msgcookie_t *aim_uncachecookie(aim_session_t *sess, fu8_t *cookie, int type)
-{
-	aim_msgcookie_t *cur, **prev;
-
-	if (!cookie || !sess->msgcookies)
-		return NULL;
-
-	for (prev = &sess->msgcookies; (cur = *prev); ) {
-		if ((cur->type == type) && 
-				(memcmp(cur->cookie, cookie, 8) == 0)) {
-			*prev = cur->next;
-			return cur;
-		}
-		prev = &cur->next;
-	}
-
-	return NULL;
-}
-
-/**
- * aim_mkcookie - generate an aim_msgcookie_t *struct from a cookie string, a type, and a data pointer.
- * @c: pointer to the cookie string array
- * @type: cookie type to use
- * @data: data to be cached with the cookie
- *
- * returns NULL on error, a pointer to the newly-allocated cookie on
- * success.
- *
- */
-faim_internal aim_msgcookie_t *aim_mkcookie(fu8_t *c, int type, void *data) 
-{
-	aim_msgcookie_t *cookie;
-
-	if (!c)
-		return NULL;
-
-	if (!(cookie = calloc(1, sizeof(aim_msgcookie_t))))
-		return NULL;
-
-	cookie->data = data;
-	cookie->type = type;
-	memcpy(cookie->cookie, c, 8);
-
-	return cookie;
-}
-
-/**
- * aim_checkcookie - check to see if a cookietuple has been cached
- * @sess: session to check for the cookie in
- * @cookie: pointer to the cookie string array
- * @type: type of the cookie to look for
- *
- * this returns a pointer to the cookie struct (still in the list) on
- * success; returns NULL on error/not found
- *
- */
-
-faim_internal aim_msgcookie_t *aim_checkcookie(aim_session_t *sess, const fu8_t *cookie, int type)
-{
-	aim_msgcookie_t *cur;
-
-	for (cur = sess->msgcookies; cur; cur = cur->next) {
-		if ((cur->type == type) && 
-				(memcmp(cur->cookie, cookie, 8) == 0))
-			return cur;   
-	}
-
-	return NULL;
-}
-
-#if 0 /* debugging feature */
-faim_internal int aim_dumpcookie(aim_session_t *sess, aim_msgcookie_t *cookie) 
-{
-
-	if (!cookie)
-		return -EINVAL;
-
-	faimdprintf(sess, 0, "\tCookie at %p: %d/%s with %p, next %p\n", cookie, 
-			cookie->type, cookie->cookie, cookie->data, cookie->next);
-
-	return 0;
-}
-#endif
-
-/**
- * aim_cookie_free - free an aim_msgcookie_t struct
- * @sess: session to remove the cookie from
- * @cookiep: the address of a pointer to the cookie struct to remove
- *
- * this function removes the cookie *cookie from teh list of cookies
- * in sess, and then frees all memory associated with it. including
- * its data! if you want to use the private data after calling this,
- * make sure you copy it first.
- *
- * returns -1 on error, 0 on success.
- *
- */
-faim_internal int aim_cookie_free(aim_session_t *sess, aim_msgcookie_t *cookie) 
-{
-	aim_msgcookie_t *cur, **prev;
-
-	if (!sess || !cookie)
-		return -EINVAL;
-
-	for (prev = &sess->msgcookies; (cur = *prev); ) {
-		if (cur == cookie)
-			*prev = cur->next;
-		else
-			prev = &cur->next;
-	}
-
-	free(cookie->data);
-	free(cookie);
-
-	return 0;
-} 
-
-/* XXX I hate switch */
-faim_internal int aim_msgcookie_gettype(int reqclass) 
-{
-	/* XXX: hokey-assed. needs fixed. */
-	switch(reqclass) {
-	case AIM_CAPS_BUDDYICON: return AIM_COOKIETYPE_OFTICON;
-	case AIM_CAPS_VOICE: return AIM_COOKIETYPE_OFTVOICE;
-	case AIM_CAPS_DIRECTIM: return AIM_COOKIETYPE_OFTIMAGE;
-	case AIM_CAPS_CHAT: return AIM_COOKIETYPE_CHAT;
-	case AIM_CAPS_GETFILE: return AIM_COOKIETYPE_OFTGET;
-	case AIM_CAPS_SENDFILE: return AIM_COOKIETYPE_OFTSEND;
-	default: return AIM_COOKIETYPE_UNKNOWN;
-	}           
-}
Index: bfaim/odir.c
===================================================================
--- libfaim/odir.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,245 +1,0 @@
-/*
- * Family 0x000f - Newer Search Method
- *
- * Used for searching for other AIM users by email address, name, 
- * location, commmon interests, and a few other similar things.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-/**
- * Subtype 0x0002 - Submit a User Search Request
- *
- * Search for an AIM screen name based on their email address.
- *
- * @param sess The oscar session.
- * @param region Should be "us-ascii" unless you know what you're doing.
- * @param email The email address you want to search for.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_odir_email(aim_session_t *sess, const char *region, const char *email)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x000f)) || !region || !email)
-		return -EINVAL;
-
-	/* Create a TLV chain, write it to the outgoing frame, then free the chain */
-	aim_tlvlist_add_raw(&tl, 0x001c, strlen(region), region);
-	aim_tlvlist_add_16(&tl, 0x000a, 0x0001); /* Type of search */
-	aim_tlvlist_add_raw(&tl, 0x0005, strlen(email), email);
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_tlvlist_size(&tl))))
-		return -ENOMEM;
-	snacid = aim_cachesnac(sess, 0x000f, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x000f, 0x0002, 0x0000, snacid);
-
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-
-/**
- * Subtype 0x0002 - Submit a User Search Request
- *
- * Search for an AIM screen name based on various info 
- * about the person.
- *
- * @param sess The oscar session.
- * @param region Should be "us-ascii" unless you know what you're doing.
- * @param first The first name of the person you want to search for.
- * @param middle The middle name of the person you want to search for.
- * @param last The last name of the person you want to search for.
- * @param maiden The maiden name of the person you want to search for.
- * @param nick The nick name of the person you want to search for.
- * @param city The city where the person you want to search for resides.
- * @param state The state where the person you want to search for resides.
- * @param country The country where the person you want to search for resides.
- * @param zip The zip code where the person you want to search for resides.
- * @param address The street address where the person you want to seach for resides.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_odir_name(aim_session_t *sess, const char *region, const char *first, const char *middle, const char *last, const char *maiden, const char *nick, const char *city, const char *state, const char *country, const char *zip, const char *address)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x000f)) || !region)
-		return -EINVAL;
-
-	/* Create a TLV chain, write it to the outgoing frame, then free the chain */
-	aim_tlvlist_add_raw(&tl, 0x001c, strlen(region), region);
-	aim_tlvlist_add_16(&tl, 0x000a, 0x0000); /* Type of search */
-	if (first)
-		aim_tlvlist_add_raw(&tl, 0x0001, strlen(first), first);
-	if (last)
-		aim_tlvlist_add_raw(&tl, 0x0002, strlen(last), last);
-	if (middle)
-		aim_tlvlist_add_raw(&tl, 0x0003, strlen(middle), middle);
-	if (maiden)
-		aim_tlvlist_add_raw(&tl, 0x0004, strlen(maiden), maiden);
-	if (country)
-		aim_tlvlist_add_raw(&tl, 0x0006, strlen(country), country);
-	if (state)
-		aim_tlvlist_add_raw(&tl, 0x0007, strlen(state), state);
-	if (city)
-		aim_tlvlist_add_raw(&tl, 0x0008, strlen(city), city);
-	if (nick)
-		aim_tlvlist_add_raw(&tl, 0x000c, strlen(nick), nick);
-	if (zip)
-		aim_tlvlist_add_raw(&tl, 0x000d, strlen(zip), zip);
-	if (address)
-		aim_tlvlist_add_raw(&tl, 0x0021, strlen(address), address);
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_tlvlist_size(&tl))))
-		return -ENOMEM;
-	snacid = aim_cachesnac(sess, 0x000f, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x000f, 0x0002, 0x0000, snacid);
-
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-
-/**
- * Subtype 0x0002 - Submit a User Search Request
- *
- * @param sess The oscar session.
- * @param interest1 An interest you want to search for.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_odir_interest(aim_session_t *sess, const char *region, const char *interest)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x000f)) || !region)
-		return -EINVAL;
-
-	/* Create a TLV chain, write it to the outgoing frame, then free the chain */
-	aim_tlvlist_add_raw(&tl, 0x001c, strlen(region), region);
-	aim_tlvlist_add_16(&tl, 0x000a, 0x0001); /* Type of search */
-	if (interest)
-		aim_tlvlist_add_raw(&tl, 0x0001, strlen(interest), interest);
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+aim_tlvlist_size(&tl))))
-		return -ENOMEM;
-	snacid = aim_cachesnac(sess, 0x000f, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x000f, 0x0002, 0x0000, snacid);
-
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-
-/**
- * Subtype 0x0003 - Receive Reply From a User Search
- *
- */
-static int parseresults(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t tmp, numresults;
-	struct aim_odir *results = NULL;
-
-	tmp = aimbs_get16(bs); /* Unknown */
-	tmp = aimbs_get16(bs); /* Unknown */
-	aim_bstream_advance(bs, tmp);
-
-	numresults = aimbs_get16(bs); /* Number of results to follow */
-
-	/* Allocate a linked list, 1 node per result */
-	while (numresults) {
-		struct aim_odir *new;
-		aim_tlvlist_t *tl = aim_tlvlist_readnum(bs, aimbs_get16(bs));
-		new = (struct aim_odir *)malloc(sizeof(struct aim_odir));
-		new->first = aim_tlv_getstr(tl, 0x0001, 1);
-		new->last = aim_tlv_getstr(tl, 0x0002, 1);
-		new->middle = aim_tlv_getstr(tl, 0x0003, 1);
-		new->maiden = aim_tlv_getstr(tl, 0x0004, 1);
-		new->email = aim_tlv_getstr(tl, 0x0005, 1);
-		new->country = aim_tlv_getstr(tl, 0x0006, 1);
-		new->state = aim_tlv_getstr(tl, 0x0007, 1);
-		new->city = aim_tlv_getstr(tl, 0x0008, 1);
-		new->sn = aim_tlv_getstr(tl, 0x0009, 1);
-		new->interest = aim_tlv_getstr(tl, 0x000b, 1);
-		new->nick = aim_tlv_getstr(tl, 0x000c, 1);
-		new->zip = aim_tlv_getstr(tl, 0x000d, 1);
-		new->region = aim_tlv_getstr(tl, 0x001c, 1);
-		new->address = aim_tlv_getstr(tl, 0x0021, 1);
-		new->next = results;
-		results = new;
-		numresults--;
-	}
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, results);
-
-	/* Now free everything from above */
-	while (results) {
-		struct aim_odir *del = results;
-		results = results->next;
-		free(del->first);
-		free(del->last);
-		free(del->middle);
-		free(del->maiden);
-		free(del->email);
-		free(del->country);
-		free(del->state);
-		free(del->city);
-		free(del->sn);
-		free(del->interest);
-		free(del->nick);
-		free(del->zip);
-		free(del->region);
-		free(del->address);
-		free(del);
-	}
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0003)
-		return parseresults(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int odir_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x000f;
-	mod->version = 0x0001;
-	mod->toolid = 0x0010;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "odir", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/oscar.c
===================================================================
--- libfaim/oscar.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,6711 +1,0 @@
-/*
- * gaim
- *
- * Some code copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
- * Some code copyright (C) 1999-2001, Eric Warmenhoven
- * Some code copyright (C) 2001-2003, Sean Egan
- * Some code copyright (C) 2001-2003, Mark Doliner <thekingant@users.sourceforge.net>
- *
- * Most libfaim code copyright (C) 1998-2001 Adam Fritzler <afritz@auk.cx>
- * Some libfaim code copyright (C) 2001-2003 Mark Doliner <thekingant@users.sourceforge.net>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- */
-#include "internal.h"
-
-#include "account.h"
-#include "accountopt.h"
-#include "buddyicon.h"
-#include "conversation.h"
-#include "core.h"
-#include "debug.h"
-#include "ft.h"
-#include "imgstore.h"
-#include "multi.h"
-#include "notify.h"
-#include "privacy.h"
-#include "prpl.h"
-#include "proxy.h"
-#include "request.h"
-#include "util.h"
-
-#include "aim.h"
-#include "md5.h"
-
-#define UC_AOL		0x02
-#define UC_ADMIN	0x04
-#define UC_UNCONFIRMED	0x08
-#define UC_NORMAL	0x10
-#define UC_AB		0x20
-#define UC_WIRELESS	0x40
-#define UC_HIPTOP	0x80
-
-#define AIMHASHDATA "http://gaim.sourceforge.net/aim_data.php3"
-
-#define OSCAR_CONNECT_STEPS 6
-
-static GaimPlugin *my_protocol = NULL;
-
-static int caps_aim = AIM_CAPS_CHAT | AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_INTEROPERATE | AIM_CAPS_ICHAT;
-static int caps_icq = AIM_CAPS_BUDDYICON | AIM_CAPS_DIRECTIM | AIM_CAPS_SENDFILE | AIM_CAPS_ICQUTF8 | AIM_CAPS_INTEROPERATE | AIM_CAPS_ICHAT;
-
-static fu8_t features_aim[] = {0x01, 0x01, 0x01, 0x02};
-static fu8_t features_icq[] = {0x01, 0x06};
-
-typedef struct _OscarData OscarData;
-struct _OscarData {
-	aim_session_t *sess;
-	aim_conn_t *conn;
-
-	guint cnpa;
-	guint paspa;
-	guint emlpa;
-	guint icopa;
-
-	gboolean iconconnecting;
-	gboolean set_icon;
-
-	GSList *create_rooms;
-
-	gboolean conf;
-	gboolean reqemail;
-	gboolean setemail;
-	char *email;
-	gboolean setnick;
-	char *newsn;
-	gboolean chpass;
-	char *oldp;
-	char *newp;
-	
-	GSList *oscar_chats;
-	GSList *direct_ims;
-	GSList *file_transfers;
-	GHashTable *buddyinfo;
-	GSList *requesticon;
-
-	gboolean killme;
-	gboolean icq;
-	guint icontimer;
-	guint getblisttimer;
-
-	struct {
-		guint maxwatchers; /* max users who can watch you */
-		guint maxbuddies; /* max users you can watch */
-		guint maxgroups; /* max groups in server list */
-		guint maxpermits; /* max users on permit list */
-		guint maxdenies; /* max users on deny list */
-		guint maxsiglen; /* max size (bytes) of profile */
-		guint maxawaymsglen; /* max size (bytes) of posted away message */
-	} rights;
-};
-
-struct create_room {
-	char *name;
-	int exchange;
-};
-
-struct chat_connection {
-	char *name;
-	char *show; /* AOL did something funny to us */
-	fu16_t exchange;
-	fu16_t instance;
-	int fd; /* this is redundant since we have the conn below */
-	aim_conn_t *conn;
-	int inpa;
-	int id;
-	GaimConnection *gc; /* i hate this. */
-	GaimConversation *cnv; /* bah. */
-	int maxlen;
-	int maxvis;
-};
-
-struct direct_im {
-	GaimConnection *gc;
-	char name[80];
-	int watcher;
-	aim_conn_t *conn;
-	gboolean connected;
-};
-
-struct ask_direct {
-	GaimConnection *gc;
-	char *sn;
-	char ip[64];
-	fu8_t cookie[8];
-};
-
-/*
- * Various PRPL-specific buddy info that we want to keep track of
- * Some other info is maintained by locate.c, and I'd like to move 
- * the rest of this to libfaim, mostly im.c
- */
-struct buddyinfo {
-	gboolean typingnot;
-	gchar *availmsg;
-	fu32_t ipaddr;
-
-	unsigned long ico_me_len;
-	unsigned long ico_me_csum;
-	time_t ico_me_time;
-	gboolean ico_informed;
-
-	unsigned long ico_len;
-	unsigned long ico_csum;
-	time_t ico_time;
-	gboolean ico_need;
-	gboolean ico_sent;
-};
-
-struct name_data {
-	GaimConnection *gc;
-	gchar *name;
-	gchar *nick;
-};
-
-static char *msgerrreason[] = {
-	N_("Invalid error"),
-	N_("Invalid SNAC"),
-	N_("Rate to host"),
-	N_("Rate to client"),
-	N_("Not logged in"),
-	N_("Service unavailable"),
-	N_("Service not defined"),
-	N_("Obsolete SNAC"),
-	N_("Not supported by host"),
-	N_("Not supported by client"),
-	N_("Refused by client"),
-	N_("Reply too big"),
-	N_("Responses lost"),
-	N_("Request denied"),
-	N_("Busted SNAC payload"),
-	N_("Insufficient rights"),
-	N_("In local permit/deny"),
-	N_("Too evil (sender)"),
-	N_("Too evil (receiver)"),
-	N_("User temporarily unavailable"),
-	N_("No match"),
-	N_("List overflow"),
-	N_("Request ambiguous"),
-	N_("Queue full"),
-	N_("Not while on AOL")
-};
-static int msgerrreasonlen = 25;
-
-/* All the libfaim->gaim callback functions */
-static int gaim_parse_auth_resp  (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_login      (aim_session_t *, aim_frame_t *, ...);
-static int gaim_handle_redirect  (aim_session_t *, aim_frame_t *, ...);
-static int gaim_info_change      (aim_session_t *, aim_frame_t *, ...);
-static int gaim_account_confirm  (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_oncoming   (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_offgoing   (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_incoming_im(aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_misses     (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_clientauto (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_userinfo   (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_motd       (aim_session_t *, aim_frame_t *, ...);
-static int gaim_chatnav_info     (aim_session_t *, aim_frame_t *, ...);
-static int gaim_conv_chat_join        (aim_session_t *, aim_frame_t *, ...);
-static int gaim_conv_chat_leave       (aim_session_t *, aim_frame_t *, ...);
-static int gaim_conv_chat_info_update (aim_session_t *, aim_frame_t *, ...);
-static int gaim_conv_chat_incoming_msg(aim_session_t *, aim_frame_t *, ...);
-static int gaim_email_parseupdate(aim_session_t *, aim_frame_t *, ...);
-static int gaim_icon_error       (aim_session_t *, aim_frame_t *, ...);
-static int gaim_icon_parseicon   (aim_session_t *, aim_frame_t *, ...);
-static int oscar_icon_req        (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_msgack     (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_ratechange (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_evilnotify (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_searcherror(aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_searchreply(aim_session_t *, aim_frame_t *, ...);
-static int gaim_bosrights        (aim_session_t *, aim_frame_t *, ...);
-static int gaim_connerr          (aim_session_t *, aim_frame_t *, ...);
-static int conninitdone_admin    (aim_session_t *, aim_frame_t *, ...);
-static int conninitdone_bos      (aim_session_t *, aim_frame_t *, ...);
-static int conninitdone_chatnav  (aim_session_t *, aim_frame_t *, ...);
-static int conninitdone_chat     (aim_session_t *, aim_frame_t *, ...);
-static int conninitdone_email    (aim_session_t *, aim_frame_t *, ...);
-static int conninitdone_icon     (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_msgerr     (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_mtn        (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_locaterights(aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_buddyrights(aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_locerr     (aim_session_t *, aim_frame_t *, ...);
-static int gaim_icbm_param_info  (aim_session_t *, aim_frame_t *, ...);
-static int gaim_parse_genericerr (aim_session_t *, aim_frame_t *, ...);
-static int gaim_memrequest       (aim_session_t *, aim_frame_t *, ...);
-static int gaim_selfinfo         (aim_session_t *, aim_frame_t *, ...);
-static int gaim_offlinemsg       (aim_session_t *, aim_frame_t *, ...);
-static int gaim_offlinemsgdone   (aim_session_t *, aim_frame_t *, ...);
-static int gaim_icqalias         (aim_session_t *, aim_frame_t *, ...);
-static int gaim_icqinfo          (aim_session_t *, aim_frame_t *, ...);
-static int gaim_popup            (aim_session_t *, aim_frame_t *, ...);
-#ifndef NOSSI
-static int gaim_ssi_parseerr     (aim_session_t *, aim_frame_t *, ...);
-static int gaim_ssi_parserights  (aim_session_t *, aim_frame_t *, ...);
-static int gaim_ssi_parselist    (aim_session_t *, aim_frame_t *, ...);
-static int gaim_ssi_parseack     (aim_session_t *, aim_frame_t *, ...);
-static int gaim_ssi_authgiven    (aim_session_t *, aim_frame_t *, ...);
-static int gaim_ssi_authrequest  (aim_session_t *, aim_frame_t *, ...);
-static int gaim_ssi_authreply    (aim_session_t *, aim_frame_t *, ...);
-static int gaim_ssi_gotadded     (aim_session_t *, aim_frame_t *, ...);
-#endif
-
-/* for DirectIM/image transfer */
-static int gaim_odc_initiate     (aim_session_t *, aim_frame_t *, ...);
-static int gaim_odc_incoming     (aim_session_t *, aim_frame_t *, ...);
-static int gaim_odc_typing       (aim_session_t *, aim_frame_t *, ...);
-static int gaim_odc_update_ui    (aim_session_t *, aim_frame_t *, ...);
-
-/* for file transfer */
-static int oscar_sendfile_estblsh(aim_session_t *, aim_frame_t *, ...);
-static int oscar_sendfile_prompt (aim_session_t *, aim_frame_t *, ...);
-static int oscar_sendfile_ack    (aim_session_t *, aim_frame_t *, ...);
-static int oscar_sendfile_done   (aim_session_t *, aim_frame_t *, ...);
-
-/* for icons */
-static gboolean gaim_icon_timerfunc(gpointer data);
-
-/* prpl actions - remove this at some point */
-/* Because I don't like forward declarations?  I think that was why... */
-static void oscar_set_info(GaimConnection *gc, const char *text);
-
-static void oscar_free_name_data(struct name_data *data) {
-	g_free(data->name);
-	g_free(data->nick);
-	g_free(data);
-}
-
-static void oscar_free_buddyinfo(void *data) {
-	struct buddyinfo *bi = data;
-	g_free(bi->availmsg);
-	g_free(bi);
-}
-
-static fu32_t oscar_encoding_check(const char *utf8)
-{
-	int i = 0;
-	fu32_t encodingflag = 0;
-
-	/* Determine how we can send this message.  Per the warnings elsewhere 
-	 * in this file, these little checks determine the simplest encoding 
-	 * we can use for a given message send using it. */
-	while (utf8[i]) {
-		if ((unsigned char)utf8[i] > 0x7f) {
-			/* not ASCII! */
-			encodingflag = AIM_IMFLAGS_ISO_8859_1;
-			break;
-		}
-		i++;
-	}
-	while (utf8[i]) {
-		/* ISO-8859-1 is 0x00-0xbf in the first byte
-		 * followed by 0xc0-0xc3 in the second */
-		if ((unsigned char)utf8[i] < 0x80) {
-			i++;
-			continue;
-		} else if (((unsigned char)utf8[i] & 0xfc) == 0xc0 &&
-			   ((unsigned char)utf8[i + 1] & 0xc0) == 0x80) {
-			i += 2;
-			continue;
-		}
-		encodingflag = AIM_IMFLAGS_UNICODE;
-		break;
-	}
-
-	return encodingflag;
-}
-
-static fu32_t oscar_encoding_parse(const char *enc)
-{
-	char *charset;
-
-	/* If anything goes wrong, fall back on ASCII and print a message */
-	if (enc == NULL) {
-		gaim_debug(GAIM_DEBUG_WARNING, "oscar",
-				   "Encoding was null, that's odd\n");
-		return 0;
-	}
-	charset = strstr(enc, "charset=");
-	if (charset == NULL) {
-		gaim_debug(GAIM_DEBUG_WARNING, "oscar",
-				   "No charset specified for info, assuming ASCII\n");
-		return 0;
-	}
-	charset += 8;
-	if (!strcmp(charset, "\"us-ascii\"") || !strcmp(charset, "\"utf-8\"")) {
-		/* UTF-8 is our native charset, ASCII is a proper subset */
-		return 0;
-	} else if (!strcmp(charset, "\"iso-8859-1\"")) {
-		return AIM_IMFLAGS_ISO_8859_1;
-	} else if (!strcmp(charset, "\"unicode-2-0\"")) {
-		return AIM_IMFLAGS_UNICODE;
-	} else {
-		gaim_debug(GAIM_DEBUG_WARNING, "oscar",
-				   "Unrecognized character set '%s', using ASCII\n", charset);
-		return 0;
-	}
-}
-
-gchar *oscar_encoding_to_utf8(const char *encoding, char *text, int textlen)
-{
-	gchar *utf8 = NULL;
-	int flags = oscar_encoding_parse(encoding);
-
-	switch (flags) {
-	case 0:
-		utf8 = g_strndup(text, textlen);
-		break;
-	case AIM_IMFLAGS_ISO_8859_1:
-		utf8 = g_convert(text, textlen, "UTF-8", "ISO-8859-1", NULL, NULL, NULL);
-		break;
-	case AIM_IMFLAGS_UNICODE:
-		utf8 = g_convert(text, textlen, "UTF-8", "UCS-2BE", NULL, NULL, NULL);
-		break;
-	}
-
-	return utf8;
-}
-
-static struct direct_im *find_direct_im(OscarData *od, const char *who) {
-	GSList *d = od->direct_ims;
-	struct direct_im *m = NULL;
-
-	while (d) {
-		m = (struct direct_im *)d->data;
-		if (!aim_sncmp(who, m->name))
-			return m;
-		d = d->next;
-	}
-
-	return NULL;
-}
-
-static char *extract_name(const char *name) {
-	char *tmp, *x;
-	int i, j;
-
-	if (!name)
-		return NULL;
-	
-	x = strchr(name, '-');
-
-	if (!x) return NULL;
-	x = strchr(++x, '-');
-	if (!x) return NULL;
-	tmp = g_strdup(++x);
-
-	for (i = 0, j = 0; x[i]; i++) {
-		char hex[3];
-		if (x[i] != '%') {
-			tmp[j++] = x[i];
-			continue;
-		}
-		strncpy(hex, x + ++i, 2); hex[2] = 0;
-		i++;
-		tmp[j++] = strtol(hex, NULL, 16);
-	}
-
-	tmp[j] = 0;
-	return tmp;
-}
-
-static struct chat_connection *find_oscar_chat(GaimConnection *gc, int id) {
-	GSList *g = ((OscarData *)gc->proto_data)->oscar_chats;
-	struct chat_connection *c = NULL;
-
-	while (g) {
-		c = (struct chat_connection *)g->data;
-		if (c->id == id)
-			break;
-		g = g->next;
-		c = NULL;
-	}
-
-	return c;
-}
-
-static struct chat_connection *find_oscar_chat_by_conn(GaimConnection *gc,
-							aim_conn_t *conn) {
-	GSList *g = ((OscarData *)gc->proto_data)->oscar_chats;
-	struct chat_connection *c = NULL;
-
-	while (g) {
-		c = (struct chat_connection *)g->data;
-		if (c->conn == conn)
-			break;
-		g = g->next;
-		c = NULL;
-	}
-
-	return c;
-}
-
-static void gaim_odc_disconnect(aim_session_t *sess, aim_conn_t *conn) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = (OscarData *)gc->proto_data;
-	GaimConversation *cnv;
-	struct direct_im *dim;
-	char *sn;
-	char buf[256];
-
-	sn = g_strdup(aim_odc_getsn(conn));
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "%s disconnected Direct IM.\n", sn);
-
-	dim = find_direct_im(od, sn);
-	od->direct_ims = g_slist_remove(od->direct_ims, dim);
-	gaim_input_remove(dim->watcher);
-
-	if (dim->connected)
-		g_snprintf(buf, sizeof buf, _("Direct IM with %s closed"), sn);
-	else 
-		g_snprintf(buf, sizeof buf, _("Direct IM with %s failed"), sn);
-
-	cnv = gaim_find_conversation_with_account(sn, gaim_connection_get_account(gc));
-	if (cnv)
-		gaim_conversation_write(cnv, NULL, buf, GAIM_MESSAGE_SYSTEM, time(NULL));
-
-	gaim_conversation_update_progress(cnv, 0);
-
-	g_free(dim); /* I guess? I don't see it anywhere else... -- mid */
-	g_free(sn);
-
-	return;
-}
-
-static void oscar_callback(gpointer data, gint source, GaimInputCondition condition) {
-	aim_conn_t *conn = (aim_conn_t *)data;
-	aim_session_t *sess = aim_conn_getsess(conn);
-	GaimConnection *gc = sess ? sess->aux_data : NULL;
-	OscarData *od;
-
-	if (!gc) {
-		gaim_debug(GAIM_DEBUG_INFO, "oscar",
-				   "oscar callback for closed connection (1).\n");
-		return;
-	}
-      
-	od = (OscarData *)gc->proto_data;
-
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
-		/* oh boy. this is probably bad. i guess the only thing we 
-		 * can really do is return? */
-		gaim_debug(GAIM_DEBUG_INFO, "oscar",
-				   "oscar callback for closed connection (2).\n");
-		gaim_debug(GAIM_DEBUG_MISC, "oscar", "gc = %p\n", gc);
-		return;
-	}
-
-	if (condition & GAIM_INPUT_READ) {
-		if (conn->type == AIM_CONN_TYPE_LISTENER) {
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "got information on rendezvous listener\n");
-			if (aim_handlerendconnect(od->sess, conn) < 0) {
-				gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-						   "connection error (rendezvous listener)\n");
-				aim_conn_kill(od->sess, &conn);
-			}
-		} else {
-			if (aim_get_command(od->sess, conn) >= 0) {
-				aim_rxdispatch(od->sess);
-				if (od->killme) {
-					gaim_debug(GAIM_DEBUG_ERROR, "oscar", "Waiting to be destroyed\n");
-					return;
-				}
-			} else {
-				if ((conn->type == AIM_CONN_TYPE_BOS) ||
-					   !(aim_getconn_type(od->sess, AIM_CONN_TYPE_BOS))) {
-					gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-							   "major connection error\n");
-					gaim_connection_error(gc, _("Disconnected."));
-				} else if (conn->type == AIM_CONN_TYPE_CHAT) {
-					struct chat_connection *c = find_oscar_chat_by_conn(gc, conn);
-					char *buf;
-					gaim_debug(GAIM_DEBUG_INFO, "oscar",
-							   "disconnected from chat room %s\n", c->name);
-					c->conn = NULL;
-					if (c->inpa > 0)
-						gaim_input_remove(c->inpa);
-					c->inpa = 0;
-					c->fd = -1;
-					aim_conn_kill(od->sess, &conn);
-					buf = g_strdup_printf(_("You have been disconnected from chat room %s."), c->name);
-					gaim_notify_error(gc, NULL, buf, NULL);
-					g_free(buf);
-				} else if (conn->type == AIM_CONN_TYPE_CHATNAV) {
-					if (od->cnpa > 0)
-						gaim_input_remove(od->cnpa);
-					od->cnpa = 0;
-					gaim_debug(GAIM_DEBUG_INFO, "oscar",
-							   "removing chatnav input watcher\n");
-					while (od->create_rooms) {
-						struct create_room *cr = od->create_rooms->data;
-						g_free(cr->name);
-						od->create_rooms =
-							g_slist_remove(od->create_rooms, cr);
-						g_free(cr);
-						gaim_notify_error(gc, NULL,
-										  _("Chat is currently unavailable"),
-										  NULL);
-					}
-					aim_conn_kill(od->sess, &conn);
-				} else if (conn->type == AIM_CONN_TYPE_AUTH) {
-					if (od->paspa > 0)
-						gaim_input_remove(od->paspa);
-					od->paspa = 0;
-					gaim_debug(GAIM_DEBUG_INFO, "oscar",
-							   "removing authconn input watcher\n");
-					aim_conn_kill(od->sess, &conn);
-				} else if (conn->type == AIM_CONN_TYPE_EMAIL) {
-					if (od->emlpa > 0)
-						gaim_input_remove(od->emlpa);
-					od->emlpa = 0;
-					gaim_debug(GAIM_DEBUG_INFO, "oscar",
-							   "removing email input watcher\n");
-					aim_conn_kill(od->sess, &conn);
-				} else if (conn->type == AIM_CONN_TYPE_ICON) {
-					if (od->icopa > 0)
-						gaim_input_remove(od->icopa);
-					od->icopa = 0;
-					gaim_debug(GAIM_DEBUG_INFO, "oscar",
-							   "removing icon input watcher\n");
-					aim_conn_kill(od->sess, &conn);
-				} else if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) {
-					if (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM)
-						gaim_odc_disconnect(od->sess, conn);
-					aim_conn_kill(od->sess, &conn);
-				} else {
-					gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-							   "holy crap! generic connection error! %hu\n",
-							   conn->type);
-					aim_conn_kill(od->sess, &conn);
-				}
-			}
-		}
-	}
-}
-
-static void oscar_debug(aim_session_t *sess, int level, const char *format, va_list va) {
-	GaimConnection *gc = sess->aux_data;
-	gchar *s = g_strdup_vprintf(format, va);
-	gchar *buf;
-
-	buf = g_strdup_printf("%s %d: %s", gaim_account_get_username(gaim_connection_get_account(gc)), level, s);
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", buf);
-	if (buf[strlen(buf)-1] != '\n')
-		gaim_debug(GAIM_DEBUG_INFO, NULL, "\n");
-	g_free(buf);
-	g_free(s);
-}
-
-static void oscar_login_connect(gpointer data, gint source, GaimInputCondition cond)
-{
-	GaimConnection *gc = data;
-	OscarData *od;
-	aim_session_t *sess;
-	aim_conn_t *conn;
-
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
-		close(source);
-		return;
-	}
-
-	od = gc->proto_data;
-	sess = od->sess;
-	conn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH);
-	conn->fd = source;
-
-	if (source < 0) {
-		gaim_connection_error(gc, _("Couldn't connect to host"));
-		return;
-	}
-
-	aim_conn_completeconnect(sess, conn);
-	gc->inpa = gaim_input_add(conn->fd, GAIM_INPUT_READ, oscar_callback, conn);
-	aim_request_login(sess, conn, gaim_account_get_username(gaim_connection_get_account(gc)));
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "Screen name sent, waiting for response\n");
-	gaim_connection_update_progress(gc, _("Screen name sent"), 1, OSCAR_CONNECT_STEPS);
-}
-
-static void oscar_login(GaimAccount *account) {
-	aim_session_t *sess;
-	aim_conn_t *conn;
-	GaimConnection *gc = gaim_account_get_connection(account);
-	OscarData *od = gc->proto_data = g_new0(OscarData, 1);
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar", "oscar_login: gc = %p\n", gc);
-
-	if (isdigit(*(gaim_account_get_username(account)))) {
-		od->icq = TRUE;
-	} else {
-		gc->flags |= GAIM_CONNECTION_HTML;
-		gc->flags |= GAIM_CONNECTION_AUTO_RESP;
-	}
-	od->buddyinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, oscar_free_buddyinfo);
-
-	sess = g_new0(aim_session_t, 1);
-	aim_session_init(sess, TRUE, 0);
-	aim_setdebuggingcb(sess, oscar_debug);
-	/*
-	 * We need an immediate queue because we don't use a while-loop 
-	 * to see if things need to be sent.
-	 */
-	aim_tx_setenqueue(sess, AIM_TX_IMMEDIATE, NULL);
-	od->sess = sess;
-	sess->aux_data = gc;
-
-	conn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, NULL);
-	if (conn == NULL) {
-		gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-				   "internal connection error\n");
-		gaim_connection_error(gc, _("Unable to login to AIM"));
-		return;
-	}
-
-	aim_conn_addhandler(sess, conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0);
-	aim_conn_addhandler(sess, conn, 0x0017, 0x0007, gaim_parse_login, 0);
-	aim_conn_addhandler(sess, conn, 0x0017, 0x0003, gaim_parse_auth_resp, 0);
-
-	conn->status |= AIM_CONN_STATUS_INPROGRESS;
-	if (gaim_proxy_connect(account, gaim_account_get_string(account, "server", FAIM_LOGIN_SERVER),
-			  gaim_account_get_int(account, "port", FAIM_LOGIN_PORT),
-			  oscar_login_connect, gc) < 0) {
-		gaim_connection_error(gc, _("Couldn't connect to host"));
-		return;
-	}
-
-	gaim_connection_update_progress(gc, _("Connecting"), 0, OSCAR_CONNECT_STEPS);
-}
-
-static void oscar_close(GaimConnection *gc) {
-	OscarData *od = (OscarData *)gc->proto_data;
-
-	while (od->oscar_chats) {
-		struct chat_connection *n = od->oscar_chats->data;
-		if (n->inpa > 0)
-			gaim_input_remove(n->inpa);
-		g_free(n->name);
-		g_free(n->show);
-		od->oscar_chats = g_slist_remove(od->oscar_chats, n);
-		g_free(n);
-	}
-	while (od->direct_ims) {
-		struct direct_im *n = od->direct_ims->data;
-		if (n->watcher > 0)
-			gaim_input_remove(n->watcher);
-		od->direct_ims = g_slist_remove(od->direct_ims, n);
-		g_free(n);
-	}
-/* BBB */
-	while (od->file_transfers) {
-		GaimXfer *xfer;
-		xfer = (GaimXfer *)od->file_transfers->data;
-		gaim_xfer_destroy(xfer);
-	}
-	while (od->requesticon) {
-		char *sn = od->requesticon->data;
-		od->requesticon = g_slist_remove(od->requesticon, sn);
-		free(sn);
-	}
-	g_hash_table_destroy(od->buddyinfo);
-	while (od->create_rooms) {
-		struct create_room *cr = od->create_rooms->data;
-		g_free(cr->name);
-		od->create_rooms = g_slist_remove(od->create_rooms, cr);
-		g_free(cr);
-	}
-	if (od->email)
-		g_free(od->email);
-	if (od->newp)
-		g_free(od->newp);
-	if (od->oldp)
-		g_free(od->oldp);
-	if (gc->inpa > 0)
-		gaim_input_remove(gc->inpa);
-	if (od->cnpa > 0)
-		gaim_input_remove(od->cnpa);
-	if (od->paspa > 0)
-		gaim_input_remove(od->paspa);
-	if (od->emlpa > 0)
-		gaim_input_remove(od->emlpa);
-	if (od->icopa > 0)
-		gaim_input_remove(od->icopa);
-	if (od->icontimer > 0)
-		g_source_remove(od->icontimer);
-	if (od->getblisttimer)
-		g_source_remove(od->getblisttimer);
-	aim_session_kill(od->sess);
-	g_free(od->sess);
-	od->sess = NULL;
-	g_free(gc->proto_data);
-	gc->proto_data = NULL;
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "Signed off.\n");
-}
-
-static void oscar_bos_connect(gpointer data, gint source, GaimInputCondition cond) {
-	GaimConnection *gc = data;
-	OscarData *od;
-	aim_session_t *sess;
-	aim_conn_t *bosconn;
-
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
-		close(source);
-		return;
-	}
-
-	od = gc->proto_data;
-	sess = od->sess;
-	bosconn = od->conn;	
-	bosconn->fd = source;
-
-	if (source < 0) {
-		gaim_connection_error(gc, _("Could Not Connect"));
-		return;
-	}
-
-	aim_conn_completeconnect(sess, bosconn);
-	gc->inpa = gaim_input_add(bosconn->fd, GAIM_INPUT_READ, oscar_callback, bosconn);
-
-	gaim_connection_update_progress(gc,
-			_("Connection established, cookie sent"), 4, OSCAR_CONNECT_STEPS);
-}
-
-/* BBB */
-/*
- * This little area in oscar.c is the nexus of file transfer code, 
- * so I wrote a little explanation of what happens.  I am such a 
- * ninja.
- *
- * The series of events for a file send is:
- *  -Create xfer and call gaim_xfer_request (this happens in oscar_ask_sendfile)
- *  -User chooses a file and oscar_xfer_init is called.  It establishs a 
- *   listening socket, then asks the remote user to connect to us (and 
- *   gives them the file name, port, IP, etc.)
- *  -They connect to us and we send them an AIM_CB_OFT_PROMPT (this happens 
- *   in oscar_sendfile_estblsh)
- *  -They send us an AIM_CB_OFT_ACK and then we start sending data
- *  -When we finish, they send us an AIM_CB_OFT_DONE and they close the 
- *   connection.
- *  -We get drunk because file transfer kicks ass.
- *
- * The series of events for a file receive is:
- *  -Create xfer and call gaim_xfer request (this happens in incomingim_chan2)
- *  -Gaim user selects file to name and location to save file to and 
- *   oscar_xfer_init is called
- *  -It connects to the remote user using the IP they gave us earlier
- *  -After connecting, they send us an AIM_CB_OFT_PROMPT.  In reply, we send 
- *   them an AIM_CB_OFT_ACK.
- *  -They begin to send us lots of raw data.
- *  -When they finish sending data we send an AIM_CB_OFT_DONE and then close 
- *   the connectionn.
- */
-static void oscar_sendfile_connected(gpointer data, gint source, GaimInputCondition condition);
-
-/* XXX - This function is pretty ugly */
-static void oscar_xfer_init(GaimXfer *xfer)
-{
-	struct aim_oft_info *oft_info = xfer->data;
-	GaimConnection *gc = oft_info->sess->aux_data;
-	OscarData *od = gc->proto_data;
-
-	if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) {
-		int i;
-
-		xfer->filename = g_path_get_basename(xfer->local_filename);
-		strncpy(oft_info->fh.name, xfer->filename, 64);
-		oft_info->fh.totsize = gaim_xfer_get_size(xfer);
-		oft_info->fh.size = gaim_xfer_get_size(xfer);
-		oft_info->fh.checksum = aim_oft_checksum_file(xfer->local_filename);
-
-		/*
-		 * First try the port specified earlier (5190).  If that fails, 
-		 * increment by 1 and try again.
-		 */
-		aim_sendfile_listen(od->sess, oft_info);
-		for (i=0; (i<5 && !oft_info->conn); i++) {
-			xfer->local_port = oft_info->port = oft_info->port + 1;
-			aim_sendfile_listen(od->sess, oft_info);
-		}
-		gaim_debug(GAIM_DEBUG_MISC, "oscar",
-				   "port is %d, ip is %s\n",
-				   xfer->local_port, oft_info->clientip);
-		if (oft_info->conn) {
-			xfer->watcher = gaim_input_add(oft_info->conn->fd, GAIM_INPUT_READ, oscar_callback, oft_info->conn);
-			aim_im_sendch2_sendfile_ask(od->sess, oft_info);
-			aim_conn_addhandler(od->sess, oft_info->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_ESTABLISHED, oscar_sendfile_estblsh, 0);
-		} else {
-			gaim_notify_error(gc, NULL, _("File Transfer Aborted"),
-							  _("Unable to establish listener socket."));
-			/* XXX - The below line causes a crash because the transfer is canceled before the "Ok" callback on the file selection thing exists, I think */
-			/* gaim_xfer_cancel_remote(xfer); */
-		}
-	} else if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) {
-		oft_info->conn = aim_newconn(od->sess, AIM_CONN_TYPE_RENDEZVOUS, NULL);
-		if (oft_info->conn) {
-			oft_info->conn->subtype = AIM_CONN_SUBTYPE_OFT_SENDFILE;
-			aim_conn_addhandler(od->sess, oft_info->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_PROMPT, oscar_sendfile_prompt, 0);
-			oft_info->conn->fd = xfer->fd = gaim_proxy_connect(gaim_connection_get_account(gc), xfer->remote_ip, xfer->remote_port, 
-								      oscar_sendfile_connected, xfer);
-			if (xfer->fd == -1) {
-				gaim_notify_error(gc, NULL, _("File Transfer Aborted"),
-								  _("Unable to establish file descriptor."));
-				/* gaim_xfer_cancel_remote(xfer); */
-			}
-		} else {
-			gaim_notify_error(gc, NULL, _("File Transfer Aborted"),
-							  _("Unable to create new connection."));
-			/* gaim_xfer_cancel_remote(xfer); */
-			/* Try a different port? Ask them to connect to us? */
-		}
-
-	}
-}
-
-static void oscar_xfer_start(GaimXfer *xfer)
-{
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "AAA - in oscar_xfer_start\n");
-	/* I'm pretty sure we don't need to do jack here.  Nor Jill. */
-}
-
-static void oscar_xfer_end(GaimXfer *xfer)
-{
-	struct aim_oft_info *oft_info = xfer->data;
-	GaimConnection *gc = oft_info->sess->aux_data;
-	OscarData *od = gc->proto_data;
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "AAA - in oscar_xfer_end\n");
-
-	if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) {
-		oft_info->fh.nrecvd = gaim_xfer_get_bytes_sent(xfer);
-		aim_oft_sendheader(oft_info->sess, AIM_CB_OFT_DONE, oft_info);
-	}
-
-	aim_conn_kill(oft_info->sess, &oft_info->conn);
-	aim_oft_destroyinfo(oft_info);
-	xfer->data = NULL;
-	od->file_transfers = g_slist_remove(od->file_transfers, xfer);
-}
-
-static void oscar_xfer_cancel_send(GaimXfer *xfer)
-{
-	struct aim_oft_info *oft_info = xfer->data;
-	GaimConnection *gc = oft_info->sess->aux_data;
-	OscarData *od = gc->proto_data;
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "AAA - in oscar_xfer_cancel_send\n");
-
-	aim_im_sendch2_sendfile_cancel(oft_info->sess, oft_info);
-
-	aim_conn_kill(oft_info->sess, &oft_info->conn);
-	aim_oft_destroyinfo(oft_info);
-	xfer->data = NULL;
-	od->file_transfers = g_slist_remove(od->file_transfers, xfer);
-}
-
-static void oscar_xfer_cancel_recv(GaimXfer *xfer)
-{
-	struct aim_oft_info *oft_info = xfer->data;
-	GaimConnection *gc = oft_info->sess->aux_data;
-	OscarData *od = gc->proto_data;
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "AAA - in oscar_xfer_cancel_recv\n");
-
-	aim_im_sendch2_sendfile_cancel(oft_info->sess, oft_info);
-
-	aim_conn_kill(oft_info->sess, &oft_info->conn);
-	aim_oft_destroyinfo(oft_info);
-	xfer->data = NULL;
-	od->file_transfers = g_slist_remove(od->file_transfers, xfer);
-}
-
-static void oscar_xfer_ack(GaimXfer *xfer, const char *buffer, size_t size)
-{
-	struct aim_oft_info *oft_info = xfer->data;
-
-	if (gaim_xfer_get_type(xfer) == GAIM_XFER_SEND) {
-		/*
-		 * If we're done sending, intercept the socket from the core ft code
-		 * and wait for the other guy to send the "done" OFT packet.
-		 */
-		if (gaim_xfer_get_bytes_remaining(xfer) <= 0) {
-			gaim_input_remove(xfer->watcher);
-			xfer->watcher = gaim_input_add(xfer->fd, GAIM_INPUT_READ, oscar_callback, oft_info->conn);
-			xfer->fd = 0;
-			gaim_xfer_set_completed(xfer, TRUE);
-		}
-	} else if (gaim_xfer_get_type(xfer) == GAIM_XFER_RECEIVE) {
-		/* Update our rolling checksum.  Like Walmart, yo. */
-		oft_info->fh.recvcsum = aim_oft_checksum_chunk(buffer, size, oft_info->fh.recvcsum);
-	}
-}
-
-static GaimXfer *oscar_find_xfer_by_cookie(GSList *fts, const char *ck)
-{
-	GaimXfer *xfer;
-	struct aim_oft_info *oft_info;
-
-	while (fts) {
-		xfer = fts->data;
-		oft_info = xfer->data;
-
-		if (oft_info && !strcmp(ck, oft_info->cookie))
-			return xfer;
-
-		fts = g_slist_next(fts);
-	}
-
-	return NULL;
-}
-
-static GaimXfer *oscar_find_xfer_by_conn(GSList *fts, aim_conn_t *conn)
-{
-	GaimXfer *xfer;
-	struct aim_oft_info *oft_info;
-
-	while (fts) {
-		xfer = fts->data;
-		oft_info = xfer->data;
-
-		if (oft_info && (conn == oft_info->conn))
-			return xfer;
-
-		fts = g_slist_next(fts);
-	}
-
-	return NULL;
-}
-
-static void oscar_ask_sendfile(GaimConnection *gc, const char *destsn) {
-	OscarData *od = (OscarData *)gc->proto_data;
-	GaimXfer *xfer;
-	struct aim_oft_info *oft_info;
-
-	/* You want to send a file to someone else, you're so generous */
-
-	/* Build the file transfer handle */
-	xfer = gaim_xfer_new(gaim_connection_get_account(gc), GAIM_XFER_SEND, destsn);
-	xfer->local_port = 5190;
-
-	/* Create the oscar-specific data */
-	oft_info = aim_oft_createinfo(od->sess, NULL, destsn, xfer->local_ip, xfer->local_port, 0, 0, NULL);
-	xfer->data = oft_info;
-
-	 /* Setup our I/O op functions */
-	gaim_xfer_set_init_fnc(xfer, oscar_xfer_init);
-	gaim_xfer_set_start_fnc(xfer, oscar_xfer_start);
-	gaim_xfer_set_end_fnc(xfer, oscar_xfer_end);
-	gaim_xfer_set_cancel_send_fnc(xfer, oscar_xfer_cancel_send);
-	gaim_xfer_set_cancel_recv_fnc(xfer, oscar_xfer_cancel_recv);
-	gaim_xfer_set_ack_fnc(xfer, oscar_xfer_ack);
-
-	/* Keep track of this transfer for later */
-	od->file_transfers = g_slist_append(od->file_transfers, xfer);
-
-	/* Now perform the request */
-	gaim_xfer_request(xfer);
-}
-
-static int gaim_parse_auth_resp(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	GaimAccount *account = gc->account;
-	aim_conn_t *bosconn;
-	char *host; int port;
-	int i, rc;
-	va_list ap;
-	struct aim_authresp_info *info;
-
-	port = gaim_account_get_int(account, "port", FAIM_LOGIN_PORT);
-
-	va_start(ap, fr);
-	info = va_arg(ap, struct aim_authresp_info *);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "inside auth_resp (Screen name: %s)\n", info->sn);
-
-	if (info->errorcode || !info->bosip || !info->cookielen || !info->cookie) {
-		char buf[256];
-		switch (info->errorcode) {
-		case 0x05:
-			/* Incorrect nick/password */
-			gc->wants_to_die = TRUE;
-			gaim_connection_error(gc, _("Incorrect nickname or password."));
-			break;
-		case 0x11:
-			/* Suspended account */
-			gc->wants_to_die = TRUE;
-			gaim_connection_error(gc, _("Your account is currently suspended."));
-			break;
-		case 0x14:
-			/* service temporarily unavailable */
-			gaim_connection_error(gc, _("The AOL Instant Messenger service is temporarily unavailable."));
-			break;
-		case 0x18:
-			/* connecting too frequently */
-			gc->wants_to_die = TRUE;
-			gaim_connection_error(gc, _("You have been connecting and disconnecting too frequently. Wait ten minutes and try again. If you continue to try, you will need to wait even longer."));
-			break;
-		case 0x1c:
-			/* client too old */
-			gc->wants_to_die = TRUE;
-			g_snprintf(buf, sizeof(buf), _("The client version you are using is too old. Please upgrade at %s"), GAIM_WEBSITE);
-			gaim_connection_error(gc, buf);
-			break;
-		default:
-			gaim_connection_error(gc, _("Authentication failed"));
-			break;
-		}
-		gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-				   "Login Error Code 0x%04hx\n", info->errorcode);
-		gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-				   "Error URL: %s\n", info->errorurl);
-		od->killme = TRUE;
-		return 1;
-	}
-
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar",
-			   "Reg status: %hu\n", info->regstatus);
-
-	if (info->email) {
-		gaim_debug(GAIM_DEBUG_MISC, "oscar", "Email: %s\n", info->email);
-	} else {
-		gaim_debug(GAIM_DEBUG_MISC, "oscar", "Email is NULL\n");
-	}
-	
-	gaim_debug(GAIM_DEBUG_MISC, "oscar", "BOSIP: %s\n", info->bosip);
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "Closing auth connection...\n");
-	aim_conn_kill(sess, &fr->conn);
-
-	bosconn = aim_newconn(sess, AIM_CONN_TYPE_BOS, NULL);
-	if (bosconn == NULL) {
-		gaim_connection_error(gc, _("Internal Error"));
-		od->killme = TRUE;
-		return 0;
-	}
-
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_bos, 0);
-	aim_conn_addhandler(sess, bosconn, 0x0009, 0x0003, gaim_bosrights, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ACK, AIM_CB_ACK_ACK, NULL, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_REDIRECT, gaim_handle_redirect, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_RIGHTSINFO, gaim_parse_locaterights, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_RIGHTSINFO, gaim_parse_buddyrights, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_ONCOMING, gaim_parse_oncoming, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_BUD, AIM_CB_BUD_OFFGOING, gaim_parse_offgoing, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_INCOMING, gaim_parse_incoming_im, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_ERROR, gaim_parse_locerr, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MISSEDCALL, gaim_parse_misses, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_CLIENTAUTORESP, gaim_parse_clientauto, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_RATECHANGE, gaim_parse_ratechange, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_EVIL, gaim_parse_evilnotify, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, AIM_CB_LOK_ERROR, gaim_parse_searcherror, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOK, 0x0003, gaim_parse_searchreply, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ERROR, gaim_parse_msgerr, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_MTN, gaim_parse_mtn, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_LOC, AIM_CB_LOC_USERINFO, gaim_parse_userinfo, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_MSG, AIM_CB_MSG_ACK, gaim_parse_msgack, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_GEN, AIM_CB_GEN_MOTD, gaim_parse_motd, 0);
-	aim_conn_addhandler(sess, bosconn, 0x0004, 0x0005, gaim_icbm_param_info, 0);
-	aim_conn_addhandler(sess, bosconn, 0x0001, 0x0001, gaim_parse_genericerr, 0);
-	aim_conn_addhandler(sess, bosconn, 0x0003, 0x0001, gaim_parse_genericerr, 0);
-	aim_conn_addhandler(sess, bosconn, 0x0009, 0x0001, gaim_parse_genericerr, 0);
-	aim_conn_addhandler(sess, bosconn, 0x0001, 0x001f, gaim_memrequest, 0);
-	aim_conn_addhandler(sess, bosconn, 0x0001, 0x000f, gaim_selfinfo, 0);
-	aim_conn_addhandler(sess, bosconn, 0x0001, 0x0021, oscar_icon_req,0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSG, gaim_offlinemsg, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_OFFLINEMSGCOMPLETE, gaim_offlinemsgdone, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_POP, 0x0002, gaim_popup, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_ALIAS, gaim_icqalias, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_ICQ, AIM_CB_ICQ_INFO, gaim_icqinfo, 0);
-#ifndef NOSSI
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_ERROR, gaim_ssi_parseerr, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RIGHTSINFO, gaim_ssi_parserights, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_LIST, gaim_ssi_parselist, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_NOLIST, gaim_ssi_parselist, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_SRVACK, gaim_ssi_parseack, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTH, gaim_ssi_authgiven, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREQ, gaim_ssi_authrequest, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_RECVAUTHREP, gaim_ssi_authreply, 0);
-	aim_conn_addhandler(sess, bosconn, AIM_CB_FAM_SSI, AIM_CB_SSI_ADDED, gaim_ssi_gotadded, 0);
-#endif
-
-	od->conn = bosconn;
-	for (i = 0; i < (int)strlen(info->bosip); i++) {
-		if (info->bosip[i] == ':') {
-			port = atoi(&(info->bosip[i+1]));
-			break;
-		}
-	}
-	host = g_strndup(info->bosip, i);
-	bosconn->status |= AIM_CONN_STATUS_INPROGRESS;
-	rc = gaim_proxy_connect(gc->account, host, port, oscar_bos_connect, gc);
-	g_free(host);
-	if (rc < 0) {
-		gaim_connection_error(gc, _("Could Not Connect"));
-		od->killme = TRUE;
-		return 0;
-	}
-	aim_sendcookie(sess, bosconn, info->cookielen, info->cookie);
-	gaim_input_remove(gc->inpa);
-
-	gaim_connection_update_progress(gc, _("Received authorization"), 3, OSCAR_CONNECT_STEPS);
-
-	return 1;
-}
-
-/* XXX - Should use gaim_url_fetch for the below stuff */
-struct pieceofcrap {
-	GaimConnection *gc;
-	unsigned long offset;
-	unsigned long len;
-	char *modname;
-	int fd;
-	aim_conn_t *conn;
-	unsigned int inpa;
-};
-
-static void damn_you(gpointer data, gint source, GaimInputCondition c)
-{
-	struct pieceofcrap *pos = data;
-	OscarData *od = pos->gc->proto_data;
-	char in = '\0';
-	int x = 0;
-	unsigned char m[17];
-
-	while (read(pos->fd, &in, 1) == 1) {
-		if (in == '\n')
-			x++;
-		else if (in != '\r')
-			x = 0;
-		if (x == 2)
-			break;
-		in = '\0';
-	}
-	if (in != '\n') {
-		char buf[256];
-		g_snprintf(buf, sizeof(buf), _("You may be disconnected shortly.  You may want to use TOC until "
-			"this is fixed.  Check %s for updates."), GAIM_WEBSITE);
-		gaim_notify_warning(pos->gc, NULL,
-							_("Gaim was unable to get a valid AIM login hash."),
-							buf);
-		gaim_input_remove(pos->inpa);
-		close(pos->fd);
-		g_free(pos);
-		return;
-	}
-	read(pos->fd, m, 16);
-	m[16] = '\0';
-	gaim_debug(GAIM_DEBUG_MISC, "oscar", "Sending hash: ");
-	for (x = 0; x < 16; x++)
-		gaim_debug(GAIM_DEBUG_MISC, NULL, "%02hhx ", (unsigned char)m[x]);
-
-	gaim_debug(GAIM_DEBUG_MISC, NULL, "\n");
-	gaim_input_remove(pos->inpa);
-	close(pos->fd);
-	aim_sendmemblock(od->sess, pos->conn, 0, 16, m, AIM_SENDMEMBLOCK_FLAG_ISHASH);
-	g_free(pos);
-}
-
-static void straight_to_hell(gpointer data, gint source, GaimInputCondition cond) {
-	struct pieceofcrap *pos = data;
-	gchar *buf;
-
-	pos->fd = source;
-
-	if (source < 0) {
-		buf = g_strdup_printf(_("You may be disconnected shortly.  You may want to use TOC until "
-			"this is fixed.  Check %s for updates."), GAIM_WEBSITE);
-		gaim_notify_warning(pos->gc, NULL,
-							_("Gaim was unable to get a valid AIM login hash."),
-							buf);
-		g_free(buf);
-		if (pos->modname)
-			g_free(pos->modname);
-		g_free(pos);
-		return;
-	}
-
-	buf = g_strdup_printf("GET " AIMHASHDATA "?offset=%ld&len=%ld&modname=%s HTTP/1.0\n\n",
-			pos->offset, pos->len, pos->modname ? pos->modname : "");
-	write(pos->fd, buf, strlen(buf));
-	g_free(buf);
-	if (pos->modname)
-		g_free(pos->modname);
-	pos->inpa = gaim_input_add(pos->fd, GAIM_INPUT_READ, damn_you, pos);
-	return;
-}
-
-/* size of icbmui.ocm, the largest module in AIM 3.5 */
-#define AIM_MAX_FILE_SIZE 98304
-
-int gaim_memrequest(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	struct pieceofcrap *pos;
-	fu32_t offset, len;
-	char *modname;
-
-	va_start(ap, fr);
-	offset = va_arg(ap, fu32_t);
-	len = va_arg(ap, fu32_t);
-	modname = va_arg(ap, char *);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar",
-			   "offset: %u, len: %u, file: %s\n",
-			   offset, len, (modname ? modname : "aim.exe"));
-
-	if (len == 0) {
-		gaim_debug(GAIM_DEBUG_MISC, "oscar", "len is 0, hashing NULL\n");
-		aim_sendmemblock(sess, fr->conn, offset, len, NULL,
-				AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
-		return 1;
-	}
-	/* uncomment this when you're convinced it's right. remember, it's been wrong before.
-	if (offset > AIM_MAX_FILE_SIZE || len > AIM_MAX_FILE_SIZE) {
-		char *buf;
-		int i = 8;
-		if (modname)
-			i += strlen(modname);
-		buf = g_malloc(i);
-		i = 0;
-		if (modname) {
-			memcpy(buf, modname, strlen(modname));
-			i += strlen(modname);
-		}
-		buf[i++] = offset & 0xff;
-		buf[i++] = (offset >> 8) & 0xff;
-		buf[i++] = (offset >> 16) & 0xff;
-		buf[i++] = (offset >> 24) & 0xff;
-		buf[i++] = len & 0xff;
-		buf[i++] = (len >> 8) & 0xff;
-		buf[i++] = (len >> 16) & 0xff;
-		buf[i++] = (len >> 24) & 0xff;
-		gaim_debug(GAIM_DEBUG_MISC, "oscar", "len + offset is invalid, "
-		           "hashing request\n");
-		aim_sendmemblock(sess, command->conn, offset, i, buf, AIM_SENDMEMBLOCK_FLAG_ISREQUEST);
-		g_free(buf);
-		return 1;
-	}
-	*/
-
-	pos = g_new0(struct pieceofcrap, 1);
-	pos->gc = sess->aux_data;
-	pos->conn = fr->conn;
-
-	pos->offset = offset;
-	pos->len = len;
-	pos->modname = modname ? g_strdup(modname) : NULL;
-
-	if (gaim_proxy_connect(pos->gc->account, "gaim.sourceforge.net", 80, straight_to_hell, pos) != 0) {
-		char buf[256];
-		if (pos->modname)
-			g_free(pos->modname);
-		g_free(pos);
-		g_snprintf(buf, sizeof(buf), _("You may be disconnected shortly.  You may want to use TOC until "
-			"this is fixed.  Check %s for updates."), GAIM_WEBSITE);
-		gaim_notify_warning(pos->gc, NULL,
-							_("Gaim was unable to get a valid login hash."),
-							buf);
-	}
-
-	return 1;
-}
-
-static int gaim_parse_login(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	GaimAccount *account = gaim_connection_get_account(gc);
-	GaimAccount *ac = gaim_connection_get_account(gc);
-#if 0
-	struct client_info_s info = {"gaim", 7, 3, 2003, "us", "en", 0x0004, 0x0000, 0x04b};
-#endif
-	va_list ap;
-	char *key;
-
-	va_start(ap, fr);
-	key = va_arg(ap, char *);
-	va_end(ap);
-
-	if (od->icq) {
-		struct client_info_s info = CLIENTINFO_ICQ_KNOWNGOOD;
-		aim_send_login(sess, fr->conn, gaim_account_get_username(ac),
-					   gaim_account_get_password(account), &info, key);
-	} else {
-		struct client_info_s info = CLIENTINFO_AIM_KNOWNGOOD;
-		aim_send_login(sess, fr->conn, gaim_account_get_username(ac),
-					   gaim_account_get_password(account), &info, key);
-	}
-
-	gaim_connection_update_progress(gc, _("Password sent"), 2, OSCAR_CONNECT_STEPS);
-
-	return 1;
-}
-
-static int conninitdone_chat(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	struct chat_connection *chatcon;
-	static int id = 1;
-
-	aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, 0x0001, gaim_parse_genericerr, 0);
-	aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERJOIN, gaim_conv_chat_join, 0);
-	aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_USERLEAVE, gaim_conv_chat_leave, 0);
-	aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_ROOMINFOUPDATE, gaim_conv_chat_info_update, 0);
-	aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CHT, AIM_CB_CHT_INCOMINGMSG, gaim_conv_chat_incoming_msg, 0);
-
-	aim_clientready(sess, fr->conn);
-
-	chatcon = find_oscar_chat_by_conn(gc, fr->conn);
-	chatcon->id = id;
-	chatcon->cnv = serv_got_joined_chat(gc, id++, chatcon->show);
-
-	return 1;
-}
-
-static int conninitdone_chatnav(aim_session_t *sess, aim_frame_t *fr, ...) {
-
-	aim_conn_addhandler(sess, fr->conn, 0x000d, 0x0001, gaim_parse_genericerr, 0);
-	aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_CTN, AIM_CB_CTN_INFO, gaim_chatnav_info, 0);
-
-	aim_clientready(sess, fr->conn);
-
-	aim_chatnav_reqrights(sess, fr->conn);
-
-	return 1;
-}
-
-static int conninitdone_email(aim_session_t *sess, aim_frame_t *fr, ...) {
-
-	aim_conn_addhandler(sess, fr->conn, 0x0018, 0x0001, gaim_parse_genericerr, 0);
-	aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_EML, AIM_CB_EML_MAILSTATUS, gaim_email_parseupdate, 0);
-
-	aim_email_sendcookies(sess);
-	aim_email_activate(sess);
-	aim_clientready(sess, fr->conn);
-
-	return 1;
-}
-
-static int conninitdone_icon(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-
-	aim_conn_addhandler(sess, fr->conn, 0x0018, 0x0001, gaim_parse_genericerr, 0);
-	aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_ICO, AIM_CB_ICO_ERROR, gaim_icon_error, 0);
-	aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_ICO, AIM_CB_ICO_RESPONSE, gaim_icon_parseicon, 0);
-
-	aim_clientready(sess, fr->conn);
-
-	od->iconconnecting = FALSE;
-
-	if (od->icontimer)
-		g_source_remove(od->icontimer);
-	od->icontimer = g_timeout_add(100, gaim_icon_timerfunc, gc);
-
-	return 1;
-}
-
-static void oscar_chatnav_connect(gpointer data, gint source, GaimInputCondition cond) {
-	GaimConnection *gc = data;
-	OscarData *od;
-	aim_session_t *sess;
-	aim_conn_t *tstconn;
-
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
-		close(source);
-		return;
-	}
-
-	od = gc->proto_data;
-	sess = od->sess;
-	tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_CHATNAV);
-	tstconn->fd = source;
-
-	if (source < 0) {
-		aim_conn_kill(sess, &tstconn);
-		gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-				   "unable to connect to chatnav server\n");
-		return;
-	}
-
-	aim_conn_completeconnect(sess, tstconn);
-	od->cnpa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn);
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "chatnav: connected\n");
-}
-
-static void oscar_auth_connect(gpointer data, gint source, GaimInputCondition cond)
-{
-	GaimConnection *gc = data;
-	OscarData *od;
-	aim_session_t *sess;
-	aim_conn_t *tstconn;
-
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
-		close(source);
-		return;
-	}
-
-	od = gc->proto_data;
-	sess = od->sess;
-	tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_AUTH);
-	tstconn->fd = source;
-
-	if (source < 0) {
-		aim_conn_kill(sess, &tstconn);
-		gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-				   "unable to connect to authorizer\n");
-		return;
-	}
-
-	aim_conn_completeconnect(sess, tstconn);
-	od->paspa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn);
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "admin: connected\n");
-}
-
-static void oscar_chat_connect(gpointer data, gint source, GaimInputCondition cond)
-{
-	struct chat_connection *ccon = data;
-	GaimConnection *gc = ccon->gc;
-	OscarData *od;
-	aim_session_t *sess;
-	aim_conn_t *tstconn;
-
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
-		close(source);
-		g_free(ccon->show);
-		g_free(ccon->name);
-		g_free(ccon);
-		return;
-	}
-
-	od = gc->proto_data;
-	sess = od->sess;
-	tstconn = ccon->conn;
-	tstconn->fd = source;
-
-	if (source < 0) {
-		aim_conn_kill(sess, &tstconn);
-		g_free(ccon->show);
-		g_free(ccon->name);
-		g_free(ccon);
-		return;
-	}
-
-	aim_conn_completeconnect(sess, ccon->conn);
-	ccon->inpa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn);
-	od->oscar_chats = g_slist_append(od->oscar_chats, ccon);
-}
-
-static void oscar_email_connect(gpointer data, gint source, GaimInputCondition cond) {
-	GaimConnection *gc = data;
-	OscarData *od;
-	aim_session_t *sess;
-	aim_conn_t *tstconn;
-
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
-		close(source);
-		return;
-	}
-
-	od = gc->proto_data;
-	sess = od->sess;
-	tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_EMAIL);
-	tstconn->fd = source;
-
-	if (source < 0) {
-		aim_conn_kill(sess, &tstconn);
-		gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-				   "unable to connect to email server\n");
-		return;
-	}
-
-	aim_conn_completeconnect(sess, tstconn);
-	od->emlpa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn);
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "email: connected\n");
-}
-
-static void oscar_icon_connect(gpointer data, gint source, GaimInputCondition cond) {
-	GaimConnection *gc = data;
-	OscarData *od;
-	aim_session_t *sess;
-	aim_conn_t *tstconn;
-
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
-		close(source);
-		return;
-	}
-
-	od = gc->proto_data;
-	sess = od->sess;
-	tstconn = aim_getconn_type_all(sess, AIM_CONN_TYPE_ICON);
-	tstconn->fd = source;
-
-	if (source < 0) {
-		aim_conn_kill(sess, &tstconn);
-		gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-				   "unable to connect to icon server\n");
-		return;
-	}
-
-	aim_conn_completeconnect(sess, tstconn);
-	od->icopa = gaim_input_add(tstconn->fd, GAIM_INPUT_READ, oscar_callback, tstconn);
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "icon: connected\n");
-}
-
-/* Hrmph. I don't know how to make this look better. --mid */
-static int gaim_handle_redirect(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	GaimAccount *account = gaim_connection_get_account(gc);
-	aim_conn_t *tstconn;
-	int i;
-	char *host;
-	int port;
-	va_list ap;
-	struct aim_redirect_data *redir;
-
-	port = gaim_account_get_int(account, "port", FAIM_LOGIN_PORT);
-
-	va_start(ap, fr);
-	redir = va_arg(ap, struct aim_redirect_data *);
-	va_end(ap);
-
-	for (i = 0; i < (int)strlen(redir->ip); i++) {
-		if (redir->ip[i] == ':') {
-			port = atoi(&(redir->ip[i+1]));
-			break;
-		}
-	}
-	host = g_strndup(redir->ip, i);
-
-	switch(redir->group) {
-	case 0x7: /* Authorizer */
-		gaim_debug(GAIM_DEBUG_INFO, "oscar",
-				   "Reconnecting with authorizor...\n");
-		tstconn = aim_newconn(sess, AIM_CONN_TYPE_AUTH, NULL);
-		if (tstconn == NULL) {
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "unable to reconnect with authorizer\n");
-			g_free(host);
-			return 1;
-		}
-		aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0);
-		aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_admin, 0);
-
-		tstconn->status |= AIM_CONN_STATUS_INPROGRESS;
-		if (gaim_proxy_connect(account, host, port, oscar_auth_connect, gc) != 0) {
-			aim_conn_kill(sess, &tstconn);
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "unable to reconnect with authorizer\n");
-			g_free(host);
-			return 1;
-		}
-		aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie);
-	break;
-
-	case 0xd: /* ChatNav */
-		tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHATNAV, NULL);
-		if (tstconn == NULL) {
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "unable to connect to chatnav server\n");
-			g_free(host);
-			return 1;
-		}
-		aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0);
-		aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_chatnav, 0);
-
-		tstconn->status |= AIM_CONN_STATUS_INPROGRESS;
-		if (gaim_proxy_connect(account, host, port, oscar_chatnav_connect, gc) != 0) {
-			aim_conn_kill(sess, &tstconn);
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "unable to connect to chatnav server\n");
-			g_free(host);
-			return 1;
-		}
-		aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie);
-	break;
-
-	case 0xe: { /* Chat */
-		struct chat_connection *ccon;
-
-		tstconn = aim_newconn(sess, AIM_CONN_TYPE_CHAT, NULL);
-		if (tstconn == NULL) {
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "unable to connect to chat server\n");
-			g_free(host);
-			return 1;
-		}
-
-		aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0);
-		aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_chat, 0);
-
-		ccon = g_new0(struct chat_connection, 1);
-		ccon->conn = tstconn;
-		ccon->gc = gc;
-		ccon->fd = -1;
-		ccon->name = g_strdup(redir->chat.room);
-		ccon->exchange = redir->chat.exchange;
-		ccon->instance = redir->chat.instance;
-		ccon->show = extract_name(redir->chat.room);
-
-		ccon->conn->status |= AIM_CONN_STATUS_INPROGRESS;
-		if (gaim_proxy_connect(account, host, port, oscar_chat_connect, ccon) != 0) {
-			aim_conn_kill(sess, &tstconn);
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "unable to connect to chat server\n");
-			g_free(host);
-			g_free(ccon->show);
-			g_free(ccon->name);
-			g_free(ccon);
-			return 1;
-		}
-		aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie);
-		gaim_debug(GAIM_DEBUG_INFO, "oscar",
-				   "Connected to chat room %s exchange %hu\n",
-				   ccon->name, ccon->exchange);
-	} break;
-
-	case 0x0010: { /* icon */
-		if (!(tstconn = aim_newconn(sess, AIM_CONN_TYPE_ICON, NULL))) {
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "unable to connect to icon server\n");
-			g_free(host);
-			return 1;
-		}
-		aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0);
-		aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_icon, 0);
-
-		tstconn->status |= AIM_CONN_STATUS_INPROGRESS;
-		if (gaim_proxy_connect(account, host, port, oscar_icon_connect, gc) != 0) {
-			aim_conn_kill(sess, &tstconn);
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "unable to connect to icon server\n");
-			g_free(host);
-			return 1;
-		}
-		aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie);
-	} break;
-
-	case 0x0018: { /* email */
-		if (!(tstconn = aim_newconn(sess, AIM_CONN_TYPE_EMAIL, NULL))) {
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "unable to connect to email server\n");
-			g_free(host);
-			return 1;
-		}
-		aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR, gaim_connerr, 0);
-		aim_conn_addhandler(sess, tstconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE, conninitdone_email, 0);
-
-		tstconn->status |= AIM_CONN_STATUS_INPROGRESS;
-		if (gaim_proxy_connect(account, host, port, oscar_email_connect, gc) != 0) {
-			aim_conn_kill(sess, &tstconn);
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "unable to connect to email server\n");
-			g_free(host);
-			return 1;
-		}
-		aim_sendcookie(sess, tstconn, redir->cookielen, redir->cookie);
-	} break;
-
-	default: /* huh? */
-		gaim_debug(GAIM_DEBUG_WARNING, "oscar",
-				   "got redirect for unknown service 0x%04hx\n",
-				   redir->group);
-		break;
-	}
-
-	g_free(host);
-	return 1;
-}
-
-static int gaim_parse_oncoming(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	struct buddyinfo *bi;
-	time_t time_idle = 0, signon = 0;
-	int type = 0;
-	int caps = 0;
-	va_list ap;
-	aim_userinfo_t *info;
-
-	va_start(ap, fr);
-	info = va_arg(ap, aim_userinfo_t *);
-	va_end(ap);
-
-	if (info->present & AIM_USERINFO_PRESENT_CAPABILITIES)
-		caps = info->capabilities;
-	if (info->flags & AIM_FLAG_ACTIVEBUDDY)
-		type |= UC_AB;
-	if (caps & AIM_CAPS_HIPTOP)
-		type |= UC_HIPTOP;
-
-	if (info->present & AIM_USERINFO_PRESENT_FLAGS) {
-		if (info->flags & AIM_FLAG_UNCONFIRMED)
-			type |= UC_UNCONFIRMED;
-		if (info->flags & AIM_FLAG_ADMINISTRATOR)
-			type |= UC_ADMIN;
-		if (info->flags & AIM_FLAG_AOL)
-			type |= UC_AOL;
-		if (info->flags & AIM_FLAG_FREE)
-			type |= UC_NORMAL;
-		if (info->flags & AIM_FLAG_AWAY)
-			type |= UC_UNAVAILABLE;
-		if (info->flags & AIM_FLAG_WIRELESS)
-			type |= UC_WIRELESS;
-	}
-	if (info->present & AIM_USERINFO_PRESENT_ICQEXTSTATUS) {
-		type = (info->icqinfo.status << 16);
-		if (!(info->icqinfo.status & AIM_ICQ_STATE_CHAT) &&
-		      (info->icqinfo.status != AIM_ICQ_STATE_NORMAL)) {
-			type |= UC_UNAVAILABLE;
-		}
-	}
-
-	if (caps & AIM_CAPS_ICQ_DIRECT)
-		caps ^= AIM_CAPS_ICQ_DIRECT;
-
-	if (info->present & AIM_USERINFO_PRESENT_IDLE) {
-		time(&time_idle);
-		time_idle -= info->idletime*60;
-	}
-
-	if (info->present & AIM_USERINFO_PRESENT_ONLINESINCE)
-		signon = info->onlinesince;
-	else if (info->present & AIM_USERINFO_PRESENT_SESSIONLEN)
-		signon = time(NULL) - info->sessionlen;
-
-	if (!aim_sncmp(gaim_account_get_username(gaim_connection_get_account(gc)), info->sn))
-		gaim_connection_set_display_name(gc, info->sn);
-
-	bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(gc->account, info->sn));
-	if (!bi) {
-		bi = g_new0(struct buddyinfo, 1);
-		g_hash_table_insert(od->buddyinfo, g_strdup(gaim_normalize(gc->account, info->sn)), bi);
-	}
-	bi->typingnot = FALSE;
-	bi->ico_informed = FALSE;
-	bi->ipaddr = info->icqinfo.ipaddr;
-
-	/* Available message stuff */
-	free(bi->availmsg);
-	if (info->avail != NULL)
-		if (info->avail_encoding) {
-			gchar *enc = g_strdup_printf("charset=\"%s\"", info->avail_encoding);
-			bi->availmsg = oscar_encoding_to_utf8(enc, info->avail, info->avail_len);
-			g_free(enc);
-		} else {
-			/* No explicit encoding means utf8.  Yay. */
-			bi->availmsg = g_strdup(info->avail);
-		}
-	else
-		bi->availmsg = NULL;
-
-	/* Server stored icon stuff */
-	if (info->iconcsumlen) {
-		const char *filename = NULL, *saved_b16 = NULL;
-		char *b16 = NULL;
-		GaimBuddy *b = NULL;
-
-		b16 = gaim_base16_encode(info->iconcsum, info->iconcsumlen);
-		b = gaim_find_buddy(gc->account, info->sn);
-		/*
-		 * If for some reason the checksum is valid, but cached file is not..
-		 * we want to know.
-		 */
-		filename = gaim_buddy_get_setting(b, "buddy_icon");
-		if (filename != NULL) {
-			if (g_file_test(filename, G_FILE_TEST_EXISTS))
-				saved_b16 = gaim_buddy_get_setting(b, "icon_checksum");
-		} else
-			saved_b16 = NULL;
-
-		if (!b16 || !saved_b16 || strcmp(b16, saved_b16)) {
-			GSList *cur = od->requesticon;
-			while (cur && aim_sncmp((char *)cur->data, info->sn))
-				cur = cur->next;
-			if (!cur) {
-				od->requesticon = g_slist_append(od->requesticon, g_strdup(gaim_normalize(gc->account, info->sn)));
-				if (od->icontimer)
-					g_source_remove(od->icontimer);
-				od->icontimer = g_timeout_add(500, gaim_icon_timerfunc, gc);
-			}
-		}
-		g_free(b16);
-	}
-
-	serv_got_update(gc, info->sn, 1, (info->warnlevel/10.0) + 0.5, signon, time_idle, type);
-
-	return 1;
-}
-
-static int gaim_parse_offgoing(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	va_list ap;
-	aim_userinfo_t *info;
-
-	va_start(ap, fr);
-	info = va_arg(ap, aim_userinfo_t *);
-	va_end(ap);
-
-	serv_got_update(gc, info->sn, 0, 0, 0, 0, 0);
-
-	g_hash_table_remove(od->buddyinfo, gaim_normalize(gc->account, info->sn));
-
-	return 1;
-}
-
-static void cancel_direct_im(struct ask_direct *d) {
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "Freeing DirectIM prompts.\n");
-
-	g_free(d->sn);
-	g_free(d);
-}
-
-static void oscar_odc_callback(gpointer data, gint source, GaimInputCondition condition) {
-	struct direct_im *dim = data;
-	GaimConnection *gc = dim->gc;
-	OscarData *od = gc->proto_data;
-	GaimConversation *cnv;
-	char buf[256];
-	struct sockaddr name;
-	socklen_t name_len = 1;
-	
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
-		g_free(dim);
-		return;
-	}
-
-	if (source < 0) {
-		g_free(dim);
-		return;
-	}
-
-	dim->conn->fd = source;
-	aim_conn_completeconnect(od->sess, dim->conn);
-	cnv = gaim_conversation_new(GAIM_CONV_IM, dim->gc->account, dim->name);
-
-	/* This is the best way to see if we're connected or not */
-	if (getpeername(source, &name, &name_len) == 0) {
-		g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), dim->name);
-		dim->connected = TRUE;
-		gaim_conversation_write(cnv, NULL, buf, GAIM_MESSAGE_SYSTEM, time(NULL));
-	}
-	od->direct_ims = g_slist_append(od->direct_ims, dim);
-	
-	dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, oscar_callback, dim->conn);
-}
-
-/* BBB */
-/*
- * This is called after a remote AIM user has connected to us.  We 
- * want to do some voodoo with the socket file descriptors, add a 
- * callback or two, and then send the AIM_CB_OFT_PROMPT.
- */
-static int oscar_sendfile_estblsh(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = (OscarData *)gc->proto_data;
-	GaimXfer *xfer;
-	struct aim_oft_info *oft_info;
-	va_list ap;
-	aim_conn_t *conn, *listenerconn;
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "AAA - in oscar_sendfile_estblsh\n");
-	va_start(ap, fr);
-	conn = va_arg(ap, aim_conn_t *);
-	listenerconn = va_arg(ap, aim_conn_t *);
-	va_end(ap);
-
-	if (!(xfer = oscar_find_xfer_by_conn(od->file_transfers, listenerconn)))
-		return 1;
-
-	if (!(oft_info = xfer->data))
-		return 1;
-
-	/* Stop watching listener conn; watch transfer conn instead */
-	gaim_input_remove(xfer->watcher);
-	aim_conn_kill(sess, &listenerconn);
-
-	oft_info->conn = conn;
-	xfer->fd = oft_info->conn->fd;
-
-	aim_conn_addhandler(sess, oft_info->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_ACK, oscar_sendfile_ack, 0);
-	aim_conn_addhandler(sess, oft_info->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DONE, oscar_sendfile_done, 0);
-	xfer->watcher = gaim_input_add(oft_info->conn->fd, GAIM_INPUT_READ, oscar_callback, oft_info->conn);
-
-	/* Inform the other user that we are connected and ready to transfer */
-	aim_oft_sendheader(sess, AIM_CB_OFT_PROMPT, oft_info);
-
-	return 0;
-}
-
-/*
- * This is the gaim callback passed to gaim_proxy_connect when connecting to another AIM 
- * user in order to transfer a file.
- */
-static void oscar_sendfile_connected(gpointer data, gint source, GaimInputCondition condition) {
-	GaimXfer *xfer;
-	struct aim_oft_info *oft_info;
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "AAA - in oscar_sendfile_connected\n");
-	if (!(xfer = data))
-		return;
-	if (!(oft_info = xfer->data))
-		return;
-	if (source < 0)
-		return;
-
-	xfer->fd = source;
-	oft_info->conn->fd = source;
-
-	aim_conn_completeconnect(oft_info->sess, oft_info->conn);
-	xfer->watcher = gaim_input_add(xfer->fd, GAIM_INPUT_READ, oscar_callback, oft_info->conn);
-
-	/* Inform the other user that we are connected and ready to transfer */
-	aim_im_sendch2_sendfile_accept(oft_info->sess, oft_info);
-
-	return;
-}
-
-/*
- * This is called when a buddy sends us some file info.  This happens when they 
- * are sending a file to you, and you have just established a connection to them.
- * You should send them the exact same info except use the real cookie.  We also 
- * get like totally ready to like, receive the file, kay?
- */
-static int oscar_sendfile_prompt(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	GaimXfer *xfer;
-	struct aim_oft_info *oft_info;
-	va_list ap;
-	aim_conn_t *conn;
-	fu8_t *cookie;
-	struct aim_fileheader_t *fh;
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "AAA - in oscar_sendfile_prompt\n");
-	va_start(ap, fr);
-	conn = va_arg(ap, aim_conn_t *);
-	cookie = va_arg(ap, fu8_t *);
-	fh = va_arg(ap, struct aim_fileheader_t *);
-	va_end(ap);
-
-	if (!(xfer = oscar_find_xfer_by_conn(od->file_transfers, conn)))
-		return 1;
-
-	if (!(oft_info = xfer->data))
-		return 1;
-
-	/* We want to stop listening with a normal thingy */
-	gaim_input_remove(xfer->watcher);
-	xfer->watcher = 0;
-
-	/* They sent us some information about the file they're sending */
-	memcpy(&oft_info->fh, fh, sizeof(*fh));
-
-	/* Fill in the cookie */
-	memcpy(&oft_info->fh.bcookie, oft_info->cookie, 8);
-
-	/* XXX - convert the name from UTF-8 to UCS-2 if necessary, and pass the encoding to the call below */
-	aim_oft_sendheader(oft_info->sess, AIM_CB_OFT_ACK, oft_info);
-	gaim_xfer_start(xfer, xfer->fd, NULL, 0);
-
-	return 0;
-}
-
-/*
- * We are sending a file to someone else.  They have just acknowledged our 
- * prompt, so we want to start sending data like there's no tomorrow.
- */
-static int oscar_sendfile_ack(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	GaimXfer *xfer;
-	va_list ap;
-	aim_conn_t *conn;
-	fu8_t *cookie;
-	struct aim_fileheader_t *fh;
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "AAA - in oscar_sendfile_ack\n");
-	va_start(ap, fr);
-	conn = va_arg(ap, aim_conn_t *);
-	cookie = va_arg(ap, fu8_t *);
-	fh = va_arg(ap, struct aim_fileheader_t *);
-	va_end(ap);
-
-	if (!(xfer = oscar_find_xfer_by_cookie(od->file_transfers, cookie)))
-		return 1;
-
-	/* We want to stop listening with a normal thingy */
-	gaim_input_remove(xfer->watcher);
-	xfer->watcher = 0;
-
-	gaim_xfer_start(xfer, xfer->fd, NULL, 0);
-
-	return 0;
-}
-
-/*
- * We just sent a file to someone.  They said they got it and everything, 
- * so we can close our direct connection and what not.
- */
-static int oscar_sendfile_done(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	GaimXfer *xfer;
-	va_list ap;
-	aim_conn_t *conn;
-	fu8_t *cookie;
-	struct aim_fileheader_t *fh;
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "AAA - in oscar_sendfile_done\n");
-	va_start(ap, fr);
-	conn = va_arg(ap, aim_conn_t *);
-	cookie = va_arg(ap, fu8_t *);
-	fh = va_arg(ap, struct aim_fileheader_t *);
-	va_end(ap);
-
-	if (!(xfer = oscar_find_xfer_by_conn(od->file_transfers, conn)))
-		return 1;
-
-	xfer->fd = conn->fd;
-	gaim_xfer_end(xfer);
-
-	return 0;
-}
-
-static void accept_direct_im(struct ask_direct *d) {
-	GaimConnection *gc = d->gc;
-	OscarData *od;
-	struct direct_im *dim;
-	char *host; int port = 4443;
-	int i, rc;
-
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
-		cancel_direct_im(d);
-		return;
-	}
-
-	od = (OscarData *)gc->proto_data;
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "Accepted DirectIM.\n");
-
-	dim = find_direct_im(od, d->sn);
-	if (dim) {
-		cancel_direct_im(d); /* 40 */
-		return;
-	}
-	dim = g_new0(struct direct_im, 1);
-	dim->gc = d->gc;
-	g_snprintf(dim->name, sizeof dim->name, "%s", d->sn);
-
-	dim->conn = aim_odc_connect(od->sess, d->sn, NULL, d->cookie);
-	if (!dim->conn) {
-		g_free(dim);
-		cancel_direct_im(d);
-		return;
-	}
-
-	aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING,
-				gaim_odc_incoming, 0);
-	aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING,
-				gaim_odc_typing, 0);
-	aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER,
-			        gaim_odc_update_ui, 0);
-	for (i = 0; i < (int)strlen(d->ip); i++) {
-		if (d->ip[i] == ':') {
-			port = atoi(&(d->ip[i+1]));
-			break;
-		}
-	}
-	host = g_strndup(d->ip, i);
-	dim->conn->status |= AIM_CONN_STATUS_INPROGRESS;
-	rc = gaim_proxy_connect(gc->account, host, port, oscar_odc_callback, dim);
-	g_free(host);
-	if (rc < 0) {
-		aim_conn_kill(od->sess, &dim->conn);
-		g_free(dim);
-		cancel_direct_im(d);
-		return;
-	}
-
-	cancel_direct_im(d);
-
-	return;
-}
-
-static int incomingim_chan1(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch1_args *args) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	gchar *tmp;
-	GaimConvImFlags flags = 0;
-	gsize convlen;
-	GError *err = NULL;
-	struct buddyinfo *bi;
-	const char *iconfile;
-
-	bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(gc->account, userinfo->sn));
-	if (!bi) {
-		bi = g_new0(struct buddyinfo, 1);
-		g_hash_table_insert(od->buddyinfo, g_strdup(gaim_normalize(gc->account, userinfo->sn)), bi);
-	}
-
-	if (args->icbmflags & AIM_IMFLAGS_AWAY)
-		flags |= GAIM_CONV_IM_AUTO_RESP;
-
-	if (args->icbmflags & AIM_IMFLAGS_TYPINGNOT)
-		bi->typingnot = TRUE;
-	else
-		bi->typingnot = FALSE;
-
-	if ((args->icbmflags & AIM_IMFLAGS_HASICON) && (args->iconlen) && (args->iconsum) && (args->iconstamp)) {
-		gaim_debug(GAIM_DEBUG_MISC, "oscar",
-				   "%s has an icon\n", userinfo->sn);
-		if ((args->iconlen != bi->ico_len) || (args->iconsum != bi->ico_csum) || (args->iconstamp != bi->ico_time)) {
-			bi->ico_need = TRUE;
-			bi->ico_len = args->iconlen;
-			bi->ico_csum = args->iconsum;
-			bi->ico_time = args->iconstamp;
-		}
-	}
-
-	if ((iconfile = gaim_account_get_buddy_icon(gaim_connection_get_account(gc))) && 
-	    (args->icbmflags & AIM_IMFLAGS_BUDDYREQ) && !bi->ico_sent && bi->ico_informed) {
-		FILE *file;
-		struct stat st;
-
-		if (!stat(iconfile, &st)) {
-			char *buf = g_malloc(st.st_size);
-			file = fopen(iconfile, "rb");
-			if (file) {
-				int len = fread(buf, 1, st.st_size, file);
-				gaim_debug(GAIM_DEBUG_INFO, "oscar",
-						   "Sending buddy icon to %s (%d bytes, "
-						   "%lu reported)\n",
-						   userinfo->sn, len, st.st_size);
-				aim_im_sendch2_icon(sess, userinfo->sn, buf, st.st_size,
-					st.st_mtime, aimutil_iconsum(buf, st.st_size));
-				fclose(file);
-			} else
-				gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-						   "Can't open buddy icon file!\n");
-			g_free(buf);
-		} else
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "Can't stat buddy icon file!\n");
-	}
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar",
-			   "Character set is %hu %hu\n", args->charset, args->charsubset);
-	if (args->icbmflags & AIM_IMFLAGS_UNICODE) {
-		/* This message is marked as UNICODE, so we have to
-		 * convert it to utf-8 before handing it to the gaim core.
-		 * This conversion should *never* fail, if it does it
-		 * means that either the incoming ICBM is corrupted or
-		 * there is something we don't understand about it.
-		 * For the record, AIM Unicode is big-endian UCS-2 */
-
-		gaim_debug(GAIM_DEBUG_INFO, "oscar", "Received UNICODE IM\n");
-
-		if (!args->msg || !args->msglen)
-			return 1;
-
-		tmp = g_convert(args->msg, args->msglen, "UTF-8", "UCS-2BE", NULL, &convlen, &err);
-		if (err) {
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "Unicode IM conversion: %s\n", err->message);
-			tmp = g_strdup(_("(There was an error receiving this message)"));
-			g_error_free(err);
-		}
-	} else {
-		/* This will get executed for both AIM_IMFLAGS_ISO_8859_1 and
-		 * unflagged messages, which are ASCII.  That's OK because
-		 * ASCII is a strict subset of ISO-8859-1; this should
-		 * help with compatibility with old, broken versions of
-		 * gaim (everything before 0.60) and other broken clients
-		 * that will happily send ISO-8859-1 without marking it as
-		 * such */
-		if (args->icbmflags & AIM_IMFLAGS_ISO_8859_1)
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "Received ISO-8859-1 IM\n");
-
-		if (!args->msg || !args->msglen)
-			return 1;
-
-		tmp = g_convert(args->msg, args->msglen, "UTF-8", "ISO-8859-1", NULL, &convlen, &err);
-		if (err) {
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "ISO-8859-1 IM conversion: %s\n", err->message);
-			tmp = g_strdup(_("(There was an error receiving this message)"));
-			g_error_free(err);
-		}
-	}
-
-	/* gaim_str_strip_cr(tmp); */
-	serv_got_im(gc, userinfo->sn, tmp, flags, time(NULL));
-	g_free(tmp);
-
-	return 1;
-}
-
-static int incomingim_chan2(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch2_args *args) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	const char *username = gaim_account_get_username(gaim_connection_get_account(gc));
-
-	if (!args)
-		return 0;
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar",
-			   "rendezvous with %s, status is %hu\n",
-			   userinfo->sn, args->status);
-
-	if (args->reqclass & AIM_CAPS_CHAT) {
-		char *name;
-		GHashTable *components;
-
-		if (!args->info.chat.roominfo.name || !args->info.chat.roominfo.exchange || !args->msg)
-			return 1;
-		components = g_hash_table_new_full(g_str_hash, g_str_equal, g_free,
-				g_free);
-		name = extract_name(args->info.chat.roominfo.name);
-		g_hash_table_replace(components, g_strdup("room"), g_strdup(name ? name : args->info.chat.roominfo.name));
-		g_hash_table_replace(components, g_strdup("exchange"), g_strdup_printf("%d", args->info.chat.roominfo.exchange));
-		serv_got_chat_invite(gc,
-				     name ? name : args->info.chat.roominfo.name,
-				     userinfo->sn,
-				     args->msg,
-				     components);
-		if (name)
-			g_free(name);
-	} else if (args->reqclass & AIM_CAPS_SENDFILE) {
-/* BBB */
-		if (args->status == AIM_RENDEZVOUS_PROPOSE) {
-			/* Someone wants to send a file (or files) to us */
-			GaimXfer *xfer;
-			struct aim_oft_info *oft_info;
-
-			if (!args->cookie || !args->port || !args->verifiedip || 
-			    !args->info.sendfile.filename || !args->info.sendfile.totsize || 
-			    !args->info.sendfile.totfiles || !args->reqclass) {
-				gaim_debug(GAIM_DEBUG_WARNING, "oscar",
-						   "%s tried to send you a file with incomplete "
-						   "information.\n", userinfo->sn);
-				if (args->proxyip)
-					gaim_debug(GAIM_DEBUG_WARNING, "oscar",
-							   "IP for a proxy server was given.  Gaim "
-							   "does not support this yet.\n");
-				return 1;
-			}
-
-			if (args->info.sendfile.subtype == AIM_OFT_SUBTYPE_SEND_DIR) {
-				/* last char of the ft req is a star, they are sending us a
-				 * directory -- remove the star and trailing slash so we dont save
-				 * directories that look like 'dirname\*'  -- arl */
-				char *tmp = strrchr(args->info.sendfile.filename, '\\');
-				if (tmp && (tmp[1] == '*')) {
-					tmp[0] = '\0';
-				}
-			}
-
-			/* Build the file transfer handle */
-			xfer = gaim_xfer_new(gc->account, GAIM_XFER_RECEIVE, userinfo->sn);
-			xfer->remote_ip = g_strdup(args->verifiedip);
-			xfer->remote_port = args->port;
-			gaim_xfer_set_filename(xfer, args->info.sendfile.filename);
-			gaim_xfer_set_size(xfer, args->info.sendfile.totsize);
-
-			/* Create the oscar-specific data */
-			oft_info = aim_oft_createinfo(od->sess, args->cookie, userinfo->sn, args->clientip, xfer->remote_port, 0, 0, NULL);
-			if (args->proxyip)
-				oft_info->proxyip = g_strdup(args->proxyip);
-			if (args->verifiedip)
-				oft_info->verifiedip = g_strdup(args->verifiedip);
-			xfer->data = oft_info;
-
-			 /* Setup our I/O op functions */
-			gaim_xfer_set_init_fnc(xfer, oscar_xfer_init);
-			gaim_xfer_set_start_fnc(xfer, oscar_xfer_start);
-			gaim_xfer_set_end_fnc(xfer, oscar_xfer_end);
-			gaim_xfer_set_cancel_send_fnc(xfer, oscar_xfer_cancel_send);
-			gaim_xfer_set_cancel_recv_fnc(xfer, oscar_xfer_cancel_recv);
-			gaim_xfer_set_ack_fnc(xfer, oscar_xfer_ack);
-
-			/*
-			 * XXX - Should do something with args->msg, args->encoding, and args->language
-			 *       probably make it apply to all ch2 messages.
-			 */
-
-			/* Keep track of this transfer for later */
-			od->file_transfers = g_slist_append(od->file_transfers, xfer);
-
-			/* Now perform the request */
-			gaim_xfer_request(xfer);
-		} else if (args->status == AIM_RENDEZVOUS_CANCEL) {
-			/* The other user wants to cancel a file transfer */
-			GaimXfer *xfer;
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "AAA - File transfer canceled by remote user\n");
-			if ((xfer = oscar_find_xfer_by_cookie(od->file_transfers, args->cookie)))
-				gaim_xfer_cancel_remote(xfer);
-		} else if (args->status == AIM_RENDEZVOUS_ACCEPT) {
-			/*
-			 * This gets sent by the receiver of a file 
-			 * as they connect directly to us.  If we don't 
-			 * get this, then maybe a third party connected 
-			 * to us, and we shouldn't send them anything.
-			 */
-		} else {
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "unknown rendezvous status!\n");
-		}
-	} else if (args->reqclass & AIM_CAPS_GETFILE) {
-	} else if (args->reqclass & AIM_CAPS_VOICE) {
-	} else if (args->reqclass & AIM_CAPS_BUDDYICON) {
-		gaim_buddy_icons_set_for_user(gaim_connection_get_account(gc),
-									  userinfo->sn, args->info.icon.icon,
-									  args->info.icon.length);
-	} else if (args->reqclass & AIM_CAPS_DIRECTIM) {
-		struct ask_direct *d = g_new0(struct ask_direct, 1);
-		char buf[256];
-
-		if (!args->verifiedip) {
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "directim kill blocked (%s)\n", userinfo->sn);
-			return 1;
-		}
-
-		gaim_debug(GAIM_DEBUG_INFO, "oscar",
-				   "%s received direct im request from %s (%s)\n",
-				   username, userinfo->sn, args->verifiedip);
-
-		d->gc = gc;
-		d->sn = g_strdup(userinfo->sn);
-		strncpy(d->ip, args->verifiedip, sizeof(d->ip));
-		memcpy(d->cookie, args->cookie, 8);
-		g_snprintf(buf, sizeof buf, _("%s has just asked to directly connect to %s"), userinfo->sn, username);
-
-		gaim_request_action(gc, NULL, buf,
-							_("This requires a direct connection between "
-							  "the two computers and is necessary for IM "
-							  "Images.  Because your IP address will be "
-							  "revealed, this may be considered a privacy "
-							  "risk."), 0, d, 2,
-							_("Connect"), G_CALLBACK(accept_direct_im),
-							_("Cancel"), G_CALLBACK(cancel_direct_im));
-	} else {
-		gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-				   "Unknown reqclass %hu\n", args->reqclass);
-	}
-
-	return 1;
-}
-
-/*
- * Authorization Functions
- * Most of these are callbacks from dialogs.  They're used by both 
- * methods of authorization (SSI and old-school channel 4 ICBM)
- */
-/* When you ask other people for authorization */
-static void gaim_auth_request(struct name_data *data, char *msg) {
-	GaimConnection *gc = data->gc;
-
-	if (g_list_find(gaim_connections_get_all(), gc)) {
-		OscarData *od = gc->proto_data;
-		GaimBuddy *buddy = gaim_find_buddy(gc->account, data->name);
-		GaimGroup *group = gaim_find_buddys_group(buddy);
-		if (buddy && group) {
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "ssi: adding buddy %s to group %s\n",
-					   buddy->name, group->name);
-			aim_ssi_sendauthrequest(od->sess, data->name, msg ? msg : _("Please authorize me so I can add you to my buddy list."));
-			if (!aim_ssi_itemlist_finditem(od->sess->ssi.local, group->name, buddy->name, AIM_SSI_TYPE_BUDDY))
-				aim_ssi_addbuddy(od->sess, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 1);
-		}
-	}
-}
-
-static void gaim_auth_request_msgprompt(struct name_data *data) {
-	gaim_request_input(data->gc, NULL, _("Authorization Request Message:"),
-					   NULL, _("Please authorize me!"), TRUE, FALSE,
-					   _("OK"), G_CALLBACK(gaim_auth_request),
-					   _("Cancel"), G_CALLBACK(oscar_free_name_data),
-					   data);
-}
-
-static void gaim_auth_dontrequest(struct name_data *data) {
-	GaimConnection *gc = data->gc;
-
-	if (g_list_find(gaim_connections_get_all(), gc)) {
-		/* OscarData *od = gc->proto_data; */
-		/* XXX - Take the buddy out of our buddy list */
-	}
-
-	oscar_free_name_data(data);
-}
-
-static void gaim_auth_sendrequest(GaimConnection *gc, const char *name) {
-	struct name_data *data = g_new(struct name_data, 1);
-	GaimBuddy *buddy;
-	gchar *dialog_msg, *nombre;
-
-	buddy = gaim_find_buddy(gc->account, name);
-	if (buddy && (gaim_get_buddy_alias_only(buddy)))
-		nombre = g_strdup_printf("%s (%s)", name, gaim_get_buddy_alias_only(buddy));
-	else
-		nombre = NULL;
-
-	dialog_msg = g_strdup_printf(_("The user %s requires authorization before being added to a buddy list.  Do you want to send an authorization request?"), (nombre ? nombre : name));
-	data->gc = gc;
-	data->name = g_strdup(name);
-	data->nick = NULL;
-
-	gaim_request_action(gc, NULL, _("Request Authorization"), dialog_msg,
-						0, data, 2,
-						_("Request Authorization"),
-						G_CALLBACK(gaim_auth_request_msgprompt),
-						_("Cancel"), G_CALLBACK(gaim_auth_dontrequest));
-
-	g_free(dialog_msg);
-	g_free(nombre);
-}
-
-/* When other people ask you for authorization */
-static void gaim_auth_grant(struct name_data *data) {
-	GaimConnection *gc = data->gc;
-
-	if (g_list_find(gaim_connections_get_all(), gc)) {
-		OscarData *od = gc->proto_data;
-#ifdef NOSSI
-		GaimBuddy *buddy;
-		gchar message;
-		message = 0;
-		buddy = gaim_find_buddy(gc->account, data->name);
-		aim_im_sendch4(od->sess, data->name, AIM_ICQMSG_AUTHGRANTED, &message);
-		gaim_account_notify_added(gc->account, NULL, data->name, (buddy ? gaim_get_buddy_alias_only(buddy) : NULL), NULL);
-#else
-		aim_ssi_sendauthreply(od->sess, data->name, 0x01, NULL);
-#endif
-	}
-
-	oscar_free_name_data(data);
-}
-
-/* When other people ask you for authorization */
-static void gaim_auth_dontgrant(struct name_data *data, char *msg) {
-	GaimConnection *gc = data->gc;
-
-	if (g_list_find(gaim_connections_get_all(), gc)) {
-		OscarData *od = gc->proto_data;
-#ifdef NOSSI
-		aim_im_sendch4(od->sess, data->name, AIM_ICQMSG_AUTHDENIED, msg ? msg : _("No reason given."));
-#else
-		aim_ssi_sendauthreply(od->sess, data->name, 0x00, msg ? msg : _("No reason given."));
-#endif
-	}
-}
-
-static void gaim_auth_dontgrant_msgprompt(struct name_data *data) {
-	gaim_request_input(data->gc, NULL, _("Authorization Denied Message:"),
-					   NULL, _("No reason given."), TRUE, FALSE,
-					   _("OK"), G_CALLBACK(gaim_auth_dontgrant),
-					   _("Cancel"), G_CALLBACK(oscar_free_name_data),
-					   data);
-}
-
-/* When someone sends you buddies */
-static void gaim_icq_buddyadd(struct name_data *data) {
-	GaimConnection *gc = data->gc;
-
-	if (g_list_find(gaim_connections_get_all(), gc)) {
-		gaim_blist_request_add_buddy(gaim_connection_get_account(gc), data->name, NULL, data->nick);
-	}
-
-	oscar_free_name_data(data);
-}
-
-static int incomingim_chan4(aim_session_t *sess, aim_conn_t *conn, aim_userinfo_t *userinfo, struct aim_incomingim_ch4_args *args, time_t t) {
-	GaimConnection *gc = sess->aux_data;
-	gchar **msg1, **msg2;
-	GError *err = NULL;
-	int i, numtoks;
-
-	if (!args->type || !args->msg || !args->uin)
-		return 1;
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "Received a channel 4 message of type 0x%02hhx.\n", args->type);
-
-	/* Split up the message at the delimeter character, then convert each string to UTF-8 */
-	msg1 = g_strsplit(args->msg, "\376", 0);
-	for (numtoks=0; msg1[numtoks]; numtoks++);
-	msg2 = (gchar **)g_malloc((numtoks+1)*sizeof(gchar *));
-	for (i=0; msg1[i]; i++) {
-		gaim_str_strip_cr(msg1[i]);
-		msg2[i] = g_convert(msg1[i], strlen(msg1[i]), "UTF-8", "ISO-8859-1", NULL, NULL, &err);
-		if (err) {
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "Error converting a string from ISO-8859-1 to "
-					   "UTF-8 in oscar ICBM channel 4 parsing\n");
-			g_error_free(err);
-		}
-	}
-	msg2[i] = NULL;
-
-	switch (args->type) {
-		case 0x01: { /* MacICQ message or basic offline message */
-			if (i >= 1) {
-				gchar *uin = g_strdup_printf("%u", args->uin);
-				if (t) { /* This is an offline message */
-					/* I think this timestamp is in UTC, or something */
-					serv_got_im(gc, uin, msg2[0], 0, t);
-				} else { /* This is a message from MacICQ/Miranda */
-					serv_got_im(gc, uin, msg2[0], 0, time(NULL));
-				}
-				g_free(uin);
-			}
-		} break;
-
-		case 0x04: { /* Someone sent you a URL */
-			if (i >= 2) {
-				if (msg2[1] != NULL) {
-					gchar *uin = g_strdup_printf("%u", args->uin);
-					gchar *message = g_strdup_printf("<A HREF=\"%s\">%s</A>",
-													 msg2[1],
-													 (msg2[0] && msg2[0][0]) ? msg2[0] : msg2[1]);
-					serv_got_im(gc, uin, message, 0, time(NULL));
-					g_free(uin);
-					g_free(message);
-				}
-			}
-		} break;
-
-		case 0x06: { /* Someone requested authorization */
-			if (i >= 6) {
-				struct name_data *data = g_new(struct name_data, 1);
-				gchar *dialog_msg = g_strdup_printf(_("The user %u wants to add you to their buddy list for the following reason:\n%s"), args->uin, msg2[5] ? msg2[5] : _("No reason given."));
-				gaim_debug(GAIM_DEBUG_INFO, "oscar",
-						   "Received an authorization request from UIN %u\n",
-						   args->uin);
-				data->gc = gc;
-				data->name = g_strdup_printf("%u", args->uin);
-				data->nick = NULL;
-
-				gaim_request_action(gc, NULL, _("Authorization Request"),
-									dialog_msg, 0, data, 2,
-									_("Authorize"),
-									G_CALLBACK(gaim_auth_grant),
-									_("Deny"),
-									G_CALLBACK(gaim_auth_dontgrant_msgprompt));
-				g_free(dialog_msg);
-			}
-		} break;
-
-		case 0x07: { /* Someone has denied you authorization */
-			if (i >= 1) {
-				gchar *dialog_msg = g_strdup_printf(_("The user %u has denied your request to add them to your buddy list for the following reason:\n%s"), args->uin, msg2[0] ? msg2[0] : _("No reason given."));
-				gaim_notify_info(gc, NULL, _("ICQ authorization denied."),
-								 dialog_msg);
-				g_free(dialog_msg);
-			}
-		} break;
-
-		case 0x08: { /* Someone has granted you authorization */
-			gchar *dialog_msg = g_strdup_printf(_("The user %u has granted your request to add them to your buddy list."), args->uin);
-			gaim_notify_info(gc, NULL, "ICQ authorization accepted.",
-							 dialog_msg);
-			g_free(dialog_msg);
-		} break;
-
-		case 0x09: { /* Message from the Godly ICQ server itself, I think */
-			if (i >= 5) {
-				gchar *dialog_msg = g_strdup_printf(_("You have received a special message\n\nFrom: %s [%s]\n%s"), msg2[0], msg2[3], msg2[5]);
-				gaim_notify_info(gc, NULL, "ICQ Server Message", dialog_msg);
-				g_free(dialog_msg);
-			}
-		} break;
-
-		case 0x0d: { /* Someone has sent you a pager message from http://www.icq.com/your_uin */
-			if (i >= 6) {
-				gchar *dialog_msg = g_strdup_printf(_("You have received an ICQ page\n\nFrom: %s [%s]\n%s"), msg2[0], msg2[3], msg2[5]);
-				gaim_notify_info(gc, NULL, "ICQ Page", dialog_msg);
-				g_free(dialog_msg);
-			}
-		} break;
-
-		case 0x0e: { /* Someone has emailed you at your_uin@pager.icq.com */
-			if (i >= 6) {
-				gchar *dialog_msg = g_strdup_printf(_("You have received an ICQ email from %s [%s]\n\nMessage is:\n%s"), msg2[0], msg2[3], msg2[5]);
-				gaim_notify_info(gc, NULL, "ICQ Email", dialog_msg);
-				g_free(dialog_msg);
-			}
-		} break;
-
-		case 0x12: {
-			/* Ack for authorizing/denying someone.  Or possibly an ack for sending any system notice */
-			/* Someone added you to their buddy list? */
-		} break;
-
-		case 0x13: { /* Someone has sent you some ICQ buddies */
-			int i, num;
-			gchar **text;
-			text = g_strsplit(args->msg, "\376", 0);
-			if (text) {
-				num = 0;
-				for (i=0; i<strlen(text[0]); i++)
-					num = num*10 + text[0][i]-48;
-				for (i=0; i<num; i++) {
-					struct name_data *data = g_new(struct name_data, 1);
-					gchar *message = g_strdup_printf(_("ICQ user %u has sent you a buddy: %s (%s)"), args->uin, text[i*2+2], text[i*2+1]);
-					data->gc = gc;
-					data->name = g_strdup(text[i*2+1]);
-					data->nick = g_strdup(text[i*2+2]);
-
-					gaim_request_action(gc, NULL, message,
-										_("Do you want to add this buddy "
-										  "to your buddy list?"),
-										0, data, 2,
-										_("Add"), G_CALLBACK(gaim_icq_buddyadd),
-										_("Decline"), G_CALLBACK(oscar_free_name_data));
-					g_free(message);
-				}
-				g_strfreev(text);
-			}
-		} break;
-
-		case 0x1a: { /* Someone has sent you a greeting card or requested buddies? */
-			/* This is boring and silly. */
-		} break;
-
-		default: {
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "Received a channel 4 message of unknown type "
-					   "(type 0x%02hhx).\n", args->type);
-		} break;
-	}
-
-	g_strfreev(msg1);
-	g_strfreev(msg2);
-
-	return 1;
-}
-
-static int gaim_parse_incoming_im(aim_session_t *sess, aim_frame_t *fr, ...) {
-	fu16_t channel;
-	int ret = 0;
-	aim_userinfo_t *userinfo;
-	va_list ap;
-
-	va_start(ap, fr);
-	channel = (fu16_t)va_arg(ap, unsigned int);
-	userinfo = va_arg(ap, aim_userinfo_t *);
-
-	switch (channel) {
-		case 1: { /* standard message */
-			struct aim_incomingim_ch1_args *args;
-			args = va_arg(ap, struct aim_incomingim_ch1_args *);
-			ret = incomingim_chan1(sess, fr->conn, userinfo, args);
-		} break;
-
-		case 2: { /* rendevous */
-			struct aim_incomingim_ch2_args *args;
-			args = va_arg(ap, struct aim_incomingim_ch2_args *);
-			ret = incomingim_chan2(sess, fr->conn, userinfo, args);
-		} break;
-
-		case 4: { /* ICQ */
-			struct aim_incomingim_ch4_args *args;
-			args = va_arg(ap, struct aim_incomingim_ch4_args *);
-			ret = incomingim_chan4(sess, fr->conn, userinfo, args, 0);
-		} break;
-
-		default: {
-			gaim_debug(GAIM_DEBUG_WARNING, "oscar",
-					   "ICBM received on unsupported channel (channel "
-					   "0x%04hx).", channel);
-		} break;
-	}
-
-	va_end(ap);
-
-	return ret;
-}
-
-static int gaim_parse_misses(aim_session_t *sess, aim_frame_t *fr, ...) {
-	char *buf;
-	va_list ap;
-	fu16_t chan, nummissed, reason;
-	aim_userinfo_t *userinfo;
-
-	va_start(ap, fr);
-	chan = (fu16_t)va_arg(ap, unsigned int);
-	userinfo = va_arg(ap, aim_userinfo_t *);
-	nummissed = (fu16_t)va_arg(ap, unsigned int);
-	reason = (fu16_t)va_arg(ap, unsigned int);
-	va_end(ap);
-
-	switch(reason) {
-		case 0: /* Invalid (0) */
-			buf = g_strdup_printf(
-				   ngettext(
-				   "You missed %hu message from %s because it was invalid.",
-				   "You missed %hu messages from %s because they were invalid.",
-				   nummissed),
-				   nummissed,
-				   userinfo->sn);
-			break;
-		case 1: /* Message too large */
-			buf = g_strdup_printf(
-				   ngettext(
-				   "You missed %hu message from %s because it was too large.",
-				   "You missed %hu messages from %s because they were too large.",
-				   nummissed),
-				   nummissed,
-				   userinfo->sn);
-			break;
-		case 2: /* Rate exceeded */
-			buf = g_strdup_printf(
-				   ngettext(
-				   "You missed %hu message from %s because the rate limit has been exceeded.",
-				   "You missed %hu messages from %s because the rate limit has been exceeded.",
-				   nummissed),
-				   nummissed,
-				   userinfo->sn);
-			break;
-		case 3: /* Evil Sender */
-			buf = g_strdup_printf(
-				   ngettext(
-				   "You missed %hu message from %s because he/she was too evil.",
-				   "You missed %hu messages from %s because he/she was too evil.",
-				   nummissed),
-				   nummissed,
-				   userinfo->sn);
-			break;
-		case 4: /* Evil Receiver */
-			buf = g_strdup_printf(
-				   ngettext(
-				   "You missed %hu message from %s because you are too evil.",
-				   "You missed %hu messages from %s because you are too evil.",
-				   nummissed),
-				   nummissed,
-				   userinfo->sn);
-			break;
-		default:
-			buf = g_strdup_printf(
-				   ngettext(
-				   "You missed %hu message from %s for an unknown reason.",
-				   "You missed %hu messages from %s for an unknown reason.",
-				   nummissed),
-				   nummissed,
-				   userinfo->sn);
-			break;
-	}
-	gaim_notify_error(sess->aux_data, NULL, buf, NULL);
-	g_free(buf);
-
-	return 1;
-}
-
-static char *gaim_icq_status(int state) {
-	/* Make a cute little string that shows the status of the dude or dudet */
-	if (state & AIM_ICQ_STATE_CHAT)
-		return g_strdup_printf(_("Free For Chat"));
-	else if (state & AIM_ICQ_STATE_DND)
-		return g_strdup_printf(_("Do Not Disturb"));
-	else if (state & AIM_ICQ_STATE_OUT)
-		return g_strdup_printf(_("Not Available"));
-	else if (state & AIM_ICQ_STATE_BUSY)
-		return g_strdup_printf(_("Occupied"));
-	else if (state & AIM_ICQ_STATE_AWAY)
-		return g_strdup_printf(_("Away"));
-	else if (state & AIM_ICQ_STATE_WEBAWARE)
-		return g_strdup_printf(_("Web Aware"));
-	else if (state & AIM_ICQ_STATE_INVISIBLE)
-		return g_strdup_printf(_("Invisible"));
-	else
-		return g_strdup_printf(_("Online"));
-}
-
-static int gaim_parse_clientauto_ch2(aim_session_t *sess, const char *who, fu16_t reason, const char *cookie) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-
-/* BBB */
-	switch (reason) {
-		case 3: { /* Decline sendfile. */
-			GaimXfer *xfer;
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "AAA - Other user declined file transfer\n");
-			if ((xfer = oscar_find_xfer_by_cookie(od->file_transfers, cookie)))
-				gaim_xfer_cancel_remote(xfer);
-		} break;
-
-		default: {
-			gaim_debug(GAIM_DEBUG_WARNING, "oscar",
-					   "Received an unknown rendezvous client auto-response "
-					   "from %s.  Type 0x%04hx\n", who, reason);
-		}
-
-	}
-
-	return 0;
-}
-
-static int gaim_parse_clientauto_ch4(aim_session_t *sess, char *who, fu16_t reason, fu32_t state, char *msg) {
-	GaimConnection *gc = sess->aux_data;
-
-	switch(reason) {
-		case 0x0003: { /* Reply from an ICQ status message request */
-			char *status_msg = gaim_icq_status(state);
-			char *dialog_msg, **splitmsg;
-
-			/* Split at (carriage return/newline)'s, then rejoin later with BRs between. */
-			splitmsg = g_strsplit(msg, "\r\n", 0);
-
-			dialog_msg = g_strdup_printf(_("<B>UIN:</B> %s<BR><B>Status:</B> %s<HR>%s"), who, status_msg, g_strjoinv("<BR>", splitmsg));
-			gaim_notify_formatted(gc, NULL, _("Buddy Information"), NULL, dialog_msg, NULL, NULL);
-
-			g_free(status_msg);
-			g_free(dialog_msg);
-			g_strfreev(splitmsg);
-		} break;
-
-		default: {
-			gaim_debug(GAIM_DEBUG_WARNING, "oscar",
-					   "Received an unknown client auto-response from %s.  "
-					   "Type 0x%04hx\n", who, reason);
-		} break;
-	} /* end of switch */
-
-	return 0;
-}
-
-static int gaim_parse_clientauto(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	fu16_t chan, reason;
-	char *who;
-
-	va_start(ap, fr);
-	chan = (fu16_t)va_arg(ap, unsigned int);
-	who = va_arg(ap, char *);
-	reason = (fu16_t)va_arg(ap, unsigned int);
-
-	if (chan == 0x0002) { /* File transfer declined */
-		char *cookie = va_arg(ap, char *);
-		return gaim_parse_clientauto_ch2(sess, who, reason, cookie);
-	} else if (chan == 0x0004) { /* ICQ message */
-		fu32_t state = 0;
-		char *msg = NULL;
-		if (reason == 0x0003) {
-			state = va_arg(ap, fu32_t);
-			msg = va_arg(ap, char *);
-		}
-		return gaim_parse_clientauto_ch4(sess, who, reason, state, msg);
-	}
-
-	va_end(ap);
-
-	return 1;
-}
-
-static int gaim_parse_genericerr(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	fu16_t reason;
-	char *m;
-
-	va_start(ap, fr);
-	reason = (fu16_t) va_arg(ap, unsigned int);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-			   "snac threw error (reason 0x%04hx: %s)\n", reason,
-			   (reason < msgerrreasonlen) ? msgerrreason[reason] : "unknown");
-
-	m = g_strdup_printf(_("SNAC threw error: %s\n"),
-			reason < msgerrreasonlen ? _(msgerrreason[reason]) : _("Unknown error"));
-	gaim_notify_error(sess->aux_data, NULL, m, NULL);
-	g_free(m);
-
-	return 1;
-}
-
-static int gaim_parse_msgerr(aim_session_t *sess, aim_frame_t *fr, ...) {
-#if 0
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	GaimXfer *xfer;
-#endif
-	va_list ap;
-	fu16_t reason;
-	char *data, *buf;
-
-	va_start(ap, fr);
-	reason = (fu16_t)va_arg(ap, unsigned int);
-	data = va_arg(ap, char *);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-			   "Message error with data %s and reason %hu\n", data, reason);
-
-/* BBB */
-#if 0
-	/* If this was a file transfer request, data is a cookie */
-	if ((xfer = oscar_find_xfer_by_cookie(od->file_transfers, data))) {
-		gaim_xfer_cancel_remote(xfer);
-		return 1;
-	}
-#endif
-
-	/* Data is assumed to be the destination sn */
-	buf = g_strdup_printf(_("Your message to %s did not get sent:"), data);
-	gaim_notify_error(sess->aux_data, NULL, buf,
-					  (reason < msgerrreasonlen) ? _(msgerrreason[reason]) : _("No reason given."));
-	g_free(buf);
-
-	return 1;
-}
-
-static int gaim_parse_mtn(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	va_list ap;
-	fu16_t type1, type2;
-	char *sn;
-
-	va_start(ap, fr);
-	type1 = (fu16_t) va_arg(ap, unsigned int);
-	sn = va_arg(ap, char *);
-	type2 = (fu16_t) va_arg(ap, unsigned int);
-	va_end(ap);
-
-	switch (type2) {
-		case 0x0000: { /* Text has been cleared */
-			serv_got_typing_stopped(gc, sn);
-		} break;
-
-		case 0x0001: { /* Paused typing */
-			serv_got_typing(gc, sn, 0, GAIM_TYPED);
-		} break;
-
-		case 0x0002: { /* Typing */
-			serv_got_typing(gc, sn, 0, GAIM_TYPING);
-		} break;
-
-		default: {
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar", "Received unknown typing notification message from %s.  Type1 is 0x%04x and type2 is 0x%04hx.\n", sn, type1, type2);
-		} break;
-	}
-
-	return 1;
-}
-
-/*
- * We get this error when there was an error in the locate family.  This 
- * happens when you request info of someone who is offline.
- */
-static int gaim_parse_locerr(aim_session_t *sess, aim_frame_t *fr, ...) {
-	gchar *buf;
-	va_list ap;
-	fu16_t reason;
-	char *destn;
-
-	va_start(ap, fr);
-	reason = (fu16_t) va_arg(ap, unsigned int);
-	destn = va_arg(ap, char *);
-	va_end(ap);
-
-	if (destn != NULL) {
-		buf = g_strdup_printf(_("User information for %s unavailable:"), destn);
-		gaim_notify_error(sess->aux_data, NULL, buf,
-						  (reason < msgerrreasonlen) ? _(msgerrreason[reason]) : _("No reason given."));
-		g_free(buf);
-	}
-
-	return 1;
-}
-
-#if 0
-static char *images(int flags) {
-	static char buf[1024];
-	g_snprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s",
-			(flags & AIM_FLAG_ACTIVEBUDDY) ? "<IMG SRC=\"ab_icon.gif\">" : "",
-			(flags & AIM_FLAG_UNCONFIRMED) ? "<IMG SRC=\"dt_icon.gif\">" : "",
-			(flags & AIM_FLAG_AOL) ? "<IMG SRC=\"aol_icon.gif\">" : "",
-			(flags & AIM_FLAG_ICQ) ? "<IMG SRC=\"icq_icon.gif\">" : "",
-			(flags & AIM_FLAG_ADMINISTRATOR) ? "<IMG SRC=\"admin_icon.gif\">" : "",
-			(flags & AIM_FLAG_FREE) ? "<IMG SRC=\"free_icon.gif\">" : "",
-			(flags & AIM_FLAG_WIRELESS) ? "<IMG SRC=\"wireless_icon.gif\">" : "");
-	return buf;
-}
-#endif
-
-static char *caps_string(guint caps)
-{
-	static char buf[512], *tmp;
-	int count = 0, i = 0;
-	guint bit = 1;
-
-	if (!caps) {
-		return NULL;
-	} else while (bit <= AIM_CAPS_LAST) {
-		if (bit & caps) {
-			switch (bit) {
-			case AIM_CAPS_BUDDYICON:
-				tmp = _("Buddy Icon");
-				break;
-			case AIM_CAPS_VOICE:
-				tmp = _("Voice");
-				break;
-			case AIM_CAPS_DIRECTIM:
-				tmp = _("AIM Direct IM");
-				break;
-			case AIM_CAPS_CHAT:
-				tmp = _("Chat");
-				break;
-			case AIM_CAPS_GETFILE:
-				tmp = _("Get File");
-				break;
-			case AIM_CAPS_SENDFILE:
-				tmp = _("Send File");
-				break;
-			case AIM_CAPS_GAMES:
-			case AIM_CAPS_GAMES2:
-				tmp = _("Games");
-				break;
-			case AIM_CAPS_SAVESTOCKS:
-				tmp = _("Add-Ins");
-				break;
-			case AIM_CAPS_SENDBUDDYLIST:
-				tmp = _("Send Buddy List");
-				break;
-			case AIM_CAPS_ICQ_DIRECT:
-				tmp = _("ICQ Direct Connect");
-				break;
-			case AIM_CAPS_APINFO:
-				tmp = _("AP User");
-				break;
-			case AIM_CAPS_ICQRTF:
-				tmp = _("ICQ RTF");
-				break;
-			case AIM_CAPS_EMPTY:
-				tmp = _("Nihilist");
-				break;
-			case AIM_CAPS_ICQSERVERRELAY:
-				tmp = _("ICQ Server Relay");
-				break;
-			case AIM_CAPS_ICQUTF8OLD:
-				tmp = _("Old ICQ UTF8");
-				break;
-			case AIM_CAPS_TRILLIANCRYPT:
-				tmp = _("Trillian Encryption");
-				break;
-			case AIM_CAPS_ICQUTF8:
-				tmp = _("ICQ UTF8");
-				break;
-			case AIM_CAPS_HIPTOP:
-				tmp = _("Hiptop");
-				break;
-			case AIM_CAPS_SECUREIM:
-				tmp = _("Security Enabled");
-				break;
-			case AIM_CAPS_VIDEO:
-				tmp = _("Video Chat");
-				break;
-			default:
-				tmp = NULL;
-				break;
-			}
-			if (tmp)
-				i += g_snprintf(buf + i, sizeof(buf) - i, "%s%s", (count ? ", " : ""),
-						tmp);
-			count++;
-		}
-		bit <<= 1;
-	}
-	return buf; 
-}
-
-static int gaim_parse_userinfo(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	GString *text;
-	gchar *info_utf8 = NULL, *away_utf8 = NULL;
-	const char *final = NULL;
-	va_list ap;
-	aim_userinfo_t *userinfo;
-
-	va_start(ap, fr);
-	userinfo = va_arg(ap, aim_userinfo_t *);
-	va_end(ap);
-
-	text = g_string_new("");
-	g_string_append_printf(text, _("Username: <b>%s</b><br>\n"), userinfo->sn);
-	g_string_append_printf(text, _("Warning Level: <b>%d%%</b><br>\n"), (int)((userinfo->warnlevel/10.0) + 0.5));
-
-	if (userinfo->present & AIM_USERINFO_PRESENT_ONLINESINCE)
-		g_string_append_printf(text, _("Online Since: <b>%s</b><br>\n"),
-					asctime(localtime((time_t *)&userinfo->onlinesince)));
-
-	if (userinfo->present & AIM_USERINFO_PRESENT_MEMBERSINCE)
-		g_string_append_printf(text, _("Member Since: <b>%s</b><br>\n"),
-					asctime(localtime((time_t *)&userinfo->membersince)));
-
-	if (userinfo->present & AIM_USERINFO_PRESENT_IDLE) {
-		gchar *itime = gaim_str_seconds_to_string(userinfo->idletime*60);
-		g_string_append_printf(text, _("Idle: <b>%s</b>"), itime);
-		g_free(itime);
-	} else
-		g_string_append_printf(text, _("Idle: <b>Active</b>"));
-
-	if ((userinfo->flags & AIM_FLAG_AWAY) && (userinfo->away_len > 0) && (userinfo->away != NULL) && (userinfo->away_encoding != NULL)) {
-		away_utf8 = oscar_encoding_to_utf8(userinfo->away_encoding, userinfo->away, userinfo->away_len);
-		if (away_utf8 != NULL) {
-			g_string_append_printf(text, "<hr>%s", away_utf8);
-			g_free(away_utf8);
-		}
-	}
-
-	if ((userinfo->info_len > 0) && (userinfo->info != NULL) && (userinfo->info_encoding != NULL)) {
-		info_utf8 = oscar_encoding_to_utf8(userinfo->info_encoding, userinfo->info, userinfo->info_len);
-		if (info_utf8 != NULL) {
-			g_string_append_printf(text, "<hr>%s", info_utf8);
-			g_free(info_utf8);
-		}
-	}
-
-	final = gaim_str_sub_away_formatters(text->str, gaim_account_get_username(gaim_connection_get_account(gc)));
-	g_string_free(text, TRUE);
-	gaim_notify_formatted(gc, NULL, _("Buddy Information"), NULL, final, NULL, NULL);
-
-	return 1;
-}
-
-static int gaim_parse_motd(aim_session_t *sess, aim_frame_t *fr, ...) {
-	char *msg;
-	fu16_t id;
-	va_list ap;
-
-	va_start(ap, fr);
-	id  = (fu16_t) va_arg(ap, unsigned int);
-	msg = va_arg(ap, char *);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar",
-			   "MOTD: %s (%hu)\n", msg ? msg : "Unknown", id);
-	if (id < 4)
-		gaim_notify_warning(sess->aux_data, NULL,
-							_("Your AIM connection may be lost."), NULL);
-
-	return 1;
-}
-
-static int gaim_chatnav_info(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	fu16_t type;
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = (OscarData *)gc->proto_data;
-
-	va_start(ap, fr);
-	type = (fu16_t) va_arg(ap, unsigned int);
-
-	switch(type) {
-		case 0x0002: {
-			fu8_t maxrooms;
-			struct aim_chat_exchangeinfo *exchanges;
-			int exchangecount, i;
-
-			maxrooms = (fu8_t) va_arg(ap, unsigned int);
-			exchangecount = va_arg(ap, int);
-			exchanges = va_arg(ap, struct aim_chat_exchangeinfo *);
-
-			gaim_debug(GAIM_DEBUG_MISC, "oscar",
-					   "chat info: Chat Rights:\n");
-			gaim_debug(GAIM_DEBUG_MISC, "oscar",
-					   "chat info: \tMax Concurrent Rooms: %hhd\n", maxrooms);
-			gaim_debug(GAIM_DEBUG_MISC, "oscar",
-					   "chat info: \tExchange List: (%d total)\n", exchangecount);
-			for (i = 0; i < exchangecount; i++)
-				gaim_debug(GAIM_DEBUG_MISC, "oscar",
-						   "chat info: \t\t%hu    %s\n",
-						   exchanges[i].number, exchanges[i].name ? exchanges[i].name : "");
-			while (od->create_rooms) {
-				struct create_room *cr = od->create_rooms->data;
-				gaim_debug(GAIM_DEBUG_INFO, "oscar",
-						   "creating room %s\n", cr->name);
-				aim_chatnav_createroom(sess, fr->conn, cr->name, cr->exchange);
-				g_free(cr->name);
-				od->create_rooms = g_slist_remove(od->create_rooms, cr);
-				g_free(cr);
-			}
-			}
-			break;
-		case 0x0008: {
-			char *fqcn, *name, *ck;
-			fu16_t instance, flags, maxmsglen, maxoccupancy, unknown, exchange;
-			fu8_t createperms;
-			fu32_t createtime;
-
-			fqcn = va_arg(ap, char *);
-			instance = (fu16_t)va_arg(ap, unsigned int);
-			exchange = (fu16_t)va_arg(ap, unsigned int);
-			flags = (fu16_t)va_arg(ap, unsigned int);
-			createtime = va_arg(ap, fu32_t);
-			maxmsglen = (fu16_t)va_arg(ap, unsigned int);
-			maxoccupancy = (fu16_t)va_arg(ap, unsigned int);
-			createperms = (fu8_t)va_arg(ap, unsigned int);
-			unknown = (fu16_t)va_arg(ap, unsigned int);
-			name = va_arg(ap, char *);
-			ck = va_arg(ap, char *);
-
-			gaim_debug(GAIM_DEBUG_MISC, "oscar",
-					   "created room: %s %hu %hu %hu %u %hu %hu %hhu %hu %s %s\n",
-					fqcn,
-					exchange, instance, flags,
-					createtime,
-					maxmsglen, maxoccupancy, createperms, unknown,
-					name, ck);
-			aim_chat_join(od->sess, od->conn, exchange, ck, instance);
-			}
-			break;
-		default:
-			gaim_debug(GAIM_DEBUG_WARNING, "oscar",
-					   "chatnav info: unknown type (%04hx)\n", type);
-			break;
-	}
-
-	va_end(ap);
-
-	return 1;
-}
-
-static int gaim_conv_chat_join(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	int count, i;
-	aim_userinfo_t *info;
-	GaimConnection *g = sess->aux_data;
-
-	struct chat_connection *c = NULL;
-
-	va_start(ap, fr);
-	count = va_arg(ap, int);
-	info  = va_arg(ap, aim_userinfo_t *);
-	va_end(ap);
-
-	c = find_oscar_chat_by_conn(g, fr->conn);
-	if (!c)
-		return 1;
-
-	for (i = 0; i < count; i++)
-		gaim_conv_chat_add_user(GAIM_CONV_CHAT(c->cnv), info[i].sn, NULL);
-
-	return 1;
-}
-
-static int gaim_conv_chat_leave(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	int count, i;
-	aim_userinfo_t *info;
-	GaimConnection *g = sess->aux_data;
-
-	struct chat_connection *c = NULL;
-
-	va_start(ap, fr);
-	count = va_arg(ap, int);
-	info  = va_arg(ap, aim_userinfo_t *);
-	va_end(ap);
-
-	c = find_oscar_chat_by_conn(g, fr->conn);
-	if (!c)
-		return 1;
-
-	for (i = 0; i < count; i++)
-		gaim_conv_chat_remove_user(GAIM_CONV_CHAT(c->cnv), info[i].sn, NULL);
-
-	return 1;
-}
-
-static int gaim_conv_chat_info_update(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	aim_userinfo_t *userinfo;
-	struct aim_chat_roominfo *roominfo;
-	char *roomname;
-	int usercount;
-	char *roomdesc;
-	fu16_t unknown_c9, unknown_d2, unknown_d5, maxmsglen, maxvisiblemsglen;
-	fu32_t creationtime;
-	GaimConnection *gc = sess->aux_data;
-	struct chat_connection *ccon = find_oscar_chat_by_conn(gc, fr->conn);
-
-	va_start(ap, fr);
-	roominfo = va_arg(ap, struct aim_chat_roominfo *);
-	roomname = va_arg(ap, char *);
-	usercount= va_arg(ap, int);
-	userinfo = va_arg(ap, aim_userinfo_t *);
-	roomdesc = va_arg(ap, char *);
-	unknown_c9 = (fu16_t)va_arg(ap, unsigned int);
-	creationtime = va_arg(ap, fu32_t);
-	maxmsglen = (fu16_t)va_arg(ap, unsigned int);
-	unknown_d2 = (fu16_t)va_arg(ap, unsigned int);
-	unknown_d5 = (fu16_t)va_arg(ap, unsigned int);
-	maxvisiblemsglen = (fu16_t)va_arg(ap, unsigned int);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar",
-			   "inside chat_info_update (maxmsglen = %hu, maxvislen = %hu)\n",
-			   maxmsglen, maxvisiblemsglen);
-
-	ccon->maxlen = maxmsglen;
-	ccon->maxvis = maxvisiblemsglen;
-
-	return 1;
-}
-
-static int gaim_conv_chat_incoming_msg(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	va_list ap;
-	aim_userinfo_t *info;
-	char *msg;
-	struct chat_connection *ccon = find_oscar_chat_by_conn(gc, fr->conn);
-
-	va_start(ap, fr);
-	info = va_arg(ap, aim_userinfo_t *);
-	msg = va_arg(ap, char *);
-	va_end(ap);
-
-	serv_got_chat_in(gc, ccon->id, info->sn, 0, msg, time((time_t)NULL));
-
-	return 1;
-}
-
-static int gaim_email_parseupdate(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	GaimConnection *gc = sess->aux_data;
-	struct aim_emailinfo *emailinfo;
-	int havenewmail;
-	char *alertitle, *alerturl;
-
-	va_start(ap, fr);
-	emailinfo = va_arg(ap, struct aim_emailinfo *);
-	havenewmail = va_arg(ap, int);
-	alertitle = va_arg(ap, char *);
-	alerturl  = va_arg(ap, char *);
-	va_end(ap);
-
-	if (emailinfo && gaim_account_get_check_mail(gc->account)) {
-		gchar *to = g_strdup_printf("%s@%s", gaim_account_get_username(gaim_connection_get_account(gc)), emailinfo->domain);
-		if (emailinfo->unread && havenewmail)
-			gaim_notify_emails(gc, emailinfo->nummsgs, FALSE, NULL, NULL, (const char **)&to, (const char **)&emailinfo->url, NULL, NULL);
-		g_free(to);
-	}
-	
-	if (alertitle)
-		gaim_debug(GAIM_DEBUG_MISC, "oscar", "Got an alert '%s' %s\n", alertitle, alerturl ? alerturl : "");
-
-	return 1;
-}
-
-static int gaim_icon_error(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	char *sn;
-
-	sn = od->requesticon->data;
-	gaim_debug(GAIM_DEBUG_MISC, "oscar",
-			   "removing %s from hash table\n", sn);
-	od->requesticon = g_slist_remove(od->requesticon, sn);
-	free(sn);
-
-	if (od->icontimer)
-		g_source_remove(od->icontimer);
-	od->icontimer = g_timeout_add(500, gaim_icon_timerfunc, gc);
-
-	return 1;
-}
-
-static int gaim_icon_parseicon(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	GSList *cur;
-	va_list ap;
-	char *sn;
-	fu8_t *iconcsum, *icon;
-	fu16_t iconcsumlen, iconlen;
-
-	va_start(ap, fr);
-	sn = va_arg(ap, char *);
-	iconcsum = va_arg(ap, fu8_t *);
-	iconcsumlen = va_arg(ap, int);
-	icon = va_arg(ap, fu8_t *);
-	iconlen = va_arg(ap, int);
-	va_end(ap);
-
-	if (iconlen > 0) {
-		char *b16;
-		GaimBuddy *b = gaim_find_buddy(gc->account, sn);
-		gaim_buddy_icons_set_for_user(gaim_connection_get_account(gc),
-									  sn, icon, iconlen);
-		b16 = gaim_base16_encode(iconcsum, iconcsumlen);
-		if (b16) {
-			gaim_buddy_set_setting(b, "icon_checksum", b16);
-			gaim_blist_save();
-			g_free(b16);
-		}
-	}
-
-	cur = od->requesticon;
-	while (cur) {
-		char *cursn = cur->data;
-		if (!aim_sncmp(cursn, sn)) {
-			od->requesticon = g_slist_remove(od->requesticon, cursn);
-			free(cursn);
-			cur = od->requesticon;
-		} else
-			cur = cur->next;
-	}
-
-	if (od->icontimer)
-		g_source_remove(od->icontimer);
-	od->icontimer = g_timeout_add(250, gaim_icon_timerfunc, gc);
-
-	return 1;
-}
-
-static gboolean gaim_icon_timerfunc(gpointer data) {
-	GaimConnection *gc = data;
-	OscarData *od = gc->proto_data;
-	aim_userinfo_t *userinfo;
-	aim_conn_t *conn;
-
-	conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_ICON);
-	if (!conn) {
-		if (!od->iconconnecting) {
-			aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_ICON);
-			od->iconconnecting = TRUE;
-		}
-		return FALSE;
-	}
-
-	if (od->set_icon) {
-		struct stat st;
-		const char *iconfile = gaim_account_get_buddy_icon(gaim_connection_get_account(gc));
-		if (iconfile == NULL) {
-			/* Set an empty icon, or something */
-		} else if (!stat(iconfile, &st)) {
-			char *buf = g_malloc(st.st_size);
-			FILE *file = fopen(iconfile, "rb");
-			if (file) {
-				fread(buf, 1, st.st_size, file);
-				fclose(file);
-				gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "Uploading icon to icon server\n");
-				aim_bart_upload(od->sess, buf, st.st_size);
-			} else
-				gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "Can't open buddy icon file!\n");
-			g_free(buf);
-		} else {
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-				   "Can't stat buddy icon file!\n");
-		}
-		od->set_icon = FALSE;
-	}
-
-	if (!od->requesticon) {
-		gaim_debug(GAIM_DEBUG_MISC, "oscar",
-				   "no more icons to request\n");
-		return FALSE;
-	}
-
-	userinfo = aim_locate_finduserinfo(od->sess, (char *)od->requesticon->data);
-	if ((userinfo != NULL) && (userinfo->iconcsumlen > 0)) {
-		aim_bart_request(od->sess, od->requesticon->data, userinfo->iconcsum, userinfo->iconcsumlen);
-		return FALSE;
-	} else {
-		char *sn = od->requesticon->data;
-		od->requesticon = g_slist_remove(od->requesticon, sn);
-		free(sn);
-	}
-
-	return TRUE;
-}
-
-/*
- * Recieved in response to an IM sent with the AIM_IMFLAGS_ACK option.
- */
-static int gaim_parse_msgack(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	fu16_t type;
-	char *sn;
-
-	va_start(ap, fr);
-	type = (fu16_t) va_arg(ap, unsigned int);
-	sn = va_arg(ap, char *);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "Sent message to %s.\n", sn);
-
-	return 1;
-}
-
-static int gaim_parse_ratechange(aim_session_t *sess, aim_frame_t *fr, ...) {
-	static const char *codes[5] = {
-		"invalid",
-		"change",
-		"warning",
-		"limit",
-		"limit cleared",
-	};
-	va_list ap;
-	fu16_t code, rateclass;
-	fu32_t windowsize, clear, alert, limit, disconnect, currentavg, maxavg;
-
-	va_start(ap, fr); 
-	code = (fu16_t)va_arg(ap, unsigned int);
-	rateclass= (fu16_t)va_arg(ap, unsigned int);
-	windowsize = va_arg(ap, fu32_t);
-	clear = va_arg(ap, fu32_t);
-	alert = va_arg(ap, fu32_t);
-	limit = va_arg(ap, fu32_t);
-	disconnect = va_arg(ap, fu32_t);
-	currentavg = va_arg(ap, fu32_t);
-	maxavg = va_arg(ap, fu32_t);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar",
-			   "rate %s (param ID 0x%04hx): curavg = %u, maxavg = %u, alert at %u, "
-		     "clear warning at %u, limit at %u, disconnect at %u (window size = %u)\n",
-		     (code < 5) ? codes[code] : codes[0],
-		     rateclass,
-		     currentavg, maxavg,
-		     alert, clear,
-		     limit, disconnect,
-		     windowsize);
-
-	/* XXX fix these values */
-	if (code == AIM_RATE_CODE_CHANGE) {
-		if (currentavg >= clear)
-			aim_conn_setlatency(fr->conn, 0);
-	} else if (code == AIM_RATE_CODE_WARNING) {
-		aim_conn_setlatency(fr->conn, windowsize/4);
-	} else if (code == AIM_RATE_CODE_LIMIT) {
-		gaim_notify_error(sess->aux_data, NULL, _("Rate limiting error."),
-						  _("The last action you attempted could not be "
-							"performed because you are over the rate limit. "
-							"Please wait 10 seconds and try again."));
-		aim_conn_setlatency(fr->conn, windowsize/2);
-	} else if (code == AIM_RATE_CODE_CLEARLIMIT) {
-		aim_conn_setlatency(fr->conn, 0);
-	}
-
-	return 1;
-}
-
-static int gaim_parse_evilnotify(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	fu16_t newevil;
-	aim_userinfo_t *userinfo;
-	GaimConnection *gc = sess->aux_data;
-
-	va_start(ap, fr);
-	newevil = (fu16_t) va_arg(ap, unsigned int);
-	userinfo = va_arg(ap, aim_userinfo_t *);
-	va_end(ap);
-
-	serv_got_eviled(gc, (userinfo && userinfo->sn) ? userinfo->sn : NULL, (newevil/10.0) + 0.5);
-
-	return 1;
-}
-
-static int gaim_selfinfo(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	aim_userinfo_t *info;
-	GaimConnection *gc = sess->aux_data;
-
-	va_start(ap, fr);
-	info = va_arg(ap, aim_userinfo_t *);
-	va_end(ap);
-
-	gc->evil = (info->warnlevel/10.0) + 0.5;
-
-	if (info->onlinesince)
-		gc->login_time_official = info->onlinesince;
-
-	return 1;
-}
-
-static int gaim_connerr(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	va_list ap;
-	fu16_t code;
-	char *msg;
-
-	va_start(ap, fr);
-	code = (fu16_t)va_arg(ap, int);
-	msg = va_arg(ap, char *);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "Disconnected.  Code is 0x%04x and msg is %s\n", code, msg);
-	if ((fr) && (fr->conn) && (fr->conn->type == AIM_CONN_TYPE_BOS)) {
-		if (code == 0x0001) {
-			gc->wants_to_die = TRUE;
-			gaim_connection_error(gc, _("You have been disconnected because you have signed on with this screen name at another location."));
-		} else {
-			gaim_connection_error(gc, _("You have been signed off for an unknown reason."));
-		}
-		od->killme = TRUE;
-	}
-
-	return 1;
-}
-
-static int conninitdone_bos(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-
-	aim_reqpersonalinfo(sess, fr->conn);
-
-#ifndef NOSSI
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: requesting rights and list\n");
-	aim_ssi_reqrights(sess);
-	aim_ssi_reqdata(sess);
-#endif
-
-	aim_locate_reqrights(sess);
-	aim_buddylist_reqrights(sess, fr->conn);
-	aim_im_reqparams(sess);
-	aim_bos_reqrights(sess, fr->conn); /* XXX - Don't call this with ssi */
-
-#ifdef NOSSI
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "bos: requesting rights\n");
-	aim_bos_reqrights(sess, fr->conn);
-	aim_bos_setgroupperm(sess, fr->conn, AIM_FLAG_ALLUSERS);
-	aim_bos_setprivacyflags(sess, fr->conn, AIM_PRIVFLAGS_ALLOWIDLE | AIM_PRIVFLAGS_ALLOWMEMBERSINCE);
-#endif
-
-	gaim_connection_update_progress(gc, _("Finalizing connection"), 5, OSCAR_CONNECT_STEPS);
-
-	return 1;
-}
-
-static int conninitdone_admin(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-
-	aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_ADM, 0x0003, gaim_info_change, 0);
-	aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_ADM, 0x0005, gaim_info_change, 0);
-	aim_conn_addhandler(sess, fr->conn, AIM_CB_FAM_ADM, 0x0007, gaim_account_confirm, 0);
-
-	aim_clientready(sess, fr->conn);
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "connected to admin\n");
-
-	if (od->chpass) {
-		gaim_debug(GAIM_DEBUG_INFO, "oscar", "changing password\n");
-		aim_admin_changepasswd(sess, fr->conn, od->newp, od->oldp);
-		g_free(od->oldp);
-		od->oldp = NULL;
-		g_free(od->newp);
-		od->newp = NULL;
-		od->chpass = FALSE;
-	}
-	if (od->setnick) {
-		gaim_debug(GAIM_DEBUG_INFO, "oscar", "formatting screenname\n");
-		aim_admin_setnick(sess, fr->conn, od->newsn);
-		g_free(od->newsn);
-		od->newsn = NULL;
-		od->setnick = FALSE;
-	}
-	if (od->conf) {
-		gaim_debug(GAIM_DEBUG_INFO, "oscar", "confirming account\n");
-		aim_admin_reqconfirm(sess, fr->conn);
-		od->conf = FALSE;
-	}
-	if (od->reqemail) {
-		gaim_debug(GAIM_DEBUG_INFO, "oscar", "requesting email\n");
-		aim_admin_getinfo(sess, fr->conn, 0x0011);
-		od->reqemail = FALSE;
-	}
-	if (od->setemail) {
-		gaim_debug(GAIM_DEBUG_INFO, "oscar", "setting email\n");
-		aim_admin_setemail(sess, fr->conn, od->email);
-		g_free(od->email);
-		od->email = NULL;
-		od->setemail = FALSE;
-	}
-
-	return 1;
-}
-
-static int gaim_icbm_param_info(aim_session_t *sess, aim_frame_t *fr, ...) {
-	struct aim_icbmparameters *params;
-	va_list ap;
-
-	va_start(ap, fr);
-	params = va_arg(ap, struct aim_icbmparameters *);
-	va_end(ap);
-
-	/* XXX - evidently this crashes on solaris. i have no clue why
-	gaim_debug(GAIM_DEBUG_MISC, "oscar", "ICBM Parameters: maxchannel = %hu, default flags = 0x%08lx, max msg len = %hu, "
-			"max sender evil = %f, max receiver evil = %f, min msg interval = %u\n",
-			params->maxchan, params->flags, params->maxmsglen,
-			((float)params->maxsenderwarn)/10.0, ((float)params->maxrecverwarn)/10.0,
-			params->minmsginterval);
-	*/
-
-	/* Maybe senderwarn and recverwarn should be user preferences... */
-	params->flags = 0x0000000b;
-	params->maxmsglen = 8000;
-	params->minmsginterval = 0;
-
-	aim_im_setparams(sess, params);
-
-	return 1;
-}
-
-static int gaim_parse_locaterights(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = (OscarData *)gc->proto_data;
-	va_list ap;
-	fu16_t maxsiglen;
-
-	va_start(ap, fr);
-	maxsiglen = (fu16_t) va_arg(ap, int);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar",
-			   "locate rights: max sig len = %d\n", maxsiglen);
-
-	od->rights.maxsiglen = od->rights.maxawaymsglen = (guint)maxsiglen;
-
-	if (od->icq)
-		aim_locate_setcaps(od->sess, caps_icq);
-	else
-		aim_locate_setcaps(od->sess, caps_aim);
-	oscar_set_info(gc, gc->account->user_info);
-
-	return 1;
-}
-
-static int gaim_parse_buddyrights(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	fu16_t maxbuddies, maxwatchers;
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = (OscarData *)gc->proto_data;
-
-	va_start(ap, fr);
-	maxbuddies = (fu16_t) va_arg(ap, unsigned int);
-	maxwatchers = (fu16_t) va_arg(ap, unsigned int);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar",
-			   "buddy list rights: Max buddies = %hu / Max watchers = %hu\n", maxbuddies, maxwatchers);
-
-	od->rights.maxbuddies = (guint)maxbuddies;
-	od->rights.maxwatchers = (guint)maxwatchers;
-
-	return 1;
-}
-
-static int gaim_bosrights(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = (OscarData *)gc->proto_data;
-	va_list ap;
-	fu16_t maxpermits, maxdenies;
-
-	va_start(ap, fr);
-	maxpermits = (fu16_t) va_arg(ap, unsigned int);
-	maxdenies = (fu16_t) va_arg(ap, unsigned int);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar",
-			   "BOS rights: Max permit = %hu / Max deny = %hu\n", maxpermits, maxdenies);
-
-	od->rights.maxpermits = (guint)maxpermits;
-	od->rights.maxdenies = (guint)maxdenies;
-
-	gaim_connection_set_state(gc, GAIM_CONNECTED);
-	serv_finish_login(gc);
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "buddy list loaded\n");
-
-	aim_clientready(sess, fr->conn);
-	aim_srv_setavailmsg(sess, NULL);
-	aim_srv_setidle(sess, 0);
-
-	if (od->icq) {
-		aim_icq_reqofflinemsgs(sess);
-		aim_icq_hideip(sess);
-	}
-
-	aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_CHATNAV);
-	if (sess->authinfo->email)
-		aim_reqservice(sess, fr->conn, AIM_CONN_TYPE_EMAIL);
-
-	return 1;
-}
-
-static int gaim_offlinemsg(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	struct aim_icq_offlinemsg *msg;
-	struct aim_incomingim_ch4_args args;
-	time_t t;
-
-	va_start(ap, fr);
-	msg = va_arg(ap, struct aim_icq_offlinemsg *);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "Received offline message.  Converting to channel 4 ICBM...\n");
-	args.uin = msg->sender;
-	args.type = msg->type;
-	args.flags = msg->flags;
-	args.msglen = msg->msglen;
-	args.msg = msg->msg;
-	t = gaim_time_build(msg->year, msg->month, msg->day, msg->hour, msg->minute, 0);
-	incomingim_chan4(sess, fr->conn, NULL, &args, t);
-
-	return 1;
-}
-
-static int gaim_offlinemsgdone(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-	aim_icq_ackofflinemsgs(sess);
-	return 1;
-}
-
-#if 0
-/*
- * Update, 2003-11-09:
- * Joseph S. Myers, a gcc dude, fixed this for gcc 3.4!  Rock on!
- *
- * It may not be my place to do this, but...
- * I feel pretty strongly that the "last 2 digits" warning is ridiculously 
- * stupid, and should not exist for % switches (%x in our case) that request 
- * a year in the preferred representation for the current locale.  For that 
- * reason I've chosen to not use this workaround (n., see kluge).
- *
- * I have a date.  I want to show it to the user in the "preferred" way.  
- * Whether that displays a 2 digit year is perfectly fine--after all, it's 
- * what the locale wanted.
- * 
- * If I have a necessity for a full representation of the year in the current 
- * locale, then I'll use a switch that returns a full representation of the 
- * year.
- *
- * If you think the preferred locale should show 4 digits instead of 2 digits 
- * (because you're anal, or whatever), then change the f***ing locale.
- *
- * I guess the bottom line is--I'm trying to show a date to the user how they 
- * prefer to see it, why the hell does gcc want me to change that?
- *
- * See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=3190
- * See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=8714
- */
-
-/*
- * This function was recommended by the STRFTIME(3) man page to remove the
- * "last 2 digits" warning.
- */
-static size_t my_strftime(char *s, size_t max, const char  *fmt,  
-			const struct tm *tm)
-{
-	return strftime(s, max, fmt, tm);
-}
-#endif
-
-static int gaim_icqinfo(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-	GaimConnection *gc = sess->aux_data;
-	gchar *buf, *tmp, *utf8;
-	gchar who[16];
-	GaimBuddy *buddy;
-	gchar *primary;
-	va_list ap;
-	struct aim_icq_info *info;
-
-	va_start(ap, fr);
-	info = va_arg(ap, struct aim_icq_info *);
-	va_end(ap);
-
-	if (!info->uin)
-		return 0;
-
-	g_snprintf(who, sizeof(who), "%u", info->uin);
-	buf = g_strdup_printf("<b>%s:</b> %s", _("UIN"), who);
-	if (info->nick && info->nick[0] && (utf8 = gaim_utf8_try_convert(info->nick))) {
-		tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Nick"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-	}
-	if (info->first && info->first[0] && (utf8 = gaim_utf8_try_convert(info->first))) {
-		tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("First Name"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-	}
-	if (info->last && info->last[0] && (utf8 = gaim_utf8_try_convert(info->last))) {
-		tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Last Name"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-	}
-	if (info->email && info->email[0] && (utf8 = gaim_utf8_try_convert(info->email))) {
-		tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Email Address"), ":</b> <a href=\"mailto:", utf8, "\">", utf8, "</a>", NULL);  g_free(tmp); g_free(utf8);
-	}
-	if (info->numaddresses && info->email2) {
-		int i;
-		for (i = 0; i < info->numaddresses; i++) {
-			if (info->email2[i] && info->email2[i][0] && (utf8 = gaim_utf8_try_convert(info->email2[i]))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Email Address"), ":</b> <a href=\"mailto:", utf8, "\">", utf8, "</a>", NULL);  g_free(tmp); g_free(utf8);
-			}
-		}
-	}
-	if (info->mobile && info->mobile[0] && (utf8 = gaim_utf8_try_convert(info->mobile))) {
-		tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Mobile Phone"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-	}
-	if (info->gender) {
-		tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Gender"), ":</b> ", info->gender==1 ? _("Female") : _("Male"), NULL);  g_free(tmp);
-	}
-	if (info->birthyear || info->birthmonth || info->birthday) {
-		char date[30];
-		struct tm tm;
-		tm.tm_mday = (int)info->birthday;
-		tm.tm_mon = (int)info->birthmonth-1;
-		tm.tm_year = (int)info->birthyear-1900;
-		strftime(date, sizeof(date), "%x", &tm);
-		tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Birthday"), ":</b> ", date, NULL);  g_free(tmp);
-	}
-	if (info->age) {
-		char age[5];
-		snprintf(age, sizeof(age), "%hhd", info->age);
-		tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Age"), ":</b> ", age, NULL);  g_free(tmp);
-	}
-	if (info->personalwebpage && info->personalwebpage[0] && (utf8 = gaim_utf8_try_convert(info->personalwebpage))) {
-		tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Personal Web Page"), ":</b> <a href=\"", utf8, "\">", utf8, "</a>", NULL);  g_free(tmp); g_free(utf8);
-	}
-	if (info->info && info->info[0] && (utf8 = gaim_utf8_try_convert(info->info))) {
-		tmp = buf;  buf = g_strconcat(tmp, "<hr><b>", _("Additional Information"), ":</b><br>", utf8, NULL);  g_free(tmp); g_free(utf8);
-	}
-	tmp = buf;  buf = g_strconcat(tmp, "<hr>\n", NULL);  g_free(tmp);
-	if ((info->homeaddr && (info->homeaddr[0])) || (info->homecity && info->homecity[0]) || (info->homestate && info->homestate[0]) || (info->homezip && info->homezip[0])) {
-		tmp = buf;  buf = g_strconcat(tmp, "<b>", _("Home Address"), ":</b>", NULL);  g_free(tmp);
-		if (info->homeaddr && info->homeaddr[0] && (utf8 = gaim_utf8_try_convert(info->homeaddr))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Address"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-		}
-		if (info->homecity && info->homecity[0] && (utf8 = gaim_utf8_try_convert(info->homecity))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("City"), ":</b> ", utf8,  NULL);  g_free(tmp); g_free(utf8);
-		}
-		if (info->homestate && info->homestate[0] && (utf8 = gaim_utf8_try_convert(info->homestate))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("State"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-		}
-		if (info->homezip && info->homezip[0] && (utf8 = gaim_utf8_try_convert(info->homezip))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Zip Code"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-		}
-		tmp = buf; buf = g_strconcat(tmp, "\n<hr>\n", NULL); g_free(tmp);
-	}
-	if ((info->workaddr && info->workaddr[0]) || (info->workcity && info->workcity[0]) || (info->workstate && info->workstate[0]) || (info->workzip && info->workzip[0])) {
-		tmp = buf;  buf = g_strconcat(tmp, "<b>", _("Work Address"), ":</b>", NULL);  g_free(tmp);
-		if (info->workaddr && info->workaddr[0] && (utf8 = gaim_utf8_try_convert(info->workaddr))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Address"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-		}
-		if (info->workcity && info->workcity[0] && (utf8 = gaim_utf8_try_convert(info->workcity))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("City"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-		}
-		if (info->workstate && info->workstate[0] && (utf8 = gaim_utf8_try_convert(info->workstate))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("State"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-		}
-		if (info->workzip && info->workzip[0] && (utf8 = gaim_utf8_try_convert(info->workzip))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Zip Code"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-		}
-		tmp = buf; buf = g_strconcat(tmp, "\n<hr>\n", NULL); g_free(tmp);
-	}
-	if ((info->workcompany && info->workcompany[0]) || (info->workdivision && info->workdivision[0]) || (info->workposition && info->workposition[0]) || (info->workwebpage && info->workwebpage[0])) {
-		tmp = buf;  buf = g_strconcat(tmp, "<b>", _("Work Information"), ":</b>", NULL);  g_free(tmp);
-		if (info->workcompany && info->workcompany[0] && (utf8 = gaim_utf8_try_convert(info->workcompany))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Company"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-		}
-		if (info->workdivision && info->workdivision[0] && (utf8 = gaim_utf8_try_convert(info->workdivision))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Division"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-		}
-		if (info->workposition && info->workposition[0] && (utf8 = gaim_utf8_try_convert(info->workposition))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Position"), ":</b> ", utf8, NULL);  g_free(tmp); g_free(utf8);
-		}
-		if (info->workwebpage && info->workwebpage[0] && (utf8 = gaim_utf8_try_convert(info->workwebpage))) {
-			tmp = buf;  buf = g_strconcat(tmp, "\n<br><b>", _("Web Page"), ":</b> <a href=\"", utf8, "\">", utf8, "</a>", NULL);  g_free(tmp); g_free(utf8);
-		}
-		tmp = buf; buf = g_strconcat(tmp, "\n<hr>\n", NULL); g_free(tmp);
-	}
-
-	buddy = gaim_find_buddy(gaim_connection_get_account(gc), who);
-	primary = g_strdup_printf(_("ICQ Info for %s"), gaim_get_buddy_alias(buddy));
-	gaim_notify_formatted(gc, NULL, primary, NULL, buf, NULL, NULL);
-	g_free(primary);
-	g_free(buf);
-
-	return 1;
-}
-
-static int gaim_icqalias(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-	GaimConnection *gc = sess->aux_data;
-	gchar who[16], *utf8;
-	GaimBuddy *b;
-	va_list ap;
-	struct aim_icq_info *info;
-
-	va_start(ap, fr);
-	info = va_arg(ap, struct aim_icq_info *);
-	va_end(ap);
-
-	if (info->uin && info->nick && info->nick[0] && (utf8 = gaim_utf8_try_convert(info->nick))) {
-		g_snprintf(who, sizeof(who), "%u", info->uin);
-		serv_got_alias(gc, who, utf8);
-		if ((b = gaim_find_buddy(gc->account, who))) {
-			gaim_buddy_set_setting(b, "servernick", utf8);
-			gaim_blist_save();
-		}
-		g_free(utf8);
-	}
-
-	return 1;
-}
-
-static int gaim_popup(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-	GaimConnection *gc = sess->aux_data;
-	gchar *text;
-	va_list ap;
-	char *msg, *url;
-	fu16_t wid, hei, delay;
-
-	va_start(ap, fr);
-	msg = va_arg(ap, char *);
-	url = va_arg(ap, char *);
-	wid = (fu16_t) va_arg(ap, int);
-	hei = (fu16_t) va_arg(ap, int);
-	delay = (fu16_t) va_arg(ap, int);
-	va_end(ap);
-
-	text = g_strdup_printf("%s<br><a href=\"%s\">%s</a>", msg, url, url);
-	gaim_notify_formatted(gc, NULL, _("Pop-Up Message"), NULL, text, NULL, NULL);
-	g_free(text);
-
-	return 1;
-}
-
-static int gaim_parse_searchreply(aim_session_t *sess, aim_frame_t *fr, ...)
-{
-	GaimConnection *gc = sess->aux_data;
-	gchar *secondary;
-	GString *text;
-	int i, num;
-	va_list ap;
-	char *email, *SNs;
-
-	va_start(ap, fr);
-	email = va_arg(ap, char *);
-	num = va_arg(ap, int);
-	SNs = va_arg(ap, char *);
-	va_end(ap);
-
-	secondary = g_strdup_printf(_("The following screennames are associated with %s"), email);
-	text = g_string_new("");
-	for (i = 0; i < num; i++)
-		g_string_append_printf(text, "%s<br>", &SNs[i * (MAXSNLEN + 1)]);
-	gaim_notify_formatted(gc, NULL, _("Search Results"), secondary, text->str, NULL, NULL);
-
-	g_free(secondary);
-	g_string_free(text, TRUE);
-
-	return 1;
-}
-
-static int gaim_parse_searcherror(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	char *email;
-	char *buf;
-
-	va_start(ap, fr);
-	email = va_arg(ap, char *);
-	va_end(ap);
-
-	buf = g_strdup_printf(_("No results found for email address %s"), email);
-	gaim_notify_error(sess->aux_data, NULL, buf, NULL);
-	g_free(buf);
-
-	return 1;
-}
-
-static int gaim_account_confirm(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	fu16_t status;
-	va_list ap;
-	char msg[256];
-
-	va_start(ap, fr);
-	status = (fu16_t) va_arg(ap, unsigned int); /* status code of confirmation request */
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "account confirmation returned status 0x%04x (%s)\n", status,
-			status ? "unknown" : "email sent");
-	if (!status) {
-		g_snprintf(msg, sizeof(msg), _("You should receive an email asking to confirm %s."),
-				gaim_account_get_username(gaim_connection_get_account(gc)));
-		gaim_notify_info(gc, NULL, _("Account Confirmation Requested"), msg);
-	}
-
-	return 1;
-}
-
-static int gaim_info_change(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	va_list ap;
-	fu16_t perms, err;
-	char *url, *sn, *email;
-	int change;
-
-	va_start(ap, fr);
-	change = va_arg(ap, int);
-	perms = (fu16_t) va_arg(ap, unsigned int);
-	err = (fu16_t) va_arg(ap, unsigned int);
-	url = va_arg(ap, char *);
-	sn = va_arg(ap, char *);
-	email = va_arg(ap, char *);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar",
-			   "account info: because of %s, perms=0x%04x, err=0x%04x, url=%s, sn=%s, email=%s\n",
-		change ? "change" : "request", perms, err, url, sn, email);
-
-	if (err && url) {
-		char *dialog_msg;
-		char *dialog_top = g_strdup_printf(_("Error Changing Account Info"));
-		switch (err) {
-			case 0x0001: {
-				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unable to format screen name because the requested screen name differs from the original."), err);
-			} break;
-			case 0x0006: {
-				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unable to format screen name because the requested screen name ends in a space."), err);
-			} break;
-			case 0x000b: {
-				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unable to format screen name because the requested screen name is too long."), err);
-			} break;
-			case 0x001d: {
-				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unable to change email address because there is already a request pending for this screen name."), err);
-			} break;
-			case 0x0021: {
-				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unable to change email address because the given address has too many screen names associated with it."), err);
-			} break;
-			case 0x0023: {
-				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unable to change email address because the given address is invalid."), err);
-			} break;
-			default: {
-				dialog_msg = g_strdup_printf(_("Error 0x%04x: Unknown error."), err);
-			} break;
-		}
-		gaim_notify_error(gc, NULL, dialog_top, dialog_msg);
-		g_free(dialog_top);
-		g_free(dialog_msg);
-		return 1;
-	}
-
-	if (sn) {
-		char *dialog_msg = g_strdup_printf(_("Your screen name is currently formatted as follows:\n%s"), sn);
-		gaim_notify_info(gc, NULL, _("Account Info"), dialog_msg);
-		g_free(dialog_msg);
-	}
-
-	if (email) {
-		char *dialog_msg = g_strdup_printf(_("The email address for %s is %s"), 
-						   gaim_account_get_username(gaim_connection_get_account(gc)), email);
-		gaim_notify_info(gc, NULL, _("Account Info"), dialog_msg);
-		g_free(dialog_msg);
-	}
-
-	return 1;
-}
-
-static void oscar_keepalive(GaimConnection *gc) {
-	OscarData *od = (OscarData *)gc->proto_data;
-	aim_flap_nop(od->sess, od->conn);
-}
-
-static int oscar_send_typing(GaimConnection *gc, const char *name, int typing) {
-	OscarData *od = (OscarData *)gc->proto_data;
-	struct direct_im *dim = find_direct_im(od, name);
-	if (dim)
-		if (typing == GAIM_TYPING)
-			aim_odc_send_typing(od->sess, dim->conn, 0x0002);
-		else if (typing == GAIM_TYPED)
-			aim_odc_send_typing(od->sess, dim->conn, 0x0001);
-		else
-			aim_odc_send_typing(od->sess, dim->conn, 0x0000);
-	else {
-		/* Don't send if this turkey is in our deny list */
-		GSList *list;
-		for (list=gc->account->deny; (list && aim_sncmp(name, list->data)); list=list->next);
-		if (!list) {
-			struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(gc->account, name));
-			if (bi && bi->typingnot) {
-				if (typing == GAIM_TYPING)
-					aim_im_sendmtn(od->sess, 0x0001, name, 0x0002);
-				else if (typing == GAIM_TYPED)
-					aim_im_sendmtn(od->sess, 0x0001, name, 0x0001);
-				else
-					aim_im_sendmtn(od->sess, 0x0001, name, 0x0000);
-			}
-		}
-	}
-	return 0;
-}
-static void oscar_ask_direct_im(GaimConnection *gc, const char *name);
-static int gaim_odc_send_im(aim_session_t *, aim_conn_t *, const char *, GaimConvImFlags);
-
-static int oscar_send_im(GaimConnection *gc, const char *name, const char *message, GaimConvImFlags imflags) {
-	OscarData *od = (OscarData *)gc->proto_data;
-	struct direct_im *dim = find_direct_im(od, name);
-	int ret = 0;
-	GError *err = NULL;
-	const char *iconfile = gaim_account_get_buddy_icon(gaim_connection_get_account(gc));
-	char *tmpmsg = NULL;
-
-	if (dim && dim->connected) {
-		/* If we're directly connected, send a direct IM */
-		ret = gaim_odc_send_im(od->sess, dim->conn, message, imflags);
-	} else if (imflags & GAIM_CONV_IM_IMAGES) {
-		/* Trying to send an IM image outside of a direct connection. */
-		oscar_ask_direct_im(gc, name);
-		ret = -ENOTCONN;
-	} else {
-		struct buddyinfo *bi;
-		struct aim_sendimext_args args;
-		struct stat st;
-		gsize len;
-
-		bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(gc->account, name));
-		if (!bi) {
-			bi = g_new0(struct buddyinfo, 1);
-			g_hash_table_insert(od->buddyinfo, g_strdup(gaim_normalize(gc->account, name)), bi);
-		}
-
-		args.flags = AIM_IMFLAGS_ACK | AIM_IMFLAGS_CUSTOMFEATURES;
-		if (od->icq) {
-			args.features = features_icq;
-			args.featureslen = sizeof(features_icq);
-			args.flags |= AIM_IMFLAGS_OFFLINE;
-		} else {
-			args.features = features_aim;
-			args.featureslen = sizeof(features_aim);
-
-			if (imflags & GAIM_CONV_IM_AUTO_RESP)
-				args.flags |= AIM_IMFLAGS_AWAY;
-		}
-
-		if (bi->ico_need) {
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "Sending buddy icon request with message\n");
-			args.flags |= AIM_IMFLAGS_BUDDYREQ;
-			bi->ico_need = FALSE;
-		}
-
-		if (iconfile && !stat(iconfile, &st)) {
-			FILE *file = fopen(iconfile, "r");
-			if (file) {
-				char *buf = g_malloc(st.st_size);
-				fread(buf, 1, st.st_size, file);
-				fclose(file);
-
-				args.iconlen   = st.st_size;
-				args.iconsum   = aimutil_iconsum(buf, st.st_size);
-				args.iconstamp = st.st_mtime;
-
-				if ((args.iconlen != bi->ico_me_len) || (args.iconsum != bi->ico_me_csum) || (args.iconstamp != bi->ico_me_time)) {
-					bi->ico_informed = FALSE;
-					bi->ico_sent     = FALSE;
-				}
-
-				if (!bi->ico_informed) {
-					gaim_debug(GAIM_DEBUG_INFO, "oscar",
-							   "Claiming to have a buddy icon\n");
-					args.flags |= AIM_IMFLAGS_HASICON;
-					bi->ico_me_len = args.iconlen;
-					bi->ico_me_csum = args.iconsum;
-					bi->ico_me_time = args.iconstamp;
-					bi->ico_informed = TRUE;
-				}
-
-				g_free(buf);
-			}
-		}
-
-		args.destsn = name;
-
-		/* For ICQ send newlines as CR/LF, for AIM send newlines as <BR> */
-		if (isdigit(name[0]))
-			tmpmsg = gaim_str_add_cr(message);
-		else
-			tmpmsg = gaim_strdup_withhtml(message);
-		len = strlen(tmpmsg);
-
-		args.flags |= oscar_encoding_check(tmpmsg);
-		if (args.flags & AIM_IMFLAGS_UNICODE) {
-			gaim_debug(GAIM_DEBUG_INFO, "oscar", "Sending Unicode IM\n");
-			args.charset = 0x0002;
-			args.charsubset = 0x0000;
-			args.msg = g_convert(tmpmsg, len, "UCS-2BE", "UTF-8", NULL, &len, &err);
-			if (err) {
-				gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-						   "Error converting a unicode message: %s\n", err->message);
-				gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-						   "This really shouldn't happen!\n");
-				/* We really shouldn't try to send the
-				 * IM now, but I'm not sure what to do */
-				g_error_free(err);
-			}
-		} else if (args.flags & AIM_IMFLAGS_ISO_8859_1) {
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "Sending ISO-8859-1 IM\n");
-			args.charset = 0x0003;
-			args.charsubset = 0x0000;
-			args.msg = g_convert(tmpmsg, len, "ISO-8859-1", "UTF-8", NULL, &len, &err);
-			if (err) {
-				gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-						   "conversion error: %s\n", err->message);
-				gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-						   "Someone tell Ethan his 8859-1 detection is wrong\n");
-				args.flags ^= AIM_IMFLAGS_ISO_8859_1 | AIM_IMFLAGS_UNICODE;
-				len = strlen(tmpmsg);
-				g_error_free(err);
-				args.msg = g_convert(tmpmsg, len, "UCS-2BE", "UTF8", NULL, &len, &err);
-				if (err) {
-					gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-							   "Error in unicode fallback: %s\n", err->message);
-					g_error_free(err);
-				}
-			}
-		} else {
-			args.charset = 0x0000;
-			args.charsubset = 0x0000;
-			args.msg = tmpmsg;
-		}
-		args.msglen = len;
-
-		ret = aim_im_sendch1_ext(od->sess, &args);
-	}
-
-	g_free(tmpmsg);
-
-	if (ret >= 0)
-		return 1;
-
-	return ret;
-}
-
-static void oscar_get_info(GaimConnection *gc, const char *name) {
-	OscarData *od = (OscarData *)gc->proto_data;
-
-	if (od->icq && isdigit(name[0]))
-		aim_icq_getallinfo(od->sess, name);
-	else
-		aim_locate_getinfoshort(od->sess, name, 0x00000003);
-}
-
-static void oscar_get_away(GaimConnection *gc, const char *who) {
-	OscarData *od = (OscarData *)gc->proto_data;
-	if (od->icq) {
-		GaimBuddy *budlight = gaim_find_buddy(gc->account, who);
-		if (budlight)
-			if ((budlight->uc & 0xffff0000) >> 16)
-				aim_im_sendch2_geticqaway(od->sess, who, (budlight->uc & 0xffff0000) >> 16);
-			else
-				gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-						   "Error: The user %s has no status message, therefore not requesting.\n", who);
-		else
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-					   "Error: Could not find %s in local buddy list, therefore unable to request status message.\n", who);
-	} else
-		aim_locate_getinfoshort(od->sess, who, 0x00000002);
-}
-
-static void oscar_set_dir(GaimConnection *gc, const char *first, const char *middle, const char *last,
-			  const char *maiden, const char *city, const char *state, const char *country, int web) {
-	/* XXX - some of these things are wrong, but i'm lazy */
-	OscarData *od = (OscarData *)gc->proto_data;
-	aim_locate_setdirinfo(od->sess, first, middle, last,
-				maiden, NULL, NULL, city, state, NULL, 0, web);
-}
-
-static void oscar_set_idle(GaimConnection *gc, int time) {
-	OscarData *od = (OscarData *)gc->proto_data;
-	aim_srv_setidle(od->sess, time);
-}
-
-static void oscar_set_info(GaimConnection *gc, const char *text) {
-	OscarData *od = (OscarData *)gc->proto_data;
-	fu32_t flags = 0;
-	char *text_html = NULL;
-	char *msg = NULL;
-	gsize msglen = 0;
-
-	if (od->rights.maxsiglen == 0)
-		gaim_notify_warning(gc, NULL, _("Unable to set AIM profile."),
-							_("You have probably requested to set your "
-							  "profile before the login procedure completed.  "
-							  "Your profile remains unset; try setting it "
-							  "again when you are fully connected."));
-
-	if (!text) {
-		aim_locate_setprofile(od->sess, NULL, "", 0, NULL, NULL, 0);
-		return;
-	}
-		
-	text_html = gaim_strdup_withhtml(text);
-	flags = oscar_encoding_check(text_html);
-	if (flags & AIM_IMFLAGS_UNICODE) {
-		msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL);
-		aim_locate_setprofile(od->sess, "unicode-2-0", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0);
-		g_free(msg);
-	} else if (flags & AIM_IMFLAGS_ISO_8859_1) {
-		msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL);
-		aim_locate_setprofile(od->sess, "iso-8859-1", msg, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0);
-		g_free(msg);
-	} else {
-		msglen = strlen(text_html);
-		aim_locate_setprofile(od->sess, "us-ascii", text_html, (msglen > od->rights.maxsiglen ? od->rights.maxsiglen : msglen), NULL, NULL, 0);
-	}
-
-	if (msglen > od->rights.maxsiglen) {
-		gchar *errstr;
-		errstr = g_strdup_printf(ngettext("The maximum profile length of %d byte "
-								 "has been exceeded.  Gaim has truncated it for you.",
-								 "The maximum profile length of %d bytes "
-								 "has been exceeded.  Gaim has truncated it for you.",
-								 od->rights.maxsiglen), od->rights.maxsiglen);
-		gaim_notify_warning(gc, NULL, _("Profile too long."), errstr);
-		g_free(errstr);
-	}
-
-	g_free(text_html);
-
-	return;
-}
-
-static void oscar_set_away_aim(GaimConnection *gc, OscarData *od, const char *text)
-{
-	fu32_t flags = 0;
-	gchar *text_html = NULL;
-	char *msg = NULL;
-	gsize msglen = 0;
-
-	if (od->rights.maxawaymsglen == 0)
-		gaim_notify_warning(gc, NULL, _("Unable to set AIM away message."),
-							_("You have probably requested to set your "
-							  "away message before the login procedure "
-							  "completed.  You remain in a \"present\" "
-							  "state; try setting it again when you are "
-							  "fully connected."));
-
-	if (gc->away) {
-		g_free(gc->away);
-		gc->away = NULL;
-	}
-
-	if (!text) {
-		aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0);
-		return;
-	}
-
-	text_html = gaim_strdup_withhtml(text);
-	flags = oscar_encoding_check(text_html);
-	if (flags & AIM_IMFLAGS_UNICODE) {
-		msg = g_convert(text_html, strlen(text_html), "UCS-2BE", "UTF-8", NULL, &msglen, NULL);
-		aim_locate_setprofile(od->sess, NULL, NULL, 0, "unicode-2-0", msg, 
-			(msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen));
-		g_free(msg);
-		gc->away = g_strndup(text, od->rights.maxawaymsglen/2);
-	} else if (flags & AIM_IMFLAGS_ISO_8859_1) {
-		msg = g_convert(text_html, strlen(text_html), "ISO-8859-1", "UTF-8", NULL, &msglen, NULL);
-		aim_locate_setprofile(od->sess, NULL, NULL, 0, "iso-8859-1", msg, 
-			(msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen));
-		g_free(msg);
-		gc->away = g_strndup(text_html, od->rights.maxawaymsglen);
-	} else {
-		msglen = strlen(text_html);
-		aim_locate_setprofile(od->sess, NULL, NULL, 0, "us-ascii", text_html, 
-			(msglen > od->rights.maxawaymsglen ? od->rights.maxawaymsglen : msglen));
-		gc->away = g_strndup(text_html, od->rights.maxawaymsglen);
-	}
-
-	if (msglen > od->rights.maxawaymsglen) {
-		gchar *errstr;
-
-		errstr = g_strdup_printf(ngettext("The maximum away message length of %d byte "
-								 "has been exceeded.  Gaim has truncated it for you.",
-								 "The maximum away message length of %d bytes "
-								 "has been exceeded.  Gaim has truncated it for you.",
-								 od->rights.maxawaymsglen), od->rights.maxawaymsglen);
-		gaim_notify_warning(gc, NULL, _("Away message too long."), errstr);
-		g_free(errstr);
-	}
-	
-	g_free(text_html);
-	return;
-}
-
-static void oscar_set_away_icq(GaimConnection *gc, OscarData *od, const char *state, const char *message)
-{
-	GaimAccount *account = gaim_connection_get_account(gc);
-	if (gc->away) {
-		g_free(gc->away);
-		gc->away = NULL;
-	}
-
-	if (strcmp(state, _("Invisible"))) {
-		if ((od->sess->ssi.received_data) && (aim_ssi_getpermdeny(od->sess->ssi.local) != account->perm_deny))
-			aim_ssi_setpermdeny(od->sess, account->perm_deny, 0xffffffff);
-		account->perm_deny = 4;
-	} else {
-		if ((od->sess->ssi.received_data) && (aim_ssi_getpermdeny(od->sess->ssi.local) != 0x03))
-			aim_ssi_setpermdeny(od->sess, 0x03, 0xffffffff);
-		account->perm_deny = 3;
-	}
-
-	if (!strcmp(state, _("Online")))
-		aim_setextstatus(od->sess, AIM_ICQ_STATE_NORMAL);
-	else if (!strcmp(state, _("Away"))) {
-		aim_setextstatus(od->sess, AIM_ICQ_STATE_AWAY);
-		gc->away = g_strdup("");
-	} else if (!strcmp(state, _("Do Not Disturb"))) {
-		aim_setextstatus(od->sess, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_DND | AIM_ICQ_STATE_BUSY);
-		gc->away = g_strdup("");
-	} else if (!strcmp(state, _("Not Available"))) {
-		aim_setextstatus(od->sess, AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY);
-		gc->away = g_strdup("");
-	} else if (!strcmp(state, _("Occupied"))) {
-		aim_setextstatus(od->sess, AIM_ICQ_STATE_AWAY | AIM_ICQ_STATE_BUSY);
-		gc->away = g_strdup("");
-	} else if (!strcmp(state, _("Free For Chat"))) {
-		aim_setextstatus(od->sess, AIM_ICQ_STATE_CHAT);
-		gc->away = g_strdup("");
-	} else if (!strcmp(state, _("Invisible"))) {
-		aim_setextstatus(od->sess, AIM_ICQ_STATE_INVISIBLE);
-		gc->away = g_strdup("");
-	} else if (!strcmp(state, GAIM_AWAY_CUSTOM)) {
-	 	if (message) {
-			aim_setextstatus(od->sess, AIM_ICQ_STATE_OUT | AIM_ICQ_STATE_AWAY);
-			gc->away = g_strdup("");
-		} else {
-			aim_setextstatus(od->sess, AIM_ICQ_STATE_NORMAL);
-		}
-	}
-
-	return;
-}
-
-static void oscar_set_away(GaimConnection *gc, const char *state, const char *message)
-{
-	OscarData *od = (OscarData *)gc->proto_data;
-
-	if (od->icq)
-		oscar_set_away_icq(gc, od, state, message);
-	else
-		oscar_set_away_aim(gc, od, message);
-
-	return;
-}
-
-static void oscar_warn(GaimConnection *gc, const char *name, int anon) {
-	OscarData *od = (OscarData *)gc->proto_data;
-	aim_im_warn(od->sess, od->conn, name, anon ? AIM_WARN_ANON : 0);
-}
-
-static void oscar_dir_search(GaimConnection *gc, const char *first, const char *middle, const char *last,
-			     const char *maiden, const char *city, const char *state, const char *country, const char *email) {
-	OscarData *od = (OscarData *)gc->proto_data;
-	if (strlen(email))
-		aim_search_address(od->sess, od->conn, email);
-}
-
-static void oscar_add_buddy(GaimConnection *gc, const char *name, GaimGroup *g) {
-	OscarData *od = (OscarData *)gc->proto_data;
-#ifdef NOSSI
-	aim_add_buddy(od->sess, od->conn, name);
-#else
-	if ((od->sess->ssi.received_data) && !(aim_ssi_itemlist_exists(od->sess->ssi.local, name))) {
-		GaimBuddy *buddy = gaim_find_buddy(gc->account, name);
-		GaimGroup *group = gaim_find_buddys_group(buddy);
-		if (buddy && group) {
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "ssi: adding buddy %s to group %s\n", name, group->name);
-			aim_ssi_addbuddy(od->sess, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0);
-		}
-	}
-#endif
-	if (od->icq)
-		aim_icq_getalias(od->sess, name);
-}
-
-static void oscar_add_buddies(GaimConnection *gc, GList *buddies) {
-	OscarData *od = (OscarData *)gc->proto_data;
-#ifdef NOSSI
-	char buf[MSG_LEN];
-	int n=0;
-	while (buddies) {
-		if (n > MSG_LEN - 18) {
-			aim_buddylist_set(od->sess, od->conn, buf);
-			n = 0;
-		}
-		n += g_snprintf(buf + n, sizeof(buf) - n, "%s&", (char *)buddies->data);
-		buddies = buddies->next;
-	}
-	aim_buddylist_set(od->sess, od->conn, buf);
-#else
-	if (od->sess->ssi.received_data) {
-		while (buddies) {
-			oscar_add_buddy(gc, (const char *)buddies->data, NULL);
-			buddies = buddies->next;
-		}
-	}
-#endif
-}
-
-static void oscar_remove_buddy(GaimConnection *gc, const char *name, const char *group) {
-	OscarData *od = (OscarData *)gc->proto_data;
-#ifdef NOSSI
-	aim_remove_buddy(od->sess, od->conn, name);
-#else
-	if (od->sess->ssi.received_data) {
-		gaim_debug(GAIM_DEBUG_INFO, "oscar",
-				   "ssi: deleting buddy %s from group %s\n", name, group);
-		aim_ssi_delbuddy(od->sess, name, group);
-	}
-#endif
-}
-
-static void oscar_remove_buddies(GaimConnection *gc, GList *buddies, const char *group) {
-	OscarData *od = (OscarData *)gc->proto_data;
-#ifdef NOSSI
-	GList *cur;
-	for (cur=buddies; cur; cur=cur->next)
-		aim_remove_buddy(od->sess, od->conn, cur->data);
-#else
-	if (od->sess->ssi.received_data) {
-		while (buddies) {
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "ssi: deleting buddy %s from group %s\n", (char *)buddies->data, group);
-			aim_ssi_delbuddy(od->sess, buddies->data, group);
-			buddies = buddies->next;
-		}
-	}
-#endif
-}
-
-#ifndef NOSSI
-static void oscar_move_buddy(GaimConnection *gc, const char *name, const char *old_group, const char *new_group) {
-	OscarData *od = (OscarData *)gc->proto_data;
-	if (od->sess->ssi.received_data && strcmp(old_group, new_group)) {
-		gaim_debug(GAIM_DEBUG_INFO, "oscar",
-				   "ssi: moving buddy %s from group %s to group %s\n", name, old_group, new_group);
-		aim_ssi_movebuddy(od->sess, old_group, new_group, name);
-	}
-}
-
-static void oscar_alias_buddy(GaimConnection *gc, const char *name, const char *alias) {
-	OscarData *od = (OscarData *)gc->proto_data;
-	if (od->sess->ssi.received_data) {
-		char *gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, name);
-		if (gname) {
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "ssi: changing the alias for buddy %s to %s\n", name, alias);
-			aim_ssi_aliasbuddy(od->sess, gname, name, alias);
-		}
-	}
-}
-
-static void oscar_rename_group(GaimConnection *g, const char *old_group, const char *new_group, GList *members) {
-	OscarData *od = (OscarData *)g->proto_data;
-
-	if (od->sess->ssi.received_data) {
-		if (aim_ssi_itemlist_finditem(od->sess->ssi.local, new_group, NULL, AIM_SSI_TYPE_GROUP)) {
-			oscar_remove_buddies(g, members, old_group);
-			oscar_add_buddies(g, members);
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "ssi: moved all buddies from group %s to %s\n", old_group, new_group);
-		} else {
-			aim_ssi_rename_group(od->sess, old_group, new_group);
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "ssi: renamed group %s to %s\n", old_group, new_group);
-		}
-	}
-}
-
-static gboolean gaim_ssi_rerequestdata(gpointer data) {
-	aim_session_t *sess = data;
-	aim_ssi_reqdata(sess);
-	return FALSE;
-}
-
-static int gaim_ssi_parseerr(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	va_list ap;
-	fu16_t reason;
-
-	va_start(ap, fr);
-	reason = (fu16_t)va_arg(ap, unsigned int);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_ERROR, "oscar", "ssi: SNAC error %hu\n", reason);
-
-	if (reason == 0x0005) {
-		gaim_notify_error(gc, NULL, _("Unable To Retrieve Buddy List"),
-						  _("Gaim was temporarily unable to retrieve your buddy list from the AIM servers.  Your buddy list is not lost, and will probably become available in a few hours."));
-		od->getblisttimer = g_timeout_add(300000, gaim_ssi_rerequestdata, od->sess);
-	}
-
-	/* Activate SSI */
-	/* Sending the enable causes other people to be able to see you, and you to see them */
-	/* Make sure your privacy setting/invisibility is set how you want it before this! */
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: activating server-stored buddy list\n");
-	aim_ssi_enable(od->sess);
-
-	return 1;
-}
-
-static int gaim_ssi_parserights(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = (OscarData *)gc->proto_data;
-	int numtypes, i;
-	fu16_t *maxitems;
-	va_list ap;
-
-	va_start(ap, fr);
-	numtypes = va_arg(ap, int);
-	maxitems = va_arg(ap, fu16_t *);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_MISC, "oscar", "ssi rights:");
-
-	for (i=0; i<numtypes; i++)
-		gaim_debug(GAIM_DEBUG_MISC, NULL, " max type 0x%04x=%hd,",
-				   i, maxitems[i]);
-
-	gaim_debug(GAIM_DEBUG_MISC, NULL, "\n");
-
-	if (numtypes >= 0)
-		od->rights.maxbuddies = maxitems[0];
-	if (numtypes >= 1)
-		od->rights.maxgroups = maxitems[1];
-	if (numtypes >= 2)
-		od->rights.maxpermits = maxitems[2];
-	if (numtypes >= 3)
-		od->rights.maxdenies = maxitems[3];
-
-	return 1;
-}
-
-static int gaim_ssi_parselist(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	GaimAccount *account = gaim_connection_get_account(gc);
-	OscarData *od = (OscarData *)gc->proto_data;
-	struct aim_ssi_item *curitem;
-	int tmp;
-	gboolean export = FALSE;
-	/* XXX - use these?
-	va_list ap;
-
-	va_start(ap, fr);
-	fmtver = (fu16_t)va_arg(ap, int);
-	numitems = (fu16_t)va_arg(ap, int);
-	items = va_arg(ap, struct aim_ssi_item);
-	timestamp = va_arg(ap, fu32_t);
-	va_end(ap); */
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "ssi: syncing local list and server list\n");
-
-	/* Clean the buddy list */
-	aim_ssi_cleanlist(sess);
-
-	/* Add from server list to local list */
-	for (curitem=sess->ssi.local; curitem; curitem=curitem->next) {
-		if ((curitem->name == NULL) || (g_utf8_validate(curitem->name, -1, NULL)))
-		switch (curitem->type) {
-			case 0x0000: { /* Buddy */
-				if (curitem->name) {
-					char *gname = aim_ssi_itemlist_findparentname(sess->ssi.local, curitem->name);
-					char *gname_utf8 = gname ? gaim_utf8_try_convert(gname) : NULL;
-					char *alias = aim_ssi_getalias(sess->ssi.local, gname, curitem->name);
-					char *alias_utf8 = alias ? gaim_utf8_try_convert(alias) : NULL;
-					GaimBuddy *buddy = gaim_find_buddy(gc->account, curitem->name);
-					/* Should gname be freed here? -- elb */
-					/* Not with the current code, but that might be cleaner -- med */
-					free(alias);
-					if (buddy) {
-						/* Get server stored alias */
-						if (alias_utf8) {
-							g_free(buddy->alias);
-							buddy->alias = g_strdup(alias_utf8);
-						}
-					} else {
-						GaimGroup *g;
-						buddy = gaim_buddy_new(gc->account, curitem->name, alias_utf8);
-
-						if (!(g = gaim_find_group(gname_utf8 ? gname_utf8 : _("Orphans")))) {
-							g = gaim_group_new(gname_utf8 ? gname_utf8 : _("Orphans"));
-							gaim_blist_add_group(g, NULL);
-						}
-
-						gaim_debug(GAIM_DEBUG_INFO, "oscar",
-								   "ssi: adding buddy %s to group %s to local list\n", curitem->name, gname_utf8 ? gname_utf8 : _("Orphans"));
-						gaim_blist_add_buddy(buddy, NULL, g, NULL);
-						export = TRUE;
-					}
-					g_free(gname_utf8);
-					g_free(alias_utf8);
-				}
-			} break;
-
-			case 0x0001: { /* Group */
-				/* Shouldn't add empty groups */
-			} break;
-
-			case 0x0002: { /* Permit buddy */
-				if (curitem->name) {
-					/* if (!find_permdeny_by_name(gc->permit, curitem->name)) { AAA */
-					GSList *list;
-					for (list=account->permit; (list && aim_sncmp(curitem->name, list->data)); list=list->next);
-					if (!list) {
-						gaim_debug(GAIM_DEBUG_INFO, "oscar",
-								   "ssi: adding permit buddy %s to local list\n", curitem->name);
-						gaim_privacy_permit_add(account, curitem->name, TRUE);
-						export = TRUE;
-					}
-				}
-			} break;
-
-			case 0x0003: { /* Deny buddy */
-				if (curitem->name) {
-					GSList *list;
-					for (list=account->deny; (list && aim_sncmp(curitem->name, list->data)); list=list->next);
-					if (!list) {
-						gaim_debug(GAIM_DEBUG_INFO, "oscar",
-								   "ssi: adding deny buddy %s to local list\n", curitem->name);
-						gaim_privacy_deny_add(account, curitem->name, TRUE);
-						export = TRUE;
-					}
-				}
-			} break;
-
-			case 0x0004: { /* Permit/deny setting */
-				if (curitem->data) {
-					fu8_t permdeny;
-					if ((permdeny = aim_ssi_getpermdeny(sess->ssi.local)) && (permdeny != account->perm_deny)) {
-						gaim_debug(GAIM_DEBUG_INFO, "oscar",
-								   "ssi: changing permdeny from %d to %hhu\n", account->perm_deny, permdeny);
-						account->perm_deny = permdeny;
-						if (od->icq && account->perm_deny == 0x03) {
-							serv_set_away(gc, "Invisible", "");
-						}
-						export = TRUE;
-					}
-				}
-			} break;
-
-			case 0x0005: { /* Presence setting */
-				/* We don't want to change Gaim's setting because it applies to all accounts */
-			} break;
-		} /* End of switch on curitem->type */
-	} /* End of for loop */
-
-	/* If changes were made, then flush buddy list to file */
-	if (export)
-		gaim_blist_save();
-
-	{ /* Add from local list to server list */
-		GaimBlistNode *gnode, *cnode, *bnode;
-		GaimGroup *group;
-		GaimBuddy *buddy;
-		GaimBuddyList *blist;
-		GSList *cur;
-
-		/* Buddies */
-		if ((blist = gaim_get_blist()))
-			for (gnode = blist->root; gnode; gnode = gnode->next) {
-				if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
-					continue;
-				group = (GaimGroup *)gnode;
-				for (cnode = gnode->child; cnode; cnode = cnode->next) {
-					if(!GAIM_BLIST_NODE_IS_CONTACT(cnode))
-						continue;
-					for (bnode = cnode->child; bnode; bnode = bnode->next) {
-						if(!GAIM_BLIST_NODE_IS_BUDDY(bnode))
-							continue;
-						buddy = (GaimBuddy *)bnode;
-						if (buddy->account == gc->account) {
-							const char *servernick = gaim_buddy_get_setting(buddy, "servernick");
-							if (servernick)
-								serv_got_alias(gc, buddy->name, servernick);
-
-							if (aim_ssi_itemlist_exists(sess->ssi.local, buddy->name)) {
-								/* Store local alias on server */
-								char *alias = aim_ssi_getalias(sess->ssi.local, group->name, buddy->name);
-								if (!alias && buddy->alias && strlen(buddy->alias))
-									aim_ssi_aliasbuddy(sess, group->name, buddy->name, buddy->alias);
-								free(alias);
-							} else {
-								gaim_debug(GAIM_DEBUG_INFO, "oscar",
-										"ssi: adding buddy %s from local list to server list\n", buddy->name);
-								aim_ssi_addbuddy(sess, buddy->name, group->name, gaim_get_buddy_alias_only(buddy), NULL, NULL, 0);
-							}
-						}
-					}
-				}
-			}
-
-		/* Permit list */
-		if (gc->account->permit) {
-			for (cur=gc->account->permit; cur; cur=cur->next)
-				if (!aim_ssi_itemlist_finditem(sess->ssi.local, NULL, cur->data, AIM_SSI_TYPE_PERMIT)) {
-					gaim_debug(GAIM_DEBUG_INFO, "oscar",
-							"ssi: adding permit %s from local list to server list\n", (char *)cur->data);
-					aim_ssi_addpermit(sess, cur->data);
-				}
-		}
-
-		/* Deny list */
-		if (gc->account->deny) {
-			for (cur=gc->account->deny; cur; cur=cur->next)
-				if (!aim_ssi_itemlist_finditem(sess->ssi.local, NULL, cur->data, AIM_SSI_TYPE_DENY)) {
-					gaim_debug(GAIM_DEBUG_INFO, "oscar",
-							"ssi: adding deny %s from local list to server list\n", (char *)cur->data);
-					aim_ssi_adddeny(sess, cur->data);
-				}
-		}
-		/* Presence settings (idle time visibility) */
-		if ((tmp = aim_ssi_getpresence(sess->ssi.local)) != 0xFFFFFFFF)
-			if (!(tmp & 0x400))
-				aim_ssi_setpresence(sess, tmp | 0x400);
-	} /* end adding buddies from local list to server list */
-
-	/* Set our ICQ status */
-	if  (od->icq && !gc->away) {
-		aim_setextstatus(sess, AIM_ICQ_STATE_NORMAL);
-	}
-
-	/* Activate SSI */
-	/* Sending the enable causes other people to be able to see you, and you to see them */
-	/* Make sure your privacy setting/invisibility is set how you want it before this! */
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "ssi: activating server-stored buddy list\n");
-	aim_ssi_enable(sess);
-
-	return 1;
-}
-
-static int gaim_ssi_parseack(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	va_list ap;
-	struct aim_ssi_tmp *retval;
-
-	va_start(ap, fr);
-	retval = va_arg(ap, struct aim_ssi_tmp *);
-	va_end(ap);
-
-	while (retval) {
-		gaim_debug(GAIM_DEBUG_MISC, "oscar",
-				   "ssi: status is 0x%04hx for a 0x%04hx action with name %s\n", retval->ack,  retval->action, retval->item ? (retval->item->name ? retval->item->name : "no name") : "no item");
-
-		if (retval->ack != 0xffff)
-		switch (retval->ack) {
-			case 0x0000: { /* added successfully */
-			} break;
-
-			case 0x000c: { /* you are over the limit, the cheat is to the limit, come on fhqwhgads */
-				gchar *buf;
-				buf = g_strdup_printf(_("Could not add the buddy %s because you have too many buddies in your buddy list.  Please remove one and try again."), (retval->name ? retval->name : _("(no name)")));
-				gaim_notify_error(gc, NULL, _("Unable To Add"), buf);
-				g_free(buf);
-			}
-
-			case 0x000e: { /* buddy requires authorization */
-				if ((retval->action == AIM_CB_SSI_ADD) && (retval->name))
-					gaim_auth_sendrequest(gc, retval->name);
-			} break;
-
-			default: { /* La la la */
-				gchar *buf;
-				gaim_debug(GAIM_DEBUG_ERROR, "oscar", "ssi: Action 0x%04hx was unsuccessful with error 0x%04hx\n", retval->action, retval->ack);
-				buf = g_strdup_printf(_("Could not add the buddy %s for an unknown reason.  The most common reason for this is that you have the maximum number of allowed buddies in your buddy list."), (retval->name ? retval->name : _("(no name)")));
-				gaim_notify_error(gc, NULL, _("Unable To Add"), buf);
-				g_free(buf);
-				/* XXX - Should remove buddy from local list */
-			} break;
-		}
-
-		retval = retval->next;
-	}
-
-	return 1;
-}
-
-static int gaim_ssi_authgiven(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	va_list ap;
-	char *sn, *msg;
-	gchar *dialog_msg, *nombre;
-	struct name_data *data;
-	GaimBuddy *buddy;
-
-	va_start(ap, fr);
-	sn = va_arg(ap, char *);
-	msg = va_arg(ap, char *);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "ssi: %s has given you permission to add him to your buddy list\n", sn);
-
-	buddy = gaim_find_buddy(gc->account, sn);
-	if (buddy && (gaim_get_buddy_alias_only(buddy)))
-		nombre = g_strdup_printf("%s (%s)", sn, gaim_get_buddy_alias_only(buddy));
-	else
-		nombre = g_strdup(sn);
-
-	dialog_msg = g_strdup_printf(_("The user %s has given you permission to add you to their buddy list.  Do you want to add them?"), nombre);
-	data = g_new(struct name_data, 1);
-	data->gc = gc;
-	data->name = g_strdup(sn);
-	data->nick = NULL;
-
-	gaim_request_yes_no(gc, NULL, _("Authorization Given"), dialog_msg,
-						0, data,
-						G_CALLBACK(gaim_icq_buddyadd),
-						G_CALLBACK(oscar_free_name_data));
-
-	g_free(dialog_msg);
-	g_free(nombre);
-
-	return 1;
-}
-
-static int gaim_ssi_authrequest(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	va_list ap;
-	char *sn, *msg;
-	gchar *dialog_msg, *nombre;
-	struct name_data *data;
-	GaimBuddy *buddy;
-
-	va_start(ap, fr);
-	sn = va_arg(ap, char *);
-	msg = va_arg(ap, char *);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "ssi: received authorization request from %s\n", sn);
-
-	buddy = gaim_find_buddy(gc->account, sn);
-	if (buddy && (gaim_get_buddy_alias_only(buddy)))
-		nombre = g_strdup_printf("%s (%s)", sn, gaim_get_buddy_alias_only(buddy));
-	else
-		nombre = g_strdup(sn);
-
-	dialog_msg = g_strdup_printf(_("The user %s wants to add you to their buddy list for the following reason:\n%s"), nombre, msg ? msg : _("No reason given."));
-	data = g_new(struct name_data, 1);
-	data->gc = gc;
-	data->name = g_strdup(sn);
-	data->nick = NULL;
-
-	gaim_request_action(gc, NULL, _("Authorization Request"), dialog_msg,
-						0, data, 2,
-						_("Authorize"), G_CALLBACK(gaim_auth_grant),
-						_("Deny"), G_CALLBACK(gaim_auth_dontgrant_msgprompt));
-
-	g_free(dialog_msg);
-	g_free(nombre);
-
-	return 1;
-}
-
-static int gaim_ssi_authreply(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	va_list ap;
-	char *sn, *msg;
-	gchar *dialog_msg, *nombre;
-	fu8_t reply;
-	GaimBuddy *buddy;
-
-	va_start(ap, fr);
-	sn = va_arg(ap, char *);
-	reply = (fu8_t)va_arg(ap, int);
-	msg = va_arg(ap, char *);
-	va_end(ap);
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "ssi: received authorization reply from %s.  Reply is 0x%04hhx\n", sn, reply);
-
-	buddy = gaim_find_buddy(gc->account, sn);
-	if (buddy && (gaim_get_buddy_alias_only(buddy)))
-		nombre = g_strdup_printf("%s (%s)", sn, gaim_get_buddy_alias_only(buddy));
-	else
-		nombre = g_strdup(sn);
-
-	if (reply) {
-		/* Granted */
-		dialog_msg = g_strdup_printf(_("The user %s has granted your request to add them to your buddy list."), nombre);
-		gaim_notify_info(gc, NULL, _("Authorization Granted"), dialog_msg);
-	} else {
-		/* Denied */
-		dialog_msg = g_strdup_printf(_("The user %s has denied your request to add them to your buddy list for the following reason:\n%s"), nombre, msg ? msg : _("No reason given."));
-		gaim_notify_info(gc, NULL, _("Authorization Denied"), dialog_msg);
-	}
-	g_free(dialog_msg);
-	g_free(nombre);
-
-	return 1;
-}
-
-static int gaim_ssi_gotadded(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	va_list ap;
-	char *sn;
-	GaimBuddy *buddy;
-
-	va_start(ap, fr);
-	sn = va_arg(ap, char *);
-	va_end(ap);
-
-	buddy = gaim_find_buddy(gc->account, sn);
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "ssi: %s added you to their buddy list\n", sn);
-	gaim_account_notify_added(gc->account, NULL, sn, (buddy ? gaim_get_buddy_alias_only(buddy) : NULL), NULL);
-
-	return 1;
-}
-#endif
-
-static GList *oscar_chat_info(GaimConnection *gc) {
-	GList *m = NULL;
-	struct proto_chat_entry *pce;
-
-	pce = g_new0(struct proto_chat_entry, 1);
-	pce->label = _("Join what group:");
-	pce->identifier = "room";
-	m = g_list_append(m, pce);
-
-	pce = g_new0(struct proto_chat_entry, 1);
-	pce->label = _("Exchange:");
-	pce->identifier = "exchange";
-	pce->is_int = TRUE;
-	pce->min = 4;
-	pce->max = 20;
-	m = g_list_append(m, pce);
-
-	return m;
-}
-
-static void oscar_join_chat(GaimConnection *g, GHashTable *data) {
-	OscarData *od = (OscarData *)g->proto_data;
-	aim_conn_t *cur;
-	char *name, *exchange;
-
-	name = g_hash_table_lookup(data, "room");
-	exchange = g_hash_table_lookup(data, "exchange");
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "Attempting to join chat room %s.\n", name);
-	if ((cur = aim_getconn_type(od->sess, AIM_CONN_TYPE_CHATNAV))) {
-		gaim_debug(GAIM_DEBUG_INFO, "oscar",
-				   "chatnav exists, creating room\n");
-		aim_chatnav_createroom(od->sess, cur, name, atoi(exchange));
-	} else {
-		/* this gets tricky */
-		struct create_room *cr = g_new0(struct create_room, 1);
-		gaim_debug(GAIM_DEBUG_INFO, "oscar",
-				   "chatnav does not exist, opening chatnav\n");
-		cr->exchange = atoi(exchange);
-		cr->name = g_strdup(name);
-		od->create_rooms = g_slist_append(od->create_rooms, cr);
-		aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_CHATNAV);
-	}
-}
-
-static void oscar_chat_invite(GaimConnection *g, int id, const char *message, const char *name) {
-	OscarData *od = (OscarData *)g->proto_data;
-	struct chat_connection *ccon = find_oscar_chat(g, id);
-	
-	if (!ccon)
-		return;
-	
-	aim_chat_invite(od->sess, od->conn, name, message ? message : "",
-			ccon->exchange, ccon->name, 0x0);
-}
-
-static void oscar_chat_leave(GaimConnection *g, int id) {
-	OscarData *od = g ? (OscarData *)g->proto_data : NULL;
-	GSList *bcs = g->buddy_chats;
-	GaimConversation *b = NULL;
-	struct chat_connection *c = NULL;
-	int count = 0;
-
-	while (bcs) {
-		count++;
-		b = (GaimConversation *)bcs->data;
-		if (id == gaim_conv_chat_get_id(GAIM_CONV_CHAT(b)))
-			break;
-		bcs = bcs->next;
-		b = NULL;
-	}
-
-	if (!b)
-		return;
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "Attempting to leave room %s (currently in %d rooms)\n", b->name, count);
-	
-	c = find_oscar_chat(g, gaim_conv_chat_get_id(GAIM_CONV_CHAT(b)));
-	if (c != NULL) {
-		if (od)
-			od->oscar_chats = g_slist_remove(od->oscar_chats, c);
-		if (c->inpa > 0)
-			gaim_input_remove(c->inpa);
-		if (g && od->sess)
-			aim_conn_kill(od->sess, &c->conn);
-		g_free(c->name);
-		g_free(c->show);
-		g_free(c);
-	}
-	/* we do this because with Oscar it doesn't tell us we left */
-	serv_got_chat_left(g, gaim_conv_chat_get_id(GAIM_CONV_CHAT(b)));
-}
-
-static int oscar_chat_send(GaimConnection *g, int id, const char *message) {
-	OscarData *od = (OscarData *)g->proto_data;
-	GSList *bcs = g->buddy_chats;
-	GaimConversation *b = NULL;
-	struct chat_connection *c = NULL;
-	char *buf, *buf2;
-	int i, j;
-
-	while (bcs) {
-		b = (GaimConversation *)bcs->data;
-		if (id == gaim_conv_chat_get_id(GAIM_CONV_CHAT(b)))
-			break;
-		bcs = bcs->next;
-		b = NULL;
-	}
-	if (!b)
-		return -EINVAL;
-
-	bcs = od->oscar_chats;
-	while (bcs) {
-		c = (struct chat_connection *)bcs->data;
-		if (b == c->cnv)
-			break;
-		bcs = bcs->next;
-		c = NULL;
-	}
-	if (!c)
-		return -EINVAL;
-
-	buf = g_malloc(strlen(message) * 4 + 1);
-	for (i = 0, j = 0; i < strlen(message); i++) {
-		if (message[i] == '\n') {
-			buf[j++] = '<';
-			buf[j++] = 'B';
-			buf[j++] = 'R';
-			buf[j++] = '>';
-		} else {
-			buf[j++] = message[i];
-		}
-	}
-	buf[j] = '\0';
-
-	if (strlen(buf) > c->maxlen)
-		return -E2BIG;
-
-	buf2 = gaim_markup_strip_html(buf);
-	if (strlen(buf2) > c->maxvis) {
-		g_free(buf2);
-		return -E2BIG;
-	}
-	g_free(buf2);
-
-	aim_chat_send_im(od->sess, c->conn, 0, buf, strlen(buf));
-	g_free(buf);
-	return 0;
-}
-
-static const char *oscar_list_icon(GaimAccount *a, GaimBuddy *b) {
-	if (!b || (b && b->name && b->name[0] == '+')) {
-		if (a != NULL && isdigit(*gaim_account_get_username(a)))
-			return "icq";
-		else
-			return "aim";
-	}
-
-	if (b != NULL && isdigit(b->name[0]))
-		return "icq";
-	return "aim";
-}
-
-static void oscar_list_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne)
-{
-	GaimAccount *account = NULL;
-	GaimConnection *gc = NULL;
-	OscarData *od = NULL;
-	char *emblems[4] = {NULL,NULL,NULL,NULL};
-	int i = 0;
-	aim_userinfo_t *userinfo = NULL;
-
-	if (b != NULL)
-		account = b->account;
-	if (account != NULL)
-		gc = account->gc;
-	if (gc != NULL)
-		od = gc->proto_data;
-
-	if (!GAIM_BUDDY_IS_ONLINE(b)) {
-		char *gname;
-		if ((b->name) && (od) && (od->sess->ssi.received_data) && 
-			(gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, b->name)) && 
-			(aim_ssi_waitingforauth(od->sess->ssi.local, gname, b->name))) {
-			emblems[i++] = "notauthorized";
-		} else {
-			emblems[i++] = "offline";
-		}
-	}
-
-	if (b->name && (b->uc & 0xffff0000) && isdigit(b->name[0])) {
-		int uc = b->uc >> 16;
-		if (uc & AIM_ICQ_STATE_INVISIBLE)
-			emblems[i++] = "invisible";
-		else if (uc & AIM_ICQ_STATE_CHAT)
-			emblems[i++] = "freeforchat";
-		else if (uc & AIM_ICQ_STATE_DND)
-			emblems[i++] = "dnd";
-		else if (uc & AIM_ICQ_STATE_OUT)
-			emblems[i++] = "na";
-		else if (uc & AIM_ICQ_STATE_BUSY)
-			emblems[i++] = "occupied";
-		else if (uc & AIM_ICQ_STATE_AWAY)
-			emblems[i++] = "away";
-	} else {
-		if (b->uc & UC_UNAVAILABLE) 
-			emblems[i++] = "away";
-	}
-	if (b->uc & UC_WIRELESS)
-		emblems[i++] = "wireless";
-	if (b->uc & UC_AOL)
-		emblems[i++] = "aol";
-	if (b->uc & UC_ADMIN)
-		emblems[i++] = "admin";
-	if (b->uc & UC_AB && i < 4)
-		emblems[i++] = "activebuddy";
-	if (b->uc & UC_HIPTOP && i < 4)
-		emblems[i++] = "hiptop";
-/*	if (b->uc & UC_UNCONFIRMED && i < 4)
-		emblems[i++] = "unconfirmed"; */
-
-	if ((i < 4) && (od != NULL)) {
-		userinfo = aim_locate_finduserinfo(od->sess, b->name);
-		if ((userinfo != NULL) && (userinfo->capabilities & AIM_CAPS_SECUREIM))
-			emblems[i++] = "secure";
-	}
-
-	*se = emblems[0];
-	*sw = emblems[1];
-	*nw = emblems[2];
-	*ne = emblems[3];
-}
-
-static char *oscar_tooltip_text(GaimBuddy *b) {
-	GaimConnection *gc = b->account->gc;
-	OscarData *od = gc->proto_data;
-	struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(b->account, b->name));
-	aim_userinfo_t *userinfo = aim_locate_finduserinfo(od->sess, b->name);
-	gchar *tmp = NULL, *ret = g_strdup("");
-
-	if (GAIM_BUDDY_IS_ONLINE(b)) {
-		if (isdigit(b->name[0])) {
-			char *status;
-			status = gaim_icq_status((b->uc & 0xffff0000) >> 16);
-			tmp = ret;
-			ret = g_strconcat(tmp, _("<b>Status:</b> "), status, "\n", NULL);
-			g_free(tmp);
-			g_free(status);
-		}
-
-		if (userinfo != NULL) {
-			char *tstr = gaim_str_seconds_to_string(time(NULL) - userinfo->onlinesince +
-				(gc->login_time_official ? gc->login_time_official - gc->login_time : 0));
-			tmp = ret;
-			ret = g_strconcat(tmp, _("<b>Logged In:</b> "), tstr, "\n", NULL);
-			g_free(tmp);
-			g_free(tstr);
-		}
-
-		if ((bi != NULL) && (bi->ipaddr)) {
-			char *tstr =  g_strdup_printf("%hhu.%hhu.%hhu.%hhu",
-							(bi->ipaddr & 0xff000000) >> 24,
-							(bi->ipaddr & 0x00ff0000) >> 16,
-							(bi->ipaddr & 0x0000ff00) >> 8,
-							(bi->ipaddr & 0x000000ff));
-			tmp = ret;
-			ret = g_strconcat(tmp, _("<b>IP Address:</b> "), tstr, "\n", NULL);
-			g_free(tmp);
-			g_free(tstr);
-		}
-
-		if ((userinfo != NULL) && (userinfo->capabilities)) {
-			char *caps = caps_string(userinfo->capabilities);
-			tmp = ret;
-			ret = g_strconcat(tmp, _("<b>Capabilities:</b> "), caps, "\n", NULL);
-			g_free(tmp);
-		}
-
-		if ((bi != NULL) && (bi->availmsg != NULL) && !(b->uc & UC_UNAVAILABLE)) {
-			gchar *escaped = g_markup_escape_text(bi->availmsg, strlen(bi->availmsg));
-			tmp = ret;
-			ret = g_strconcat(tmp, _("<b>Available:</b> "), escaped, "\n", NULL);
-			g_free(tmp);
-			g_free(escaped);
-		}
-
-		if ((userinfo != NULL) && (userinfo->flags & AIM_FLAG_AWAY) && (userinfo->away_len > 0) && (userinfo->away != NULL) && (userinfo->away_encoding != NULL)) {
-			gchar *away_utf8 = oscar_encoding_to_utf8(userinfo->away_encoding, userinfo->away, userinfo->away_len);
-			if (away_utf8 != NULL) {
-				gchar *tmp1, *tmp2;
-				const char *tmp3;
-				tmp1 = gaim_strreplace(away_utf8, "<BR>", "\n");
-				tmp2 = gaim_markup_strip_html(tmp1);
-				g_free(tmp1);
-				tmp1 = g_markup_escape_text(tmp2, strlen(tmp2));
-				g_free(tmp2);
-				tmp3 = gaim_str_sub_away_formatters(tmp1, gaim_account_get_username(gaim_connection_get_account(gc)));
-				g_free(tmp1);
-				tmp = ret;
-				ret = g_strconcat(tmp, _("<b>Away Message:</b> "), tmp3, "\n", NULL);
-				g_free(tmp);
-				g_free(away_utf8);
-			}
-		}
-	} else {
-		char *gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, b->name);
-		if (aim_ssi_waitingforauth(od->sess->ssi.local, gname, b->name)) {
-			tmp = ret;
-			ret = g_strconcat(tmp, _("<b>Status:</b> Not Authorized"), "\n", NULL);
-			g_free(tmp);
-		} else {
-			tmp = ret;
-			ret = g_strconcat(tmp, _("<b>Status:</b> Offline"), "\n", NULL);
-			g_free(tmp);
-		}
-	}
-
-	/* remove the trailing newline character */
-	if (ret)
-		ret[strlen(ret)-1] = '\0';
-	return ret;
-}
-
-static char *oscar_status_text(GaimBuddy *b) {
-	GaimConnection *gc = b->account->gc;
-	OscarData *od = gc->proto_data;
-	gchar *ret = NULL;
-
-	if ((b->uc & UC_UNAVAILABLE) || (((b->uc & 0xffff0000) >> 16) & AIM_ICQ_STATE_CHAT)) {
-		if (isdigit(b->name[0]))
-			ret = gaim_icq_status((b->uc & 0xffff0000) >> 16);
-		else
-			ret = g_strdup(_("Away"));
-	} else if (GAIM_BUDDY_IS_ONLINE(b)) {
-		struct buddyinfo *bi = g_hash_table_lookup(od->buddyinfo, gaim_normalize(b->account, b->name));
-		if (bi->availmsg)
-			ret = g_markup_escape_text(bi->availmsg, strlen(bi->availmsg));
-	} else {
-		char *gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, b->name);
-		if (aim_ssi_waitingforauth(od->sess->ssi.local, gname, b->name))
-			ret = g_strdup(_("Not Authorized"));
-		else
-			ret = g_strdup(_("Offline"));
-	}
-
-	return ret;
-}
-
-
-static int oscar_icon_req(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = gc->proto_data;
-	va_list ap;
-	fu16_t type;
-	fu8_t flags = 0, length = 0;
-	char *md5 = NULL;
-
-
-	va_start(ap, fr);
-	type = va_arg(ap, int);
-
-	switch(type) {
-		case 0x0000:
-		case 0x0001: {
-			flags = va_arg(ap, int);
-			length = va_arg(ap, int);
-			md5 = va_arg(ap, char *);
-
-			if (flags == 0x41) {
-				if (!aim_getconn_type(od->sess, AIM_CONN_TYPE_ICON) && !od->iconconnecting) {
-					od->iconconnecting = TRUE;
-					od->set_icon = TRUE;
-					aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_ICON);
-				} else {
-					struct stat st;
-					const char *iconfile = gaim_account_get_buddy_icon(gaim_connection_get_account(gc));
-					if (iconfile == NULL) {
-						/* Set an empty icon, or something */
-					} else if (!stat(iconfile, &st)) {
-						char *buf = g_malloc(st.st_size);
-						FILE *file = fopen(iconfile, "rb");
-						if (file) {
-							fread(buf, 1, st.st_size, file);
-							fclose(file);
-							gaim_debug(GAIM_DEBUG_INFO, "oscar",
-								   "Uploading icon to icon server\n");
-							aim_bart_upload(od->sess, buf, st.st_size);
-						} else
-							gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-								   "Can't open buddy icon file!\n");
-						g_free(buf);
-					} else {
-						gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-							   "Can't stat buddy icon file!\n");
-					}
-				}
-			} else if (flags == 0x81)
-				aim_ssi_seticon(od->sess, md5, length); 
-		} break;
-
-		case 0x0002: { /* We just set an "available" message? */
-		} break;
-	}
-
-	va_end(ap);
-
-	return 0;
-}
-
-/*
- * We have just established a socket with the other dude, so set up some handlers.
- */
-static int gaim_odc_initiate(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = (OscarData *)gc->proto_data;
-	GaimConversation *cnv;
-	struct direct_im *dim;
-	char buf[256];
-	char *sn;
-	va_list ap;
-	aim_conn_t *newconn, *listenerconn;
-
-	va_start(ap, fr);
-	newconn = va_arg(ap, aim_conn_t *);
-	listenerconn = va_arg(ap, aim_conn_t *);
-	va_end(ap);
-
-	aim_conn_close(listenerconn);
-	aim_conn_kill(sess, &listenerconn);
-
-	sn = g_strdup(aim_odc_getsn(newconn));
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "DirectIM: initiate success to %s\n", sn);
-	dim = find_direct_im(od, sn);
-
-	cnv = gaim_conversation_new(GAIM_CONV_IM, dim->gc->account, sn);
-	gaim_input_remove(dim->watcher);
-	dim->conn = newconn;
-	dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ, oscar_callback, dim->conn);
-	dim->connected = TRUE;
-	g_snprintf(buf, sizeof buf, _("Direct IM with %s established"), sn);
-	g_free(sn);
-	gaim_conversation_write(cnv, NULL, buf, GAIM_MESSAGE_SYSTEM, time(NULL));
-
-	aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMINCOMING, gaim_odc_incoming, 0);
-	aim_conn_addhandler(sess, newconn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIMTYPING, gaim_odc_typing, 0);
-	aim_conn_addhandler(sess, newconn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_IMAGETRANSFER, gaim_odc_update_ui, 0);
-
-	return 1;
-}
-
-/*
- * This is called when each chunk of an image is received.  It can be used to 
- * update a progress bar, or to eat lots of dry cat food.  Wet cat food is 
- * nasty, you sicko.
- */
-static int gaim_odc_update_ui(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	char *sn;
-	double percent;
-	GaimConnection *gc = sess->aux_data;
-	OscarData *od = (OscarData *)gc->proto_data;
-	GaimConversation *c;
-	struct direct_im *dim;
-
-	va_start(ap, fr);
-	sn = va_arg(ap, char *);
-	percent = va_arg(ap, double);
-	va_end(ap);
-
-	if (!(dim = find_direct_im(od, sn)))
-		return 1;
-	if (dim->watcher) {
-		gaim_input_remove(dim->watcher);   /* Otherwise, the callback will callback */
-		dim->watcher = 0;
-	}
-	/* XXX is this really necessary? */
-	gaim_core_mainloop_finish_events();
-
-	c = gaim_find_conversation_with_account(sn, gaim_connection_get_account(gc));
-	if (c != NULL)
-		gaim_conversation_update_progress(c, percent);
-	dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ,
-				      oscar_callback, dim->conn);
-
-	return 1;
-}
-
-/*
- * This is called after a direct IM has been received in its entirety.  This 
- * function is passed a long chunk of data which contains the IM with any 
- * data chunks (images) appended to it.
- *
- * This function rips out all the data chunks and creates an imgstore for 
- * each one.  In order to do this, it first goes through the IM and takes 
- * out all the IMG tags.  When doing so, it rewrites the original IMG tag 
- * with one compatable with the imgstore Gaim core code. For each one, we 
- * then read in chunks of data from the end of the message and actually 
- * create the img store using the given data.
- *
- * For somewhat easy reference, here's a sample message
- * (without the whitespace and asterisks):
- *
- * <HTML><BODY BGCOLOR="#ffffff">
- *     <FONT LANG="0">
- *     This is a really stupid picture:<BR>
- *     <IMG SRC="Sample.jpg" ID="1" WIDTH="283" HEIGHT="212" DATASIZE="9894"><BR>
- *     Yeah it is<BR>
- *     Here is another one:<BR>
- *     <IMG SRC="Soap Bubbles.bmp" ID="2" WIDTH="256" HEIGHT="256" DATASIZE="65978">   
- *     </FONT>
- * </BODY></HTML>
- * <BINARY>
- *     <DATA ID="1" SIZE="9894">datadatadatadata</DATA>
- *     <DATA ID="2" SIZE="65978">datadatadatadata</DATA>
- * </BINARY>
- */
-static int gaim_odc_incoming(aim_session_t *sess, aim_frame_t *fr, ...) {
-	GaimConnection *gc = sess->aux_data;
-	GaimConvImFlags imflags = 0;
-	GString *newmsg = g_string_new("");
-	GSList *images = NULL;
-	va_list ap;
-	const char *sn, *msg, *msgend, *binary;
-	size_t len;
-	int encoding, isawaymsg;
-
-	va_start(ap, fr);
-	sn = va_arg(ap, const char *);
-	msg = va_arg(ap, const char *);
-	len = va_arg(ap, size_t);
-	encoding = va_arg(ap, int);
-	isawaymsg = va_arg(ap, int);
-	va_end(ap);
-	msgend = msg + len;
-
-	gaim_debug(GAIM_DEBUG_INFO, "oscar",
-			   "Got DirectIM message from %s\n", sn);
-
-	if (isawaymsg)
-		imflags |= GAIM_CONV_IM_AUTO_RESP;
-
-	/* message has a binary trailer */
-	if ((binary = gaim_strcasestr(msg, "<binary>"))) {
-		GData *attribs;
-		const char *tmp, *start, *end, *last = NULL;
-
-		tmp = msg;
-
-		/* for each valid image tag... */
-		while (gaim_markup_find_tag("img", tmp, &start, &end, &attribs)) {
-			const char *id, *src, *datasize;
-			const char *tag = NULL, *data = NULL;
-			size_t size;
-			int imgid = 0;
-
-			/* update the location of the last img tag */
-			last = end;
-
-			/* grab attributes */
-			id       = g_datalist_get_data(&attribs, "id");
-			src      = g_datalist_get_data(&attribs, "src");
-			datasize = g_datalist_get_data(&attribs, "datasize");
-
-			/* if we have id & datasize, build the data tag */
-			if (id && datasize)
-				tag = g_strdup_printf("<data id=\"%s\" size=\"%s\">", id, datasize);
-
-			/* if we have a tag, find the start of the data */
-			if (tag && (data = gaim_strcasestr(binary, tag)))
-				data += strlen(tag);
-
-			/* check the data is here and store it */
-			if (data + (size = atoi(datasize)) <= msgend)
-				imgid = gaim_imgstore_add(data, size, src);
-
-			/* if we have a stored image... */
-			if (imgid) {
-				/* append the message up to the tag */
-				newmsg = g_string_append_len(newmsg, tmp, start - tmp);
-
-				/* write the new image tag */
-				g_string_append_printf(newmsg, "<IMG ID=\"%d\">", imgid);
-
-				/* and record the image number */
-				images = g_slist_append(images, GINT_TO_POINTER(imgid));
-			} else {
-				/* otherwise, copy up to the end of the tag */
-				newmsg = g_string_append_len(newmsg, tmp, (end + 1) - tmp);
-			}
-
-			/* clear the attribute list */
-			g_datalist_clear(&attribs);
-
-			/* continue from the end of the tag */
-			tmp = end + 1;
-		}
-
-		/* append any remaining message data (without the > :-) */
-		if (last++ && (last < binary))
-			newmsg = g_string_append_len(newmsg, last, binary - last);
-
-		/* set the flag if we caught any images */
-		if (images)
-			imflags |= GAIM_CONV_IM_IMAGES;
-	} else {
-		g_string_append_len(newmsg, msg, len);
-	}
-
-	/* XXX - I imagine Paco-Paco will want to do some voodoo with the encoding here */
-	serv_got_im(gc, sn, newmsg->str, imflags, time(NULL));
-
-	/* free up the message */
-	g_string_free(newmsg, TRUE);
-
-	/* unref any images we allocated */
-	if (images) {
-		GSList *tmp;
-		int id;
-
-		for (tmp = images; tmp != NULL; tmp = tmp->next) {
-			id = GPOINTER_TO_INT(tmp->data);
-			gaim_imgstore_unref(id);
-		}
-
-		g_slist_free(images);
-	}
-
-	return 1;
-}
-
-static int gaim_odc_typing(aim_session_t *sess, aim_frame_t *fr, ...) {
-	va_list ap;
-	char *sn;
-	int typing;
-	GaimConnection *gc = sess->aux_data;
-
-	va_start(ap, fr);
-	sn = va_arg(ap, char *);
-	typing = va_arg(ap, int);
-	va_end(ap);
-
-	if (typing == 0x0002) {
-		/* I had to leave this. It's just too funny. It reminds me of my sister. */
-		gaim_debug(GAIM_DEBUG_INFO, "oscar",
-				   "ohmigod! %s has started typing (DirectIM). He's going to send you a message! *squeal*\n", sn);
-		serv_got_typing(gc, sn, 0, GAIM_TYPING);
-	} else if (typing == 0x0001)
-		serv_got_typing(gc, sn, 0, GAIM_TYPED);
-	else
-		serv_got_typing_stopped(gc, sn);
-	return 1;
-}
-
-static int gaim_odc_send_im(aim_session_t *sess, aim_conn_t *conn, const char *message, GaimConvImFlags imflags) {
-	char *buf;
-	size_t len;
-	int ret;
-
-	if (imflags & GAIM_CONV_IM_IMAGES) {
-		GString *msg = g_string_new("");
-		GString *data = g_string_new("<BINARY>");
-		GData *attribs;
-		const char *tmp, *start, *end, *last = NULL;
-		int oscar_id = 0;
-
-		tmp = message;
-
-		/* for each valid IMG tag... */
-		while (gaim_markup_find_tag("img", tmp, &start, &end, &attribs)) {
-			GaimStoredImage *image = NULL;
-			const char *id;
-
-			last = end;
-			id = g_datalist_get_data(&attribs, "id");
-
-			/* ... if it refers to a valid gaim image ... */
-			if (id && (image = gaim_imgstore_get(atoi(id)))) {
-				/* ... append the message from start to the tag ... */
-				msg = g_string_append_len(msg, tmp, start - tmp);
-				oscar_id++;
-
-				/* ... insert a new img tag with the oscar id ... */
-				if (image->filename)
-					g_string_append_printf(msg,
-						"<IMG SRC=\"file://%s\" ID=\"%d\" DATASIZE=\"%d\">",
-						image->filename, oscar_id, (int)image->size);
-				else
-					g_string_append_printf(msg,
-						"<IMG ID=\"%d\" DATASIZE=\"%d\">",
-						oscar_id, (int)image->size);
-
-				/* ... and append the data to the binary section ... */
-				g_string_append_printf(data, "<DATA ID=\"%d\" SIZE=\"%d\">",
-					oscar_id, (int)image->size);
-				data = g_string_append_len(data, image->data, image->size);
-				data = g_string_append(data, "</DATA>");
-			} else {
-				/* ... otherwise, allow the possibly invalid img tag through. */
-				/* should we do something else? */
-				msg = g_string_append_len(msg, tmp, (end + 1) - tmp);
-			}
-
-			g_datalist_clear(&attribs);
-
-			/* continue from the end of the tag */
-			tmp = end + 1;
-		}
-
-		/* append any remaining message data (without the > :-) */
-		if (last++ && *last)
-			msg = g_string_append(msg, last);
-
-		/* if we inserted any images in the binary section, append it */
-		if (oscar_id) {
-			msg = g_string_append_len(msg, data->str, data->len);
-			msg = g_string_append(msg, "</BINARY>");
-		}
-
-		len = msg->len;
-		buf = msg->str;
-		g_string_free(msg, FALSE);
-		g_string_free(data, TRUE);
-	} else {
-		len = strlen(message);
-		buf = g_memdup(message, len+1);
-	}
-
-	/* XXX - The last parameter below is the encoding.  Let Paco-Paco do something with it. */
-	if (imflags & GAIM_CONV_IM_AUTO_RESP)
-		ret =  aim_odc_send_im(sess, conn, buf, len, 0, 1);
-	else
-		ret =  aim_odc_send_im(sess, conn, buf, len, 0, 0);
-
-	g_free(buf);
-
-	return ret;
-}
-
-struct ask_do_dir_im {
-	char *who;
-	GaimConnection *gc;
-};
-
-static void oscar_cancel_direct_im(struct ask_do_dir_im *data) {
-	g_free(data->who);
-	g_free(data);
-}
-
-static void oscar_direct_im(struct ask_do_dir_im *data) {
-	GaimConnection *gc = data->gc;
-	OscarData *od;
-	struct direct_im *dim;
-
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
-		g_free(data->who);
-		g_free(data);
-		return;
-	}
-
-	od = (OscarData *)gc->proto_data;
-
-	dim = find_direct_im(od, data->who);
-	if (dim) {
-		if (!(dim->connected)) {  /* We'll free the old, unconnected dim, and start over */
-			od->direct_ims = g_slist_remove(od->direct_ims, dim);
-			gaim_input_remove(dim->watcher);
-			g_free(dim);
-			gaim_debug(GAIM_DEBUG_INFO, "oscar",
-					   "Gave up on old direct IM, trying again\n");
-		} else {
-			gaim_notify_error(gc, NULL, "DirectIM already open.", NULL);
-			g_free(data->who);
-			g_free(data);
-			return;
-		}
-	}
-	dim = g_new0(struct direct_im, 1);
-	dim->gc = gc;
-	g_snprintf(dim->name, sizeof dim->name, "%s", data->who);
-
-	dim->conn = aim_odc_initiate(od->sess, data->who);
-	if (dim->conn != NULL) {
-		od->direct_ims = g_slist_append(od->direct_ims, dim);
-		dim->watcher = gaim_input_add(dim->conn->fd, GAIM_INPUT_READ,
-						oscar_callback, dim->conn);
-		aim_conn_addhandler(od->sess, dim->conn, AIM_CB_FAM_OFT, AIM_CB_OFT_DIRECTIM_ESTABLISHED,
-					gaim_odc_initiate, 0);
-	} else {
-		gaim_notify_error(gc, NULL, _("Unable to open Direct IM"), NULL);
-		g_free(dim);
-	}
-
-	g_free(data->who);
-	g_free(data);
-}
-
-static void oscar_ask_direct_im(GaimConnection *gc, const char *who) {
-	gchar *buf;
-	struct ask_do_dir_im *data = g_new0(struct ask_do_dir_im, 1);
-	data->who = g_strdup(who);
-	data->gc = gc;
-	buf = g_strdup_printf(_("You have selected to open a Direct IM connection with %s."), who);
-
-	gaim_request_action(gc, NULL, buf,
-						_("Because this reveals your IP address, it "
-						  "may be considered a privacy risk.  Do you "
-						  "wish to continue?"),
-						0, data, 2,
-						_("Connect"), G_CALLBACK(oscar_direct_im),
-						_("Cancel"), G_CALLBACK(oscar_cancel_direct_im));
-	g_free(buf);
-}
-
-static void oscar_set_permit_deny(GaimConnection *gc) {
-	GaimAccount *account = gaim_connection_get_account(gc);
-	OscarData *od = (OscarData *)gc->proto_data;
-#ifdef NOSSI
-	GSList *list, *g = gaim_blist_groups(), *g1;
-	char buf[MAXMSGLEN];
-	int at;
-
-	switch(account->perm_deny) {
-	case 1: 
-		aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_DENYADD, gaim_account_get_username(account));
-		break;
-	case 2:
-		aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_PERMITADD, gaim_account_get_username(account));
-		break;
-	case 3:
-		list = account->permit;
-		at = 0;
-		while (list) {
-			at += g_snprintf(buf + at, sizeof(buf) - at, "%s&", (char *)list->data);
-			list = list->next;
-		}
-		aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_PERMITADD, buf);
-		break;
-	case 4:
-		list = account->deny;
-		at = 0;
-		while (list) {
-			at += g_snprintf(buf + at, sizeof(buf) - at, "%s&", (char *)list->data);
-			list = list->next;
-		}
-		aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_DENYADD, buf);
-		break;
-	case 5:
-		g1 = g;
-		at = 0;
-		while (g1) {
-			list = gaim_blist_members((struct group *)g->data);
-			GSList list1 = list;
-			while (list1) {
-				struct buddy *b = list1->data;
-				if(b->account == account)
-					at += g_snprintf(buf + at, sizeof(buf) - at, "%s&", b->name);
-				list1 = list1->next;
-			}
-			g_slist_free(list);
-			g1 = g1->next;
-		}
-		g_slist_free(g);
-		aim_bos_changevisibility(od->sess, od->conn, AIM_VISIBILITYCHANGE_PERMITADD, buf);
-		break;
-	default:
-		break;
-	}
-	signoff_blocked(gc);
-#else
-	if (od->sess->ssi.received_data)
-		aim_ssi_setpermdeny(od->sess, account->perm_deny, 0xffffffff);
-#endif
-}
-
-static void oscar_add_permit(GaimConnection *gc, const char *who) {
-#ifdef NOSSI
-	if (gc->account->permdeny == 3)
-		oscar_set_permit_deny(gc);
-#else
-	OscarData *od = (OscarData *)gc->proto_data;
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: About to add a permit\n");
-	if (od->sess->ssi.received_data)
-		aim_ssi_addpermit(od->sess, who);
-#endif
-}
-
-static void oscar_add_deny(GaimConnection *gc, const char *who) {
-#ifdef NOSSI
-	if (gc->account->permdeny == 4)
-		oscar_set_permit_deny(gc);
-#else
-	OscarData *od = (OscarData *)gc->proto_data;
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: About to add a deny\n");
-	if (od->sess->ssi.received_data)
-		aim_ssi_adddeny(od->sess, who);
-#endif
-}
-
-static void oscar_rem_permit(GaimConnection *gc, const char *who) {
-#ifdef NOSSI
-	if (gc->account->permdeny == 3)
-		oscar_set_permit_deny(gc);
-#else
-	OscarData *od = (OscarData *)gc->proto_data;
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: About to delete a permit\n");
-	if (od->sess->ssi.received_data)
-		aim_ssi_delpermit(od->sess, who);
-#endif
-}
-
-static void oscar_rem_deny(GaimConnection *gc, const char *who) {
-#ifdef NOSSI
-	if (gc->account->permdeny == 4)
-		oscar_set_permit_deny(gc);
-#else
-	OscarData *od = (OscarData *)gc->proto_data;
-	gaim_debug(GAIM_DEBUG_INFO, "oscar", "ssi: About to delete a deny\n");
-	if (od->sess->ssi.received_data)
-		aim_ssi_deldeny(od->sess, who);
-#endif
-}
-
-static GList *oscar_away_states(GaimConnection *gc)
-{
-	OscarData *od = gc->proto_data;
-	GList *m = NULL;
-
-	if (!od->icq)
-		return g_list_append(m, GAIM_AWAY_CUSTOM);
-
-	m = g_list_append(m, _("Online"));
-	m = g_list_append(m, _("Away"));
-	m = g_list_append(m, _("Do Not Disturb"));
-	m = g_list_append(m, _("Not Available"));
-	m = g_list_append(m, _("Occupied"));
-	m = g_list_append(m, _("Free For Chat"));
-	m = g_list_append(m, _("Invisible"));
-
-	return m;
-}
-
-static void oscar_ssi_editcomment(struct name_data *data, const char *text) {
-	OscarData *od = data->gc->proto_data;
-	GaimBuddy *b;
-	GaimGroup *g;
-
-	if (!(b = gaim_find_buddy(gaim_connection_get_account(data->gc), data->name))) {
-		oscar_free_name_data(data);
-		return;
-	}
-
-	if (!(g = gaim_find_buddys_group(b))) {
-		oscar_free_name_data(data);
-		return;
-	}
-
-	aim_ssi_editcomment(od->sess, g->name, data->name, text);
-	oscar_free_name_data(data);
-}
-
-static void oscar_buddycb_edit_comment(GaimConnection *gc, const char *name) {
-	OscarData *od = gc->proto_data;
-	struct name_data *data = g_new(struct name_data, 1);
-	GaimBuddy *b;
-	GaimGroup *g;
-	char *comment;
-	gchar *comment_utf8;
-
-	if (!(b = gaim_find_buddy(gaim_connection_get_account(gc), name)))
-		return;
-	if (!(g = gaim_find_buddys_group(b)))
-		return;
-	comment = aim_ssi_getcomment(od->sess->ssi.local, g->name, name);
-	comment_utf8 = comment ? gaim_utf8_try_convert(comment) : NULL;
-
-	data->gc = gc;
-	data->name = g_strdup(name);
-	data->nick = NULL;
-
-	gaim_request_input(gc, NULL, _("Buddy Comment:"), NULL,
-					   comment_utf8, TRUE, FALSE,
-					   _("OK"), G_CALLBACK(oscar_ssi_editcomment),
-					   _("Cancel"), G_CALLBACK(oscar_free_name_data),
-					   data);
-
-	free(comment);
-	g_free(comment_utf8);
-}
-
-static GList *oscar_buddy_menu(GaimConnection *gc, const char *who) {
-	OscarData *od = gc->proto_data;
-	GList *m = NULL;
-	struct proto_buddy_menu *pbm;
-
-	pbm = g_new0(struct proto_buddy_menu, 1);
-	pbm->label = _("Edit Buddy Comment");
-	pbm->callback = oscar_buddycb_edit_comment;
-	pbm->gc = gc;
-	m = g_list_append(m, pbm);
-
-	if (od->icq) {
-#if 0
-		pbm = g_new0(struct proto_buddy_menu, 1);
-		pbm->label = _("Get Status Msg");
-		pbm->callback = oscar_get_icqstatusmsg;
-		pbm->gc = gc;
-		m = g_list_append(m, pbm);
-#endif
-	} else {
-		GaimBuddy *b = gaim_find_buddy(gc->account, who);
-		aim_userinfo_t *userinfo;
-
-		if (b)
-			userinfo = aim_locate_finduserinfo(od->sess, b->name);
-
-		if (b && userinfo && aim_sncmp(gaim_account_get_username(gaim_connection_get_account(gc)), who) && GAIM_BUDDY_IS_ONLINE(b)) {
-			if (userinfo->capabilities & AIM_CAPS_DIRECTIM) {
-				pbm = g_new0(struct proto_buddy_menu, 1);
-				pbm->label = _("Direct IM");
-				pbm->callback = oscar_ask_direct_im;
-				pbm->gc = gc;
-				m = g_list_append(m, pbm);
-			}
-
-			if (userinfo->capabilities & AIM_CAPS_SENDFILE) {
-				pbm = g_new0(struct proto_buddy_menu, 1);
-				pbm->label = _("Send File");
-				pbm->callback = oscar_ask_sendfile;
-				pbm->gc = gc;
-				m = g_list_append(m, pbm);
-			}
-#if 0
-			if (userinfo->capabilities & AIM_CAPS_GETFILE) {
-				pbm = g_new0(struct proto_buddy_menu, 1);
-				pbm->label = _("Get File");
-				pbm->callback = oscar_ask_getfile;
-				pbm->gc = gc;
-				m = g_list_append(m, pbm);
-			}
-#endif
-		}
-	}
-
-	if (od->sess->ssi.received_data) {
-		char *gname = aim_ssi_itemlist_findparentname(od->sess->ssi.local, who);
-		if (gname && aim_ssi_waitingforauth(od->sess->ssi.local, gname, who)) {
-			pbm = g_new0(struct proto_buddy_menu, 1);
-			pbm->label = _("Re-request Authorization");
-			pbm->callback = gaim_auth_sendrequest;
-			pbm->gc = gc;
-			m = g_list_append(m, pbm);
-		}
-	}
-	
-	return m;
-}
-
-static void oscar_format_screenname(GaimConnection *gc, const char *nick) {
-	OscarData *od = gc->proto_data;
-	if (!aim_sncmp(gaim_account_get_username(gaim_connection_get_account(gc)), nick)) {
-		if (!aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH)) {
-			od->setnick = TRUE;
-			od->newsn = g_strdup(nick);
-			aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH);
-		} else {
-			aim_admin_setnick(od->sess, aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH), nick);
-		}
-	} else {
-		gaim_notify_error(gc, NULL, _("The new formatting is invalid."),
-						  _("Screenname formatting can change only capitalization and whitespace."));
-	}
-}
-
-static void oscar_show_format_screenname(GaimConnection *gc)
-{
-	gaim_request_input(gc, NULL, _("New screenname formatting:"), NULL,
-					   gaim_connection_get_display_name(gc), FALSE, FALSE,
-					   _("OK"), G_CALLBACK(oscar_format_screenname),
-					   _("Cancel"), NULL,
-					   gc);
-}
-
-static void oscar_confirm_account(GaimConnection *gc)
-{
-	OscarData *od = gc->proto_data;
-	aim_conn_t *conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH);
-
-	if (conn) {
-		aim_admin_reqconfirm(od->sess, conn);
-	} else {
-		od->conf = TRUE;
-		aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH);
-	}
-}
-
-static void oscar_show_email(GaimConnection *gc)
-{
-	OscarData *od = gc->proto_data;
-	aim_conn_t *conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH);
-
-	if (conn) {
-		aim_admin_getinfo(od->sess, conn, 0x11);
-	} else {
-		od->reqemail = TRUE;
-		aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH);
-	}
-}
-
-static void oscar_change_email(GaimConnection *gc, const char *email)
-{
-	OscarData *od = gc->proto_data;
-	aim_conn_t *conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH);
-
-	if (conn) {
-		aim_admin_setemail(od->sess, conn, email);
-	} else {
-		od->setemail = TRUE;
-		od->email = g_strdup(email);
-		aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH);
-	}
-}
-
-static void oscar_show_change_email(GaimConnection *gc)
-{
-	gaim_request_input(gc, NULL, _("Change Address To:"), NULL, NULL,
-					   FALSE, FALSE,
-					   _("OK"), G_CALLBACK(oscar_change_email),
-					   _("Cancel"), NULL,
-					   gc);
-}
-
-static void oscar_show_awaitingauth(GaimConnection *gc)
-{
-	OscarData *od = gc->proto_data;
-	gchar *nombre, *text, *tmp;
-	GaimBlistNode *gnode, *cnode, *bnode;
-	int num=0;
-
-	text = g_strdup("");
-
-	for (gnode = gaim_get_blist()->root; gnode; gnode = gnode->next) {
-		GaimGroup *group = (GaimGroup *)gnode;
-		if(!GAIM_BLIST_NODE_IS_GROUP(gnode))
-			continue;
-		for (cnode = gnode->child; cnode; cnode = cnode->next) {
-			if(!GAIM_BLIST_NODE_IS_CONTACT(cnode))
-				continue;
-			for (bnode = cnode->child; bnode; bnode = bnode->next) {
-				GaimBuddy *buddy = (GaimBuddy *)bnode;
-				if(!GAIM_BLIST_NODE_IS_BUDDY(bnode))
-					continue;
-				if (buddy->account == gc->account && aim_ssi_waitingforauth(od->sess->ssi.local, group->name, buddy->name)) {
-					if (gaim_get_buddy_alias_only(buddy))
-						nombre = g_strdup_printf(" %s (%s)", buddy->name, gaim_get_buddy_alias_only(buddy));
-					else
-						nombre = g_strdup_printf(" %s", buddy->name);
-					tmp = g_strdup_printf("%s%s<br>", text, nombre);
-					g_free(text);
-					text = tmp;
-					g_free(nombre);
-					num++;
-				}
-			}
-		}
-	}
-
-	if (!num) {
-		g_free(text);
-		text = g_strdup(_("<i>you are not waiting for authorization</i>"));
-	}
-
-	gaim_notify_formatted(gc, NULL, _("You are awaiting authorization from "
-						  "the following buddies"),	_("You can re-request "
-						  "authorization from these buddies by "
-						  "right-clicking on them and selecting "
-						  "\"Re-request Authorization.\""), text, NULL, NULL);
-	g_free(text);
-}
-
-static void search_by_email_cb(GaimConnection *gc, const char *email)
-{
-	serv_dir_search(gc, "", "", "", "", "", "", "", email);
-}
-
-static void oscar_show_find_email(GaimConnection *gc)
-{
-	gaim_request_input(gc, _("Find Buddy by E-mail"),
-					   _("Search for a buddy by e-mail address"),
-					   _("Type the e-mail address of the buddy you are "
-						 "searching for."),
-					   NULL, FALSE, FALSE,
-					   _("Search"), G_CALLBACK(search_by_email_cb),
-					   _("Cancel"), NULL, gc);
-}
-
-#if 0
-static void oscar_setavailmsg(GaimConnection *gc, char *text) {
-	OscarData *od = (OscarData *)gc->proto_data;
-
-	aim_locate_setprofile(od->sess, NULL, NULL, 0, NULL, "", 0);
-	aim_srv_setavailmsg(od->sess, text);
-}
-
-static void oscar_show_setavailmsg(GaimConnection *gc)
-{
-	gaim_request_input(gc, NULL, _("Available Message:"), NULL,
-					   _("I'm doing work and hoping for a distraction--IM me!"), 
-					   TRUE, FALSE,
-					   _("OK"), G_CALLBACK(oscar_setavailmsg),
-					   _("Cancel"), NULL,
-					   gc);
-}
-#endif
-
-static void oscar_show_set_info(GaimConnection *gc)
-{
-	gaim_account_request_change_user_info(gaim_connection_get_account(gc));
-}
-
-static void oscar_change_pass(GaimConnection *gc)
-{
-	gaim_account_request_change_password(gaim_connection_get_account(gc));
-}
-
-static void oscar_show_chpassurl(GaimConnection *gc)
-{
-	OscarData *od = gc->proto_data;
-	gchar *substituted = gaim_strreplace(od->sess->authinfo->chpassurl, "%s", gaim_account_get_username(gaim_connection_get_account(gc)));
-	gaim_notify_uri(gc, substituted);
-	g_free(substituted);
-}
-
-static void oscar_show_imforwardingurl(GaimConnection *gc)
-{
-	gaim_notify_uri(gc, "http://mymobile.aol.com/dbreg/register?action=imf&clientID=1");
-}
-
-static void oscar_set_icon(GaimConnection *gc, const char *iconfile)
-{
-	OscarData *od = gc->proto_data;
-	aim_session_t *sess = od->sess;
-	FILE *file;
-	struct stat st;
-
-	if (iconfile == NULL) {
-		/* Set an empty icon, or something */
-	} else if (!stat(iconfile, &st)) {
-		char *buf = g_malloc(st.st_size);
-		file = fopen(iconfile, "rb");
-		if (file) {
-			md5_state_t *state;
-			char md5[16];
-			int len = fread(buf, 1, st.st_size, file);
-			fclose(file);
-			state = g_malloc(sizeof(md5_state_t));
-			md5_init(state);
-			md5_append(state, buf, len);
-			md5_finish(state, md5);
-			g_free(state);
-			aim_ssi_seticon(sess, md5, 16);
-		} else
-			gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-				   "Can't open buddy icon file!\n");
-		g_free(buf);
-	} else
-		gaim_debug(GAIM_DEBUG_ERROR, "oscar",
-			   "Can't stat buddy icon file!\n");
-}
-
-
-static GList *oscar_actions(GaimConnection *gc)
-{
-	OscarData *od = gc->proto_data;
-	struct proto_actions_menu *pam;
-	GList *m = NULL;
-
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set User Info");
-	pam->callback = oscar_show_set_info;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
-
-#if 0
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set Available Message");
-	pam->callback = oscar_show_setavailmsg;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
-#endif
-
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Change Password");
-	pam->callback = oscar_change_pass;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
-
-	if (od->sess->authinfo->chpassurl) {
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Change Password (URL)");
-		pam->callback = oscar_show_chpassurl;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
-	}
-
-	if (od->sess->authinfo->chpassurl) {
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Configure IM Forwarding (URL)");
-		pam->callback = oscar_show_imforwardingurl;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
-	}
-
-	if (!od->icq) {
-		/* AIM actions */
-		m = g_list_append(m, NULL);
-
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Format Screenname");
-		pam->callback = oscar_show_format_screenname;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
-
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Confirm Account");
-		pam->callback = oscar_confirm_account;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
-
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Display Current Registered Address");
-		pam->callback = oscar_show_email;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
-
-		pam = g_new0(struct proto_actions_menu, 1);
-		pam->label = _("Change Current Registered Address");
-		pam->callback = oscar_show_change_email;
-		pam->gc = gc;
-		m = g_list_append(m, pam);
-	}
-
-	m = g_list_append(m, NULL);
-
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Show Buddies Awaiting Authorization");
-	pam->callback = oscar_show_awaitingauth;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
-
-	m = g_list_append(m, NULL);
-
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Search for Buddy by Email");
-	pam->callback = oscar_show_find_email;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
-
-/*	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Search for Buddy by Information");
-	pam->callback = show_find_info;
-	pam->gc = gc;
-	m = g_list_append(m, pam); */
-
-	return m;
-}
-
-static void oscar_change_passwd(GaimConnection *gc, const char *old, const char *new)
-{
-	OscarData *od = gc->proto_data;
-
-	if (od->icq) {
-		aim_icq_changepasswd(od->sess, new);
-	} else {
-		aim_conn_t *conn = aim_getconn_type(od->sess, AIM_CONN_TYPE_AUTH);
-		if (conn) {
-			aim_admin_changepasswd(od->sess, conn, new, old);
-		} else {
-			od->chpass = TRUE;
-			od->oldp = g_strdup(old);
-			od->newp = g_strdup(new);
-			aim_reqservice(od->sess, od->conn, AIM_CONN_TYPE_AUTH);
-		}
-	}
-}
-
-static void oscar_convo_closed(GaimConnection *gc, const char *who)
-{
-	OscarData *od = gc->proto_data;
-	struct direct_im *dim = find_direct_im(od, who);
-
-	if (!dim)
-		return;
-
-	od->direct_ims = g_slist_remove(od->direct_ims, dim);
-	gaim_input_remove(dim->watcher);
-	aim_conn_kill(od->sess, &dim->conn);
-	g_free(dim);
-}
-
-static GaimPluginProtocolInfo prpl_info =
-{
-	GAIM_PROTO_OSCAR,
-	OPT_PROTO_MAIL_CHECK | OPT_PROTO_BUDDY_ICON | OPT_PROTO_IM_IMAGE,
-	NULL,
-	NULL,
-	oscar_list_icon,
-	oscar_list_emblems,
-	oscar_status_text,
-	oscar_tooltip_text,
-	oscar_away_states,
-	oscar_actions,
-	oscar_buddy_menu,
-	oscar_chat_info,
-	oscar_login,
-	oscar_close,
-	oscar_send_im,
-	oscar_set_info,
-	oscar_send_typing,
-	oscar_get_info,
-	oscar_set_away,
-	oscar_get_away,
-	oscar_set_dir,
-	NULL,
-	oscar_dir_search,
-	oscar_set_idle,
-	oscar_change_passwd,
-	oscar_add_buddy,
-	oscar_add_buddies,
-	oscar_remove_buddy,
-	oscar_remove_buddies,
-	oscar_add_permit,
-	oscar_add_deny,
-	oscar_rem_permit,
-	oscar_rem_deny,
-	oscar_set_permit_deny,
-	oscar_warn,
-	oscar_join_chat,
-	oscar_chat_invite,
-	oscar_chat_leave,
-	NULL,
-	oscar_chat_send,
-	oscar_keepalive,
-	NULL,
-	NULL,
-	NULL,
-#ifndef NOSSI
-	oscar_alias_buddy,
-	oscar_move_buddy,
-	oscar_rename_group,
-#else
-	NULL,
-	NULL,
-	NULL,
-#endif
-	NULL,
-	oscar_convo_closed,
-	NULL,
-	oscar_set_icon
-};
-
-static GaimPluginInfo info =
-{
-	2,                                                /**< api_version    */
-	GAIM_PLUGIN_PROTOCOL,                             /**< type           */
-	NULL,                                             /**< ui_requirement */
-	0,                                                /**< flags          */
-	NULL,                                             /**< dependencies   */
-	GAIM_PRIORITY_DEFAULT,                            /**< priority       */
-
-	"prpl-oscar",                                     /**< id             */
-	"AIM/ICQ",                                        /**< name           */
-	VERSION,                                          /**< version        */
-	                                                  /**  summary        */
-	N_("AIM/ICQ Protocol Plugin"),
-	                                                  /**  description    */
-	N_("AIM/ICQ Protocol Plugin"),
-	NULL,                                             /**< author         */
-	GAIM_WEBSITE,                                     /**< homepage       */
-
-	NULL,                                             /**< load           */
-	NULL,                                             /**< unload         */
-	NULL,                                             /**< destroy        */
-
-	NULL,                                             /**< ui_info        */
-	&prpl_info                                        /**< extra_info     */
-};
-
-static void
-init_plugin(GaimPlugin *plugin)
-{
-	GaimAccountOption *option;
-
-	option = gaim_account_option_string_new(_("Auth host"), "server",
-											"login.oscar.aol.com");
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
-											   option);
-
-	option = gaim_account_option_int_new(_("Auth port"), "port", 5190);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
-											   option);
-
-	my_protocol = plugin;
-}
-
-GAIM_INIT_PLUGIN(oscar, init_plugin, info);
Index: bfaim/popups.c
===================================================================
--- libfaim/popups.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,64 +1,0 @@
-/*
- * Family 0x0008 - Popups.
- *
- * Popups are just what it sounds like.  They're a way for the server to
- * open up an informative box on the client's screen.
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-/*
- * This is all there is to it.
- *
- * The message is probably HTML.
- * 
- */
-static int parsepopup(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_rxcallback_t userfunc;
-	aim_tlvlist_t *tl;
-	int ret = 0;
-	char *msg, *url;
-	fu16_t width, height, delay;
-
-	tl = aim_tlvlist_read(bs);
-
-	msg = aim_tlv_getstr(tl, 0x0001, 1);
-	url = aim_tlv_getstr(tl, 0x0002, 1);
-	width = aim_tlv_get16(tl, 0x0003, 1);
-	height = aim_tlv_get16(tl, 0x0004, 1);
-	delay = aim_tlv_get16(tl, 0x0005, 1);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, msg, url, width, height, delay);
-
-	aim_tlvlist_free(&tl);
-	free(msg);
-	free(url);
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0002)
-		return parsepopup(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int popups_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x0008;
-	mod->version = 0x0001;
-	mod->toolid = 0x0104;
-	mod->toolversion = 0x0001;
-	mod->flags = 0;
-	strncpy(mod->name, "popups", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/rxhandlers.c
===================================================================
--- libfaim/rxhandlers.c	(revision 54666e08c3ce1872c899386b31a80bca27a0874a)
+++ 	(revision )
@@ -1,583 +1,0 @@
-/*
- * rxhandlers.c
- *
- * This file contains most all of the incoming packet handlers, along
- * with aim_rxdispatch(), the Rx dispatcher.  Queue/list management is
- * actually done in aim_rxqueue.c.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-struct aim_rxcblist_s {
-	fu16_t family;
-	fu16_t type;
-	aim_rxcallback_t handler;
-	fu16_t flags;
-	struct aim_rxcblist_s *next;
-};
-
-faim_internal aim_module_t *aim__findmodulebygroup(aim_session_t *sess, fu16_t group)
-{
-	aim_module_t *cur;
-
-	for (cur = (aim_module_t *)sess->modlistv; cur; cur = cur->next) {
-		if (cur->family == group)
-			return cur;
-	}
-
-	return NULL;
-}
-
-faim_internal aim_module_t *aim__findmodule(aim_session_t *sess, const char *name)
-{
-	aim_module_t *cur;
-
-	for (cur = (aim_module_t *)sess->modlistv; cur; cur = cur->next) {
-		if (strcmp(name, cur->name) == 0)
-			return cur;
-	}
-
-	return NULL;
-}
-
-faim_internal int aim__registermodule(aim_session_t *sess, int (*modfirst)(aim_session_t *, aim_module_t *))
-{
-	aim_module_t *mod;
-
-	if (!sess || !modfirst)
-		return -1;
-
-	if (!(mod = malloc(sizeof(aim_module_t))))
-		return -1;
-	memset(mod, 0, sizeof(aim_module_t));
-
-	if (modfirst(sess, mod) == -1) {
-		free(mod);
-		return -1;
-	}
-
-	if (aim__findmodule(sess, mod->name)) {
-		if (mod->shutdown)
-			mod->shutdown(sess, mod);
-		free(mod);
-		return -1;
-	}
-
-	mod->next = (aim_module_t *)sess->modlistv;
-	sess->modlistv = mod;
-
-	faimdprintf(sess, 1, "registered module %s (family 0x%04x, version = 0x%04x, tool 0x%04x, tool version 0x%04x)\n", mod->name, mod->family, mod->version, mod->toolid, mod->toolversion);
-
-	return 0;
-}
-
-faim_internal void aim__shutdownmodules(aim_session_t *sess)
-{
-	aim_module_t *cur;
-
-	for (cur = (aim_module_t *)sess->modlistv; cur; ) {
-		aim_module_t *tmp;
-
-		tmp = cur->next;
-
-		if (cur->shutdown)
-			cur->shutdown(sess, cur);
-
-		free(cur);
-
-		cur = tmp;
-	}
-
-	sess->modlistv = NULL;
-
-	return;
-}
-
-static int consumesnac(aim_session_t *sess, aim_frame_t *rx)
-{
-	aim_module_t *cur;
-	aim_modsnac_t snac;
-
-	if (aim_bstream_empty(&rx->data) < 10)
-		return 0;
-
-	snac.family = aimbs_get16(&rx->data);
-	snac.subtype = aimbs_get16(&rx->data);
-	snac.flags = aimbs_get16(&rx->data);
-	snac.id = aimbs_get32(&rx->data);
-
-	/* SNAC flags are apparently uniform across all SNACs, so we handle them here */
-	if (snac.flags & 0x0001) {
-		/*
-		 * This means the SNAC will be followed by another SNAC with 
-		 * related information.  We don't need to do anything about 
-		 * this here.
-		 */
-	}
-	if (snac.flags & 0x8000) {
-		/*
-		 * This packet contains the version of the family that this SNAC is 
-		 * in.  You get this when your SSI module is version 2 or higher.  
-		 * For now we have no need for this, but you could always save 
-		 * it as a part of aim_modnsac_t, or something.  The format is...
-		 * 2 byte length of total mini-header (which is 6 bytes), then TLV 
-		 * of  type 0x0001, length 0x0002, value is the 2 byte version 
-		 * number
-		 */
-		aim_bstream_advance(&rx->data, aimbs_get16(&rx->data));
-	}
-
-	for (cur = (aim_module_t *)sess->modlistv; cur; cur = cur->next) {
-
-		if (!(cur->flags & AIM_MODFLAG_MULTIFAMILY) && 
-				(cur->family != snac.family))
-			continue;
-
-		if (cur->snachandler(sess, cur, rx, &snac, &rx->data))
-			return 1;
-
-	}
-
-	return 0;
-}
-
-static int consumenonsnac(aim_session_t *sess, aim_frame_t *rx, fu16_t family, fu16_t subtype)
-{
-	aim_module_t *cur;
-	aim_modsnac_t snac;
-
-	snac.family = family;
-	snac.subtype = subtype;
-	snac.flags = snac.id = 0;
-
-	for (cur = (aim_module_t *)sess->modlistv; cur; cur = cur->next) {
-
-		if (!(cur->flags & AIM_MODFLAG_MULTIFAMILY) && 
-				(cur->family != snac.family))
-			continue;
-
-		if (cur->snachandler(sess, cur, rx, &snac, &rx->data))
-			return 1;
-
-	}
-
-	return 0;
-}
-
-static int negchan_middle(aim_session_t *sess, aim_frame_t *fr)
-{
-	aim_tlvlist_t *tlvlist;
-	char *msg = NULL;
-	fu16_t code = 0;
-	aim_rxcallback_t userfunc;
-	int ret = 1;
-
-	if (aim_bstream_empty(&fr->data) == 0) {
-		/* XXX should do something with this */
-		return 1;
-	}
-
-	/* Used only by the older login protocol */
-	/* XXX remove this special case? */
-	if (fr->conn->type == AIM_CONN_TYPE_AUTH)
-		return consumenonsnac(sess, fr, 0x0017, 0x0003);
-
-	tlvlist = aim_tlvlist_read(&fr->data);
-
-	if (aim_tlv_gettlv(tlvlist, 0x0009, 1))
-		code = aim_tlv_get16(tlvlist, 0x0009, 1);
-
-	if (aim_tlv_gettlv(tlvlist, 0x000b, 1))
-		msg = aim_tlv_getstr(tlvlist, 0x000b, 1);
-
-	if ((userfunc = aim_callhandler(sess, fr->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNERR))) 
-		ret = userfunc(sess, fr, code, msg);
-
-	aim_tlvlist_free(&tlvlist);
-
-	free(msg);
-
-	return ret;
-}
-
-/*
- * Bleck functions get called when there's no non-bleck functions
- * around to cleanup the mess...
- */
-faim_internal int bleck(aim_session_t *sess, aim_frame_t *frame, ...)
-{
-	fu16_t family, subtype;
-	fu16_t maxf, maxs;
-
-	static const char *channels[6] = {
-		"Invalid (0)",
-		"FLAP Version",
-		"SNAC",
-		"Invalid (3)",
-		"Negotiation",
-		"FLAP NOP"
-	};
-	static const int maxchannels = 5;
-	
-	/* XXX: this is ugly. and big just for debugging. */
-	static const char *literals[14][25] = {
-		{"Invalid", 
-		 NULL
-		},
-		{"General", 
-		 "Invalid",
-		 "Error",
-		 "Client Ready",
-		 "Server Ready",
-		 "Service Request",
-		 "Redirect",
-		 "Rate Information Request",
-		 "Rate Information",
-		 "Rate Information Ack",
-		 NULL,
-		 "Rate Information Change",
-		 "Server Pause",
-		 NULL,
-		 "Server Resume",
-		 "Request Personal User Information",
-		 "Personal User Information",
-		 "Evil Notification",
-		 NULL,
-		 "Migration notice",
-		 "Message of the Day",
-		 "Set Privacy Flags",
-		 "Well Known URL",
-		 "NOP"
-		},
-		{"Location", 
-		 "Invalid",
-		 "Error",
-		 "Request Rights",
-		 "Rights Information", 
-		 "Set user information", 
-		 "Request User Information", 
-		 "User Information", 
-		 "Watcher Sub Request",
-		 "Watcher Notification"
-		},
-		{"Buddy List Management", 
-		 "Invalid", 
-		 "Error", 
-		 "Request Rights",
-		 "Rights Information",
-		 "Add Buddy", 
-		 "Remove Buddy", 
-		 "Watcher List Query", 
-		 "Watcher List Response", 
-		 "Watcher SubRequest", 
-		 "Watcher Notification", 
-		 "Reject Notification", 
-		 "Oncoming Buddy", 
-		 "Offgoing Buddy"
-		},
-		{"Messeging", 
-		 "Invalid",
-		 "Error", 
-		 "Add ICBM Parameter",
-		 "Remove ICBM Parameter", 
-		 "Request Parameter Information",
-		 "Parameter Information",
-		 "Outgoing Message", 
-		 "Incoming Message",
-		 "Evil Request",
-		 "Evil Reply", 
-		 "Missed Calls",
-		 "Message Error", 
-		 "Host Ack"
-		},
-		{"Advertisements", 
-		 "Invalid", 
-		 "Error", 
-		 "Request Ad",
-		 "Ad Data (GIFs)"
-		},
-		{"Invitation / Client-to-Client", 
-		 "Invalid",
-		 "Error",
-		 "Invite a Friend",
-		 "Invitation Ack"
-		},
-		{"Administrative", 
-		 "Invalid",
-		 "Error",
-		 "Information Request",
-		 "Information Reply",
-		 "Information Change Request",
-		 "Information Chat Reply",
-		 "Account Confirm Request",
-		 "Account Confirm Reply",
-		 "Account Delete Request",
-		 "Account Delete Reply"
-		},
-		{"Popups", 
-		 "Invalid",
-		 "Error",
-		 "Display Popup"
-		},
-		{"BOS", 
-		 "Invalid",
-		 "Error",
-		 "Request Rights",
-		 "Rights Response",
-		 "Set group permission mask",
-		 "Add permission list entries",
-		 "Delete permission list entries",
-		 "Add deny list entries",
-		 "Delete deny list entries",
-		 "Server Error"
-		},
-		{"User Lookup", 
-		 "Invalid",
-		 "Error",
-		 "Search Request",
-		 "Search Response"
-		},
-		{"Stats", 
-		 "Invalid",
-		 "Error",
-		 "Set minimum report interval",
-		 "Report Events"
-		},
-		{"Translate", 
-		 "Invalid",
-		 "Error",
-		 "Translate Request",
-		 "Translate Reply",
-		},
-		{"Chat Navigation", 
-		 "Invalid",
-		 "Error",
-		 "Request rights",
-		 "Request Exchange Information",
-		 "Request Room Information",
-		 "Request Occupant List",
-		 "Search for Room",
-		 "Outgoing Message", 
-		 "Incoming Message",
-		 "Evil Request", 
-		 "Evil Reply", 
-		 "Chat Error",
-		}
-	};
-
-	maxf = sizeof(literals) / sizeof(literals[0]);
-	maxs = sizeof(literals[0]) / sizeof(literals[0][0]);
-
-	if (frame->hdr.flap.type == 0x02) {
-
-		family = aimbs_get16(&frame->data);
-		subtype = aimbs_get16(&frame->data);
-		
-		if ((family < maxf) && (subtype+1 < maxs) && (literals[family][subtype] != NULL))
-			faimdprintf(sess, 0, "bleck: channel %s: null handler for %04x/%04x (%s)\n", channels[frame->hdr.flap.type], family, subtype, literals[family][subtype+1]);
-		else
-			faimdprintf(sess, 0, "bleck: channel %s: null handler for %04x/%04x (no literal)\n", channels[frame->hdr.flap.type], family, subtype);
-	} else {
-
-		if (frame->hdr.flap.type <= maxchannels)
-			faimdprintf(sess, 0, "bleck: channel %s (0x%02x)\n", channels[frame->hdr.flap.type], frame->hdr.flap.type);
-		else
-			faimdprintf(sess, 0, "bleck: unknown channel 0x%02x\n", frame->hdr.flap.type);
-
-	}
-		
-	return 1;
-}
-
-faim_export int aim_conn_addhandler(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t type, aim_rxcallback_t newhandler, fu16_t flags)
-{
-	struct aim_rxcblist_s *newcb;
-
-	if (!conn)
-		return -1;
-
-	faimdprintf(sess, 1, "aim_conn_addhandler: adding for %04x/%04x\n", family, type);
-
-	if (!(newcb = (struct aim_rxcblist_s *)calloc(1, sizeof(struct aim_rxcblist_s))))
-		return -1;
-
-	newcb->family = family;
-	newcb->type = type;
-	newcb->flags = flags;
-	newcb->handler = newhandler ? newhandler : bleck;
-	newcb->next = NULL;
-
-	if (!conn->handlerlist)
-		conn->handlerlist = (void *)newcb;
-	else {
-		struct aim_rxcblist_s *cur;
-
-		for (cur = (struct aim_rxcblist_s *)conn->handlerlist; cur->next; cur = cur->next)
-			;
-		cur->next = newcb;
-	}
-
-	return 0;
-}
-
-faim_export int aim_clearhandlers(aim_conn_t *conn)
-{
-	struct aim_rxcblist_s *cur;
-
-	if (!conn)
-		return -1;
-
-	for (cur = (struct aim_rxcblist_s *)conn->handlerlist; cur; ) {
-		struct aim_rxcblist_s *tmp;
-
-		tmp = cur->next;
-		free(cur);
-		cur = tmp;
-	}
-	conn->handlerlist = NULL;
-
-	return 0;
-}
-
-faim_internal aim_rxcallback_t aim_callhandler(aim_session_t *sess, aim_conn_t *conn, fu16_t family, fu16_t type)
-{
-	struct aim_rxcblist_s *cur;
-
-	if (!conn)
-		return NULL;
-
-	faimdprintf(sess, 1, "aim_callhandler: calling for %04x/%04x\n", family, type);
-
-	for (cur = (struct aim_rxcblist_s *)conn->handlerlist; cur; cur = cur->next) {
-		if ((cur->family == family) && (cur->type == type))
-			return cur->handler;
-	}
-
-	if (type == AIM_CB_SPECIAL_DEFAULT) {
-		faimdprintf(sess, 1, "aim_callhandler: no default handler for family 0x%04x\n", family);
-		return NULL; /* prevent infinite recursion */
-	}
-
-	faimdprintf(sess, 1, "aim_callhandler: no handler for  0x%04x/0x%04x\n", family, type);
-
-	return aim_callhandler(sess, conn, family, AIM_CB_SPECIAL_DEFAULT);
-}
-
-faim_internal void aim_clonehandlers(aim_session_t *sess, aim_conn_t *dest, aim_conn_t *src)
-{
-	struct aim_rxcblist_s *cur;
-
-	for (cur = (struct aim_rxcblist_s *)src->handlerlist; cur; cur = cur->next) {
-		aim_conn_addhandler(sess, dest, cur->family, cur->type, 
-						cur->handler, cur->flags);
-	}
-
-	return;
-}
-
-faim_internal int aim_callhandler_noparam(aim_session_t *sess, aim_conn_t *conn,fu16_t family, fu16_t type, aim_frame_t *ptr)
-{
-	aim_rxcallback_t userfunc;
-
-	if ((userfunc = aim_callhandler(sess, conn, family, type)))
-		return userfunc(sess, ptr);
-
-	return 1; /* XXX */
-}
-
-/*
- * aim_rxdispatch()
- *
- * Basically, heres what this should do:
- *   1) Determine correct packet handler for this packet
- *   2) Mark the packet handled (so it can be dequeued in purge_queue())
- *   3) Send the packet to the packet handler
- *   4) Go to next packet in the queue and start over
- *   5) When done, run purge_queue() to purge handled commands
- *
- * TODO: Clean up.
- * TODO: More support for mid-level handlers.
- * TODO: Allow for NULL handlers.
- *
- */
-faim_export void aim_rxdispatch(aim_session_t *sess)
-{
-	int i;
-	aim_frame_t *cur;
-
-	for (cur = sess->queue_incoming, i = 0; cur; cur = cur->next, i++) {
-
-		/*
-		 * XXX: This is still fairly ugly.
-		 */
-
-		if (cur->handled)
-			continue;
-
-		if (cur->hdrtype == AIM_FRAMETYPE_FLAP) {
-			if (cur->hdr.flap.type == 0x01) {
-				cur->handled = aim_callhandler_noparam(sess, cur->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_FLAPVER, cur); /* XXX use consumenonsnac */
-				continue;
-
-			} else if (cur->hdr.flap.type == 0x02) {
-				if ((cur->handled = consumesnac(sess, cur)))
-					continue;
-
-			} else if (cur->hdr.flap.type == 0x04) {
-				cur->handled = negchan_middle(sess, cur);
-				continue;
-
-			} else if (cur->hdr.flap.type == 0x05) {
-
-			}
-
-		} else if (cur->hdrtype == AIM_FRAMETYPE_OFT) {
-			if (cur->conn->type == AIM_CONN_TYPE_RENDEZVOUS) {
-				aim_rxdispatch_rendezvous(sess, cur);
-				cur->handled = 1;
-				continue;
-
-			} else if (cur->conn->type == AIM_CONN_TYPE_LISTENER) {
-				/* not possible */
-				faimdprintf(sess, 0, "rxdispatch called on LISTENER connection!\n");
-				cur->handled = 1;
-				continue;
-			}
-		}
-
-		if (!cur->handled) {
-			consumenonsnac(sess, cur, 0xffff, 0xffff); /* last chance! */
-			cur->handled = 1;
-		}
-	}
-
-	/* 
-	 * This doesn't have to be called here.  It could easily be done
-	 * by a seperate thread or something. It's an administrative operation,
-	 * and can take a while. Though the less you call it the less memory
-	 * you'll have :)
-	 */
-	aim_purge_rxqueue(sess);
-
-	return;
-}
-
-faim_internal int aim_parse_unknown(aim_session_t *sess, aim_frame_t *frame, ...)
-{
-	int i;
-
-	faimdprintf(sess, 1, "\nRecieved unknown packet:");
-
-	for (i = 0; aim_bstream_empty(&frame->data); i++) {
-		if ((i % 8) == 0)
-			faimdprintf(sess, 1, "\n\t");
-
-		faimdprintf(sess, 1, "0x%2x ", aimbs_get8(&frame->data));
-	}
-
-	faimdprintf(sess, 1, "\n\n");
-
-	return 1;
-}
Index: bfaim/rxqueue.c
===================================================================
--- libfaim/rxqueue.c	(revision e374dee70435f8c596358571092675644a9ba731)
+++ 	(revision )
@@ -1,290 +1,0 @@
-/*
- * rxqueue.c
- *
- * This file contains the management routines for the receive
- * (incoming packet) queue.  The actual packet handlers are in
- * aim_rxhandlers.c.
- */
-
-#define FAIM_INTERNAL
-#include <aim.h> 
-
-#ifndef _WIN32
-#include <sys/socket.h>
-#endif
-
-/*
- *
- */
-faim_internal int aim_recv(int fd, void *buf, size_t count)
-{
-	int left, cur; 
-
-	for (cur = 0, left = count; left; ) {
-		int ret;
-		
-		ret = recv(fd, ((unsigned char *)buf)+cur, left, 0);
-
-		/* Of course EOF is an error, only morons disagree with that. */
-		if (ret <= 0)
-			return -1;
-
-		cur += ret;
-		left -= ret;
-	}
-
-	return cur;
-}
-
-/*
- * Read into a byte stream.  Will not read more than count, but may read
- * less if there is not enough room in the stream buffer.
- */
-faim_internal int aim_bstream_recv(aim_bstream_t *bs, int fd, size_t count)
-{
-	int red = 0;
-
-	if (!bs || (fd < 0) || (count < 0))
-		return -1;
-	
-	if (count > (bs->len - bs->offset))
-		count = bs->len - bs->offset; /* truncate to remaining space */
-
-	if (count) {
-
-		red = aim_recv(fd, bs->data + bs->offset, count);
-
-		if (red <= 0)
-			return -1;
-	}
-
-	bs->offset += red;
-
-	return red;
-}
-
-/**
- * aim_frame_destroy - free aim_frame_t
- * @frame: the frame to free
- *
- * returns -1 on error; 0 on success.
- *
- */
-faim_internal void aim_frame_destroy(aim_frame_t *frame)
-{
-
-	free(frame->data.data); /* XXX aim_bstream_free */
-	free(frame);
-
-	return;
-}
-
-/*
- * Read a FLAP header from conn into fr, and return the number of bytes in the payload.
- */
-static int aim_get_command_flap(aim_session_t *sess, aim_conn_t *conn, aim_frame_t *fr)
-{
-	fu8_t flaphdr_raw[6];
-	aim_bstream_t flaphdr;
-	fu16_t payloadlen;
-	
-	aim_bstream_init(&flaphdr, flaphdr_raw, sizeof(flaphdr_raw));
-
-	/*
-	 * Read FLAP header.  Six bytes:
-	 *   0 char  -- Always 0x2a
-	 *   1 char  -- Channel ID.  Usually 2 -- 1 and 4 are used during login.
-	 *   2 short -- Sequence number
-	 *   4 short -- Number of data bytes that follow.
-	 */
-	if (aim_bstream_recv(&flaphdr, conn->fd, 6) < 6) {
-		aim_conn_close(conn);
-		return -1;
-	}
-
-	aim_bstream_rewind(&flaphdr);
-
-	/*
-	 * This shouldn't happen unless the socket breaks, the server breaks,
-	 * or we break.  We must handle it just in case.
-	 */
-	if (aimbs_get8(&flaphdr) != 0x2a) {
-		fu8_t start;
-
-		aim_bstream_rewind(&flaphdr);
-		start = aimbs_get8(&flaphdr);
-		faimdprintf(sess, 0, "FLAP framing disrupted (0x%02x)", start);
-		aim_conn_close(conn);
-		return -1;
-	}	
-
-	/* we're doing FLAP if we're here */
-	fr->hdrtype = AIM_FRAMETYPE_FLAP;
-
-	fr->hdr.flap.type = aimbs_get8(&flaphdr);
-	fr->hdr.flap.seqnum = aimbs_get16(&flaphdr);
-	payloadlen = aimbs_get16(&flaphdr); /* length of payload */
-
-	return payloadlen;
-}
-
-/*
- * Read a rendezvous header from conn into fr, and return the number of bytes in the payload.
- */
-static int aim_get_command_rendezvous(aim_session_t *sess, aim_conn_t *conn, aim_frame_t *fr)
-{
-	fu8_t rendhdr_raw[8];
-	aim_bstream_t rendhdr;
-
-	aim_bstream_init(&rendhdr, rendhdr_raw, sizeof(rendhdr_raw));
-
-	if (aim_bstream_recv(&rendhdr, conn->fd, 8) < 8) {
-		aim_conn_close(conn);
-		return -1;
-	}
-
-	aim_bstream_rewind(&rendhdr);
-
-	fr->hdrtype = AIM_FRAMETYPE_OFT; /* a misnomer--rendezvous */
-
-	aimbs_getrawbuf(&rendhdr, fr->hdr.rend.magic, 4);
-	fr->hdr.rend.hdrlen = aimbs_get16(&rendhdr) - 8;
-	fr->hdr.rend.type = aimbs_get16(&rendhdr);
-
-	return fr->hdr.rend.hdrlen;
-}
-
-/*
- * Grab a single command sequence off the socket, and enqueue it in the incoming event queue 
- * in a separate struct.
- */
-faim_export int aim_get_command(aim_session_t *sess, aim_conn_t *conn)
-{
-	aim_frame_t *newrx;
-	fu16_t payloadlen;
-
-	if (!sess || !conn)
-		return -EINVAL;
-
-	if (conn->fd == -1)
-		return -1; /* it's an aim_conn_close()'d connection */
-
-	if (conn->fd < 3) /* can happen when people abuse the interface */
-		return -1;
-
-	if (conn->status & AIM_CONN_STATUS_INPROGRESS)
-		return aim_conn_completeconnect(sess, conn);
-
-	if (!(newrx = (aim_frame_t *)calloc(sizeof(aim_frame_t), 1)))
-		return -ENOMEM;
-
-	/*
-	 * Rendezvous (client to client) connections do not speak FLAP, so this 
-	 * function will break on them.
-	 */
-	if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) {
-		int ret = aim_get_command_rendezvous(sess, conn, newrx);
-
-		if (ret < 0) {
-			free(newrx);
-			return -1;
-		}
-
-		payloadlen = ret;
-	} else if (conn->type == AIM_CONN_TYPE_LISTENER) {
-		faimdprintf(sess, 0, "AIM_CONN_TYPE_LISTENER on fd %d\n", conn->fd);
-		free(newrx);
-		return -1;
-	} else
-		payloadlen = aim_get_command_flap(sess, conn, newrx);
-
-	newrx->nofree = 0; /* free by default */
-
-	if (payloadlen) {
-		fu8_t *payload = NULL;
-
-		if (!(payload = (fu8_t *) malloc(payloadlen))) {
-			aim_frame_destroy(newrx);
-			return -1;
-		}
-
-		aim_bstream_init(&newrx->data, payload, payloadlen);
-
-		/* read the payload */
-		if (aim_bstream_recv(&newrx->data, conn->fd, payloadlen) < payloadlen) {
-			aim_frame_destroy(newrx); /* free's payload */
-			aim_conn_close(conn);
-			return -1;
-		}
-	} else
-		aim_bstream_init(&newrx->data, NULL, 0);
-
-
-	aim_bstream_rewind(&newrx->data);
-
-	newrx->conn = conn;
-
-	newrx->next = NULL;  /* this will always be at the bottom */
-
-	if (!sess->queue_incoming)
-		sess->queue_incoming = newrx;
-	else {
-		aim_frame_t *cur;
-
-		for (cur = sess->queue_incoming; cur->next; cur = cur->next)
-			;
-		cur->next = newrx;
-	}
-
-	newrx->conn->lastactivity = time(NULL);
-
-	return 0;  
-}
-
-/*
- * Purge recieve queue of all handled commands (->handled==1).  Also
- * allows for selective freeing using ->nofree so that the client can
- * keep the data for various purposes.  
- *
- * If ->nofree is nonzero, the frame will be delinked from the global list, 
- * but will not be free'ed.  The client _must_ keep a pointer to the
- * data -- libfaim will not!  If the client marks ->nofree but
- * does not keep a pointer, it's lost forever.
- *
- */
-faim_export void aim_purge_rxqueue(aim_session_t *sess)
-{
-	aim_frame_t *cur, **prev;
-
-	for (prev = &sess->queue_incoming; (cur = *prev); ) {
-		if (cur->handled) {
-
-			*prev = cur->next;
-			
-			if (!cur->nofree)
-				aim_frame_destroy(cur);
-
-		} else
-			prev = &cur->next;
-	}
-
-	return;
-}
-
-/*
- * Since aim_get_command will aim_conn_kill dead connections, we need
- * to clean up the rxqueue of unprocessed connections on that socket.
- *
- * XXX: this is something that was handled better in the old connection
- * handling method, but eh.
- */
-faim_internal void aim_rxqueue_cleanbyconn(aim_session_t *sess, aim_conn_t *conn)
-{
-	aim_frame_t *currx;
-
-	for (currx = sess->queue_incoming; currx; currx = currx->next) {
-		if ((!currx->handled) && (currx->conn == conn))
-			currx->handled = 1;
-	}	
-	return;
-}
Index: bfaim/search.c
===================================================================
--- libfaim/search.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,134 +1,0 @@
-/*
- * Family 0x000a - User Search.
- *
- * TODO: Add aim_usersearch_name()
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-/*
- * Subtype 0x0001
- *
- * XXX can this be integrated with the rest of the error handling?
- */
-static int error(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	aim_snac_t *snac2;
-
-	/* XXX the modules interface should have already retrieved this for us */
-	if (!(snac2 = aim_remsnac(sess, snac->id))) {
-		faimdprintf(sess, 2, "search error: couldn't get a snac for 0x%08lx\n", snac->id);
-		return 0;
-	}
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, snac2->data /* address */);
-
-	/* XXX freesnac()? */
-	if (snac2)
-		free(snac2->data);
-	free(snac2);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0002
- *
- */
-faim_export int aim_search_address(aim_session_t *sess, aim_conn_t *conn, const char *address)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !conn || !address)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+strlen(address))))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x000a, 0x0002, 0x0000, strdup(address), strlen(address)+1);
-	aim_putsnac(&fr->data, 0x000a, 0x0002, 0x0000, snacid);
-	
-	aimbs_putraw(&fr->data, address, strlen(address)); 
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0003
- *
- */
-static int reply(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int j = 0, m, ret = 0;
-	aim_tlvlist_t *tlvlist;
-	char *cur = NULL, *buf = NULL;
-	aim_rxcallback_t userfunc;
-	aim_snac_t *snac2;
-	char *searchaddr = NULL;
-
-	if ((snac2 = aim_remsnac(sess, snac->id)))
-		searchaddr = (char *)snac2->data;
-
-	tlvlist = aim_tlvlist_read(bs);
-	m = aim_tlvlist_count(&tlvlist);
-
-	/* XXX uhm.
-	 * This is the only place that uses something other than 1 for the 3rd 
-	 * parameter to aim_tlv_gettlv_whatever().
-	 */
-	while ((cur = aim_tlv_getstr(tlvlist, 0x0001, j+1)) && j < m) {
-		buf = realloc(buf, (j+1) * (MAXSNLEN+1));
-
-		strncpy(&buf[j * (MAXSNLEN+1)], cur, MAXSNLEN);
-		free(cur);
-
-		j++; 
-	}
-
-	aim_tlvlist_free(&tlvlist);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, searchaddr, j, buf);
-
-	/* XXX freesnac()? */
-	if (snac2)
-		free(snac2->data);
-	free(snac2);
-
-	free(buf);
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0001)
-		return error(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0003)
-		return reply(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int search_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x000a;
-	mod->version = 0x0001;
-	mod->toolid = 0x0110;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "search", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/service.c
===================================================================
--- libfaim/service.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,1089 +1,0 @@
-/*
- * Family 0x0001 - This is a very special group.  All connections support
- * this group, as it does some particularly good things (like rate limiting).
- */
-
-#define FAIM_INTERNAL
-#define FAIM_NEED_CONN_INTERNAL
-#include <aim.h>
-
-#include "md5.h"
-
-/* Subtype 0x0002 - Client Online */
-faim_export int aim_clientready(aim_session_t *sess, aim_conn_t *conn)
-{
-	aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;
-	struct snacgroup *sg;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!ins)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0001, 0x0002, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0001, 0x0002, 0x0000, snacid);
-
-	/*
-	 * Send only the tool versions that the server cares about (that it
-	 * marked as supporting in the server ready SNAC).  
-	 */
-	for (sg = ins->groups; sg; sg = sg->next) {
-		aim_module_t *mod;
-
-		if ((mod = aim__findmodulebygroup(sess, sg->group))) {
-			aimbs_put16(&fr->data, mod->family);
-			aimbs_put16(&fr->data, mod->version);
-			aimbs_put16(&fr->data, mod->toolid);
-			aimbs_put16(&fr->data, mod->toolversion);
-		} else
-			faimdprintf(sess, 1, "aim_clientready: server supports group 0x%04x but we don't!\n", sg->group);
-	}
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0003 - Host Online
- * 
- * See comments in conn.c about how the group associations are supposed
- * to work, and how they really work.
- *
- * This info probably doesn't even need to make it to the client.
- *
- * We don't actually call the client here.  This starts off the connection
- * initialization routine required by all AIM connections.  The next time
- * the client is called is the CONNINITDONE callback, which should be 
- * shortly after the rate information is acknowledged.
- * 
- */
-static int hostonline(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	fu16_t *families;
-	int famcount;
-
-
-	if (!(families = malloc(aim_bstream_empty(bs))))
-		return 0;
-
-	for (famcount = 0; aim_bstream_empty(bs); famcount++) {
-		families[famcount] = aimbs_get16(bs);
-		aim_conn_addgroup(rx->conn, families[famcount]);
-	}
-
-	free(families);
-
-
-	/*
-	 * Next step is in the Host Versions handler.
-	 *
-	 * Note that we must send this before we request rates, since
-	 * the format of the rate information depends on the versions we
-	 * give it.
-	 *
-	 */
-	aim_setversions(sess, rx->conn);
-
-	return 1; 
-}
-
-/* Subtype 0x0004 - Service request */
-faim_export int aim_reqservice(aim_session_t *sess, aim_conn_t *conn, fu16_t serviceid)
-{
-	return aim_genericreq_s(sess, conn, 0x0001, 0x0004, &serviceid);
-}
-
-/* Subtype 0x0005 - Redirect */
-static int redirect(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	struct aim_redirect_data redir;
-	aim_rxcallback_t userfunc;
-	aim_tlvlist_t *tlvlist;
-	aim_snac_t *origsnac = NULL;
-	int ret = 0;
-
-	memset(&redir, 0, sizeof(redir));
-
-	tlvlist = aim_tlvlist_read(bs);
-
-	if (!aim_tlv_gettlv(tlvlist, 0x000d, 1) ||
-			!aim_tlv_gettlv(tlvlist, 0x0005, 1) ||
-			!aim_tlv_gettlv(tlvlist, 0x0006, 1)) {
-		aim_tlvlist_free(&tlvlist);
-		return 0;
-	}
-
-	redir.group = aim_tlv_get16(tlvlist, 0x000d, 1);
-	redir.ip = aim_tlv_getstr(tlvlist, 0x0005, 1);
-	redir.cookielen = aim_tlv_gettlv(tlvlist, 0x0006, 1)->length;
-	redir.cookie = aim_tlv_getstr(tlvlist, 0x0006, 1);
-
-	/* Fetch original SNAC so we can get csi if needed */
-	origsnac = aim_remsnac(sess, snac->id);
-
-	if ((redir.group == AIM_CONN_TYPE_CHAT) && origsnac) {
-		struct chatsnacinfo *csi = (struct chatsnacinfo *)origsnac->data;
-
-		redir.chat.exchange = csi->exchange;
-		redir.chat.room = csi->name;
-		redir.chat.instance = csi->instance;
-	}
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, &redir);
-
-	free((void *)redir.ip);
-	free((void *)redir.cookie);
-
-	if (origsnac)
-		free(origsnac->data);
-	free(origsnac);
-
-	aim_tlvlist_free(&tlvlist);
-
-	return ret;
-}
-
-/* Subtype 0x0006 - Request Rate Information. */
-faim_internal int aim_reqrates(aim_session_t *sess, aim_conn_t *conn)
-{
-	return aim_genericreq_n_snacid(sess, conn, 0x0001, 0x0006);
-}
-
-/*
- * OSCAR defines several 'rate classes'.  Each class has seperate
- * rate limiting properties (limit level, alert level, disconnect
- * level, etc), and a set of SNAC family/type pairs associated with
- * it.  The rate classes, their limiting properties, and the definitions
- * of which SNACs are belong to which class, are defined in the
- * Rate Response packet at login to each host.  
- *
- * Logically, all rate offenses within one class count against further
- * offenses for other SNACs in the same class (ie, sending messages
- * too fast will limit the number of user info requests you can send,
- * since those two SNACs are in the same rate class).
- *
- * Since the rate classes are defined dynamically at login, the values
- * below may change. But they seem to be fairly constant.
- *
- * Currently, BOS defines five rate classes, with the commonly used
- * members as follows...
- *
- *  Rate class 0x0001:
- *  	- Everything thats not in any of the other classes
- *
- *  Rate class 0x0002:
- * 	- Buddy list add/remove
- *	- Permit list add/remove
- *	- Deny list add/remove
- *
- *  Rate class 0x0003:
- *	- User information requests
- *	- Outgoing ICBMs
- *
- *  Rate class 0x0004:
- *	- A few unknowns: 2/9, 2/b, and f/2
- *
- *  Rate class 0x0005:
- *	- Chat room create
- *	- Outgoing chat ICBMs
- *
- * The only other thing of note is that class 5 (chat) has slightly looser
- * limiting properties than class 3 (normal messages).  But thats just a 
- * small bit of trivia for you.
- *
- * The last thing that needs to be learned about the rate limiting
- * system is how the actual numbers relate to the passing of time.  This
- * seems to be a big mystery.
- * 
- */
-
-static void rc_addclass(struct rateclass **head, struct rateclass *inrc)
-{
-	struct rateclass *rc, *rc2;
-
-	if (!(rc = malloc(sizeof(struct rateclass))))
-		return;
-
-	memcpy(rc, inrc, sizeof(struct rateclass));
-	rc->next = NULL;
-
-	for (rc2 = *head; rc2 && rc2->next; rc2 = rc2->next)
-		;
-
-	if (!rc2)
-		*head = rc;
-	else
-		rc2->next = rc;
-
-	return;
-}
-
-static struct rateclass *rc_findclass(struct rateclass **head, fu16_t id)
-{
-	struct rateclass *rc;
-
-	for (rc = *head; rc; rc = rc->next) {
-		if (rc->classid == id)
-			return rc;
-	}
-
-	return NULL;
-}
-
-static void rc_addpair(struct rateclass *rc, fu16_t group, fu16_t type)
-{
-	struct snacpair *sp, *sp2;
-
-	if (!(sp = malloc(sizeof(struct snacpair))))
-		return;
-	memset(sp, 0, sizeof(struct snacpair));
-
-	sp->group = group;
-	sp->subtype = type;
-	sp->next = NULL;
-
-	for (sp2 = rc->members; sp2 && sp2->next; sp2 = sp2->next)
-		;
-
-	if (!sp2)
-		rc->members = sp;
-	else
-		sp2->next = sp;
-
-	return;
-}
-
-/* Subtype 0x0007 - Rate Parameters */
-static int rateresp(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_conn_inside_t *ins = (aim_conn_inside_t *)rx->conn->inside;
-	fu16_t numclasses, i;
-	aim_rxcallback_t userfunc;
-
-
-	/*
-	 * First are the parameters for each rate class.
-	 */
-	numclasses = aimbs_get16(bs);
-	for (i = 0; i < numclasses; i++) {
-		struct rateclass rc;
-
-		memset(&rc, 0, sizeof(struct rateclass));
-
-		rc.classid = aimbs_get16(bs);
-		rc.windowsize = aimbs_get32(bs);
-		rc.clear = aimbs_get32(bs);
-		rc.alert = aimbs_get32(bs);
-		rc.limit = aimbs_get32(bs);
-		rc.disconnect = aimbs_get32(bs);
-		rc.current = aimbs_get32(bs);
-		rc.max = aimbs_get32(bs);
-
-		/*
-		 * The server will send an extra five bytes of parameters
-		 * depending on the version we advertised in 1/17.  If we
-		 * didn't send 1/17 (evil!), then this will crash and you
-		 * die, as it will default to the old version but we have 
-		 * the new version hardcoded here. 
-		 */
-		if (mod->version >= 3)
-			aimbs_getrawbuf(bs, rc.unknown, sizeof(rc.unknown));
-
-		faimdprintf(sess, 1, "--- Adding rate class %d to connection type %d: window size = %ld, clear = %ld, alert = %ld, limit = %ld, disconnect = %ld, current = %ld, max = %ld\n", rx->conn->type, rc.classid, rc.windowsize, rc.clear, rc.alert, rc.limit, rc.disconnect, rc.current, rc.max);
-
-		rc_addclass(&ins->rates, &rc);
-	}
-
-	/*
-	 * Then the members of each class.
-	 */
-	for (i = 0; i < numclasses; i++) {
-		fu16_t classid, count;
-		struct rateclass *rc;
-		int j;
-
-		classid = aimbs_get16(bs);
-		count = aimbs_get16(bs);
-
-		rc = rc_findclass(&ins->rates, classid);
-
-		for (j = 0; j < count; j++) {
-			fu16_t group, subtype;
-
-			group = aimbs_get16(bs);
-			subtype = aimbs_get16(bs);
-
-			if (rc)
-				rc_addpair(rc, group, subtype);
-		}
-	}
-
-	/*
-	 * We don't pass the rate information up to the client, as it really
-	 * doesn't care.  The information is stored in the connection, however
-	 * so that we can do more fun stuff later (not really).
-	 */
-
-	/*
-	 * Last step in the conn init procedure is to acknowledge that we
-	 * agree to these draconian limitations.
-	 */
-	aim_rates_addparam(sess, rx->conn);
-
-	/*
-	 * Finally, tell the client it's ready to go...
-	 */
-	if ((userfunc = aim_callhandler(sess, rx->conn, AIM_CB_FAM_SPECIAL, AIM_CB_SPECIAL_CONNINITDONE)))
-		userfunc(sess, rx);
-
-
-	return 1;
-}
-
-/* Subtype 0x0008 - Add Rate Parameter */
-faim_internal int aim_rates_addparam(aim_session_t *sess, aim_conn_t *conn)
-{
-	aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;
-	aim_frame_t *fr;	
-	aim_snacid_t snacid;
-	struct rateclass *rc;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512)))
-		return -ENOMEM; 
-
-	snacid = aim_cachesnac(sess, 0x0001, 0x0008, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0001, 0x0008, 0x0000, snacid);
-
-	for (rc = ins->rates; rc; rc = rc->next)
-		aimbs_put16(&fr->data, rc->classid);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/* Subtype 0x0009 - Delete Rate Parameter */
-faim_internal int aim_rates_delparam(aim_session_t *sess, aim_conn_t *conn)
-{
-	aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;
-	aim_frame_t *fr;	
-	aim_snacid_t snacid;
-	struct rateclass *rc;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 512)))
-		return -ENOMEM; 
-
-	snacid = aim_cachesnac(sess, 0x0001, 0x0009, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0001, 0x0009, 0x0000, snacid);
-
-	for (rc = ins->rates; rc; rc = rc->next)
-		aimbs_put16(&fr->data, rc->classid);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/* Subtype 0x000a - Rate Change */
-static int ratechange(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t code, rateclass;
-	fu32_t currentavg, maxavg, windowsize, clear, alert, limit, disconnect;
-
-	code = aimbs_get16(bs);
-	rateclass = aimbs_get16(bs);
-	
-	windowsize = aimbs_get32(bs);
-	clear = aimbs_get32(bs);
-	alert = aimbs_get32(bs);
-	limit = aimbs_get32(bs);
-	disconnect = aimbs_get32(bs);
-	currentavg = aimbs_get32(bs);
-	maxavg = aimbs_get32(bs);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, code, rateclass, windowsize, clear, alert, limit, disconnect, currentavg, maxavg);
-
-	return ret;
-}
-
-/*
- * How Migrations work.
- *
- * The server sends a Server Pause message, which the client should respond to 
- * with a Server Pause Ack, which contains the families it needs on this 
- * connection. The server will send a Migration Notice with an IP address, and 
- * then disconnect. Next the client should open the connection and send the 
- * cookie.  Repeat the normal login process and pretend this never happened.
- *
- * The Server Pause contains no data.
- *
- */
-
-/* Subtype 0x000b - Service Pause */
-static int serverpause(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx);
-
-	return ret;
-}
-
-/*
- * Subtype 0x000c - Service Pause Acknowledgement
- *
- * It is rather important that aim_sendpauseack() gets called for the exact
- * same connection that the Server Pause callback was called for, since
- * libfaim extracts the data for the SNAC from the connection structure.
- *
- * Of course, if you don't do that, more bad things happen than just what
- * libfaim can cause.
- *
- */
-faim_export int aim_sendpauseack(aim_session_t *sess, aim_conn_t *conn)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;
-	struct snacgroup *sg;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1024)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0001, 0x000c, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0001, 0x000c, 0x0000, snacid);
-
-	/*
-	 * This list should have all the groups that the original 
-	 * Host Online / Server Ready said this host supports.  And 
-	 * we want them all back after the migration.
-	 */
-	for (sg = ins->groups; sg; sg = sg->next)
-		aimbs_put16(&fr->data, sg->group);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/* Subtype 0x000d - Service Resume */
-static int serverresume(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx);
-
-	return ret;
-}
-
-/* Subtype 0x000e - Request self-info */
-faim_export int aim_reqpersonalinfo(aim_session_t *sess, aim_conn_t *conn)
-{
-	return aim_genericreq_n_snacid(sess, conn, 0x0001, 0x000e);
-}
-
-/* Subtype 0x000f - Self User Info */
-static int selfinfo(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	aim_userinfo_t userinfo;
-
-	aim_info_extract(sess, bs, &userinfo);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, &userinfo);
-
-	aim_info_free(&userinfo);
-
-	return ret;
-}
-
-/* Subtype 0x0010 - Evil Notification */
-static int evilnotify(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t newevil;
-	aim_userinfo_t userinfo;
-
-	memset(&userinfo, 0, sizeof(aim_userinfo_t));
-	
-	newevil = aimbs_get16(bs);
-
-	if (aim_bstream_empty(bs))
-		aim_info_extract(sess, bs, &userinfo);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, newevil, &userinfo);
-
-	aim_info_free(&userinfo);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0011 - Idle Notification
- *
- * Should set your current idle time in seconds.  Note that this should
- * never be called consecutively with a non-zero idle time.  That makes
- * OSCAR do funny things.  Instead, just set it once you go idle, and then
- * call it again with zero when you're back.
- *
- */
-faim_export int aim_srv_setidle(aim_session_t *sess, fu32_t idletime)
-{
-	aim_conn_t *conn;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_BOS)))
-		return -EINVAL;
-
-	return aim_genericreq_l(sess, conn, 0x0001, 0x0011, &idletime);
-}
-
-/*
- * Subtype 0x0012 - Service Migrate
- *
- * This is the final SNAC sent on the original connection during a migration.
- * It contains the IP and cookie used to connect to the new server, and 
- * optionally a list of the SNAC groups being migrated.
- *
- */
-static int migrate(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_rxcallback_t userfunc;
-	int ret = 0;
-	fu16_t groupcount, i;
-	aim_tlvlist_t *tl;
-	char *ip = NULL;
-	aim_tlv_t *cktlv;
-
-	/*
-	 * Apparently there's some fun stuff that can happen right here. The
-	 * migration can actually be quite selective about what groups it
-	 * moves to the new server.  When not all the groups for a connection
-	 * are migrated, or they are all migrated but some groups are moved
-	 * to a different server than others, it is called a bifurcated 
-	 * migration.
-	 *
-	 * Let's play dumb and not support that.
-	 *
-	 */
-	groupcount = aimbs_get16(bs);
-	for (i = 0; i < groupcount; i++) {
-		fu16_t group;
-
-		group = aimbs_get16(bs);
-
-		faimdprintf(sess, 0, "bifurcated migration unsupported -- group 0x%04x\n", group);
-	}
-
-	tl = aim_tlvlist_read(bs);
-
-	if (aim_tlv_gettlv(tl, 0x0005, 1))
-		ip = aim_tlv_getstr(tl, 0x0005, 1);
-
-	cktlv = aim_tlv_gettlv(tl, 0x0006, 1);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, ip, cktlv ? cktlv->value : NULL);
-
-	aim_tlvlist_free(&tl);
-	free(ip);
-
-	return ret;
-}
-
-/* Subtype 0x0013 - Message of the Day */
-static int motd(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	aim_rxcallback_t userfunc;
-	char *msg = NULL;
-	int ret = 0;
-	aim_tlvlist_t *tlvlist;
-	fu16_t id;
-
-	/*
-	 * Code.
-	 *
-	 * Valid values:
-	 *   1 Mandatory upgrade
-	 *   2 Advisory upgrade
-	 *   3 System bulletin
-	 *   4 Nothing's wrong ("top o the world" -- normal)
-	 *   5 Lets-break-something. 
-	 *
-	 */
-	id = aimbs_get16(bs);
-
-	/* 
-	 * TLVs follow 
-	 */
-	tlvlist = aim_tlvlist_read(bs);
-
-	msg = aim_tlv_getstr(tlvlist, 0x000b, 1);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, id, msg);
-
-	free(msg);
-
-	aim_tlvlist_free(&tlvlist);
-
-	return ret;
-}
-
-/* 
- * Subtype 0x0014 - Set privacy flags
- *
- * Normally 0x03.
- *
- *  Bit 1:  Allows other AIM users to see how long you've been idle.
- *  Bit 2:  Allows other AIM users to see how long you've been a member.
- *
- */
-faim_export int aim_bos_setprivacyflags(aim_session_t *sess, aim_conn_t *conn, fu32_t flags)
-{
-	return aim_genericreq_l(sess, conn, 0x0001, 0x0014, &flags);
-}
-
-/*
- * Subtype 0x0016 - No-op
- *
- * WinAIM sends these every 4min or so to keep the connection alive.  Its not 
- * really necessary.
- *
- * Wha?  No?  Since when?  I think WinAIM sends an empty channel 3 
- * SNAC as a no-op...
- */
-faim_export int aim_nop(aim_session_t *sess, aim_conn_t *conn)
-{
-	return aim_genericreq_n(sess, conn, 0x0001, 0x0016);
-}
-
-/* 
- * Subtype 0x0017 - Set client versions
- *
- * If you've seen the clientonline/clientready SNAC you're probably 
- * wondering what the point of this one is.  And that point seems to be
- * that the versions in the client online SNAC are sent too late for the
- * server to be able to use them to change the protocol for the earlier
- * login packets (client versions are sent right after Host Online is 
- * received, but client online versions aren't sent until quite a bit later).
- * We can see them already making use of this by changing the format of
- * the rate information based on what version of group 1 we advertise here.
- *
- */
-faim_internal int aim_setversions(aim_session_t *sess, aim_conn_t *conn)
-{
-	aim_conn_inside_t *ins = (aim_conn_inside_t *)conn->inside;
-	struct snacgroup *sg;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!ins)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 1152)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0001, 0x0017, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0001, 0x0017, 0x0000, snacid);
-
-	/*
-	 * Send only the versions that the server cares about (that it
-	 * marked as supporting in the server ready SNAC).  
-	 */
-	for (sg = ins->groups; sg; sg = sg->next) {
-		aim_module_t *mod;
-
-		if ((mod = aim__findmodulebygroup(sess, sg->group))) {
-			aimbs_put16(&fr->data, mod->family);
-			aimbs_put16(&fr->data, mod->version);
-		} else
-			faimdprintf(sess, 1, "aim_setversions: server supports group 0x%04x but we don't!\n", sg->group);
-	}
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/* Subtype 0x0018 - Host versions */
-static int hostversions(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int vercount;
-	fu8_t *versions;
-
-	/* This is frivolous. (Thank you SmarterChild.) */
-	vercount = aim_bstream_empty(bs)/4;
-	versions = aimbs_getraw(bs, aim_bstream_empty(bs));
-	free(versions);
-
-	/*
-	 * Now request rates.
-	 */
-	aim_reqrates(sess, rx->conn);
-
-	return 1;
-}
-
-/* 
- * Subtype 0x001e - Extended Status
- *
- * Sets your ICQ status (available, away, do not disturb, etc.)
- *
- * These are the same TLVs seen in user info.  You can 
- * also set 0x0008 and 0x000c.
- */
-faim_export int aim_setextstatus(aim_session_t *sess, fu32_t status)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	aim_tlvlist_t *tl = NULL;
-	fu32_t data;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0004)))
-		return -EINVAL;
-
-	data = AIM_ICQ_STATE_HIDEIP | AIM_ICQ_STATE_WEBAWARE | status; /* yay for error checking ;^) */
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 8)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0001, 0x001e, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, 0x0001, 0x001e, 0x0000, snacid);
-	
-	aim_tlvlist_add_32(&tl, 0x0006, data);
-	aim_tlvlist_write(&fr->data, &tl);
-	aim_tlvlist_free(&tl);
-	
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/* 
- * Subtype 0x001e - Extended Status.
- *
- * Sets your "available" message.  This is currently only supported by iChat 
- * and Gaim.
- *
- * These are the same TLVs seen in user info.  You can 
- * also set 0x0008 and 0x000c.
- */
-faim_export int aim_srv_setavailmsg(aim_session_t *sess, char *msg)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, 0x0001)))
-		return -EINVAL;
-
-	if (msg != NULL) {
-		if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + strlen(msg) + 8)))
-			return -ENOMEM;
-
-		snacid = aim_cachesnac(sess, 0x0001, 0x001e, 0x0000, NULL, 0);
-		aim_putsnac(&fr->data, 0x0001, 0x001e, 0x0000, snacid);
-
-		aimbs_put16(&fr->data, 0x001d); /* userinfo TLV type */
-		aimbs_put16(&fr->data, strlen(msg)+8); /* total length of userinfo TLV data */
-		aimbs_put16(&fr->data, 0x0002);
-		aimbs_put8(&fr->data, 0x04);
-		aimbs_put8(&fr->data, strlen(msg)+4);
-		aimbs_put16(&fr->data, strlen(msg));
-		aimbs_putraw(&fr->data, msg, strlen(msg));
-		aimbs_put16(&fr->data, 0x0000);
-	} else {
-		if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 4 + 8)))
-			return -ENOMEM;
-
-		snacid = aim_cachesnac(sess, 0x0001, 0x001e, 0x0000, NULL, 0);
-		aim_putsnac(&fr->data, 0x0001, 0x001e, 0x0000, snacid);
-
-		aimbs_put16(&fr->data, 0x001d);
-		aimbs_put16(&fr->data, 0x0008);
-		aimbs_put16(&fr->data, 0x0002);
-		aimbs_put16(&fr->data, 0x0404);
-		aimbs_put16(&fr->data, 0x0000);
-		aimbs_put16(&fr->data, 0x0000);
-	}
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Starting this past week (26 Mar 2001, say), AOL has started sending
- * this nice little extra SNAC.  AFAIK, it has never been used until now.
- *
- * The request contains eight bytes.  The first four are an offset, the
- * second four are a length.
- *
- * The offset is an offset into aim.exe when it is mapped during execution
- * on Win32.  So far, AOL has only been requesting bytes in static regions
- * of memory.  (I won't put it past them to start requesting data in
- * less static regions -- regions that are initialized at run time, but still
- * before the client recieves this request.)
- *
- * When the client recieves the request, it adds it to the current ds
- * (0x00400000) and dereferences it, copying the data into a buffer which
- * it then runs directly through the MD5 hasher.  The 16 byte output of
- * the hash is then sent back to the server.
- *
- * If the client does not send any data back, or the data does not match
- * the data that the specific client should have, the client will get the
- * following message from "AOL Instant Messenger":
- *    "You have been disconnected from the AOL Instant Message Service (SM) 
- *     for accessing the AOL network using unauthorized software.  You can
- *     download a FREE, fully featured, and authorized client, here 
- *     http://www.aol.com/aim/download2.html"
- * The connection is then closed, recieving disconnect code 1, URL
- * http://www.aim.aol.com/errors/USER_LOGGED_OFF_NEW_LOGIN.html.  
- *
- * Note, however, that numerous inconsistencies can cause the above error, 
- * not just sending back a bad hash.  Do not immediatly suspect this code
- * if you get disconnected.  AOL and the open/free software community have
- * played this game for a couple years now, generating the above message
- * on numerous ocassions.
- *
- * Anyway, neener.  We win again.
- *
- */
-/* Subtype 0x001f - Client verification */
-static int memrequest(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu32_t offset, len;
-	aim_tlvlist_t *list;
-	char *modname;
-
-	offset = aimbs_get32(bs);
-	len = aimbs_get32(bs);
-	list = aim_tlvlist_read(bs);
-
-	modname = aim_tlv_getstr(list, 0x0001, 1);
-
-	faimdprintf(sess, 1, "data at 0x%08lx (%d bytes) of requested\n", offset, len, modname ? modname : "aim.exe");
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, offset, len, modname);
-
-	free(modname);
-	aim_tlvlist_free(&list);
-
-	return ret;
-}
-
-#if 0
-static void dumpbox(aim_session_t *sess, unsigned char *buf, int len)
-{
-	int i;
-
-	if (!sess || !buf || !len)
-		return;
-
-	faimdprintf(sess, 1, "\nDump of %d bytes at %p:", len, buf);
-
-	for (i = 0; i < len; i++) {
-		if ((i % 8) == 0)
-			faimdprintf(sess, 1, "\n\t");
-
-		faimdprintf(sess, 1, "0x%2x ", buf[i]);
-	}
-
-	faimdprintf(sess, 1, "\n\n");
-
-	return;
-}
-#endif
-
-/* Subtype 0x0020 - Client verification reply */
-faim_export int aim_sendmemblock(aim_session_t *sess, aim_conn_t *conn, fu32_t offset, fu32_t len, const fu8_t *buf, fu8_t flag)
-{
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !conn)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+2+16)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, 0x0001, 0x0020, 0x0000, NULL, 0);
-
-	aim_putsnac(&fr->data, 0x0001, 0x0020, 0x0000, snacid);
-	aimbs_put16(&fr->data, 0x0010); /* md5 is always 16 bytes */
-
-	if ((flag == AIM_SENDMEMBLOCK_FLAG_ISHASH) && buf && (len == 0x10)) { /* we're getting a hash */
-
-		aimbs_putraw(&fr->data, buf, 0x10); 
-
-	} else if (buf && (len > 0)) { /* use input buffer */
-		md5_state_t state;
-		md5_byte_t digest[0x10];
-
-		md5_init(&state);	
-		md5_append(&state, (const md5_byte_t *)buf, len);
-		md5_finish(&state, digest);
-
-		aimbs_putraw(&fr->data, (fu8_t *)digest, 0x10);
-
-	} else if (len == 0) { /* no length, just hash NULL (buf is optional) */
-		md5_state_t state;
-		fu8_t nil = '\0';
-		md5_byte_t digest[0x10];
-
-		/*
-		 * These MD5 routines are stupid in that you have to have
-		 * at least one append.  So thats why this doesn't look 
-		 * real logical.
-		 */
-		md5_init(&state);
-		md5_append(&state, (const md5_byte_t *)&nil, 0);
-		md5_finish(&state, digest);
-
-		aimbs_putraw(&fr->data, (fu8_t *)digest, 0x10);
-
-	} else {
-
-		/* 
-		 * This data is correct for AIM 3.5.1670.
-		 *
-		 * Using these blocks is as close to "legal" as you can get
-		 * without using an AIM binary.
-		 *
-		 */
-		if ((offset == 0x03ffffff) && (len == 0x03ffffff)) {
-
-#if 1 /* with "AnrbnrAqhfzcd" */
-			aimbs_put32(&fr->data, 0x44a95d26);
-			aimbs_put32(&fr->data, 0xd2490423);
-			aimbs_put32(&fr->data, 0x93b8821f);
-			aimbs_put32(&fr->data, 0x51c54b01);
-#else /* no filename */
-			aimbs_put32(&fr->data, 0x1df8cbae);
-			aimbs_put32(&fr->data, 0x5523b839);
-			aimbs_put32(&fr->data, 0xa0e10db3);
-			aimbs_put32(&fr->data, 0xa46d3b39);
-#endif
-
-		} else if ((offset == 0x00001000) && (len == 0x00000000)) {
-
-			aimbs_put32(&fr->data, 0xd41d8cd9);
-			aimbs_put32(&fr->data, 0x8f00b204);
-			aimbs_put32(&fr->data, 0xe9800998);
-			aimbs_put32(&fr->data, 0xecf8427e);
-
-		} else
-			faimdprintf(sess, 0, "sendmemblock: WARNING: unknown hash request\n");
-
-	}
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0021 - Receive our extended status
- *
- * This is used for iChat's "available" messages, and maybe ICQ extended 
- * status messages?  It's also used to tell the client whether or not it 
- * needs to upload an SSI buddy icon... who engineers this stuff, anyway?
- */
-static int aim_parse_extstatus(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t type;
-	fu8_t flags, length;
-
-	type = aimbs_get16(bs); 
-	flags = aimbs_get8(bs);
-	length = aimbs_get8(bs);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype))) {
-		switch (type) {
-		case 0x0000:
-		case 0x0001: { /* buddy icon checksum */
-			/* not sure what the difference between 1 and 0 is */
-			fu8_t *md5 = aimbs_getraw(bs, length);
-			ret = userfunc(sess, rx, type, flags, length, md5);
-			free(md5);
-			} break;
-		case 0x0002: { /* available message */
-			/* there is a second length that is just for the message */
-			char *msg = aimbs_getstr(bs, aimbs_get16(bs));
-			ret = userfunc(sess, rx, msg);
-			free(msg);
-			} break;
-		}
-	}
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0003)
-		return hostonline(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0005)
-		return redirect(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0007)
-		return rateresp(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x000a)
-		return ratechange(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x000b)
-		return serverpause(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x000d)
-		return serverresume(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x000f)
-		return selfinfo(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0010)
-		return evilnotify(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0012)
-		return migrate(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0013)
-		return motd(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0018)
-		return hostversions(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x001f)
-		return memrequest(sess, mod, rx, snac, bs);
-	else if (snac->subtype == 0x0021)
-		return aim_parse_extstatus(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int service_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x0001;
-	mod->version = 0x0003;
-	mod->toolid = 0x0110;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "service", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/snac.c
===================================================================
--- libfaim/snac.c	(revision e374dee70435f8c596358571092675644a9ba731)
+++ 	(revision )
@@ -1,148 +1,0 @@
-/*
- *
- * Various SNAC-related dodads... 
- *
- * outstanding_snacs is a list of aim_snac_t structs.  A SNAC should be added
- * whenever a new SNAC is sent and it should remain in the list until the
- * response for it has been receieved.  
- *
- * cleansnacs() should be called periodically by the client in order
- * to facilitate the aging out of unreplied-to SNACs. This can and does
- * happen, so it should be handled.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-/*
- * Called from aim_session_init() to initialize the hash.
- */
-faim_internal void aim_initsnachash(aim_session_t *sess)
-{
-	int i;
-
-	for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++)
-		sess->snac_hash[i] = NULL;
-
-	return;
-}
-
-faim_internal aim_snacid_t aim_cachesnac(aim_session_t *sess, const fu16_t family, const fu16_t type, const fu16_t flags, const void *data, const int datalen)
-{
-	aim_snac_t snac;
-
-	snac.id = sess->snacid_next++;
-	snac.family = family;
-	snac.type = type;
-	snac.flags = flags;
-
-	if (datalen) {
-		if (!(snac.data = malloc(datalen)))
-			return 0; /* er... */
-		memcpy(snac.data, data, datalen);
-	} else
-		snac.data = NULL;
-
-	return aim_newsnac(sess, &snac);
-}
-
-/*
- * Clones the passed snac structure and caches it in the
- * list/hash.
- */
-faim_internal aim_snacid_t aim_newsnac(aim_session_t *sess, aim_snac_t *newsnac)
-{
-	aim_snac_t *snac;
-	int index;
-
-	if (!newsnac)
-		return 0;
-
-	if (!(snac = malloc(sizeof(aim_snac_t))))
-		return 0;
-	memcpy(snac, newsnac, sizeof(aim_snac_t));
-	snac->issuetime = time(NULL);
-
-	index = snac->id % FAIM_SNAC_HASH_SIZE;
-
-	snac->next = (aim_snac_t *)sess->snac_hash[index];
-	sess->snac_hash[index] = (void *)snac;
-
-	return snac->id;
-}
-
-/*
- * Finds a snac structure with the passed SNAC ID, 
- * removes it from the list/hash, and returns a pointer to it.
- *
- * The returned structure must be freed by the caller.
- *
- */
-faim_internal aim_snac_t *aim_remsnac(aim_session_t *sess, aim_snacid_t id) 
-{
-	aim_snac_t *cur, **prev;
-	int index;
-
-	index = id % FAIM_SNAC_HASH_SIZE;
-
-	for (prev = (aim_snac_t **)&sess->snac_hash[index]; (cur = *prev); ) {
-		if (cur->id == id) {
-			*prev = cur->next;
-			if (cur->flags & AIM_SNACFLAGS_DESTRUCTOR) {
-				free(cur->data);
-				cur->data = NULL;
-			}
-			return cur;
-		} else
-			prev = &cur->next;
-	}
-
-	return cur;
-}
-
-/*
- * This is for cleaning up old SNACs that either don't get replies or
- * a reply was never received for.  Garabage collection. Plain and simple.
- *
- * maxage is the _minimum_ age in seconds to keep SNACs.
- *
- */
-faim_export void aim_cleansnacs(aim_session_t *sess, int maxage)
-{
-	int i;
-
-	for (i = 0; i < FAIM_SNAC_HASH_SIZE; i++) {
-		aim_snac_t *cur, **prev;
-		time_t curtime;
-
-		if (!sess->snac_hash[i])
-			continue;
-
-		curtime = time(NULL); /* done here in case we waited for the lock */
-
-		for (prev = (aim_snac_t **)&sess->snac_hash[i]; (cur = *prev); ) {
-			if ((curtime - cur->issuetime) > maxage) {
-
-				*prev = cur->next;
-
-				free(cur->data);
-				free(cur);
-			} else
-				prev = &cur->next;
-		}
-	}
-
-	return;
-}
-
-faim_internal int aim_putsnac(aim_bstream_t *bs, fu16_t family, fu16_t subtype, fu16_t flags, aim_snacid_t snacid)
-{
-
-	aimbs_put16(bs, family);
-	aimbs_put16(bs, subtype);
-	aimbs_put16(bs, flags);
-	aimbs_put32(bs, snacid);
-
-	return 10;
-}
Index: bfaim/ssi.c
===================================================================
--- libfaim/ssi.c	(revision 0154e2d932e8d0248f6052152feb1fd0ffceedc4)
+++ 	(revision )
@@ -1,1963 +1,0 @@
-/*
- * Family 0x0013 - Server-Side/Stored Information.
- *
- * Relatively new facility that allows certain types of information, such as 
- * a user's buddy list, permit/deny list, and permit/deny preferences, to be 
- * stored on the server, so that they can be accessed from any client.
- *
- * We keep 2 copies of SSI data:
- * 1) An exact copy of what is stored on the AIM servers.
- * 2) A local copy that we make changes to, and then send diffs 
- *    between this and the exact copy to keep them in sync.
- *
- * All the "aim_ssi_itemlist_bleh" functions near the top just modify the list 
- * that is given to them (i.e. they don't send SNACs).
- *
- * The SNAC sending and receiving functions are lower down in the file, and 
- * they're simpler.  They are in the order of the subtypes they deal with, 
- * starting with the request rights function (subtype 0x0002), then parse 
- * rights (subtype 0x0003), then--well, you get the idea.
- *
- * This is entirely too complicated.
- * You don't know the half of it.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-/**
- * Locally rebuild the 0x00c8 TLV in the additional data of the given group.
- *
- * @param list A pointer to a pointer to the current list of items.
- * @param name A null terminated string containing the group name, or NULL 
- *        if you want to modify the master group.
- * @return Return a pointer to the modified item.
- */
-static struct aim_ssi_item *aim_ssi_itemlist_rebuildgroup(struct aim_ssi_item *list, const char *name)
-{
-	int newlen;
-	struct aim_ssi_item *cur, *group;
-
-	if (!list)
-		return NULL;
-
-	/* Find the group */
-	if (!(group = aim_ssi_itemlist_finditem(list, name, NULL, AIM_SSI_TYPE_GROUP)))
-		return NULL;
-
-	/* Find the length for the new additional data */
-	newlen = 0;
-	if (group->gid == 0x0000) {
-		for (cur=list; cur; cur=cur->next)
-			if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000))
-				newlen += 2;
-	} else {
-		for (cur=list; cur; cur=cur->next)
-			if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY))
-				newlen += 2;
-	}
-
-	/* Build the new TLV list */
-	if (newlen > 0) {
-		fu8_t *newdata;
-
-		if (!(newdata = (fu8_t *)malloc((newlen)*sizeof(fu8_t))))
-			return NULL;
-		newlen = 0;
-		if (group->gid == 0x0000) {
-			for (cur=list; cur; cur=cur->next)
-				if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid != 0x0000))
-						newlen += aimutil_put16(newdata+newlen, cur->gid);
-		} else {
-			for (cur=list; cur; cur=cur->next)
-				if ((cur->gid == group->gid) && (cur->type == AIM_SSI_TYPE_BUDDY))
-						newlen += aimutil_put16(newdata+newlen, cur->bid);
-		}
-		aim_tlvlist_replace_raw(&group->data, 0x00c8, newlen, newdata);
-
-		free(newdata);
-	}
-
-	return group;
-}
-
-/**
- * Locally add a new item to the given item list.
- *
- * @param list A pointer to a pointer to the current list of items.
- * @param name A null terminated string of the name of the new item, or NULL if the 
- *        item should have no name.
- * @param gid The group ID# you want the new item to have, or 0xFFFF if we should pick something.
- * @param bid The buddy ID# you want the new item to have, or 0xFFFF if we should pick something.
- * @param type The type of the item, 0x0000 for a contact, 0x0001 for a group, etc.
- * @param data The additional data for the new item.
- * @return A pointer to the newly created item.
- */
-static struct aim_ssi_item *aim_ssi_itemlist_add(struct aim_ssi_item **list, const char *name, fu16_t gid, fu16_t bid, fu16_t type, aim_tlvlist_t *data)
-{
-	int i;
-	struct aim_ssi_item *cur, *new;
-
-	if (!list)
-		return NULL;
-
-	if (!(new = (struct aim_ssi_item *)malloc(sizeof(struct aim_ssi_item))))
-		return NULL;
-
-	/* Set the name */
-	if (name) {
-		new->name = (char *)malloc((strlen(name)+1)*sizeof(char));
-		strcpy(new->name, name);
-	} else
-		new->name = NULL;
-
-	/* Set the group ID# and buddy ID# */
-	new->gid = gid;
-	new->bid = bid;
-	if (type == AIM_SSI_TYPE_GROUP) {
-		if ((new->gid == 0xFFFF) && name) {
-			do {
-				new->gid += 0x0001;
-				for (cur=*list, i=0; ((cur) && (!i)); cur=cur->next)
-					if ((cur->type == AIM_SSI_TYPE_GROUP) && (cur->gid == new->gid))
-						i=1;
-			} while (i);
-		}
-	} else {
-		if (new->bid == 0xFFFF) {
-			do {
-				new->bid += 0x0001;
-				for (cur=*list, i=0; ((cur) && (!i)); cur=cur->next)
-					if ((cur->bid == new->bid) && (cur->gid == new->gid))
-						i=1;
-			} while (i);
-		}
-	}
-
-	/* Set the type */
-	new->type = type;
-
-	/* Set the TLV list */
-	new->data = aim_tlvlist_copy(data);
-
-	/* Add the item to the list in the correct numerical position.  Fancy, eh? */
-	if (*list) {
-		if ((new->gid < (*list)->gid) || ((new->gid == (*list)->gid) && (new->bid < (*list)->bid))) {
-			new->next = *list;
-			*list = new;
-		} else {
-			struct aim_ssi_item *prev;
-			for ((prev=*list, cur=(*list)->next); (cur && ((new->gid > cur->gid) || ((new->gid == cur->gid) && (new->bid > cur->bid)))); prev=cur, cur=cur->next);
-			new->next = prev->next;
-			prev->next = new;
-		}
-	} else {
-		new->next = *list;
-		*list = new;
-	}
-
-	return new;
-}
-
-/**
- * Locally delete an item from the given item list.
- *
- * @param list A pointer to a pointer to the current list of items.
- * @param del A pointer to the item you want to remove from the list.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-static int aim_ssi_itemlist_del(struct aim_ssi_item **list, struct aim_ssi_item *del)
-{
-	if (!list || !(*list) || !del)
-		return -EINVAL;
-
-	/* Remove the item from the list */
-	if (*list == del) {
-		*list = (*list)->next;
-	} else {
-		struct aim_ssi_item *cur;
-		for (cur=*list; (cur->next && (cur->next!=del)); cur=cur->next);
-		if (cur->next)
-			cur->next = del->next;
-	}
-
-	/* Free the removed item */
-	free(del->name);
-	aim_tlvlist_free(&del->data);
-	free(del);
-
-	return 0;
-}
-
-/**
- * Compare two items to see if they have the same data.
- *
- * @param cur1 A pointer to a pointer to the first item.
- * @param cur2 A pointer to a pointer to the second item.
- * @return Return 0 if no differences, or a number if there are differences.
- */
-static int aim_ssi_itemlist_cmp(struct aim_ssi_item *cur1, struct aim_ssi_item *cur2)
-{
-	if (!cur1 || !cur2)
-		return 1;
-
-	if (cur1->data && !cur2->data)
-		return 2;
-
-	if (!cur1->data && cur2->data)
-		return 3;
-
-	if ((cur1->data && cur2->data) && (aim_tlvlist_cmp(cur1->data, cur2->data)))
-			return 4;
-
-	if (cur1->name && !cur2->name)
-		return 5;
-
-	if (!cur1->name && cur2->name)
-		return 6;
-
-	if (cur1->name && cur2->name && aim_sncmp(cur1->name, cur2->name))
-		return 7;
-
-	if (cur1->gid != cur2->gid)
-		return 8;
-
-	if (cur1->bid != cur2->bid)
-		return 9;
-
-	if (cur1->type != cur2->type)
-		return 10;
-
-	return 0;
-}
-
-faim_export int aim_ssi_itemlist_valid(struct aim_ssi_item *list, struct aim_ssi_item *item)
-{
-	struct aim_ssi_item *cur;
-	for (cur=list; cur; cur=cur->next)
-		if (cur == item)
-			return 1;
-	return 0;
-}
-
-/**
- * Locally find an item given a group ID# and a buddy ID#.
- *
- * @param list A pointer to the current list of items.
- * @param gid The group ID# of the desired item.
- * @param bid The buddy ID# of the desired item.
- * @return Return a pointer to the item if found, else return NULL;
- */
-faim_export struct aim_ssi_item *aim_ssi_itemlist_find(struct aim_ssi_item *list, fu16_t gid, fu16_t bid)
-{
-	struct aim_ssi_item *cur;
-	for (cur=list; cur; cur=cur->next)
-		if ((cur->gid == gid) && (cur->bid == bid))
-			return cur;
-	return NULL;
-}
-
-/**
- * Locally find an item given a group name, screen name, and type.  If group name 
- * and screen name are null, then just return the first item of the given type.
- *
- * @param list A pointer to the current list of items.
- * @param gn The group name of the desired item.
- * @param bn The buddy name of the desired item.
- * @param type The type of the desired item.
- * @return Return a pointer to the item if found, else return NULL;
- */
-faim_export struct aim_ssi_item *aim_ssi_itemlist_finditem(struct aim_ssi_item *list, const char *gn, const char *sn, fu16_t type)
-{
-	struct aim_ssi_item *cur;
-	if (!list)
-		return NULL;
-
-	if (gn && sn) { /* For finding buddies in groups */
-		for (cur=list; cur; cur=cur->next)
-			if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, sn))) {
-				struct aim_ssi_item *curg;
-				for (curg=list; curg; curg=curg->next)
-					if ((curg->type == AIM_SSI_TYPE_GROUP) && (curg->gid == cur->gid) && (curg->name) && !(aim_sncmp(curg->name, gn)))
-						return cur;
-			}
-
-	} else if (gn) { /* For finding groups */
-		for (cur=list; cur; cur=cur->next) {
-			if ((cur->type == type) && (cur->bid == 0x0000) && (cur->name) && !(aim_sncmp(cur->name, gn))) {
-				return cur;
-			}
-		}
-
-	} else if (sn) { /* For finding permits, denies, and ignores */
-		for (cur=list; cur; cur=cur->next) {
-			if ((cur->type == type) && (cur->name) && !(aim_sncmp(cur->name, sn))) {
-				return cur;
-			}
-		}
-
-	/* For stuff without names--permit deny setting, visibility mask, etc. */
-	} else for (cur=list; cur; cur=cur->next) {
-		if ((cur->type == type) && (!cur->name))
-			return cur;
-	}
-
-	return NULL;
-}
-
-/**
- * Check if the given buddy exists in any group in the buddy list.
- *
- * @param list A pointer to the current list of items.
- * @param sn The group name of the desired item.
- * @return Return a pointer to the name of the item if found, else return NULL;
- */
-faim_export struct aim_ssi_item *aim_ssi_itemlist_exists(struct aim_ssi_item *list, const char *sn)
-{
-	struct aim_ssi_item *cur;
-	if (!list || !sn)
-		return NULL;
-	for (cur=list; cur; cur=cur->next)
-		if ((cur->type == AIM_SSI_TYPE_BUDDY) && (cur->name) && (!aim_sncmp(cur->name, sn)))
-			return cur;
-	return NULL;
-}
-
-/**
- * Locally find the parent item of the given buddy name.
- *
- * @param list A pointer to the current list of items.
- * @param bn The buddy name of the desired item.
- * @return Return a pointer to the name of the item if found, else return NULL;
- */
-faim_export char *aim_ssi_itemlist_findparentname(struct aim_ssi_item *list, const char *sn)
-{
-	struct aim_ssi_item *cur, *curg;
-	if (!list || !sn)
-		return NULL;
-	if (!(cur = aim_ssi_itemlist_exists(list, sn)))
-		return NULL;
-	if (!(curg = aim_ssi_itemlist_find(list, cur->gid, 0x0000)))
-		return NULL;
-	return curg->name;
-}
-
-/**
- * Locally find the permit/deny setting item, and return the setting.
- *
- * @param list A pointer to the current list of items.
- * @return Return the current SSI permit deny setting, or 0 if no setting was found.
- */
-faim_export int aim_ssi_getpermdeny(struct aim_ssi_item *list)
-{
-	struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PDINFO);
-	if (cur) {
-		aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x00ca, 1);
-		if (tlv && tlv->value)
-			return aimutil_get8(tlv->value);
-	}
-	return 0;
-}
-
-/**
- * Locally find the presence flag item, and return the setting.  The returned setting is a 
- * bitmask of the user flags that you are visible to.  See the AIM_FLAG_* #defines 
- * in aim.h
- *
- * @param list A pointer to the current list of items.
- * @return Return the current visibility mask.
- */
-faim_export fu32_t aim_ssi_getpresence(struct aim_ssi_item *list)
-{
-	struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS);
-	if (cur) {
-		aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x00c9, 1);
-		if (tlv && tlv->length)
-			return aimutil_get32(tlv->value);
-	}
-	return 0xFFFFFFFF;
-}
-
-/**
- * Locally find the alias of the given buddy.
- *
- * @param list A pointer to the current list of items.
- * @param gn The group of the buddy.
- * @param sn The name of the buddy.
- * @return A pointer to a NULL terminated string that is the buddy's 
- *         alias, or NULL if the buddy has no alias.  You should free
- *         this returned value!
- */
-faim_export char *aim_ssi_getalias(struct aim_ssi_item *list, const char *gn, const char *sn)
-{
-	struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY);
-	if (cur) {
-		aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x0131, 1);
-		if (tlv && tlv->length) {
-			char *alias = (char *)malloc((tlv->length+1)*sizeof(char));
-			strncpy(alias, tlv->value, tlv->length);
-			alias[tlv->length] = 0;
-			return alias;
-		}
-	}
-	return NULL;
-}
-
-/**
- * Locally find the comment of the given buddy.
- *
- * @param list A pointer to the current list of items.
- * @param gn The group of the buddy.
- * @param sn The name of the buddy.
- * @return A pointer to a NULL terminated string that is the buddy's 
- *         comment, or NULL if the buddy has no comment.  You should free
- *         this returned value!
- */
-faim_export char *aim_ssi_getcomment(struct aim_ssi_item *list, const char *gn, const char *sn)
-{
-	struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY);
-	if (cur) {
-		aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x013c, 1);
-		if (tlv && tlv->length) {
-			char *alias = (char *)malloc((tlv->length+1)*sizeof(char));
-			strncpy(alias, tlv->value, tlv->length);
-			alias[tlv->length] = 0;
-			return alias;
-		}
-	}
-	return NULL;
-}
-
-/**
- * Locally find if you are waiting for authorization for a buddy.
- *
- * @param list A pointer to the current list of items.
- * @param gn The group of the buddy.
- * @param sn The name of the buddy.
- * @return A pointer to a NULL terminated string that is the buddies 
- *         alias, or NULL if the buddy has no alias.  You should free
- *         this returned value!
- */
-faim_export int aim_ssi_waitingforauth(struct aim_ssi_item *list, const char *gn, const char *sn)
-{
-	struct aim_ssi_item *cur = aim_ssi_itemlist_finditem(list, gn, sn, AIM_SSI_TYPE_BUDDY);
-	if (cur) {
-		if (aim_tlv_gettlv(cur->data, 0x0066, 1))
-			return 1;
-	}
-	return 0;
-}
-
-/**
- * If there are changes, then create temporary items and 
- * call addmoddel.
- *
- * @param sess The oscar session.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-static int aim_ssi_sync(aim_session_t *sess)
-{
-	struct aim_ssi_item *cur1, *cur2;
-	struct aim_ssi_tmp *cur, *new;
-
-	if (!sess)
-		return -EINVAL;
-
-	/* If we're waiting for an ack, we shouldn't do anything else */
-	if (sess->ssi.waiting_for_ack)
-		return 0;
-
-	/*
-	 * Compare the 2 lists and create an aim_ssi_tmp for each difference.  
-	 * We should only send either additions, modifications, or deletions 
-	 * before waiting for an acknowledgement.  So first do deletions, then 
-	 * additions, then modifications.  Also, both the official and the local 
-	 * list should be in ascending numerical order for the group ID#s and the 
-	 * buddy ID#s, which makes things more efficient.  I think.
-	 */
-
-	/* Additions */
-	if (!sess->ssi.pending) {
-		for (cur1=sess->ssi.local; cur1; cur1=cur1->next) {
-			if (!aim_ssi_itemlist_find(sess->ssi.official, cur1->gid, cur1->bid)) {
-				new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp));
-				new->action = AIM_CB_SSI_ADD;
-				new->ack = 0xffff;
-				new->name = NULL;
-				new->item = cur1;
-				new->next = NULL;
-				if (sess->ssi.pending) {
-					for (cur=sess->ssi.pending; cur->next; cur=cur->next);
-					cur->next = new;
-				} else
-					sess->ssi.pending = new;
-			}
-		}
-	}
-
-	/* Deletions */
-	if (!sess->ssi.pending) {
-		for (cur1=sess->ssi.official; cur1; cur1=cur1->next) {
-			if (!aim_ssi_itemlist_find(sess->ssi.local, cur1->gid, cur1->bid)) {
-				new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp));
-				new->action = AIM_CB_SSI_DEL;
-				new->ack = 0xffff;
-				new->name = NULL;
-				new->item = cur1;
-				new->next = NULL;
-				if (sess->ssi.pending) {
-					for (cur=sess->ssi.pending; cur->next; cur=cur->next);
-					cur->next = new;
-				} else
-					sess->ssi.pending = new;
-			}
-		}
-	}
-
-	/* Modifications */
-	if (!sess->ssi.pending) {
-		for (cur1=sess->ssi.local; cur1; cur1=cur1->next) {
-			cur2 = aim_ssi_itemlist_find(sess->ssi.official, cur1->gid, cur1->bid);
-			if (cur2 && (aim_ssi_itemlist_cmp(cur1, cur2))) {
-				new = (struct aim_ssi_tmp *)malloc(sizeof(struct aim_ssi_tmp));
-				new->action = AIM_CB_SSI_MOD;
-				new->ack = 0xffff;
-				new->name = NULL;
-				new->item = cur1;
-				new->next = NULL;
-				if (sess->ssi.pending) {
-					for (cur=sess->ssi.pending; cur->next; cur=cur->next);
-					cur->next = new;
-				} else
-					sess->ssi.pending = new;
-			}
-		}
-	}
-
-	/* We're out of stuff to do, so tell the AIM servers we're done and exit */
-	if (!sess->ssi.pending) {
-		aim_ssi_modend(sess);
-		return 0;
-	}
-
-	/* Make sure we don't send anything else between now 
-	 * and when we receive the ack for the following operation */
-	sess->ssi.waiting_for_ack = 1;
-
-	/* Now go mail off our data and wait 4 to 6 weeks */
-	aim_ssi_addmoddel(sess);
-
-	return 0;
-}
-
-/**
- * Free all SSI data.
- *
- * This doesn't remove it from the server, that's different.
- *
- * @param sess The oscar session.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-static int aim_ssi_freelist(aim_session_t *sess)
-{
-	struct aim_ssi_item *cur, *del;
-	struct aim_ssi_tmp *curtmp, *deltmp;
-
-	cur = sess->ssi.official;
-	while (cur) {
-		del = cur;
-		cur = cur->next;
-		free(del->name);
-		aim_tlvlist_free(&del->data);
-		free(del);
-	}
-
-	cur = sess->ssi.local;
-	while (cur) {
-		del = cur;
-		cur = cur->next;
-		free(del->name);
-		aim_tlvlist_free(&del->data);
-		free(del);
-	}
-
-	curtmp = sess->ssi.pending;
-	while (curtmp) {
-		deltmp = curtmp;
-		curtmp = curtmp->next;
-		free(deltmp);
-	}
-
-	sess->ssi.numitems = 0;
-	sess->ssi.official = NULL;
-	sess->ssi.local = NULL;
-	sess->ssi.pending = NULL;
-	sess->ssi.timestamp = (time_t)0;
-
-	return 0;
-}
-
-/**
- * Delete all SSI data.
- *
- * @param sess The oscar session.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_deletelist(aim_session_t *sess)
-{
-	struct aim_ssi_item *cur, *del;
-
-	if (!sess)
-		return -EINVAL;
-
-	/* Free the local list */
-	cur = sess->ssi.local;
-	while (cur) {
-		del = cur;
-		cur = cur->next;
-		free(del->name);
-		aim_tlvlist_free(&del->data);
-		free(del);
-	}
-	sess->ssi.local = NULL;
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-
-	return 0;
-}
-
-/**
- * This "cleans" the ssi list.  It does the following:
- * 1) Makes sure all buddies, permits, and denies have names.
- * 2) Makes sure that all buddies are in a group that exist.
- * 3) Deletes any empty groups
- *
- * @param sess The oscar session.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_cleanlist(aim_session_t *sess)
-{
-	struct aim_ssi_item *cur, *next;
-
-	if (!sess)
-		return -EINVAL;
-
-	/* Delete any buddies, permits, or denies with empty names. */
-	/* If there are any buddies directly in the master group, add them to a real group. */
-	/* DESTROY any buddies that are directly in the master group. */
-	/* Do the same for buddies that are in a non-existant group. */
-	/* This will kind of mess up if you hit the item limit, but this function isn't too critical */
-	cur = sess->ssi.local;
-	while (cur) {
-		next = cur->next;
-		if (!cur->name) {
-			if (cur->type == AIM_SSI_TYPE_BUDDY)
-				aim_ssi_delbuddy(sess, NULL, NULL);
-			else if (cur->type == AIM_SSI_TYPE_PERMIT)
-				aim_ssi_delpermit(sess, NULL);
-			else if (cur->type == AIM_SSI_TYPE_DENY)
-				aim_ssi_deldeny(sess, NULL);
-		} else if ((cur->type == AIM_SSI_TYPE_BUDDY) && ((cur->gid == 0x0000) || (!aim_ssi_itemlist_find(sess->ssi.local, cur->gid, 0x0000)))) {
-			aim_ssi_addbuddy(sess, cur->name, "orphans", NULL, NULL, NULL, 0);
-			aim_ssi_delbuddy(sess, cur->name, NULL);
-		}
-		cur = next;
-	}
-
-	/* Check if there are empty groups and delete them */
-	cur = sess->ssi.local;
-	while (cur) {
-		next = cur->next;
-		if (cur->type == AIM_SSI_TYPE_GROUP) {
-			aim_tlv_t *tlv = aim_tlv_gettlv(cur->data, 0x00c8, 1);
-			if (!tlv || !tlv->length)
-				aim_ssi_itemlist_del(&sess->ssi.local, cur);
-		}
-		cur = next;
-	}
-
-	/* Check if the master group is empty */
-	if ((cur = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000)) && (!cur->data))
-		aim_ssi_itemlist_del(&sess->ssi.local, cur);
-
-	return 0;
-}
-
-/**
- * Add a buddy to the list.
- *
- * @param sess The oscar session.
- * @param name The name of the item.
- * @param group The group of the item.
- * @param alias The alias/nickname of the item, or NULL.
- * @param comment The buddy comment for the item, or NULL.
- * @param smsnum The locally assigned SMS number, or NULL.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_addbuddy(aim_session_t *sess, const char *name, const char *group, const char *alias, const char *comment, const char *smsnum, int needauth)
-{
-	struct aim_ssi_item *parent;
-	aim_tlvlist_t *data = NULL;
-
-	if (!sess || !name || !group)
-		return -EINVAL;
-
-	/* Find the parent */
-	if (!(parent = aim_ssi_itemlist_finditem(sess->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP))) {
-		/* Find the parent's parent (the master group) */
-		if (!(parent = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000)))
-			if (!(parent = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0x0000, AIM_SSI_TYPE_GROUP, NULL)))
-				return -ENOMEM;
-		/* Add the parent */
-		if (!(parent = aim_ssi_itemlist_add(&sess->ssi.local, group, 0xFFFF, 0x0000, AIM_SSI_TYPE_GROUP, NULL)))
-			return -ENOMEM;
-
-		/* Modify the parent's parent (the master group) */
-		aim_ssi_itemlist_rebuildgroup(sess->ssi.local, NULL);
-	}
-
-	/* Create a TLV list for the new buddy */
-	if (needauth)
-		aim_tlvlist_add_noval(&data, 0x0066);
-	if (alias)
-		aim_tlvlist_add_raw(&data, 0x0131, strlen(alias), alias);
-	if (smsnum)
-		aim_tlvlist_add_raw(&data, 0x013a, strlen(smsnum), smsnum);
-	if (comment)
-		aim_tlvlist_add_raw(&data, 0x013c, strlen(comment), comment);
-
-	/* Add that bad boy */
-	aim_ssi_itemlist_add(&sess->ssi.local, name, parent->gid, 0xFFFF, AIM_SSI_TYPE_BUDDY, data);
-	aim_tlvlist_free(&data);
-
-	/* Modify the parent group */
-	aim_ssi_itemlist_rebuildgroup(sess->ssi.local, group);
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-
-	return 0;
-}
-
-/**
- * Add a permit buddy to the list.
- *
- * @param sess The oscar session.
- * @param name The name of the item..
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_addpermit(aim_session_t *sess, const char *name)
-{
-
-	if (!sess || !name)
-		return -EINVAL;
-
-	/* Add that bad boy */
-	aim_ssi_itemlist_add(&sess->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_PERMIT, NULL);
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-
-	return 0;
-}
-
-/**
- * Add a deny buddy to the list.
- *
- * @param sess The oscar session.
- * @param name The name of the item..
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_adddeny(aim_session_t *sess, const char *name)
-{
-
-	if (!sess || !name)
-		return -EINVAL;
-
-	/* Add that bad boy */
-	aim_ssi_itemlist_add(&sess->ssi.local, name, 0x0000, 0xFFFF, AIM_SSI_TYPE_DENY, NULL);
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-
-	return 0;
-}
-
-/**
- * Deletes a buddy from the list.
- *
- * @param sess The oscar session.
- * @param name The name of the item, or NULL.
- * @param group The group of the item, or NULL.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_delbuddy(aim_session_t *sess, const char *name, const char *group)
-{
-	struct aim_ssi_item *del;
-
-	if (!sess)
-		return -EINVAL;
-
-	/* Find the buddy */
-	if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, group, name, AIM_SSI_TYPE_BUDDY)))
-		return -EINVAL;
-
-	/* Remove the item from the list */
-	aim_ssi_itemlist_del(&sess->ssi.local, del);
-
-	/* Modify the parent group */
-	aim_ssi_itemlist_rebuildgroup(sess->ssi.local, group);
-
-	/* Check if we should delete the parent group */
-	if ((del = aim_ssi_itemlist_finditem(sess->ssi.local, group, NULL, AIM_SSI_TYPE_GROUP)) && (!del->data)) {
-		aim_ssi_itemlist_del(&sess->ssi.local, del);
-
-		/* Modify the parent group */
-		aim_ssi_itemlist_rebuildgroup(sess->ssi.local, NULL);
-
-		/* Check if we should delete the parent's parent (the master group) */
-		if ((del = aim_ssi_itemlist_find(sess->ssi.local, 0x0000, 0x0000)) && (!del->data)) {
-			aim_ssi_itemlist_del(&sess->ssi.local, del);
-		}
-	}
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-
-	return 0;
-}
-
-/**
- * Deletes a permit buddy from the list.
- *
- * @param sess The oscar session.
- * @param name The name of the item, or NULL.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_delpermit(aim_session_t *sess, const char *name)
-{
-	struct aim_ssi_item *del;
-
-	if (!sess)
-		return -EINVAL;
-
-	/* Find the item */
-	if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, name, AIM_SSI_TYPE_PERMIT)))
-		return -EINVAL;
-
-	/* Remove the item from the list */
-	aim_ssi_itemlist_del(&sess->ssi.local, del);
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-
-	return 0;
-}
-
-/**
- * Deletes a deny buddy from the list.
- *
- * @param sess The oscar session.
- * @param name The name of the item, or NULL.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_deldeny(aim_session_t *sess, const char *name)
-{
-	struct aim_ssi_item *del;
-
-	if (!sess)
-		return -EINVAL;
-
-	/* Find the item */
-	if (!(del = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, name, AIM_SSI_TYPE_DENY)))
-		return -EINVAL;
-
-	/* Remove the item from the list */
-	aim_ssi_itemlist_del(&sess->ssi.local, del);
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-
-	return 0;
-}
-
-/**
- * Move a buddy from one group to another group.  This basically just deletes the 
- * buddy and re-adds it.
- *
- * @param sess The oscar session.
- * @param oldgn The group that the buddy is currently in.
- * @param newgn The group that the buddy should be moved in to.
- * @param sn The name of the buddy to be moved.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_movebuddy(aim_session_t *sess, const char *oldgn, const char *newgn, const char *sn)
-{
-	aim_ssi_addbuddy(sess, sn, newgn, aim_ssi_getalias(sess->ssi.local, oldgn, sn), NULL, NULL, aim_ssi_waitingforauth(sess->ssi.local, oldgn, sn));
-	aim_ssi_delbuddy(sess, sn, oldgn);
-	return 0;
-}
-
-/**
- * Change the alias stored on the server for a given buddy.
- *
- * @param sess The oscar session.
- * @param gn The group that the buddy is currently in.
- * @param sn The screen name of the buddy.
- * @param alias The new alias for the buddy, or NULL if you want to remove 
- *        a buddy's comment.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_aliasbuddy(aim_session_t *sess, const char *gn, const char *sn, const char *alias)
-{
-	struct aim_ssi_item *tmp;
-
-	if (!sess || !gn || !sn)
-		return -EINVAL;
-
-	if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, gn, sn, AIM_SSI_TYPE_BUDDY)))
-		return -EINVAL;
-
-	/* Either add or remove the 0x0131 TLV from the TLV chain */
-	if ((alias != NULL) && (strlen(alias) > 0))
-		aim_tlvlist_replace_raw(&tmp->data, 0x0131, strlen(alias), alias);
-	else
-		aim_tlvlist_remove(&tmp->data, 0x0131);
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-
-	return 0;
-}
-
-/**
- * Change the comment stored on the server for a given buddy.
- *
- * @param sess The oscar session.
- * @param gn The group that the buddy is currently in.
- * @param sn The screen name of the buddy.
- * @param alias The new comment for the buddy, or NULL if you want to remove 
- *        a buddy's comment.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_editcomment(aim_session_t *sess, const char *gn, const char *sn, const char *comment)
-{
-	struct aim_ssi_item *tmp;
-
-	if (!sess || !gn || !sn)
-		return -EINVAL;
-
-	if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, gn, sn, AIM_SSI_TYPE_BUDDY)))
-		return -EINVAL;
-
-	/* Either add or remove the 0x0131 TLV from the TLV chain */
-	if ((comment != NULL) && (strlen(comment) > 0))
-		aim_tlvlist_replace_raw(&tmp->data, 0x013c, strlen(comment), comment);
-	else
-		aim_tlvlist_remove(&tmp->data, 0x013c);
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-
-	return 0;
-}
-
-/**
- * Rename a group.
- *
- * @param sess The oscar session.
- * @param oldgn The old group name.
- * @param newgn The new group name.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_rename_group(aim_session_t *sess, const char *oldgn, const char *newgn)
-{
-	struct aim_ssi_item *group;
-
-	if (!sess || !oldgn || !newgn)
-		return -EINVAL;
-
-	if (!(group = aim_ssi_itemlist_finditem(sess->ssi.local, oldgn, NULL, AIM_SSI_TYPE_GROUP)))
-		return -EINVAL;
-
-	free(group->name);
-	group->name = (char *)malloc((strlen(newgn)+1)*sizeof(char));
-	strcpy(group->name, newgn);
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-
-	return 0;
-}
-
-/**
- * Stores your permit/deny setting on the server, and starts using it.
- *
- * @param sess The oscar session.
- * @param permdeny Your permit/deny setting.  Can be one of the following:
- *        1 - Allow all users
- *        2 - Block all users
- *        3 - Allow only the users below
- *        4 - Block only the users below
- *        5 - Allow only users on my buddy list
- * @param vismask A bitmask of the class of users to whom you want to be 
- *        visible.  See the AIM_FLAG_BLEH #defines in aim.h
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_setpermdeny(aim_session_t *sess, fu8_t permdeny, fu32_t vismask)
-{
-	struct aim_ssi_item *tmp;
-
-	if (!sess)
-		return -EINVAL;
-
-	/* Find the PDINFO item, or add it if it does not exist */
-	if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, NULL, AIM_SSI_TYPE_PDINFO)))
-		tmp = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PDINFO, NULL);
-
-	/* Need to add the 0x00ca TLV to the TLV chain */
-	aim_tlvlist_replace_8(&tmp->data, 0x00ca, permdeny);
-
-	/* Need to add the 0x00cb TLV to the TLV chain */
-	aim_tlvlist_replace_32(&tmp->data, 0x00cb, vismask);
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-
-	return 0;
-}
-
-/**
- * Set buddy icon information
- *
- * @param sess The oscar session.
- * @param iconcsum The MD5 checksum of the icon you are using.
- * @param iconcsumlen Length of the MD5 checksum given above.  Should be 0x10 bytes.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_seticon(aim_session_t *sess, fu8_t *iconsum, fu16_t iconsumlen)
-{
-	struct aim_ssi_item *tmp;
-	fu8_t *csumdata;
-
-	if (!sess || !iconsum || !iconsumlen)
-		return -EINVAL;
-
-	/* Find the ICONINFO item, or add it if it does not exist */
-	if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO))) {
-		tmp = aim_ssi_itemlist_add(&sess->ssi.local, "1", 0x0000, 0x51F4, AIM_SSI_TYPE_ICONINFO, NULL);
-	}
-
-	/* Need to add the 0x00d5 TLV to the TLV chain */
-	if (!(csumdata = (fu8_t *)malloc((iconsumlen+2)*sizeof(fu8_t))))
-		return -ENOMEM;
-	csumdata[0] = 0x00;
-	csumdata[1] = 0x10;
-	memcpy(&csumdata[2], iconsum, iconsumlen);
-	aim_tlvlist_replace_raw(&tmp->data, 0x00d5, (iconsumlen+2) * sizeof(fu8_t), csumdata);
-	free(csumdata);
-
-	/* Need to add the 0x0131 TLV to the TLV chain, used to cache the icon */
-	aim_tlvlist_replace_noval(&tmp->data, 0x0131);
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-	return 0;
-}
-
-/**
- * Remove a reference to a server stored buddy icon.  This will make your 
- * icon stop showing up to other people.
- *
- * @param sess The oscar session.
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_delicon(aim_session_t *sess)
-{
-	struct aim_ssi_item *tmp;
-
-	if (!sess)
-		return -EINVAL;
-
-	/* Find the ICONINFO item and delete it if it exists*/
-	if ((tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, "1", AIM_SSI_TYPE_ICONINFO)))
-		aim_ssi_itemlist_del(&sess->ssi.local, tmp);
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-	return 0;
-}
-
-/**
- * Stores your setting for whether you should show up as idle or not.
- *
- * @param sess The oscar session.
- * @param presence I think it's a bitmask, but I only know what one of the bits is:
- *        0x00000002 - Hide wireless?
- *        0x00000400 - Allow others to see your idle time
- * @return Return 0 if no errors, otherwise return the error number.
- */
-faim_export int aim_ssi_setpresence(aim_session_t *sess, fu32_t presence) {
-	struct aim_ssi_item *tmp;
-
-	if (!sess)
-		return -EINVAL;
-
-	/* Find the PRESENCEPREFS item, or add it if it does not exist */
-	if (!(tmp = aim_ssi_itemlist_finditem(sess->ssi.local, NULL, NULL, AIM_SSI_TYPE_PRESENCEPREFS)))
-		tmp = aim_ssi_itemlist_add(&sess->ssi.local, NULL, 0x0000, 0xFFFF, AIM_SSI_TYPE_PRESENCEPREFS, NULL);
-
-	/* Need to add the x00c9 TLV to the TLV chain */
-	aim_tlvlist_replace_32(&tmp->data, 0x00c9, presence);
-
-	/* Sync our local list with the server list */
-	aim_ssi_sync(sess);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0002 - Request SSI Rights.
- */
-faim_export int aim_ssi_reqrights(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))
-		return -EINVAL;
-
-	return aim_genericreq_n_snacid(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_REQRIGHTS);
-}
-
-/*
- * Subtype 0x0003 - SSI Rights Information.
- */
-static int parserights(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0, i;
-	aim_rxcallback_t userfunc;
-	aim_tlvlist_t *tlvlist;
-	aim_tlv_t *tlv;
-	aim_bstream_t bstream;
-	fu16_t *maxitems;
-
-	/* This SNAC is made up of a bunch of TLVs */
-	tlvlist = aim_tlvlist_read(bs);
-
-	/* TLV 0x0004 contains the maximum number of each item */
-	if (!(tlv = aim_tlv_gettlv(tlvlist, 0x0004, 1))) {
-		aim_tlvlist_free(&tlvlist);
-		return 0;
-	}
-
-	aim_bstream_init(&bstream, tlv->value, tlv->length);
-
-	if (!(maxitems = (fu16_t *)malloc((tlv->length/2)*sizeof(fu16_t)))) {
-		aim_tlvlist_free(&tlvlist);
-		return 0;
-	}
-
-	for (i=0; i<(tlv->length/2); i++)
-		maxitems[i] = aimbs_get16(&bstream);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, tlv->length/2, maxitems);
-
-	aim_tlvlist_free(&tlvlist);
-	free(maxitems);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0004 - Request SSI Data when you don't have a timestamp and 
- * revision number.
- * 
- */
-faim_export int aim_ssi_reqdata(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))
-		return -EINVAL;
-
-	/* Free any current data, just in case */
-	aim_ssi_freelist(sess);
-
-	return aim_genericreq_n_snacid(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_REQDATA);
-}
-
-/*
- * Subtype 0x0005 - Request SSI Data when you have a timestamp and revision 
- * number.
- *
- * The data will only be sent if it is newer than the posted local
- * timestamp and revision.
- * 
- * Note that the client should never increment the revision, only the server.
- * 
- */
-faim_export int aim_ssi_reqifchanged(aim_session_t *sess, time_t timestamp, fu16_t numitems)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+4+2)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_REQIFCHANGED, 0x0000, NULL, 0);
-
-	aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_REQIFCHANGED, 0x0000, snacid);
-	aimbs_put32(&fr->data, timestamp);
-	aimbs_put16(&fr->data, numitems);
-
-	aim_tx_enqueue(sess, fr);
-
-	/* Free any current data, just in case */
-	aim_ssi_freelist(sess);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0006 - SSI Data.
- */
-static int parsedata(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu8_t fmtver; /* guess */
-	fu16_t namelen, gid, bid, type;
-	char *name;
-	aim_tlvlist_t *data;
-
-	fmtver = aimbs_get8(bs); /* Version of ssi data.  Should be 0x00 */
-	sess->ssi.numitems += aimbs_get16(bs); /* # of items in this SSI SNAC */
-
-	/* Read in the list */
-	while (aim_bstream_empty(bs) > 4) { /* last four bytes are timestamp */
-		if ((namelen = aimbs_get16(bs)))
-			name = aimbs_getstr(bs, namelen);
-		else
-			name = NULL;
-		gid = aimbs_get16(bs);
-		bid = aimbs_get16(bs);
-		type = aimbs_get16(bs);
-		data = aim_tlvlist_readlen(bs, aimbs_get16(bs));
-		aim_ssi_itemlist_add(&sess->ssi.official, name, gid, bid, type, data);
-		free(name);
-		aim_tlvlist_free(&data);
-	}
-
-	/* Read in the timestamp */
-	sess->ssi.timestamp = aimbs_get32(bs);
-
-	if (!(snac->flags & 0x0001)) {
-		/* Make a copy of the list */
-		struct aim_ssi_item *cur;
-		for (cur=sess->ssi.official; cur; cur=cur->next)
-			aim_ssi_itemlist_add(&sess->ssi.local, cur->name, cur->gid, cur->bid, cur->type, cur->data);
-
-		sess->ssi.received_data = 1;
-
-		if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-			ret = userfunc(sess, rx, fmtver, sess->ssi.numitems, sess->ssi.official, sess->ssi.timestamp);
-	}
-
-	return ret;
-}
-
-/*
- * Subtype 0x0007 - SSI Activate Data.
- *
- * Should be sent after receiving 13/6 or 13/f to tell the server you
- * are ready to begin using the list.  It will promptly give you the
- * presence information for everyone in your list and put your permit/deny
- * settings into effect.
- * 
- */
-faim_export int aim_ssi_enable(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))
-		return -EINVAL;
-
-	return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, 0x0007);
-}
-
-/*
- * Subtype 0x0008/0x0009/0x000a - SSI Add/Mod/Del Item(s).
- *
- * Sends the SNAC to add, modify, or delete an item from the server-stored
- * information.  These 3 SNACs all have an identical structure.  The only
- * difference is the subtype that is set for the SNAC.
- * 
- */
-faim_export int aim_ssi_addmoddel(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-	int snaclen;
-	struct aim_ssi_tmp *cur;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sess->ssi.pending || !sess->ssi.pending->item)
-		return -EINVAL;
-
-	/* Calculate total SNAC size */
-	snaclen = 10; /* For family, subtype, flags, and SNAC ID */
-	for (cur=sess->ssi.pending; cur; cur=cur->next) {
-		snaclen += 10; /* For length, GID, BID, type, and length */
-		if (cur->item->name)
-			snaclen += strlen(cur->item->name);
-		if (cur->item->data)
-			snaclen += aim_tlvlist_size(&cur->item->data);
-	}
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, snaclen)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, sess->ssi.pending->action, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, AIM_CB_FAM_SSI, sess->ssi.pending->action, 0x0000, snacid);
-
-	for (cur=sess->ssi.pending; cur; cur=cur->next) {
-		aimbs_put16(&fr->data, cur->item->name ? strlen(cur->item->name) : 0);
-		if (cur->item->name)
-			aimbs_putraw(&fr->data, cur->item->name, strlen(cur->item->name));
-		aimbs_put16(&fr->data, cur->item->gid);
-		aimbs_put16(&fr->data, cur->item->bid);
-		aimbs_put16(&fr->data, cur->item->type);
-		aimbs_put16(&fr->data, cur->item->data ? aim_tlvlist_size(&cur->item->data) : 0);
-		if (cur->item->data)
-			aim_tlvlist_write(&fr->data, &cur->item->data);
-	}
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0008 - Incoming SSI add.
- *
- * XXX - It would probably be good for the client to actually do something when it gets this.
- */
-static int parseadd(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	char *name;
-	fu16_t len, gid, bid, type;
-	aim_tlvlist_t *data;
-
-	while (aim_bstream_empty(bs)) {
-		if ((len = aimbs_get16(bs)))
-			name = aimbs_getstr(bs, len);
-		else
-			name = NULL;
-		gid = aimbs_get16(bs);
-		bid = aimbs_get16(bs);
-		type = aimbs_get16(bs);
-		if ((len = aimbs_get16(bs)))
-			data = aim_tlvlist_readlen(bs, len);
-		else
-			data = NULL;
-
-		aim_ssi_itemlist_add(&sess->ssi.local, name, gid, bid, type, data);
-		aim_ssi_itemlist_add(&sess->ssi.official, name, gid, bid, type, data);
-		aim_tlvlist_free(&data);
-
-		if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-			ret = userfunc(sess, rx);
-
-		free(name);
-	}
-
-	return ret;
-}
-
-/*
- * Subtype 0x0009 - Incoming SSI mod.
- *
- * XXX - It would probably be good for the client to actually do something when it gets this.
- */
-static int parsemod(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	char *name;
-	fu16_t len, gid, bid, type;
-	aim_tlvlist_t *data;
-	struct aim_ssi_item *item;
-
-	while (aim_bstream_empty(bs)) {
-		if ((len = aimbs_get16(bs)))
-			name = aimbs_getstr(bs, len);
-		else
-			name = NULL;
-		gid = aimbs_get16(bs);
-		bid = aimbs_get16(bs);
-		type = aimbs_get16(bs);
-		if ((len = aimbs_get16(bs)))
-			data = aim_tlvlist_readlen(bs, len);
-		else
-			data = NULL;
-
-		/* Replace the 2 local items with the given one */
-		if ((item = aim_ssi_itemlist_find(sess->ssi.local, gid, bid))) {
-			item->type = type;
-			free(item->name);
-			if (name) {
-				item->name = (char *)malloc((strlen(name)+1)*sizeof(char));
-				strcpy(item->name, name);
-			} else
-				item->name = NULL;
-			aim_tlvlist_free(&item->data);
-			item->data = aim_tlvlist_copy(data);
-		}
-
-		if ((item = aim_ssi_itemlist_find(sess->ssi.official, gid, bid))) {
-			item->type = type;
-			free(item->name);
-			if (name) {
-				item->name = (char *)malloc((strlen(name)+1)*sizeof(char));
-				strcpy(item->name, name);
-			} else
-				item->name = NULL;
-			aim_tlvlist_free(&item->data);
-			item->data = aim_tlvlist_copy(data);
-		}
-
-		if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-			ret = userfunc(sess, rx);
-
-		free(name);
-		aim_tlvlist_free(&data);
-	}
-
-	return ret;
-}
-
-/*
- * Subtype 0x000a - Incoming SSI del.
- *
- * XXX - It would probably be good for the client to actually do something when it gets this.
- */
-static int parsedel(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t gid, bid;
-	struct aim_ssi_item *del;
-
-	while (aim_bstream_empty(bs)) {
-		aim_bstream_advance(bs, aimbs_get16(bs));
-		gid = aimbs_get16(bs);
-		bid = aimbs_get16(bs);
-		aimbs_get16(bs);
-		aim_bstream_advance(bs, aimbs_get16(bs));
-
-		if ((del = aim_ssi_itemlist_find(sess->ssi.local, gid, bid)))
-			aim_ssi_itemlist_del(&sess->ssi.local, del);
-		if ((del = aim_ssi_itemlist_find(sess->ssi.official, gid, bid)))
-			aim_ssi_itemlist_del(&sess->ssi.official, del);
-
-		if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-			ret = userfunc(sess, rx);
-	}
-
-	return ret;
-}
-
-/*
- * Subtype 0x000e - SSI Add/Mod/Del Ack.
- *
- * Response to add, modify, or delete SNAC (sent with aim_ssi_addmoddel).
- *
- */
-static int parseack(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	struct aim_ssi_tmp *cur, *del;
-
-	/* Read in the success/failure flags from the ack SNAC */
-	cur = sess->ssi.pending;
-	while (cur && (aim_bstream_empty(bs)>0)) {
-		cur->ack = aimbs_get16(bs);
-		cur = cur->next;
-	}
-
-	/*
-	 * If outcome is 0, then add the item to the item list, or replace the other item, 
-	 * or remove the old item.  If outcome is non-zero, then remove the item from the 
-	 * local list, or unmodify it, or add it.
-	 */
-	for (cur=sess->ssi.pending; (cur && (cur->ack != 0xffff)); cur=cur->next) {
-	if (cur->item) {
-		if (cur->ack) {
-			/* Our action was unsuccessful, so change the local list back to how it was */
-			if (cur->action == AIM_CB_SSI_ADD) {
-				/* Remove the item from the local list */
-				/* Make sure cur->item is still valid memory */
-				if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) {
-					if (cur->item->name) {
-						cur->name = (char *)malloc((strlen(cur->item->name)+1)*sizeof(char));
-						strcpy(cur->name, cur->item->name);
-					}
-					aim_ssi_itemlist_del(&sess->ssi.local, cur->item);
-				}
-				cur->item = NULL;
-
-			} else if (cur->action == AIM_CB_SSI_MOD) {
-				/* Replace the local item with the item from the official list */
-				if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) {
-					struct aim_ssi_item *cur1;
-					if ((cur1 = aim_ssi_itemlist_find(sess->ssi.official, cur->item->gid, cur->item->bid))) {
-						free(cur->item->name);
-						if (cur1->name) {
-							cur->item->name = (char *)malloc((strlen(cur1->name)+1)*sizeof(char));
-							strcpy(cur->item->name, cur1->name);
-						} else
-							cur->item->name = NULL;
-						aim_tlvlist_free(&cur->item->data);
-						cur->item->data = aim_tlvlist_copy(cur1->data);
-					}
-				} else
-					cur->item = NULL;
-
-			} else if (cur->action == AIM_CB_SSI_DEL) {
-				/* Add the item back into the local list */
-				if (aim_ssi_itemlist_valid(sess->ssi.official, cur->item)) {
-					aim_ssi_itemlist_add(&sess->ssi.local, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data);
-				} else
-					cur->item = NULL;
-			}
-
-		} else {
-			/* Do the exact opposite */
-			if (cur->action == AIM_CB_SSI_ADD) {
-			/* Add the local item to the official list */
-				if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) {
-					aim_ssi_itemlist_add(&sess->ssi.official, cur->item->name, cur->item->gid, cur->item->bid, cur->item->type, cur->item->data);
-				} else
-					cur->item = NULL;
-
-			} else if (cur->action == AIM_CB_SSI_MOD) {
-				/* Replace the official item with the item from the local list */
-				if (aim_ssi_itemlist_valid(sess->ssi.local, cur->item)) {
-					struct aim_ssi_item *cur1;
-					if ((cur1 = aim_ssi_itemlist_find(sess->ssi.official, cur->item->gid, cur->item->bid))) {
-						free(cur1->name);
-						if (cur->item->name) {
-							cur1->name = (char *)malloc((strlen(cur->item->name)+1)*sizeof(char));
-							strcpy(cur1->name, cur->item->name);
-						} else
-							cur1->name = NULL;
-						aim_tlvlist_free(&cur1->data);
-						cur1->data = aim_tlvlist_copy(cur->item->data);
-					}
-				} else
-					cur->item = NULL;
-
-			} else if (cur->action == AIM_CB_SSI_DEL) {
-				/* Remove the item from the official list */
-				if (aim_ssi_itemlist_valid(sess->ssi.official, cur->item))
-					aim_ssi_itemlist_del(&sess->ssi.official, cur->item);
-				cur->item = NULL;
-			}
-
-		}
-	} /* End if (cur->item) */
-	} /* End for loop */
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, sess->ssi.pending);
-
-	/* Free all aim_ssi_tmp's with an outcome */
-	cur = sess->ssi.pending;
-	while (cur && (cur->ack != 0xffff)) {
-		del = cur;
-		cur = cur->next;
-		free(del->name);
-		free(del);
-	}
-	sess->ssi.pending = cur;
-
-	/* If we're not waiting for any more acks, then send more SNACs */
-	if (!sess->ssi.pending) {
-		sess->ssi.pending = NULL;
-		sess->ssi.waiting_for_ack = 0;
-		aim_ssi_sync(sess);
-	}
-
-	return ret;
-}
-
-/*
- * Subtype 0x000f - SSI Data Unchanged.
- *
- * Response to aim_ssi_reqifchanged() if the server-side data is not newer than
- * posted local stamp/revision.
- *
- */
-static int parsedataunchanged(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-
-	sess->ssi.received_data = 1;
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0011 - SSI Begin Data Modification.
- *
- * Tells the server you're going to start modifying data.
- * 
- */
-faim_export int aim_ssi_modbegin(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))
-		return -EINVAL;
-
-	return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTART);
-}
-
-/*
- * Subtype 0x0012 - SSI End Data Modification.
- *
- * Tells the server you're finished modifying data.
- *
- */
-faim_export int aim_ssi_modend(aim_session_t *sess)
-{
-	aim_conn_t *conn;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)))
-		return -EINVAL;
-
-	return aim_genericreq_n(sess, conn, AIM_CB_FAM_SSI, AIM_CB_SSI_EDITSTOP);
-}
-
-/*
- * Subtype 0x0014 - Grant authorization
- *
- * Authorizes a contact so they can add you to their contact list.
- *
- */
-faim_export int aim_ssi_sendauth(aim_session_t *sess, char *sn, char *msg)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTH, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTH, 0x0000, snacid);
-
-	/* Screen name */
-	aimbs_put8(&fr->data, strlen(sn));
-	aimbs_putraw(&fr->data, sn, strlen(sn));
-
-	/* Message (null terminated) */
-	aimbs_put16(&fr->data, msg ? strlen(msg) : 0);
-	if (msg) {
-		aimbs_putraw(&fr->data, msg, strlen(msg));
-		aimbs_put8(&fr->data, 0x00);
-	}
-
-	/* Unknown */
-	aimbs_put16(&fr->data, 0x0000);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0015 - Receive an authorization grant
- */
-static int receiveauthgrant(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t tmp;
-	char *sn, *msg;
-
-	/* Read screen name */
-	if ((tmp = aimbs_get8(bs)))
-		sn = aimbs_getstr(bs, tmp);
-	else
-		sn = NULL;
-
-	/* Read message (null terminated) */
-	if ((tmp = aimbs_get16(bs)))
-		msg = aimbs_getstr(bs, tmp);
-	else
-		msg = NULL;
-
-	/* Unknown */
-	tmp = aimbs_get16(bs);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, sn, msg);
-
-	free(sn);
-	free(msg);
-
-	return ret;
-}
-
-/*
- * Subtype 0x0018 - Send authorization request
- *
- * Sends a request for authorization to the given contact.  The request will either be
- * granted, denied, or dropped.
- *
- */
-faim_export int aim_ssi_sendauthrequest(aim_session_t *sess, char *sn, char *msg)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10+1+strlen(sn)+2+(msg ? strlen(msg)+1 : 0)+2)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREQ, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREQ, 0x0000, snacid);
-
-	/* Screen name */
-	aimbs_put8(&fr->data, strlen(sn));
-	aimbs_putraw(&fr->data, sn, strlen(sn));
-
-	/* Message (null terminated) */
-	aimbs_put16(&fr->data, msg ? strlen(msg) : 0);
-	if (msg) {
-		aimbs_putraw(&fr->data, msg, strlen(msg));
-		aimbs_put8(&fr->data, 0x00);
-	}
-
-	/* Unknown */
-	aimbs_put16(&fr->data, 0x0000);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x0019 - Receive an authorization request
- */
-static int receiveauthrequest(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t tmp;
-	char *sn, *msg;
-
-	/* Read screen name */
-	if ((tmp = aimbs_get8(bs)))
-		sn = aimbs_getstr(bs, tmp);
-	else
-		sn = NULL;
-
-	/* Read message (null terminated) */
-	if ((tmp = aimbs_get16(bs)))
-		msg = aimbs_getstr(bs, tmp);
-	else
-		msg = NULL;
-
-	/* Unknown */
-	tmp = aimbs_get16(bs);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, sn, msg);
-
-	free(sn);
-	free(msg);
-
-	return ret;
-}
-
-/*
- * Subtype 0x001a - Send authorization reply
- *
- * Sends a reply to a request for authorization.  The reply can either 
- * grant authorization or deny authorization.
- *
- * if reply=0x00 then deny
- * if reply=0x01 then grant
- *
- */
-faim_export int aim_ssi_sendauthreply(aim_session_t *sess, char *sn, fu8_t reply, char *msg)
-{
-	aim_conn_t *conn;
-	aim_frame_t *fr;
-	aim_snacid_t snacid;
-
-	if (!sess || !(conn = aim_conn_findbygroup(sess, AIM_CB_FAM_SSI)) || !sn)
-		return -EINVAL;
-
-	if (!(fr = aim_tx_new(sess, conn, AIM_FRAMETYPE_FLAP, 0x02, 10 + 1+strlen(sn) + 1 + 2+(msg ? strlen(msg)+1 : 0) + 2)))
-		return -ENOMEM;
-
-	snacid = aim_cachesnac(sess, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREP, 0x0000, NULL, 0);
-	aim_putsnac(&fr->data, AIM_CB_FAM_SSI, AIM_CB_SSI_SENDAUTHREP, 0x0000, snacid);
-
-	/* Screen name */
-	aimbs_put8(&fr->data, strlen(sn));
-	aimbs_putraw(&fr->data, sn, strlen(sn));
-
-	/* Grant or deny */
-	aimbs_put8(&fr->data, reply);
-
-	/* Message (null terminated) */
-	aimbs_put16(&fr->data, msg ? (strlen(msg)+1) : 0);
-	if (msg) {
-		aimbs_putraw(&fr->data, msg, strlen(msg));
-		aimbs_put8(&fr->data, 0x00);
-	}
-
-	/* Unknown */
-	aimbs_put16(&fr->data, 0x0000);
-
-	aim_tx_enqueue(sess, fr);
-
-	return 0;
-}
-
-/*
- * Subtype 0x001b - Receive an authorization reply
- * You get this bad boy when other people respond to the authorization 
- * request that you have previously sent them.
- */
-static int receiveauthreply(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t tmp;
-	fu8_t reply;
-	char *sn, *msg;
-
-	/* Read screen name */
-	if ((tmp = aimbs_get8(bs)))
-		sn = aimbs_getstr(bs, tmp);
-	else
-		sn = NULL;
-
-	/* Read reply */
-	reply = aimbs_get8(bs);
-
-	/* Read message (null terminated) */
-	if ((tmp = aimbs_get16(bs)))
-		msg = aimbs_getstr(bs, tmp);
-	else
-		msg = NULL;
-
-	/* Unknown */
-	tmp = aimbs_get16(bs);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, sn, reply, msg);
-
-	free(sn);
-	free(msg);
-
-	return ret;
-}
-
-/*
- * Subtype 0x001c - Receive a message telling you someone added you to their list.
- */
-static int receiveadded(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t tmp;
-	char *sn;
-
-	/* Read screen name */
-	if ((tmp = aimbs_get8(bs)))
-		sn = aimbs_getstr(bs, tmp);
-	else
-		sn = NULL;
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, sn);
-
-	free(sn);
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == AIM_CB_SSI_RIGHTSINFO)
-		return parserights(sess, mod, rx, snac, bs);
-	else if (snac->subtype == AIM_CB_SSI_LIST)
-		return parsedata(sess, mod, rx, snac, bs);
-	else if (snac->subtype == AIM_CB_SSI_ADD)
-		return parseadd(sess, mod, rx, snac, bs);
-	else if (snac->subtype == AIM_CB_SSI_MOD)
-		return parsemod(sess, mod, rx, snac, bs);
-	else if (snac->subtype == AIM_CB_SSI_DEL)
-		return parsedel(sess, mod, rx, snac, bs);
-	else if (snac->subtype == AIM_CB_SSI_SRVACK)
-		return parseack(sess, mod, rx, snac, bs);
-	else if (snac->subtype == AIM_CB_SSI_NOLIST)
-		return parsedataunchanged(sess, mod, rx, snac, bs);
-	else if (snac->subtype == AIM_CB_SSI_RECVAUTH)
-		return receiveauthgrant(sess, mod, rx, snac, bs);
-	else if (snac->subtype == AIM_CB_SSI_RECVAUTHREQ)
-		return receiveauthrequest(sess, mod, rx, snac, bs);
-	else if (snac->subtype == AIM_CB_SSI_RECVAUTHREP)
-		return receiveauthreply(sess, mod, rx, snac, bs);
-	else if (snac->subtype == AIM_CB_SSI_ADDED)
-		return receiveadded(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-static void ssi_shutdown(aim_session_t *sess, aim_module_t *mod)
-{
-	aim_ssi_freelist(sess);
-}
-
-faim_internal int ssi_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = AIM_CB_FAM_SSI;
-	mod->version = 0x0004;
-	mod->toolid = 0x0110;
-	mod->toolversion = 0x0629;
-	mod->flags = 0;
-	strncpy(mod->name, "ssi", sizeof(mod->name));
-	mod->snachandler = snachandler;
-	mod->shutdown = ssi_shutdown;
-
-	return 0;
-}
Index: bfaim/stamp-h
===================================================================
--- libfaim/stamp-h	(revision 5e53c4a15eca8b264df0aedf726d4545bc5b4b46)
+++ 	(revision )
@@ -1,1 +1,0 @@
-timestamp
Index: bfaim/stats.c
===================================================================
--- libfaim/stats.c	(revision e374dee70435f8c596358571092675644a9ba731)
+++ 	(revision )
@@ -1,44 +1,0 @@
-/*
- * Family 0x000b - Statistics.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-static int reportinterval(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-	int ret = 0;
-	aim_rxcallback_t userfunc;
-	fu16_t interval;
-
-	interval = aimbs_get16(bs);
-
-	if ((userfunc = aim_callhandler(sess, rx->conn, snac->family, snac->subtype)))
-		ret = userfunc(sess, rx, interval);
-
-	return ret;
-}
-
-static int snachandler(aim_session_t *sess, aim_module_t *mod, aim_frame_t *rx, aim_modsnac_t *snac, aim_bstream_t *bs)
-{
-
-	if (snac->subtype == 0x0002)
-		return reportinterval(sess, mod, rx, snac, bs);
-
-	return 0;
-}
-
-faim_internal int stats_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x000b;
-	mod->version = 0x0001;
-	mod->toolid = 0x0104;
-	mod->toolversion = 0x0001;
-	mod->flags = 0;
-	strncpy(mod->name, "stats", sizeof(mod->name));
-	mod->snachandler = snachandler;
-
-	return 0;
-}
Index: bfaim/tlv.c
===================================================================
--- libfaim/tlv.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,823 +1,0 @@
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-static aim_tlv_t *createtlv(fu16_t type, fu16_t length, fu8_t *value)
-{
-	aim_tlv_t *ret;
-
-	if (!(ret = (aim_tlv_t *)malloc(sizeof(aim_tlv_t))))
-		return NULL;
-	ret->type = type;
-	ret->length = length;
-	ret->value = value;
-
-	return ret;
-}
-
-static void freetlv(aim_tlv_t **oldtlv)
-{
-
-	if (!oldtlv || !*oldtlv)
-		return;
-	
-	free((*oldtlv)->value);
-	free(*oldtlv);
-	*oldtlv = NULL;
-
-	return;
-}
-
-/**
- * Read a TLV chain from a buffer.
- *
- * Reads and parses a series of TLV patterns from a data buffer; the
- * returned structure is manipulatable with the rest of the TLV
- * routines.  When done with a TLV chain, aim_tlvlist_free() should
- * be called to free the dynamic substructures.
- *
- * XXX There should be a flag setable here to have the tlvlist contain
- * bstream references, so that at least the ->value portion of each 
- * element doesn't need to be malloc/memcpy'd.  This could prove to be
- * just as effecient as the in-place TLV parsing used in a couple places
- * in libfaim.
- *
- * @param bs Input bstream
- */
-faim_internal aim_tlvlist_t *aim_tlvlist_read(aim_bstream_t *bs)
-{
-	aim_tlvlist_t *list = NULL, *cur;
-	
-	while (aim_bstream_empty(bs) > 0) {
-		fu16_t type, length;
-
-		type = aimbs_get16(bs);
-		length = aimbs_get16(bs);
-
-#if 0 /* temporarily disabled until I know if they're still doing it or not */
-		/*
-		 * Okay, so now AOL has decided that any TLV of
-		 * type 0x0013 can only be two bytes, despite
-		 * what the actual given length is.  So here 
-		 * we dump any invalid TLVs of that sort.  Hopefully
-		 * theres no special cases to this special case.
-		 *   - mid (30jun2000)
-		 */
-		if ((type == 0x0013) && (length != 0x0002))
-			length = 0x0002;
-#else
-		if (0)
-			;
-#endif
-		else {
-
-			if (length > aim_bstream_empty(bs)) {
-				aim_tlvlist_free(&list);
-				return NULL;
-			}
-
-			cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t));
-			if (!cur) {
-				aim_tlvlist_free(&list);
-				return NULL;
-			}
-
-			memset(cur, 0, sizeof(aim_tlvlist_t));
-
-			cur->tlv = createtlv(type, length, NULL);
-			if (!cur->tlv) {
-				free(cur);
-				aim_tlvlist_free(&list);
-				return NULL;
-			}
-			if (cur->tlv->length > 0) {
-				cur->tlv->value = aimbs_getraw(bs, length);	
-				if (!cur->tlv->value) {
-					freetlv(&cur->tlv);
-					free(cur);
-					aim_tlvlist_free(&list);
-					return NULL;
-				}
-			}
-
-			cur->next = list;
-			list = cur;
-		}
-	}
-
-	return list;
-}
-
-/**
- * Read a TLV chain from a buffer.
- *
- * Reads and parses a series of TLV patterns from a data buffer; the
- * returned structure is manipulatable with the rest of the TLV
- * routines.  When done with a TLV chain, aim_tlvlist_free() should
- * be called to free the dynamic substructures.
- *
- * XXX There should be a flag setable here to have the tlvlist contain
- * bstream references, so that at least the ->value portion of each 
- * element doesn't need to be malloc/memcpy'd.  This could prove to be
- * just as effecient as the in-place TLV parsing used in a couple places
- * in libfaim.
- *
- * @param bs Input bstream
- * @param num The max number of TLVs that will be read, or -1 if unlimited.  
- *        There are a number of places where you want to read in a tlvchain, 
- *        but the chain is not at the end of the SNAC, and the chain is 
- *        preceeded by the number of TLVs.  So you can limit that with this.
- */
-faim_internal aim_tlvlist_t *aim_tlvlist_readnum(aim_bstream_t *bs, fu16_t num)
-{
-	aim_tlvlist_t *list = NULL, *cur;
-
-	while ((aim_bstream_empty(bs) > 0) && (num != 0)) {
-		fu16_t type, length;
-
-		type = aimbs_get16(bs);
-		length = aimbs_get16(bs);
-
-		if (length > aim_bstream_empty(bs)) {
-			aim_tlvlist_free(&list);
-			return NULL;
-		}
-
-		cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t));
-		if (!cur) {
-			aim_tlvlist_free(&list);
-			return NULL;
-		}
-
-		memset(cur, 0, sizeof(aim_tlvlist_t));
-
-		cur->tlv = createtlv(type, length, NULL);
-		if (!cur->tlv) {
-			free(cur);
-			aim_tlvlist_free(&list);
-			return NULL;
-		}
-		if (cur->tlv->length > 0) {
-			cur->tlv->value = aimbs_getraw(bs, length);
-			if (!cur->tlv->value) {
-				freetlv(&cur->tlv);
-				free(cur);
-				aim_tlvlist_free(&list);
-				return NULL;
-			}
-		}
-
-		if (num > 0)
-			num--;
-		cur->next = list;
-		list = cur;
-	}
-
-	return list;
-}
-
-/**
- * Read a TLV chain from a buffer.
- *
- * Reads and parses a series of TLV patterns from a data buffer; the
- * returned structure is manipulatable with the rest of the TLV
- * routines.  When done with a TLV chain, aim_tlvlist_free() should
- * be called to free the dynamic substructures.
- *
- * XXX There should be a flag setable here to have the tlvlist contain
- * bstream references, so that at least the ->value portion of each 
- * element doesn't need to be malloc/memcpy'd.  This could prove to be
- * just as effecient as the in-place TLV parsing used in a couple places
- * in libfaim.
- *
- * @param bs Input bstream
- * @param len The max length in bytes that will be read.
- *        There are a number of places where you want to read in a tlvchain, 
- *        but the chain is not at the end of the SNAC, and the chain is 
- *        preceeded by the length of the TLVs.  So you can limit that with this.
- */
-faim_internal aim_tlvlist_t *aim_tlvlist_readlen(aim_bstream_t *bs, fu16_t len)
-{
-	aim_tlvlist_t *list = NULL, *cur;
-
-	while ((aim_bstream_empty(bs) > 0) && (len > 0)) {
-		fu16_t type, length;
-
-		type = aimbs_get16(bs);
-		length = aimbs_get16(bs);
-
-		if (length > aim_bstream_empty(bs)) {
-			aim_tlvlist_free(&list);
-			return NULL;
-		}
-
-		cur = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t));
-		if (!cur) {
-			aim_tlvlist_free(&list);
-			return NULL;
-		}
-
-		memset(cur, 0, sizeof(aim_tlvlist_t));
-
-		cur->tlv = createtlv(type, length, NULL);
-		if (!cur->tlv) {
-			free(cur);
-			aim_tlvlist_free(&list);
-			return NULL;
-		}
-		if (cur->tlv->length > 0) {
-			cur->tlv->value = aimbs_getraw(bs, length);
-			if (!cur->tlv->value) {
-				freetlv(&cur->tlv);
-				free(cur);
-				aim_tlvlist_free(&list);
-				return NULL;
-			}
-		}
-
-		len -= aim_tlvlist_size(&cur);
-		cur->next = list;
-		list = cur;
-	}
-
-	return list;
-}
-
-/**
- * Duplicate a TLV chain.
- * This is pretty pelf exslanatory.
- *
- * @param orig The TLV chain you want to make a copy of.
- * @return A newly allocated TLV chain.
- */
-faim_internal aim_tlvlist_t *aim_tlvlist_copy(aim_tlvlist_t *orig)
-{
-	aim_tlvlist_t *new = NULL;
-
-	while (orig) {
-		aim_tlvlist_add_raw(&new, orig->tlv->type, orig->tlv->length, orig->tlv->value);
-		orig = orig->next;
-	}
-
-	return new;
-}
-
-/*
- * Compare two TLV lists for equality.  This probably is not the most 
- * efficient way to do this.
- *
- * @param one One of the TLV chains to compare.
- * @param two The other TLV chain to compare.
- * @preturn Retrun 0 if the lists are the same, return 1 if they are different.
- */
-faim_internal int aim_tlvlist_cmp(aim_tlvlist_t *one, aim_tlvlist_t *two)
-{
-	aim_bstream_t bs1, bs2;
-
-	if (aim_tlvlist_size(&one) != aim_tlvlist_size(&two))
-		return 1;
-
-	aim_bstream_init(&bs1, ((fu8_t *)malloc(aim_tlvlist_size(&one)*sizeof(fu8_t))), aim_tlvlist_size(&one));
-	aim_bstream_init(&bs2, ((fu8_t *)malloc(aim_tlvlist_size(&two)*sizeof(fu8_t))), aim_tlvlist_size(&two));
-
-	aim_tlvlist_write(&bs1, &one);
-	aim_tlvlist_write(&bs2, &two);
-
-	if (memcmp(bs1.data, bs2.data, bs1.len)) {
-		free(bs1.data);
-		free(bs2.data);
-		return 1;
-	}
-
-	free(bs1.data);
-	free(bs2.data);
-
-	return 0;
-}
-
-/**
- * Free a TLV chain structure
- * @list: Chain to be freed
- *
- * Walks the list of TLVs in the passed TLV chain and
- * frees each one. Note that any references to this data
- * should be removed before calling this.
- *
- */
-faim_internal void aim_tlvlist_free(aim_tlvlist_t **list)
-{
-	aim_tlvlist_t *cur;
-
-	if (!list || !*list)
-		return;
-
-	for (cur = *list; cur; ) {
-		aim_tlvlist_t *tmp;
-		
-		freetlv(&cur->tlv);
-
-		tmp = cur->next;
-		free(cur);
-		cur = tmp;
-	}
-
-	list = NULL;
-
-	return;
-}
-
-/**
- * Count the number of TLVs in a chain.
- *
- * @param list Chain to be counted.
- * @return The number of TLVs stored in the passed chain.
- */
-faim_internal int aim_tlvlist_count(aim_tlvlist_t **list)
-{
-	aim_tlvlist_t *cur;
-	int count;
-
-	if (!list || !*list)
-		return 0;
-
-	for (cur = *list, count = 0; cur; cur = cur->next)
-		count++;
-
-	return count;
-}
-
-/**
- * Count the number of bytes in a TLV chain.
- *
- * @param list Chain to be sized
- * @return The number of bytes that would be needed to 
- *         write the passed TLV chain to a data buffer.
- */
-faim_internal int aim_tlvlist_size(aim_tlvlist_t **list)
-{
-	aim_tlvlist_t *cur;
-	int size;
-
-	if (!list || !*list)
-		return 0;
-
-	for (cur = *list, size = 0; cur; cur = cur->next)
-		size += (4 + cur->tlv->length);
-
-	return size;
-}
-
-/**
- * Adds the passed string as a TLV element of the passed type
- * to the TLV chain.
- *
- * @param list Desination chain (%NULL pointer if empty).
- * @param type TLV type.
- * @length Length of string to add (not including %NULL).
- * @value String to add.
- * @retun The size of the value added.
- */
-faim_internal int aim_tlvlist_add_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t length, const fu8_t *value)
-{
-	aim_tlvlist_t *newtlv, *cur;
-
-	if (list == NULL)
-		return 0;
-
-	if (!(newtlv = (aim_tlvlist_t *)malloc(sizeof(aim_tlvlist_t))))
-		return 0;
-	memset(newtlv, 0x00, sizeof(aim_tlvlist_t));
-
-	if (!(newtlv->tlv = createtlv(type, length, NULL))) {
-		free(newtlv);
-		return 0;
-	}
-	if (newtlv->tlv->length > 0) {
-		newtlv->tlv->value = (fu8_t *)malloc(newtlv->tlv->length);
-		memcpy(newtlv->tlv->value, value, newtlv->tlv->length);
-	}
-
-	if (!*list)
-		*list = newtlv;
-	else {
-		for(cur = *list; cur->next; cur = cur->next)
-			;
-		cur->next = newtlv;
-	}
-
-	return newtlv->tlv->length;
-}
-
-/**
- * Add a one byte integer to a TLV chain.
- *
- * @param list Destination chain.
- * @param type TLV type to add.
- * @param value Value to add.
- * @retun The size of the value added.
- */
-faim_internal int aim_tlvlist_add_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value)
-{
-	fu8_t v8[1];
-
-	aimutil_put8(v8, value);
-
-	return aim_tlvlist_add_raw(list, type, 1, v8);
-}
-
-/**
- * Add a two byte integer to a TLV chain.
- *
- * @param list Destination chain.
- * @param type TLV type to add.
- * @param value Value to add.
- * @retun The size of the value added.
- */
-faim_internal int aim_tlvlist_add_16(aim_tlvlist_t **list, const fu16_t type, const fu16_t value)
-{
-	fu8_t v16[2];
-
-	aimutil_put16(v16, value);
-
-	return aim_tlvlist_add_raw(list, type, 2, v16);
-}
-
-/**
- * Add a four byte integer to a TLV chain.
- *
- * @param list Destination chain.
- * @param type TLV type to add.
- * @param value Value to add.
- * @retun The size of the value added.
- */
-faim_internal int aim_tlvlist_add_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value)
-{
-	fu8_t v32[4];
-
-	aimutil_put32(v32, value);
-
-	return aim_tlvlist_add_raw(list, type, 4, v32);
-}
-
-/**
- * Adds a block of capability blocks to a TLV chain. The bitfield
- * passed in should be a bitwise %OR of any of the %AIM_CAPS constants:
- *
- *     %AIM_CAPS_BUDDYICON   Supports Buddy Icons
- *     %AIM_CAPS_VOICE       Supports Voice Chat
- *     %AIM_CAPS_IMIMAGE     Supports DirectIM/IMImage
- *     %AIM_CAPS_CHAT        Supports Chat
- *     %AIM_CAPS_GETFILE     Supports Get File functions
- *     %AIM_CAPS_SENDFILE    Supports Send File functions
- *
- * @param list Destination chain
- * @param type TLV type to add
- * @param caps Bitfield of capability flags to send
- * @retun The size of the value added.
- */
-faim_internal int aim_tlvlist_add_caps(aim_tlvlist_t **list, const fu16_t type, const fu32_t caps)
-{
-	fu8_t buf[16*16]; /* XXX icky fixed length buffer */
-	aim_bstream_t bs;
-
-	if (!caps)
-		return 0; /* nothing there anyway */
-
-	aim_bstream_init(&bs, buf, sizeof(buf));
-
-	aim_putcap(&bs, caps);
-
-	return aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf);
-}
-
-/**
- * Adds the given userinfo struct to a TLV chain.
- *
- * @param list Destination chain.
- * @param type TLV type to add.
- * @retun The size of the value added.
- */
-faim_internal int aim_tlvlist_add_userinfo(aim_tlvlist_t **list, fu16_t type, aim_userinfo_t *userinfo)
-{
-	fu8_t buf[1024]; /* bleh */
-	aim_bstream_t bs;
-
-	aim_bstream_init(&bs, buf, sizeof(buf));
-
-	aim_putuserinfo(&bs, userinfo);
-
-	return aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf);
-}
-
-/**
- * Adds a TLV with a zero length to a TLV chain.
- *
- * @param list Destination chain.
- * @param type TLV type to add.
- * @retun The size of the value added.
- */
-faim_internal int aim_tlvlist_add_noval(aim_tlvlist_t **list, const fu16_t type)
-{
-	return aim_tlvlist_add_raw(list, type, 0, NULL);
-}
-
-/*
- * Note that the inner TLV chain will not be modifiable as a tlvchain once
- * it is written using this.  Or rather, it can be, but updates won't be
- * made to this.
- *
- * XXX should probably support sublists for real.
- * 
- * This is so neat.
- *
- */
-faim_internal int aim_tlvlist_add_frozentlvlist(aim_tlvlist_t **list, fu16_t type, aim_tlvlist_t **tl)
-{
-	fu8_t *buf;
-	int buflen;
-	aim_bstream_t bs;
-
-	buflen = aim_tlvlist_size(tl);
-
-	if (buflen <= 0)
-		return 0;
-
-	if (!(buf = malloc(buflen)))
-		return 0;
-
-	aim_bstream_init(&bs, buf, buflen);
-
-	aim_tlvlist_write(&bs, tl);
-
-	aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf);
-
-	free(buf);
-
-	return buflen;
-}
-
-/**
- * Substitute a TLV of a given type with a new TLV of the same type.  If 
- * you attempt to replace a TLV that does not exist, this function will 
- * just add a new TLV as if you called aim_tlvlist_add_raw().
- *
- * @param list Desination chain (%NULL pointer if empty).
- * @param type TLV type.
- * @param length Length of string to add (not including %NULL).
- * @param value String to add.
- * @return The length of the TLV.
- */
-faim_internal int aim_tlvlist_replace_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t length, const fu8_t *value)
-{
-	aim_tlvlist_t *cur;
-
-	if (list == NULL)
-		return 0;
-
-	for (cur = *list; ((cur != NULL) && (cur->tlv->type != type)); cur = cur->next);
-	if (cur == NULL)
-		return aim_tlvlist_add_raw(list, type, length, value);
-
-	free(cur->tlv->value);
-	cur->tlv->length = length;
-	if (cur->tlv->length > 0) {
-		cur->tlv->value = (fu8_t *)malloc(cur->tlv->length);
-		memcpy(cur->tlv->value, value, cur->tlv->length);
-	} else
-		cur->tlv->value = NULL;
-
-	return cur->tlv->length;
-}
-
-/**
- * Substitute a TLV of a given type with a new TLV of the same type.  If 
- * you attempt to replace a TLV that does not exist, this function will 
- * just add a new TLV as if you called aim_tlvlist_add_raw().
- *
- * @param list Desination chain (%NULL pointer if empty).
- * @param type TLV type.
- * @return The length of the TLV.
- */
-faim_internal int aim_tlvlist_replace_noval(aim_tlvlist_t **list, const fu16_t type)
-{
-	return aim_tlvlist_replace_raw(list, type, 0, NULL);
-}
-
-/**
- * Substitute a TLV of a given type with a new TLV of the same type.  If 
- * you attempt to replace a TLV that does not exist, this function will 
- * just add a new TLV as if you called aim_tlvlist_add_raw().
- *
- * @param list Desination chain (%NULL pointer if empty).
- * @param type TLV type.
- * @param value 8 bit value to add.
- * @return The length of the TLV.
- */
-faim_internal int aim_tlvlist_replace_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value)
-{
-	fu8_t v8[1];
-
-	aimutil_put8(v8, value);
-
-	return aim_tlvlist_replace_raw(list, type, 1, v8);
-}
-
-/**
- * Substitute a TLV of a given type with a new TLV of the same type.  If 
- * you attempt to replace a TLV that does not exist, this function will 
- * just add a new TLV as if you called aim_tlvlist_add_raw().
- *
- * @param list Desination chain (%NULL pointer if empty).
- * @param type TLV type.
- * @param value 32 bit value to add.
- * @return The length of the TLV.
- */
-faim_internal int aim_tlvlist_replace_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value)
-{
-	fu8_t v32[4];
-
-	aimutil_put32(v32, value);
-
-	return aim_tlvlist_replace_raw(list, type, 4, v32);
-}
-
-/**
- * Remove a TLV of a given type.  If you attempt to remove a TLV that 
- * does not exist, nothing happens.
- *
- * @param list Desination chain (%NULL pointer if empty).
- * @param type TLV type.
- */
-faim_internal void aim_tlvlist_remove(aim_tlvlist_t **list, const fu16_t type)
-{
-	aim_tlvlist_t *del;
-
-	if (!list || !(*list))
-		return;
-
-	/* Remove the item from the list */
-	if ((*list)->tlv->type == type) {
-		del = *list;
-		*list = (*list)->next;
-	} else {
-		aim_tlvlist_t *cur;
-		for (cur=*list; (cur->next && (cur->next->tlv->type!=type)); cur=cur->next);
-		if (!cur->next)
-			return;
-		del = cur->next;
-		cur->next = del->next;
-	}
-
-	/* Free the removed item */
-	free(del->tlv->value);
-	free(del->tlv);
-	free(del);
-}
-
-/**
- * aim_tlvlist_write - Write a TLV chain into a data buffer.
- * @buf: Destination buffer
- * @buflen: Maximum number of bytes that will be written to buffer
- * @list: Source TLV chain
- *
- * Copies a TLV chain into a raw data buffer, writing only the number
- * of bytes specified. This operation does not free the chain; 
- * aim_tlvlist_free() must still be called to free up the memory used
- * by the chain structures.
- *
- * XXX clean this up, make better use of bstreams 
- */
-faim_internal int aim_tlvlist_write(aim_bstream_t *bs, aim_tlvlist_t **list)
-{
-	int goodbuflen;
-	aim_tlvlist_t *cur;
-
-	/* do an initial run to test total length */
-	goodbuflen = aim_tlvlist_size(list);
-
-	if (goodbuflen > aim_bstream_empty(bs))
-		return 0; /* not enough buffer */
-
-	/* do the real write-out */
-	for (cur = *list; cur; cur = cur->next) {
-		aimbs_put16(bs, cur->tlv->type);
-		aimbs_put16(bs, cur->tlv->length);
-		if (cur->tlv->length)
-			aimbs_putraw(bs, cur->tlv->value, cur->tlv->length);
-	}
-
-	return 1; /* XXX this is a nonsensical return */
-}
-
-
-/**
- * Grab the Nth TLV of type type in the TLV list list.
- *
- * Returns a pointer to an aim_tlv_t of the specified type; 
- * %NULL on error.  The @nth parameter is specified starting at %1.
- * In most cases, there will be no more than one TLV of any type
- * in a chain.
- *
- * @param list Source chain.
- * @param type Requested TLV type.
- * @param nth Index of TLV of type to get.
- * @return The TLV you were looking for, or NULL if one could not be found.
- */
-faim_internal aim_tlv_t *aim_tlv_gettlv(aim_tlvlist_t *list, const fu16_t type, const int nth)
-{
-	aim_tlvlist_t *cur;
-	int i;
-
-	for (cur = list, i = 0; cur; cur = cur->next) {
-		if (cur && cur->tlv) {
-			if (cur->tlv->type == type)
-				i++;
-			if (i >= nth)
-				return cur->tlv;
-		}
-	}
-
-	return NULL;
-}
-
-/**
- * Retrieve the data from the nth TLV in the given TLV chain as a string.
- *
- * @param list Source TLV chain.
- * @param type TLV type to search for.
- * @param nth Index of TLV to return.
- * @return The value of the TLV you were looking for, or NULL if one could 
- *         not be found.  This is a dynamic buffer and must be freed by the 
- *         caller.
- */
-faim_internal char *aim_tlv_getstr(aim_tlvlist_t *list, const fu16_t type, const int nth)
-{
-	aim_tlv_t *tlv;
-	char *newstr;
-
-	if (!(tlv = aim_tlv_gettlv(list, type, nth)))
-		return NULL;
-
-	newstr = (char *) malloc(tlv->length + 1);
-	memcpy(newstr, tlv->value, tlv->length);
-	newstr[tlv->length] = '\0';
-
-	return newstr;
-}
-
-/**
- * Retrieve the data from the nth TLV in the given TLV chain as an 8bit 
- * integer.
- *
- * @param list Source TLV chain.
- * @param type TLV type to search for.
- * @param nth Index of TLV to return.
- * @return The value the TLV you were looking for, or 0 if one could 
- *         not be found.
- */
-faim_internal fu8_t aim_tlv_get8(aim_tlvlist_t *list, const fu16_t type, const int nth)
-{
-	aim_tlv_t *tlv;
-
-	if (!(tlv = aim_tlv_gettlv(list, type, nth)))
-		return 0; /* erm */
-	return aimutil_get8(tlv->value);
-}
-
-/**
- * Retrieve the data from the nth TLV in the given TLV chain as a 16bit 
- * integer.
- *
- * @param list Source TLV chain.
- * @param type TLV type to search for.
- * @param nth Index of TLV to return.
- * @return The value the TLV you were looking for, or 0 if one could 
- *         not be found.
- */
-faim_internal fu16_t aim_tlv_get16(aim_tlvlist_t *list, const fu16_t type, const int nth)
-{
-	aim_tlv_t *tlv;
-
-	if (!(tlv = aim_tlv_gettlv(list, type, nth)))
-		return 0; /* erm */
-	return aimutil_get16(tlv->value);
-}
-
-/**
- * Retrieve the data from the nth TLV in the given TLV chain as a 32bit 
- * integer.
- *
- * @param list Source TLV chain.
- * @param type TLV type to search for.
- * @param nth Index of TLV to return.
- * @return The value the TLV you were looking for, or 0 if one could 
- *         not be found.
- */
-faim_internal fu32_t aim_tlv_get32(aim_tlvlist_t *list, const fu16_t type, const int nth)
-{
-	aim_tlv_t *tlv;
-
-	if (!(tlv = aim_tlv_gettlv(list, type, nth)))
-		return 0; /* erm */
-	return aimutil_get32(tlv->value);
-}
Index: bfaim/translate.c
===================================================================
--- libfaim/translate.c	(revision 862371bb6a5ff5a6491550028e73824b698508bb)
+++ 	(revision )
@@ -1,27 +1,0 @@
-/*
- * Family 0x000c - Translation.
- *
- * I have no idea why this group was issued.  I have never seen anything
- * that uses it.  From what I remember, the last time I tried to poke at
- * the server with this group, it whined about not supporting it.
- *
- * But we advertise it anyway, because its fun.
- * 
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-faim_internal int translate_modfirst(aim_session_t *sess, aim_module_t *mod)
-{
-
-	mod->family = 0x000c;
-	mod->version = 0x0001;
-	mod->toolid = 0x0104;
-	mod->toolversion = 0x0001;
-	mod->flags = 0;
-	strncpy(mod->name, "translate", sizeof(mod->name));
-	mod->snachandler = NULL;
-
-	return 0;
-}
Index: bfaim/txqueue.c
===================================================================
--- libfaim/txqueue.c	(revision cf02dd64c267036375fdf872c3528766fe980d54)
+++ 	(revision )
@@ -1,439 +1,0 @@
-/*
- * txqueue.c
- *
- * Herein lies all the mangement routines for the transmit (Tx) queue.
- *
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-
-#ifndef _WIN32
-#include <sys/socket.h>
-#else
-#include "win32dep.h"
-#endif
-
-/*
- * Allocate a new tx frame.
- *
- * This is more for looks than anything else.
- *
- * Right now, that is.  If/when we implement a pool of transmit
- * frames, this will become the request-an-unused-frame part.
- *
- * framing = AIM_FRAMETYPE_OFT/FLAP
- * chan = channel for FLAP, hdrtype for OFT
- *
- */
-faim_internal aim_frame_t *aim_tx_new(aim_session_t *sess, aim_conn_t *conn, fu8_t framing, fu16_t chan, int datalen)
-{
-	aim_frame_t *fr;
-
-	if (!conn) {
-		faimdprintf(sess, 0, "aim_tx_new: ERROR: no connection specified\n");
-		return NULL;
-	}
-
-	/* For sanity... */
-	if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) || (conn->type == AIM_CONN_TYPE_LISTENER)) {
-		if (framing != AIM_FRAMETYPE_OFT) {
-			faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for rendezvous connection\n");
-			return NULL;
-		}
-	} else {
-		if (framing != AIM_FRAMETYPE_FLAP) {
-			faimdprintf(sess, 0, "aim_tx_new: attempted to allocate inappropriate frame type for FLAP connection\n");
-			return NULL;
-		}
-	}
-
-	if (!(fr = (aim_frame_t *)malloc(sizeof(aim_frame_t))))
-		return NULL;
-	memset(fr, 0, sizeof(aim_frame_t));
-
-	fr->conn = conn; 
-
-	fr->hdrtype = framing;
-
-	if (fr->hdrtype == AIM_FRAMETYPE_FLAP) {
-
-		fr->hdr.flap.type = chan;
-
-	} else if (fr->hdrtype == AIM_FRAMETYPE_OFT) {
-
-		fr->hdr.rend.type = chan;
-
-	} else 
-		faimdprintf(sess, 0, "tx_new: unknown framing\n");
-
-	if (datalen > 0) {
-		fu8_t *data;
-
-		if (!(data = (unsigned char *)malloc(datalen))) {
-			aim_frame_destroy(fr);
-			return NULL;
-		}
-
-		aim_bstream_init(&fr->data, data, datalen);
-	}
-
-	return fr;
-}
-
-/*
- * aim_tx_enqeue__queuebased()
- *
- * The overall purpose here is to enqueue the passed in command struct
- * into the outgoing (tx) queue.  Basically...
- *   1) Make a scope-irrelevent copy of the struct
- *   3) Mark as not-sent-yet
- *   4) Enqueue the struct into the list
- *   6) Return
- *
- * Note that this is only used when doing queue-based transmitting;
- * that is, when sess->tx_enqueue is set to &aim_tx_enqueue__queuebased.
- *
- */
-static int aim_tx_enqueue__queuebased(aim_session_t *sess, aim_frame_t *fr)
-{
-
-	if (!fr->conn) {
-		faimdprintf(sess, 1, "aim_tx_enqueue: WARNING: enqueueing packet with no connecetion\n");
-		fr->conn = aim_getconn_type(sess, AIM_CONN_TYPE_BOS);
-	}
-
-	if (fr->hdrtype == AIM_FRAMETYPE_FLAP) {
-		/* assign seqnum -- XXX should really not assign until hardxmit */
-		fr->hdr.flap.seqnum = aim_get_next_txseqnum(fr->conn);
-	}
-
-	fr->handled = 0; /* not sent yet */
-
-	/* see overhead note in aim_rxqueue counterpart */
-	if (!sess->queue_outgoing)
-		sess->queue_outgoing = fr;
-	else {
-		aim_frame_t *cur;
-
-		for (cur = sess->queue_outgoing; cur->next; cur = cur->next)
-			;
-		cur->next = fr;
-	}
-
-	return 0;
-}
-
-/*
- * aim_tx_enqueue__immediate()
- *
- * Parallel to aim_tx_enqueue__queuebased, however, this bypasses
- * the whole queue mess when you want immediate writes to happen.
- *
- * Basically the same as its __queuebased couterpart, however
- * instead of doing a list append, it just calls aim_tx_sendframe()
- * right here. 
- * 
- */
-static int aim_tx_enqueue__immediate(aim_session_t *sess, aim_frame_t *fr)
-{
-
-	if (!fr->conn) {
-		faimdprintf(sess, 1, "aim_tx_enqueue: ERROR: packet has no connection\n");
-		aim_frame_destroy(fr);
-		return 0;
-	}
-
-	if (fr->hdrtype == AIM_FRAMETYPE_FLAP)
-		fr->hdr.flap.seqnum = aim_get_next_txseqnum(fr->conn);
-
-	fr->handled = 0; /* not sent yet */
-
-	aim_tx_sendframe(sess, fr);
-
-	aim_frame_destroy(fr);
-
-	return 0;
-}
-
-faim_export int aim_tx_setenqueue(aim_session_t *sess, int what, int (*func)(aim_session_t *, aim_frame_t *))
-{
-	
-	if (what == AIM_TX_QUEUED)
-		sess->tx_enqueue = &aim_tx_enqueue__queuebased;
-	else if (what == AIM_TX_IMMEDIATE) 
-		sess->tx_enqueue = &aim_tx_enqueue__immediate;
-	else if (what == AIM_TX_USER) {
-		if (!func)
-			return -EINVAL;
-		sess->tx_enqueue = func;
-	} else
-		return -EINVAL; /* unknown action */
-
-	return 0;
-}
-
-faim_internal int aim_tx_enqueue(aim_session_t *sess, aim_frame_t *fr)
-{
-	
-	/*
-	 * If we want to send a connection thats inprogress, we have to force
-	 * them to use the queue based version. Otherwise, use whatever they
-	 * want.
-	 */
-	if (fr && fr->conn && 
-			(fr->conn->status & AIM_CONN_STATUS_INPROGRESS)) {
-		return aim_tx_enqueue__queuebased(sess, fr);
-	}
-
-	return (*sess->tx_enqueue)(sess, fr);
-}
-
-/* 
- *  aim_get_next_txseqnum()
- *
- *   This increments the tx command count, and returns the seqnum
- *   that should be stamped on the next FLAP packet sent.  This is
- *   normally called during the final step of packet preparation
- *   before enqueuement (in aim_tx_enqueue()).
- *
- */
-faim_internal flap_seqnum_t aim_get_next_txseqnum(aim_conn_t *conn)
-{
-	flap_seqnum_t ret;
-	
-	ret = ++conn->seqnum;
-
-	return ret;
-}
-
-static int aim_send(int fd, const void *buf, size_t count)
-{
-	int left, cur;
-
-	for (cur = 0, left = count; left; ) {
-		int ret;
-
-		ret = send(fd, ((unsigned char *)buf)+cur, left, 0);
-		if (ret == -1)
-			return -1;
-		else if (ret == 0)
-			return cur;
-
-		cur += ret;
-		left -= ret;
-	}
-
-	return cur;
-}
-
-static int aim_bstream_send(aim_bstream_t *bs, aim_conn_t *conn, size_t count)
-{
-	int wrote = 0;
-	if (!bs || !conn || (count < 0))
-		return -EINVAL;
-
-	if (count > aim_bstream_empty(bs))
-		count = aim_bstream_empty(bs); /* truncate to remaining space */
-
-	if (count) {
-		if ((conn->type == AIM_CONN_TYPE_RENDEZVOUS) && 
-		    (conn->subtype == AIM_CONN_SUBTYPE_OFT_DIRECTIM)) {
-			/* I strongly suspect that this is a horrible thing to do
-			 * and I feel really guilty doing it. */
-			const char *sn = aim_odc_getsn(conn);
-			aim_rxcallback_t userfunc;
-			while (count - wrote > 1024) {
-				wrote = wrote + aim_send(conn->fd, bs->data + bs->offset + wrote, 1024);
-				if ((userfunc=aim_callhandler(conn->sessv, conn, 
-								AIM_CB_FAM_SPECIAL, 
-								AIM_CB_SPECIAL_IMAGETRANSFER)))
-				  userfunc(conn->sessv, NULL, sn, 
-					   count-wrote>1024 ? ((double)wrote / count) : 1);
-			}
-		}
-		if (count - wrote) {
-			wrote = wrote + aim_send(conn->fd, bs->data + bs->offset + wrote, count - wrote);
-		}
-
-	}
-
-	if (((aim_session_t *)conn->sessv)->debug >= 2) {
-		int i;
-		aim_session_t *sess = (aim_session_t *)conn->sessv;
-
-		faimdprintf(sess, 2, "\nOutgoing data: (%d bytes)", wrote);
-		for (i = 0; i < wrote; i++) {
-			if (!(i % 8)) 
-				faimdprintf(sess, 2, "\n\t");
-			faimdprintf(sess, 2, "0x%02x ", *(bs->data + bs->offset + i));
-		}
-		faimdprintf(sess, 2, "\n");
-	}
-
-	bs->offset += wrote;
-
-	return wrote;
-}
-
-static int sendframe_flap(aim_session_t *sess, aim_frame_t *fr)
-{
-	aim_bstream_t obs;
-	fu8_t *obs_raw;
-	int payloadlen, err = 0, obslen;
-
-	payloadlen = aim_bstream_curpos(&fr->data);
-
-	if (!(obs_raw = malloc(6 + payloadlen)))
-		return -ENOMEM;
-
-	aim_bstream_init(&obs, obs_raw, 6 + payloadlen);
-
-	/* FLAP header */
-	aimbs_put8(&obs, 0x2a);
-	aimbs_put8(&obs, fr->hdr.flap.type);
-	aimbs_put16(&obs, fr->hdr.flap.seqnum);
-	aimbs_put16(&obs, payloadlen);
-
-	/* payload */
-	aim_bstream_rewind(&fr->data);
-	aimbs_putbs(&obs, &fr->data, payloadlen);
-
-	obslen = aim_bstream_curpos(&obs);
-	aim_bstream_rewind(&obs);
-	if (aim_bstream_send(&obs, fr->conn, obslen) != obslen)
-		err = -errno;
-	
-	free(obs_raw); /* XXX aim_bstream_free */
-
-	fr->handled = 1;
-	fr->conn->lastactivity = time(NULL);
-
-	return err;
-}
-
-static int sendframe_rendezvous(aim_session_t *sess, aim_frame_t *fr)
-{
-	aim_bstream_t bs;
-	fu8_t *bs_raw;
-	int err = 0;
-	int totlen = 8 + aim_bstream_curpos(&fr->data);
-
-	if (!(bs_raw = malloc(totlen)))
-		return -1;
-
-	aim_bstream_init(&bs, bs_raw, totlen);
-
-	aimbs_putraw(&bs, fr->hdr.rend.magic, 4);
-	aimbs_put16(&bs, 8 + fr->hdr.rend.hdrlen);
-	aimbs_put16(&bs, fr->hdr.rend.type);
-
-	/* payload */
-	aim_bstream_rewind(&fr->data);
-	aimbs_putbs(&bs, &fr->data, totlen - 8);
-
-	aim_bstream_rewind(&bs);
-
-	if (aim_bstream_send(&bs, fr->conn, totlen) != totlen)
-		err = -errno;
-
-	free(bs_raw); /* XXX aim_bstream_free */
-
-	fr->handled = 1;
-	fr->conn->lastactivity = time(NULL);
-
-	return err;
-}
-
-faim_internal int aim_tx_sendframe(aim_session_t *sess, aim_frame_t *fr)
-{
-	if (fr->hdrtype == AIM_FRAMETYPE_FLAP)
-		return sendframe_flap(sess, fr);
-	else if (fr->hdrtype == AIM_FRAMETYPE_OFT)
-		return sendframe_rendezvous(sess, fr);
-	return -1;
-}
-
-faim_export int aim_tx_flushqueue(aim_session_t *sess)
-{
-	aim_frame_t *cur;
-
-	for (cur = sess->queue_outgoing; cur; cur = cur->next) {
-
-		if (cur->handled)
-	       		continue; /* already been sent */
-
-		if (cur->conn && (cur->conn->status & AIM_CONN_STATUS_INPROGRESS))
-			continue;
-
-		/*
-		 * And now for the meager attempt to force transmit
-		 * latency and avoid missed messages.
-		 */
-		if ((cur->conn->lastactivity + cur->conn->forcedlatency) >= time(NULL)) {
-			/* 
-			 * XXX should be a break! we dont want to block the 
-			 * upper layers
-			 *
-			 * XXX or better, just do this right.
-			 *
-			 */
-			sleep((cur->conn->lastactivity + cur->conn->forcedlatency) - time(NULL));
-		}
-
-		/* XXX this should call the custom "queuing" function!! */
-		aim_tx_sendframe(sess, cur);
-	}
-
-	/* purge sent commands from queue */
-	aim_tx_purgequeue(sess);
-
-	return 0;
-}
-
-/*
- *  aim_tx_purgequeue()
- *  
- *  This is responsable for removing sent commands from the transmit 
- *  queue. This is not a required operation, but it of course helps
- *  reduce memory footprint at run time!  
- *
- */
-faim_export void aim_tx_purgequeue(aim_session_t *sess)
-{
-	aim_frame_t *cur, **prev;
-
-	for (prev = &sess->queue_outgoing; (cur = *prev); ) {
-
-		if (cur->handled) {
-			*prev = cur->next;
-
-			aim_frame_destroy(cur);
-
-		} else
-			prev = &cur->next;
-	}
-
-	return;
-}
-
-/**
- * aim_tx_cleanqueue - get rid of packets waiting for tx on a dying conn
- * @sess: session
- * @conn: connection that's dying
- *
- * for now this simply marks all packets as sent and lets them
- * disappear without warning.
- *
- */
-faim_internal void aim_tx_cleanqueue(aim_session_t *sess, aim_conn_t *conn)
-{
-	aim_frame_t *cur;
-
-	for (cur = sess->queue_outgoing; cur; cur = cur->next) {
-		if (cur->conn == conn)
-			cur->handled = 1;
-	}
-
-	return;
-}
Index: bfaim/util.c
===================================================================
--- libfaim/util.c	(revision e374dee70435f8c596358571092675644a9ba731)
+++ 	(revision )
@@ -1,210 +1,0 @@
-/*
- * A little bit of this
- * A little bit of that
- * It started with a kiss
- * Now we're up to bat
- */
-
-#define FAIM_INTERNAL
-#include <aim.h>
-#include <ctype.h>
-
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
-
-faim_internal void faimdprintf(aim_session_t *sess, int dlevel, const char *format, ...)
-{
-	if (!sess) {
-		fprintf(stderr, "faimdprintf: no session! boo! (%d, %s)\n", dlevel, format);
-		return;
-	}
-	if ((dlevel <= sess->debug) && sess->debugcb) {
-		va_list ap;
-		va_start(ap, format);
-		sess->debugcb(sess, dlevel, format, ap);
-		va_end(ap);
-	}
-
-	return;
-}
-
-faim_export int aimutil_putstr(char *dest, const char *src, int len)
-{
-	memcpy(dest, src, len);
-	return len;
-}
-
-/*
- * Tokenizing functions.  Used to portably replace strtok/sep.
- *   -- DMP.
- *
- */
-faim_export int aimutil_tokslen(char *toSearch, int theindex, char dl)
-{
-	int curCount = 1;
-	char *next;
-	char *last;
-	int toReturn;
-
-	last = toSearch;
-	next = strchr(toSearch, dl);
-
-	while(curCount < theindex && next != NULL) {
-		curCount++;
-		last = next + 1;
-		next = strchr(last, dl);
-	}
-
-	if ((curCount < theindex) || (next == NULL))
-		toReturn = strlen(toSearch) - (curCount - 1);
-	else
-		toReturn = next - toSearch - (curCount - 1);
-
-	return toReturn;
-}
-
-faim_export int aimutil_itemcnt(char *toSearch, char dl)
-{
-	int curCount;
-	char *next;
-
-	curCount = 1;
-
-	next = strchr(toSearch, dl);
-
-	while(next != NULL) {
-		curCount++;
-		next = strchr(next + 1, dl);
-	}
-
-	return curCount;
-}
-
-faim_export char *aimutil_itemindex(char *toSearch, int theindex, char dl)
-{
-	int curCount;
-	char *next;
-	char *last;
-	char *toReturn;
-
-	curCount = 0;
-
-	last = toSearch;
-	next = strchr(toSearch, dl);
-
-	while (curCount < theindex && next != NULL) {
-		curCount++;
-		last = next + 1;
-		next = strchr(last, dl);
-	}
-
-	if (curCount < theindex) {
-		toReturn = malloc(sizeof(char));
-		*toReturn = '\0';
-	}
-	next = strchr(last, dl);
-
-	if (curCount < theindex) {
-		toReturn = malloc(sizeof(char));
-		*toReturn = '\0';
-	} else {
-		if (next == NULL) {
-			toReturn = malloc((strlen(last) + 1) * sizeof(char));
-			strcpy(toReturn, last);
-		} else {
-			toReturn = malloc((next - last + 1) * sizeof(char));
-			memcpy(toReturn, last, (next - last));
-			toReturn[next - last] = '\0';
-		}
-	}
-	return toReturn;
-}
-
-/**
- * Calculate the checksum of a given icon.
- *
- */
-faim_export fu16_t aimutil_iconsum(const fu8_t *buf, int buflen)
-{
-	fu32_t sum;
-	int i;
-
-	for (i=0, sum=0; i+1<buflen; i+=2)
-		sum += (buf[i+1] << 8) + buf[i];
-	if (i < buflen)
-		sum += buf[i];
-	sum = ((sum & 0xffff0000) >> 16) + (sum & 0x0000ffff);
-
-	return sum;
-}
-
-faim_export int aim_util_getlocalip(fu8_t *ip)
-{
-	struct hostent *hptr;
-	char localhost[129];
-
-	/* XXX if available, use getaddrinfo() */
-	/* XXX allow client to specify which IP to use for multihomed boxes */
-
-	if (gethostname(localhost, 128) < 0)
-		return -1;
-
-	if (!(hptr = gethostbyname(localhost)))
-		return -1;
-	memcpy(ip, hptr->h_addr_list[0], 4);
-
-	return 0;
-}
-
-/*
-* int snlen(const char *)
-* 
-* This takes a screen name and returns its length without
-* spaces.  If there are no spaces in the SN, then the 
-* return is equal to that of strlen().
-*
-*/
-faim_export int aim_snlen(const char *sn)
-{
-	int i = 0;
-
-	if (!sn)
-		return 0;
-
-	while (*sn != '\0') {
-		if (*sn != ' ')
-			i++;
-		sn++;
-	}
-
-	return i;
-}
-
-/*
-* int sncmp(const char *, const char *)
-*
-* This takes two screen names and compares them using the rules
-* on screen names for AIM/AOL.  Mainly, this means case and space
-* insensitivity (all case differences and spacing differences are
-* ignored, with the exception that screen names can not start with 
-* a space).
-*
-* Return: 0 if equal
-*     non-0 if different
-*
-*/
-faim_export int aim_sncmp(const char *sn1, const char *sn2)
-{
-
-	do {
-		while (*sn2 == ' ')
-			sn2++;
-		while (*sn1 == ' ')
-			sn1++;
-		if (toupper(*sn1) != toupper(*sn2))
-			return 1;
-	} while ((*sn1 != '\0') && sn1++ && sn2++);
-
-	return 0;
-}
Index: st.c
===================================================================
--- list.c	(revision 50622a59357b6958f78b136d6d25ce31540f7c59)
+++ 	(revision )
@@ -1,102 +1,0 @@
-#include "owl.h"
-#include <stdlib.h>
-
-static const char fileIdent[] = "$Id$";
-
-#define INITSIZE 10
-#define GROWBY 1.5
-
-int owl_list_create(owl_list *l)
-{
-  l->size=0;
-  l->list=(void **)owl_malloc(INITSIZE*sizeof(void *));
-  l->avail=INITSIZE;
-  if (l->list==NULL) return(-1);
-  return(0);
-}
-
-int owl_list_get_size(owl_list *l)
-{
-  return(l->size);
-}
-
-
-void owl_list_grow(owl_list *l, int n) /*noproto*/
-{
-  void *ptr;
-
-  if ((l->size+n) > l->avail) {
-    ptr=owl_realloc(l->list, l->avail*GROWBY*sizeof(void *));
-    if (ptr==NULL) abort();
-    l->list=ptr;
-    l->avail=l->avail*GROWBY;
-  }
-
-}
-
-void *owl_list_get_element(owl_list *l, int n)
-{
-  if (n>l->size-1) return(NULL);
-  return(l->list[n]);
-}
-
-int owl_list_insert_element(owl_list *l, int at, void *element)
-{
-  int i;
-  if(at < 0 || at > l->size) return -1;
-  owl_list_grow(l, 1);
-
-  for (i=l->size; i>at; i--) {
-    l->list[i]=l->list[i-1];
-  }
-
-  l->list[at] = element;
-  l->size++;
-  return(0);
-}
-
-int owl_list_append_element(owl_list *l, void *element)
-{
-  return owl_list_insert_element(l, l->size, element);
-}
-
-int owl_list_prepend_element(owl_list *l, void *element)
-{
-  return owl_list_insert_element(l, 0, element);
-}
-
-int owl_list_remove_element(owl_list *l, int n)
-{
-  int i;
-
-  if (n>l->size-1) return(-1);
-  for (i=n; i<l->size-1; i++) {
-    l->list[i]=l->list[i+1];
-  }
-  l->size--;
-  return(0);
-}
-
-/* todo: might leak memory */
-int owl_list_replace_element(owl_list *l, int n, void *element)
-{
-  if (n>l->size-1) return(-1);
-
-  l->list[n]=element;
-  return(0);
-}
-
-void owl_list_free_all(owl_list *l, void (*elefree)(void *))
-{
-  int i;
-
-  for (i=0; i<l->size; i++) {
-    (elefree)(l->list[i]);
-  }
-  owl_free(l->list);
-}
-
-void owl_list_free_simple(owl_list *l)
-{
-  if (l->list) owl_free(l->list);
-}
Index: gging.c
===================================================================
--- logging.c	(revision d8671a139b04d17e8b6303452daae01425a318ec)
+++ 	(revision )
@@ -1,347 +1,0 @@
-#include "owl.h"
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/param.h>
-
-static const char fileIdent[] = "$Id$";
-
-/* This is now the one function that should be called to log a
- * message.  It will do all the work necessary by calling the other
- * functions in this file as necessary.
- */
-void owl_log_message(owl_message *m) {
-  owl_function_debugmsg("owl_log_message: entering");
-
-  if (m == NULL) {
-    owl_function_debugmsg("owl_log_message: passed null message");
-    return;
-  }
-
-  /* should we be logging this message? */
-  if (!owl_log_shouldlog_message(m)) {
-    owl_function_debugmsg("owl_log_message: not logging message");
-    return;
-  }
-
-  /* handle incmoing messages */
-  if (owl_message_is_direction_in(m)) {
-    owl_log_incoming(m);
-    owl_function_debugmsg("owl_log_message: leaving");
-    return;
-  }
-
-  /* handle outgoing messages */
-  owl_log_outgoing(m);
-
-  owl_function_debugmsg("owl_log_message: leaving");
-}
-
-/* Return 1 if we should log the given message, otherwise return 0 */
-int owl_log_shouldlog_message(owl_message *m) {
-  owl_filter *f;
-
-  /* If there's a logfilter and this message matches it, log */
-  f=owl_global_get_filter(&g, owl_global_get_logfilter(&g));
-  if (f && owl_filter_message_match(f, m)) return(1);
-
-  /* otherwise we do things based on the logging variables */
-
-  /* skip login/logout messages if appropriate */
-  if (!owl_global_is_loglogins(&g) && owl_message_is_loginout(m)) return(0);
-      
-  /* check direction */
-  if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_IN) && owl_message_is_direction_out(m)) {
-    return(0);
-  }
-  if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_OUT) && owl_message_is_direction_in(m)) {
-    return(0);
-  }
-
-  if (owl_message_is_type_zephyr(m)) {
-    if (owl_message_is_personal(m) && !owl_global_is_logging(&g)) return(0);
-    if (!owl_message_is_personal(m) && !owl_global_is_classlogging(&g)) return(0);
-  } else {
-    if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
-      if (!owl_global_is_logging(&g)) return(0);
-    } else {
-      if (!owl_global_is_classlogging(&g)) return(0);
-    }
-  }
-  return(1);
-}
-
-void owl_log_zephyr(owl_message *m, FILE *file) {
-    char *tmp;
-    tmp=short_zuser(owl_message_get_sender(m));
-    fprintf(file, "Class: %s Instance: %s", owl_message_get_class(m), owl_message_get_instance(m));
-    if (strcmp(owl_message_get_opcode(m), "")) fprintf(file, " Opcode: %s", owl_message_get_opcode(m));
-    fprintf(file, "\n");
-    fprintf(file, "Time: %s Host: %s\n", owl_message_get_timestr(m), owl_message_get_hostname(m));
-    fprintf(file, "From: %s <%s>\n\n", owl_message_get_zsig(m), tmp);
-    fprintf(file, "%s\n\n", owl_message_get_body(m));
-    owl_free(tmp);
-}
-
-void owl_log_aim(owl_message *m, FILE *file) {
-    fprintf(file, "From: <%s> To: <%s>\n", owl_message_get_sender(m), owl_message_get_recipient(m));
-    fprintf(file, "Time: %s\n\n", owl_message_get_timestr(m));
-    if (owl_message_is_login(m))
-        fprintf(file, "LOGIN\n\n");
-    else if (owl_message_is_logout(m))
-        fprintf(file, "LOGOUT\n\n");
-    else
-        fprintf(file, "%s\n\n", owl_message_get_body(m));
-}
-
-void owl_log_jabber(owl_message *m, FILE *file) {
-    fprintf(file, "From: <%s> To: <%s>\n",owl_message_get_sender(m), owl_message_get_recipient(m));
-    fprintf(file, "Time: %s\n\n", owl_message_get_timestr(m));
-    fprintf(file, "%s\n\n",owl_message_get_body(m));
-}
-
-void owl_log_generic(owl_message *m, FILE *file) {
-    fprintf(file, "From: <%s> To: <%s>\n", owl_message_get_sender(m), owl_message_get_recipient(m));
-    fprintf(file, "Time: %s\n\n", owl_message_get_timestr(m));
-    fprintf(file, "%s\n\n", owl_message_get_body(m));
-}
-
-void owl_log_append(owl_message *m, char *filename) {
-    FILE *file;
-    file=fopen(filename, "a");
-    if (!file) {
-        owl_function_error("Unable to open file for logging");
-        return;
-    }
-    if (owl_message_is_type_zephyr(m)) {
-        owl_log_zephyr(m, file);
-    } else if (owl_message_is_type_jabber(m)) {
-        owl_log_jabber(m, file);
-    } else if (owl_message_is_type_aim(m)) {
-        owl_log_aim(m, file);
-    } else {
-        owl_log_generic(m, file);
-    }
-    fclose(file);
-}
-
-void owl_log_outgoing(owl_message *m)
-{
-  char filename[MAXPATHLEN], *logpath;
-  char *to, *temp;
-
-  /* expand ~ in path names */
-  logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
-
-  /* Figure out what path to log to */
-  if (owl_message_is_type_zephyr(m)) {
-    /* If this has CC's, do all but the "recipient" which we'll do below */
-    to = owl_message_get_cc_without_recipient(m);
-    if (to != NULL) {
-      temp = strtok(to, " ");
-      while (temp != NULL) {
-          temp = short_zuser(temp);
-          snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp);
-          owl_log_append(m, filename);
-          temp = strtok(NULL, " ");
-      }
-      owl_free(to);
-    }
-    to = short_zuser(owl_message_get_recipient(m));
-  } else if (owl_message_is_type_jabber(m)) {
-    to = owl_sprintf("jabber:%s", owl_message_get_recipient(m));
-    owl_text_tr(to, '/', '_');
-  } else if (owl_message_is_type_aim(m)) {
-    char *temp2;
-    temp = owl_aim_normalize_screenname(owl_message_get_recipient(m));
-    temp2 = g_utf8_strdown(temp,-1);
-    to = owl_sprintf("aim:%s", temp2);
-    owl_free(temp2);
-    owl_free(temp);
-  } else {
-    to = owl_sprintf("loopback");
-  }
-
-  snprintf(filename, MAXPATHLEN, "%s/%s", logpath, to);
-  owl_log_append(m, filename);
-  owl_free(to);
-
-  snprintf(filename, MAXPATHLEN, "%s/all", logpath);
-  owl_log_append(m, filename);
-  owl_free(logpath);
-}
-
-
-void owl_log_outgoing_zephyr_error(char *to, char *text)
-{
-  FILE *file;
-  char filename[MAXPATHLEN], *logpath;
-  char *tobuff, *zwriteline;
-  owl_message *m;
-
-  /* create a present message so we can pass it to
-   * owl_log_shouldlog_message()
-   */
-  zwriteline=owl_sprintf("zwrite %s", to);
-  m=owl_function_make_outgoing_zephyr(text, zwriteline, "");
-  owl_free(zwriteline);
-  if (!owl_log_shouldlog_message(m)) {
-    owl_message_free(m);
-    return;
-  }
-  owl_message_free(m);
-
-  /* chop off a local realm */
-  tobuff=short_zuser(to);
-
-  /* expand ~ in path names */
-  logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
-
-  snprintf(filename, MAXPATHLEN, "%s/%s", logpath, tobuff);
-  file=fopen(filename, "a");
-  if (!file) {
-    owl_function_error("Unable to open file for outgoing logging");
-    owl_free(logpath);
-    owl_free(tobuff);
-    return;
-  }
-  fprintf(file, "ERROR (owl): %s\n%s\n", tobuff, text);
-  if (text[strlen(text)-1]!='\n') {
-    fprintf(file, "\n");
-  }
-  fclose(file);
-
-  snprintf(filename, MAXPATHLEN, "%s/all", logpath);
-  owl_free(logpath);
-  file=fopen(filename, "a");
-  if (!file) {
-    owl_function_error("Unable to open file for outgoing logging");
-    owl_free(tobuff);
-    return;
-  }
-  fprintf(file, "ERROR (owl): %s\n%s\n", tobuff, text);
-  if (text[strlen(text)-1]!='\n') {
-    fprintf(file, "\n");
-  }
-  fclose(file);
-
-  owl_free(tobuff);
-}
-
-void owl_log_incoming(owl_message *m)
-{
-  char filename[MAXPATHLEN], allfilename[MAXPATHLEN], *logpath;
-  char *frombuff=NULL, *from=NULL;
-  int len, ch, i, personal;
-
-  /* figure out if it's a "personal" message or not */
-  if (owl_message_is_type_zephyr(m)) {
-    if (owl_message_is_personal(m)) {
-      personal = 1;
-    } else {
-      personal = 0;
-    }
-  } else if (owl_message_is_type_jabber(m)) {
-    /* This needs to be fixed to handle groupchat */
-    char* msgtype = owl_message_get_attribute_value(m,"jtype");
-    if (msgtype && !strcmp(msgtype,"groupchat")) {
-      personal = 0;
-    } else {
-      personal = 1;
-    }
-  } else {
-    if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
-      personal = 1;
-    } else {
-      personal = 0;
-    }
-  }
-
-
-  if (owl_message_is_type_zephyr(m)) {
-    if (personal) {
-      from=frombuff=short_zuser(owl_message_get_sender(m));
-    } else {
-      from=frombuff=owl_strdup(owl_message_get_class(m));
-    }
-  } else if (owl_message_is_type_aim(m)) {
-    /* we do not yet handle chat rooms */
-    char *normalto, *temp;
-    temp = owl_aim_normalize_screenname(owl_message_get_sender(m));
-    normalto = g_utf8_strdown(temp, -1);
-    from=frombuff=owl_sprintf("aim:%s", normalto);
-    owl_free(normalto);
-    owl_free(temp);
-  } else if (owl_message_is_type_loopback(m)) {
-    from=frombuff=owl_strdup("loopback");
-  } else if (owl_message_is_type_jabber(m)) {
-    if (personal) {
-      from=frombuff=owl_sprintf("jabber:%s",owl_message_get_sender(m));
-    } else {
-      from=frombuff=owl_sprintf("jabber:%s",owl_message_get_recipient(m));
-    }
-  } else {
-    from=frombuff=owl_strdup("unknown");
-  }
-  
-  /* check for malicious sender formats */
-  len=strlen(frombuff);
-  if (len<1 || len>35) from="weird";
-  if (strchr(frombuff, '/')) from="weird";
-
-  ch=frombuff[0];
-  if (!g_ascii_isalnum(ch)) from="weird";
-
-  for (i=0; i<len; i++) {
-    if (frombuff[i]<'!' || frombuff[i]>='~') from="weird";
-  }
-
-  if (!strcmp(frombuff, ".") || !strcasecmp(frombuff, "..")) from="weird";
-
-  if (!personal) {
-    if (strcmp(from, "weird")) {
-      char* temp = g_utf8_strdown(frombuff, -1);
-      if (temp) {
-	owl_free(frombuff);
-	from = frombuff = temp;
-      }
-    }
-  }
-
-  /* create the filename (expanding ~ in path names) */
-  if (personal) {
-    logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
-    snprintf(filename, MAXPATHLEN, "%s/%s", logpath, from);
-    snprintf(allfilename, MAXPATHLEN, "%s/all", logpath);
-    owl_log_append(m, allfilename);
-
-  } else {
-    logpath = owl_text_substitute(owl_global_get_classlogpath(&g), "~", owl_global_get_homedir(&g));
-    snprintf(filename, MAXPATHLEN, "%s/%s", logpath, from);
-  }
-
-  owl_log_append(m, filename);
-
-  if (personal && owl_message_is_type_zephyr(m)) {
-    /* We want to log to all of the CC'd people who were not us, or
-     * the sender, as well.
-     */
-    char *cc, *temp;
-    cc = owl_message_get_cc_without_recipient(m);
-    if (cc != NULL) {
-      temp = strtok(cc, " ");
-      while (temp != NULL) {
-        temp = short_zuser(temp);
-        if (strcasecmp(temp, frombuff) != 0) {
-          snprintf(filename, MAXPATHLEN, "%s/%s", logpath, temp);
-          owl_log_append(m, filename);
-        }
-        temp = strtok(NULL, " ");
-      }
-      owl_free(cc);
-    }
-  }
-
-  owl_free(frombuff);
-  owl_free(logpath);
-}
Index: inwin.c
===================================================================
--- mainwin.c	(revision c2c5c7772ea161470617ef920e22ef7570df5238)
+++ 	(revision )
@@ -1,162 +1,0 @@
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-void owl_mainwin_init(owl_mainwin *mw)
-{
-  mw->curtruncated=0;
-  mw->lastdisplayed=-1;
-}
-
-void owl_mainwin_redisplay(owl_mainwin *mw)
-{
-  owl_message *m;
-  int i, p, q, lines, isfull, viewsize;
-  int x, y, savey, recwinlines, start;
-  int topmsg, curmsg, fgcolor, bgcolor;
-  WINDOW *recwin;
-  owl_view *v;
-  owl_list *filtlist;
-  owl_filter *f;
-
-  recwin=owl_global_get_curs_recwin(&g);
-  topmsg=owl_global_get_topmsg(&g);
-  curmsg=owl_global_get_curmsg(&g);
-  v=owl_global_get_current_view(&g);
-  owl_fmtext_reset_colorpairs();
-
-  if (v==NULL) {
-    owl_function_debugmsg("Hit a null window in owl_mainwin_redisplay.");
-    return;
-  }
-
-  werase(recwin);
-
-  recwinlines=owl_global_get_recwin_lines(&g);
-  topmsg=owl_global_get_topmsg(&g);
-  viewsize=owl_view_get_size(v);
-
-  /* if there are no messages or if topmsg is past the end of the messages,
-   * just draw a blank screen */
-  if (viewsize==0 || topmsg>=viewsize) {
-    if (viewsize==0) {
-      owl_global_set_topmsg(&g, 0);
-    }
-    mw->curtruncated=0;
-    mw->lastdisplayed=-1;
-    wnoutrefresh(recwin);
-    owl_global_set_needrefresh(&g);
-    return;
-  }
-
-  /* write the messages out */
-  isfull=0;
-  mw->curtruncated=0;
-  mw->lasttruncated=0;
-
-  for (i=topmsg; i<viewsize; i++) {
-    if (isfull) break;
-    m=owl_view_get_element(v, i);
-
-    /* hold on to y in case this is the current message or deleted */
-    getyx(recwin, y, x);
-    savey=y;
-
-    /* if it's the current message, account for a vert_offset */
-    if (i==owl_global_get_curmsg(&g)) {
-      start=owl_global_get_curmsg_vert_offset(&g);
-      lines=owl_message_get_numlines(m)-start;
-    } else {
-      start=0;
-      lines=owl_message_get_numlines(m);
-    }
-
-    /* if we match filters set the color */
-    fgcolor=OWL_COLOR_DEFAULT;
-    bgcolor=OWL_COLOR_DEFAULT;
-    filtlist=owl_global_get_filterlist(&g);
-    q=owl_list_get_size(filtlist);
-    for (p=0; p<q; p++) {
-      f=owl_list_get_element(filtlist, p);
-      if ((owl_filter_get_fgcolor(f)!=OWL_COLOR_DEFAULT) ||
-          (owl_filter_get_bgcolor(f)!=OWL_COLOR_DEFAULT)) {
-        if (owl_filter_message_match(f, m)) {
-          if (owl_filter_get_fgcolor(f)!=OWL_COLOR_DEFAULT) fgcolor=owl_filter_get_fgcolor(f);
-          if (owl_filter_get_bgcolor(f)!=OWL_COLOR_DEFAULT) bgcolor=owl_filter_get_bgcolor(f);
-	}
-      }
-    }
-
-    /* if we'll fill the screen print a partial message */
-    if ((y+lines > recwinlines) && (i==owl_global_get_curmsg(&g))) mw->curtruncated=1;
-    if (y+lines > recwinlines) mw->lasttruncated=1;
-    if (y+lines > recwinlines-1) {
-      isfull=1;
-      owl_message_curs_waddstr(m, owl_global_get_curs_recwin(&g),
-			       start,
-			       start+recwinlines-y,
-			       owl_global_get_rightshift(&g),
-			       owl_global_get_cols(&g)+owl_global_get_rightshift(&g)-1,
-			       fgcolor, bgcolor);
-    } else {
-      /* otherwise print the whole thing */
-      owl_message_curs_waddstr(m, owl_global_get_curs_recwin(&g),
-			       start,
-			       start+lines,
-			       owl_global_get_rightshift(&g),
-			       owl_global_get_cols(&g)+owl_global_get_rightshift(&g)-1,
-			       fgcolor, bgcolor);
-    }
-
-
-    /* is it the current message and/or deleted? */
-    getyx(recwin, y, x);
-    wattrset(recwin, A_NORMAL);
-    if (owl_global_get_rightshift(&g)==0) {   /* this lame and should be fixed */
-      if (m==owl_view_get_element(v, curmsg)) {
-	wmove(recwin, savey, 0);
-	wattron(recwin, A_BOLD);	
-	if (owl_global_get_curmsg_vert_offset(&g)>0) {
-	  waddstr(recwin, "+");
-	} else {
-	  waddstr(recwin, "-");
-	}
-	if (!owl_message_is_delete(m)) {
-	  waddstr(recwin, ">");
-	} else {
-	  waddstr(recwin, "D");
-	}
-	wmove(recwin, y, x);
-	wattroff(recwin, A_BOLD);
-      } else if (owl_message_is_delete(m)) {
-	wmove(recwin, savey, 0);
-	waddstr(recwin, " D");
-	wmove(recwin, y, x);
-      }
-    }
-    wattroff(recwin, A_BOLD);
-  }
-  mw->lastdisplayed=i-1;
-
-  wnoutrefresh(recwin);
-  owl_global_set_needrefresh(&g);
-}
-
-
-int owl_mainwin_is_curmsg_truncated(owl_mainwin *mw)
-{
-  if (mw->curtruncated) return(1);
-  return(0);
-}
-
-int owl_mainwin_is_last_msg_truncated(owl_mainwin *mw)
-{
-  if (mw->lasttruncated) return(1);
-  return(0);
-}
-
-int owl_mainwin_get_last_msg(owl_mainwin *mw)
-{
-  /* return the number of the last message displayed. -1 if none */
-  return(mw->lastdisplayed);
-}
Index: ssage.c
===================================================================
--- message.c	(revision 147d88077919720ae7689914594bbda67e87d83b)
+++ 	(revision )
@@ -1,1024 +1,0 @@
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <time.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-static owl_fmtext_cache fmtext_cache[OWL_FMTEXT_CACHE_SIZE];
-static owl_fmtext_cache * fmtext_cache_next = fmtext_cache;
-
-void owl_message_init_fmtext_cache ()
-{
-    int i;
-    for(i = 0; i < OWL_FMTEXT_CACHE_SIZE; i++) {
-        owl_fmtext_init_null(&(fmtext_cache[i].fmtext));
-        fmtext_cache[i].message = NULL;
-    }
-}
-
-owl_fmtext_cache * owl_message_next_fmtext() /*noproto*/
-{
-    owl_fmtext_cache * f = fmtext_cache_next;
-    if(fmtext_cache_next->message != NULL) {
-        owl_message_invalidate_format(fmtext_cache_next->message);
-    }
-    fmtext_cache_next++;
-    if(fmtext_cache_next - fmtext_cache == OWL_FMTEXT_CACHE_SIZE)
-        fmtext_cache_next = fmtext_cache;
-    return f;
-}
-
-void owl_message_init(owl_message *m)
-{
-  m->id=owl_global_get_nextmsgid(&g);
-  owl_message_set_direction_none(m);
-  m->delete=0;
-
-  owl_message_set_hostname(m, "");
-  owl_list_create(&(m->attributes));
-  
-  /* save the time */
-  m->time=time(NULL);
-  m->timestr=owl_strdup(ctime(&(m->time)));
-  m->timestr[strlen(m->timestr)-1]='\0';
-
-  m->fmtext = NULL;
-}
-
-/* add the named attribute to the message.  If an attribute with the
- * name already exists, replace the old value with the new value
- */
-void owl_message_set_attribute(owl_message *m, char *attrname, char *attrvalue)
-{
-  int i, j;
-  owl_pair *p = NULL, *pair = NULL;
-
-  /* look for an existing pair with this key, */
-  j=owl_list_get_size(&(m->attributes));
-  for (i=0; i<j; i++) {
-    p=owl_list_get_element(&(m->attributes), i);
-    if (!strcmp(owl_pair_get_key(p), attrname)) {
-      owl_free(owl_pair_get_value(p));
-      pair = p;
-      break;
-    }
-  }
-
-  if(pair ==  NULL) {
-    pair = owl_malloc(sizeof(owl_pair));
-    owl_pair_create(pair, owl_global_intern(&g, attrname), NULL);
-    owl_list_append_element(&(m->attributes), pair);
-  }
-  owl_pair_set_value(pair, owl_validate_or_convert(attrvalue));
-}
-
-/* return the value associated with the named attribute, or NULL if
- * the attribute does not exist
- */
-char *owl_message_get_attribute_value(owl_message *m, char *attrname)
-{
-  int i, j;
-  owl_pair *p;
-
-  j=owl_list_get_size(&(m->attributes));
-  for (i=0; i<j; i++) {
-    p=owl_list_get_element(&(m->attributes), i);
-    if (!strcmp(owl_pair_get_key(p), attrname)) {
-      return(owl_pair_get_value(p));
-    }
-  }
-
-  /*
-  owl_function_debugmsg("No attribute %s found for message %i",
-			attrname,
-			owl_message_get_id(m));
-  */
-  return(NULL);
-}
-
-/* We cheat and indent it for now, since we really want this for
- * the 'info' function.  Later there should just be a generic
- * function to indent fmtext.
- */
-void owl_message_attributes_tofmtext(owl_message *m, owl_fmtext *fm) {
-  int i, j;
-  owl_pair *p;
-  char *buff;
-
-  owl_fmtext_init_null(fm);
-
-  j=owl_list_get_size(&(m->attributes));
-  for (i=0; i<j; i++) {
-    p=owl_list_get_element(&(m->attributes), i);
-    buff=owl_sprintf("  %-15.15s: %-35.35s\n", owl_pair_get_key(p), owl_pair_get_value(p));
-    if(buff == NULL) {
-      buff=owl_sprintf("  %-15.15s: %-35.35s\n", owl_pair_get_key(p), "<error>");
-      if(buff == NULL)
-        buff=owl_strdup("   <error>\n");
-    }
-    owl_fmtext_append_normal(fm, buff);
-    owl_free(buff);
-  }
-}
-
-void owl_message_invalidate_format(owl_message *m)
-{
-  if(m->fmtext) {
-    m->fmtext->message = NULL;
-    owl_fmtext_clear(&(m->fmtext->fmtext));
-    m->fmtext=NULL;
-  }
-}
-
-owl_fmtext *owl_message_get_fmtext(owl_message *m)
-{
-  owl_message_format(m);
-  return(&(m->fmtext->fmtext));
-}
-
-void owl_message_format(owl_message *m)
-{
-  owl_style *s;
-  owl_view *v;
-
-  if (!m->fmtext) {
-    m->fmtext = owl_message_next_fmtext();
-    m->fmtext->message = m;
-    /* for now we assume there's just the one view and use that style */
-    v=owl_global_get_current_view(&g);
-    s=owl_view_get_style(v);
-
-    owl_style_get_formattext(s, &(m->fmtext->fmtext), m);
-  }
-}
-
-void owl_message_set_class(owl_message *m, char *class)
-{
-  owl_message_set_attribute(m, "class", class);
-}
-
-char *owl_message_get_class(owl_message *m)
-{
-  char *class;
-
-  class=owl_message_get_attribute_value(m, "class");
-  if (!class) return("");
-  return(class);
-}
-
-void owl_message_set_instance(owl_message *m, char *inst)
-{
-  owl_message_set_attribute(m, "instance", inst);
-}
-
-char *owl_message_get_instance(owl_message *m)
-{
-  char *instance;
-
-  instance=owl_message_get_attribute_value(m, "instance");
-  if (!instance) return("");
-  return(instance);
-}
-
-void owl_message_set_sender(owl_message *m, char *sender)
-{
-  owl_message_set_attribute(m, "sender", sender);
-}
-
-char *owl_message_get_sender(owl_message *m)
-{
-  char *sender;
-
-  sender=owl_message_get_attribute_value(m, "sender");
-  if (!sender) return("");
-  return(sender);
-}
-
-void owl_message_set_zsig(owl_message *m, char *zsig)
-{
-  owl_message_set_attribute(m, "zsig", zsig);
-}
-
-char *owl_message_get_zsig(owl_message *m)
-{
-  char *zsig;
-
-  zsig=owl_message_get_attribute_value(m, "zsig");
-  if (!zsig) return("");
-  return(zsig);
-}
-
-void owl_message_set_recipient(owl_message *m, char *recip)
-{
-  owl_message_set_attribute(m, "recipient", recip);
-}
-
-char *owl_message_get_recipient(owl_message *m)
-{
-  /* this is stupid for outgoing messages, we need to fix it. */
-
-  char *recip;
-
-  recip=owl_message_get_attribute_value(m, "recipient");
-  if (!recip) return("");
-  return(recip);
-}
-
-void owl_message_set_realm(owl_message *m, char *realm)
-{
-  owl_message_set_attribute(m, "realm", realm);
-}
-
-char *owl_message_get_realm(owl_message *m)
-{
-  char *realm;
-  
-  realm=owl_message_get_attribute_value(m, "realm");
-  if (!realm) return("");
-  return(realm);
-}
-
-void owl_message_set_body(owl_message *m, char *body)
-{
-  owl_message_set_attribute(m, "body", body);
-}
-
-char *owl_message_get_body(owl_message *m)
-{
-  char *body;
-
-  body=owl_message_get_attribute_value(m, "body");
-  if (!body) return("");
-  return(body);
-}
-
-
-void owl_message_set_opcode(owl_message *m, char *opcode)
-{
-  owl_message_set_attribute(m, "opcode", opcode);
-}
-
-char *owl_message_get_opcode(owl_message *m)
-{
-  char *opcode;
-
-  opcode=owl_message_get_attribute_value(m, "opcode");
-  if (!opcode) return("");
-  return(opcode);
-}
-
-
-void owl_message_set_islogin(owl_message *m)
-{
-  owl_message_set_attribute(m, "loginout", "login");
-}
-
-
-void owl_message_set_islogout(owl_message *m)
-{
-  owl_message_set_attribute(m, "loginout", "logout");
-}
-
-int owl_message_is_loginout(owl_message *m)
-{
-  char *res;
-
-  res=owl_message_get_attribute_value(m, "loginout");
-  if (!res) return(0);
-  return(1);
-}
-
-int owl_message_is_login(owl_message *m)
-{
-  char *res;
-
-  res=owl_message_get_attribute_value(m, "loginout");
-  if (!res) return(0);
-  if (!strcmp(res, "login")) return(1);
-  return(0);
-}
-
-
-int owl_message_is_logout(owl_message *m)
-{
-  char *res;
-
-  res=owl_message_get_attribute_value(m, "loginout");
-  if (!res) return(0);
-  if (!strcmp(res, "logout")) return(1);
-  return(0);
-}
-
-void owl_message_set_isprivate(owl_message *m)
-{
-  owl_message_set_attribute(m, "isprivate", "true");
-}
-
-int owl_message_is_private(owl_message *m)
-{
-  char *res;
-
-  res=owl_message_get_attribute_value(m, "isprivate");
-  if (!res) return(0);
-  return !strcmp(res, "true");
-}
-
-char *owl_message_get_timestr(owl_message *m)
-{
-  if (m->timestr) return(m->timestr);
-  return("");
-}
-
-/* caller must free the return */
-char *owl_message_get_shorttimestr(owl_message *m)
-{
-  struct tm *tmstruct;
-  char *out;
-
-  tmstruct=localtime(&(m->time));
-  out=owl_sprintf("%2.2i:%2.2i", tmstruct->tm_hour, tmstruct->tm_min);
-  if (out) return(out);
-  return("??:??");
-}
-
-void owl_message_set_type_admin(owl_message *m)
-{
-  owl_message_set_attribute(m, "type", "admin");
-}
-
-void owl_message_set_type_loopback(owl_message *m)
-{
-  owl_message_set_attribute(m, "type", "loopback");
-}
-
-void owl_message_set_type_zephyr(owl_message *m)
-{
-  owl_message_set_attribute(m, "type", "zephyr");
-}
-
-void owl_message_set_type_aim(owl_message *m)
-{
-  owl_message_set_attribute(m, "type", "AIM");
-}
-
-void owl_message_set_type(owl_message *m, char* type)
-{
-  owl_message_set_attribute(m, "type", type);
-}
-
-int owl_message_is_type(owl_message *m, char *type) {
-  char * t = owl_message_get_attribute_value(m, "type");
-  if(!t) return 0;
-  return !strcasecmp(t, type);
-}
-						
-int owl_message_is_type_admin(owl_message *m)
-{
-  return owl_message_is_type(m, "admin");
-}
-
-int owl_message_is_type_generic(owl_message *m)
-{
-  char * t = owl_message_get_attribute_value(m, "type");
-  return (t == NULL);
-}
-
-int owl_message_is_type_zephyr(owl_message *m)
-{
-  return owl_message_is_type(m, "zephyr");
-}
-
-int owl_message_is_type_aim(owl_message *m)
-{
-  return owl_message_is_type(m, "aim");
-}
-
-/* XXX TODO: deprecate this */
-int owl_message_is_type_jabber(owl_message *m)
-{
-  return owl_message_is_type(m, "jabber");
-}
-
-int owl_message_is_type_loopback(owl_message *m)
-{
-  return owl_message_is_type(m, "loopback");
-}
-
-int owl_message_is_pseudo(owl_message *m)
-{
-  if (owl_message_get_attribute_value(m, "pseudo")) return(1);
-  return(0);
-}
-
-char *owl_message_get_text(owl_message *m)
-{
-  owl_message_format(m);
-  return(owl_fmtext_get_text(&(m->fmtext->fmtext)));
-}
-
-void owl_message_set_direction_in(owl_message *m)
-{
-  m->direction=OWL_MESSAGE_DIRECTION_IN;
-}
-
-void owl_message_set_direction_out(owl_message *m)
-{
-  m->direction=OWL_MESSAGE_DIRECTION_OUT;
-}
-
-void owl_message_set_direction_none(owl_message *m)
-{
-  m->direction=OWL_MESSAGE_DIRECTION_NONE;
-}
-
-void owl_message_set_direction(owl_message *m, int direction)
-{
-  m->direction=direction;
-}
-
-int owl_message_is_direction_in(owl_message *m)
-{
-  if (m->direction==OWL_MESSAGE_DIRECTION_IN) return(1);
-  return(0);
-}
-
-int owl_message_is_direction_out(owl_message *m)
-{
-  if (m->direction==OWL_MESSAGE_DIRECTION_OUT) return(1);
-  return(0);
-}
-
-int owl_message_is_direction_none(owl_message *m)
-{
-  if (m->direction==OWL_MESSAGE_DIRECTION_NONE) return(1);
-  return(0);
-}
-
-int owl_message_get_numlines(owl_message *m)
-{
-  if (m == NULL) return(0);
-  owl_message_format(m);
-  return(owl_fmtext_num_lines(&(m->fmtext->fmtext)));
-}
-
-void owl_message_mark_delete(owl_message *m)
-{
-  if (m == NULL) return;
-  m->delete=1;
-}
-
-void owl_message_unmark_delete(owl_message *m)
-{
-  if (m == NULL) return;
-  m->delete=0;
-}
-
-char *owl_message_get_zwriteline(owl_message *m)
-{
-  char *z = owl_message_get_attribute_value(m, "zwriteline");
-  if (!z) return "";
-  return z;
-}
-
-void owl_message_set_zwriteline(owl_message *m, char *line)
-{
-  owl_message_set_attribute(m, "zwriteline", line);
-}
-
-int owl_message_is_delete(owl_message *m)
-{
-  if (m == NULL) return(0);
-  if (m->delete==1) return(1);
-  return(0);
-}
-
-#ifdef HAVE_LIBZEPHYR
-ZNotice_t *owl_message_get_notice(owl_message *m)
-{
-  return(&(m->notice));
-}
-#else
-void *owl_message_get_notice(owl_message *m)
-{
-  return(NULL);
-}
-#endif
-
-void owl_message_set_hostname(owl_message *m, char *hostname)
-{
-  m->hostname=owl_global_intern(&g, hostname);
-}
-
-char *owl_message_get_hostname(owl_message *m)
-{
-  return(m->hostname);
-}
-
-void owl_message_curs_waddstr(owl_message *m, WINDOW *win, int aline, int bline, int acol, int bcol, int fgcolor, int bgcolor)
-{
-  owl_fmtext a, b;
-
-  /* this will ensure that our cached copy is up to date */
-  owl_message_format(m);
-
-  owl_fmtext_init_null(&a);
-  owl_fmtext_init_null(&b);
-  
-  owl_fmtext_truncate_lines(&(m->fmtext->fmtext), aline, bline-aline, &a);
-  owl_fmtext_truncate_cols(&a, acol, bcol, &b);
-  owl_fmtext_colorize(&b, fgcolor);
-  owl_fmtext_colorizebg(&b, bgcolor);
-
-  owl_fmtext_curs_waddstr(&b, win);
-
-  owl_fmtext_free(&a);
-  owl_fmtext_free(&b);
-}
-
-int owl_message_is_personal(owl_message *m)
-{
-  owl_filter * f = owl_global_get_filter(&g, "personal");
-  if(!f) {
-      owl_function_error("personal filter is not defined");
-      return (0);
-  }
-  return owl_filter_message_match(f, m);
-}
-
-int owl_message_is_question(owl_message *m)
-{
-  if(!owl_message_is_type_admin(m)) return 0;
-  if(owl_message_get_attribute_value(m, "question") != NULL) return 1;
-  return 0;
-}
-
-int owl_message_is_answered(owl_message *m) {
-  char *q;
-  if(!owl_message_is_question(m)) return 0;
-  q = owl_message_get_attribute_value(m, "question");
-  if(!q) return 0;
-  return !strcmp(q, "answered");
-}
-
-void owl_message_set_isanswered(owl_message *m) {
-  owl_message_set_attribute(m, "question", "answered");
-}
-
-int owl_message_is_from_me(owl_message *m)
-{
-  if (owl_message_is_type_zephyr(m)) {
-    if (!strcasecmp(owl_message_get_sender(m), owl_zephyr_get_sender())) {
-      return(1);
-    } else {
-      return(0);
-    }
-  } else if (owl_message_is_type_aim(m)) {
-    if (!strcasecmp(owl_message_get_sender(m), owl_global_get_aim_screenname(&g))) {
-      return(1);
-    } else {
-      return(0);
-    }
-  } else if (owl_message_is_type_admin(m)) {
-    return(0);
-  }
-  return(0);
-}
-
-int owl_message_is_mail(owl_message *m)
-{
-  if (owl_message_is_type_zephyr(m)) {
-    if (!strcasecmp(owl_message_get_class(m), "mail") && owl_message_is_private(m)) {
-      return(1);
-    } else {
-      return(0);
-    }
-  }
-  return(0);
-}
-
-int owl_message_is_ping(owl_message *m)
-{
-  if (owl_message_is_type_zephyr(m)) {
-    if (!strcasecmp(owl_message_get_opcode(m), "ping")) {
-      return(1);
-    } else {
-      return(0);
-    }
-  }
-  return(0);
-}
-
-/* caller must free return value. */
-char *owl_message_get_cc(owl_message *m)
-{
-  char *cur, *out, *end;
-
-  cur = owl_message_get_body(m);
-  while (*cur && *cur==' ') cur++;
-  if (strncasecmp(cur, "cc:", 3)) return(NULL);
-  cur+=3;
-  while (*cur && *cur==' ') cur++;
-  out = owl_strdup(cur);
-  end = strchr(out, '\n');
-  if (end) end[0] = '\0';
-  return(out);
-}
-
-/* caller must free return value */
-char *owl_message_get_cc_without_recipient(owl_message *m)
-{
-  char *cc, *out, *end, *user, *shortuser, *recip;
-
-  cc = owl_message_get_cc(m);
-  if (cc == NULL)
-    return NULL;
-
-  recip = short_zuser(owl_message_get_recipient(m));
-  out = owl_malloc(strlen(cc));
-  end = out;
-
-  user = strtok(cc, " ");
-  while (user != NULL) {
-    shortuser = short_zuser(user);
-    if (strcasecmp(shortuser, recip) != 0) {
-      strcpy(end, user);
-      end[strlen(user)] = ' ';
-      end += strlen(user) + 1;
-    }
-    free(shortuser);
-    user = strtok(NULL, " ");
-  }
-  end[0] = '\0';
-
-  owl_free(recip);
-  owl_free(cc);
-
-  if (strlen(out) == 0) {
-    owl_free(out);
-    out = NULL;
-  }
-
-  return(out);
-}
-
-int owl_message_get_id(owl_message *m)
-{
-  return(m->id);
-}
-
-char *owl_message_get_type(owl_message *m) {
-  char * type = owl_message_get_attribute_value(m, "type");
-  if(!type) {
-    return "generic";
-  }
-  return type;
-}
-
-char *owl_message_get_direction(owl_message *m) {
-  switch (m->direction) {
-  case OWL_MESSAGE_DIRECTION_IN:
-    return("in");
-  case OWL_MESSAGE_DIRECTION_OUT:
-    return("out");
-  case OWL_MESSAGE_DIRECTION_NONE:
-    return("none");
-  default:
-    return("unknown");
-  }
-}
-
-int owl_message_parse_direction(char *d) {
-  if(!strcmp(d, "in")) {
-    return OWL_MESSAGE_DIRECTION_IN;
-  } else if(!strcmp(d, "out")) {
-    return OWL_MESSAGE_DIRECTION_OUT;
-  } else {
-    return OWL_MESSAGE_DIRECTION_NONE;
-  }
-}
-
-
-char *owl_message_get_login(owl_message *m) {
-  if (owl_message_is_login(m)) {
-    return "login";
-  } else if (owl_message_is_logout(m)) {
-    return "logout";
-  } else {
-    return "none";
-  }
-}
-
-
-char *owl_message_get_header(owl_message *m) {
-  return owl_message_get_attribute_value(m, "adminheader");
-}
-
-/* return 1 if the message contains "string", 0 otherwise.  This is
- * case insensitive because the functions it uses are
- */
-int owl_message_search(owl_message *m, char *string)
-{
-
-  owl_message_format(m); /* is this necessary? */
-  
-  return (owl_fmtext_search(&(m->fmtext->fmtext), string));
-}
-
-
-/* if loginout == -1 it's a logout message
- *                 0 it's not a login/logout message
- *                 1 it's a login message
- */
-void owl_message_create_aim(owl_message *m, char *sender, char *recipient, char *text, int direction, int loginout)
-{
-  owl_message_init(m);
-  owl_message_set_body(m, text);
-  owl_message_set_sender(m, sender);
-  owl_message_set_recipient(m, recipient);
-  owl_message_set_type_aim(m);
-
-  if (direction==OWL_MESSAGE_DIRECTION_IN) {
-    owl_message_set_direction_in(m);
-  } else if (direction==OWL_MESSAGE_DIRECTION_OUT) {
-    owl_message_set_direction_out(m);
-  }
-
-  /* for now all messages that aren't loginout are private */
-  if (!loginout) {
-    owl_message_set_isprivate(m);
-  }
-
-  if (loginout==-1) {
-    owl_message_set_islogout(m);
-  } else if (loginout==1) {
-    owl_message_set_islogin(m);
-  }
-}
-
-void owl_message_create_admin(owl_message *m, char *header, char *text)
-{
-  owl_message_init(m);
-  owl_message_set_type_admin(m);
-  owl_message_set_body(m, text);
-  owl_message_set_attribute(m, "adminheader", header); /* just a hack for now */
-}
-
-/* caller should set the direction */
-void owl_message_create_loopback(owl_message *m, char *text)
-{
-  owl_message_init(m);
-  owl_message_set_type_loopback(m);
-  owl_message_set_body(m, text);
-  owl_message_set_sender(m, "loopsender");
-  owl_message_set_recipient(m, "looprecip");
-  owl_message_set_isprivate(m);
-}
-
-#ifdef HAVE_LIBZEPHYR
-void owl_message_create_from_znotice(owl_message *m, ZNotice_t *n)
-{
-  struct hostent *hent;
-  char *ptr, *tmp, *tmp2;
-  int len;
-
-  owl_message_init(m);
-  
-  owl_message_set_type_zephyr(m);
-  owl_message_set_direction_in(m);
-  
-  /* first save the full notice */
-  memcpy(&(m->notice), n, sizeof(ZNotice_t));
-
-  /* a little gross, we'll replace \r's with ' ' for now */
-  owl_zephyr_hackaway_cr(&(m->notice));
-  
-  /* save the time, we need to nuke the string saved by message_init */
-  if (m->timestr) owl_free(m->timestr);
-  m->time=n->z_time.tv_sec;
-  m->timestr=owl_strdup(ctime(&(m->time)));
-  m->timestr[strlen(m->timestr)-1]='\0';
-
-  /* set other info */
-  owl_message_set_sender(m, n->z_sender);
-  owl_message_set_class(m, n->z_class);
-  owl_message_set_instance(m, n->z_class_inst);
-  owl_message_set_recipient(m, n->z_recipient);
-  if (n->z_opcode) {
-    owl_message_set_opcode(m, n->z_opcode);
-  } else {
-    owl_message_set_opcode(m, "");
-  }
-  owl_message_set_zsig(m, owl_zephyr_get_zsig(n, &len));
-
-  if ((ptr=strchr(n->z_recipient, '@'))!=NULL) {
-    owl_message_set_realm(m, ptr+1);
-  } else {
-    owl_message_set_realm(m, owl_zephyr_get_realm());
-  }
-
-  /* Set the "isloginout" attribute if it's a login message */
-  if (!strcasecmp(n->z_class, "login") || !strcasecmp(n->z_class, OWL_WEBZEPHYR_CLASS)) {
-    if (!strcasecmp(n->z_opcode, "user_login") || !strcasecmp(n->z_opcode, "user_logout")) {
-      tmp=owl_zephyr_get_field(n, 1);
-      owl_message_set_attribute(m, "loginhost", tmp);
-      owl_free(tmp);
-
-      tmp=owl_zephyr_get_field(n, 3);
-      owl_message_set_attribute(m, "logintty", tmp);
-      owl_free(tmp);
-    }
-
-    if (!strcasecmp(n->z_opcode, "user_login")) {
-      owl_message_set_islogin(m);
-    } else if (!strcasecmp(n->z_opcode, "user_logout")) {
-      owl_message_set_islogout(m);
-    }
-  }
-
-  
-  /* set the "isprivate" attribute if it's a private zephyr.
-   ``private'' means recipient is non-empty and doesn't start wit 
-   `@' */
-  if (*n->z_recipient && *n->z_recipient != '@') {
-    owl_message_set_isprivate(m);
-  }
-
-  /* set the "isauto" attribute if it's an autoreply */
-  if (!strcasecmp(n->z_message, "Automated reply:") ||
-      !strcasecmp(n->z_opcode, "auto")) {
-    owl_message_set_attribute(m, "isauto", "");
-  }
-
-  /* save the hostname */
-  owl_function_debugmsg("About to do gethostbyaddr");
-  hent=gethostbyaddr((char *) &(n->z_uid.zuid_addr), sizeof(n->z_uid.zuid_addr), AF_INET);
-  if (hent && hent->h_name) {
-    owl_message_set_hostname(m, hent->h_name);
-  } else {
-    owl_message_set_hostname(m, inet_ntoa(n->z_sender_addr));
-  }
-
-  /* set the body */
-  tmp=owl_zephyr_get_message(n, m);
-  if (owl_global_is_newlinestrip(&g)) {
-    tmp2=owl_util_stripnewlines(tmp);
-    owl_message_set_body(m, tmp2);
-    owl_free(tmp2);
-  } else {
-    owl_message_set_body(m, tmp);
-  }
-  owl_free(tmp);
-
-#ifdef OWL_ENABLE_ZCRYPT
-  /* if zcrypt is enabled try to decrypt the message */
-  if (owl_global_is_zcrypt(&g) && !strcasecmp(n->z_opcode, "crypt")) {
-    char *out;
-    int ret;
-
-    out=owl_malloc(strlen(owl_message_get_body(m))*16+20);
-    ret=owl_zcrypt_decrypt(out, owl_message_get_body(m), owl_message_get_class(m), owl_message_get_instance(m));
-    if (ret==0) {
-      owl_message_set_body(m, out);
-    } else {
-      owl_free(out);
-    }
-  }
-#endif  
-}
-#else
-void owl_message_create_from_znotice(owl_message *m, void *n)
-{
-}
-#endif
-
-/* If 'direction' is '0' it is a login message, '1' is a logout message. */
-void owl_message_create_pseudo_zlogin(owl_message *m, int direction, char *user, char *host, char *time, char *tty)
-{
-  char *longuser, *ptr;
-
-#ifdef HAVE_LIBZEPHYR
-  memset(&(m->notice), 0, sizeof(ZNotice_t));
-#endif
-  
-  longuser=long_zuser(user);
-  
-  owl_message_init(m);
-  
-  owl_message_set_type_zephyr(m);
-  owl_message_set_direction_in(m);
-
-  owl_message_set_attribute(m, "pseudo", "");
-  owl_message_set_attribute(m, "loginhost", host ? host : "");
-  owl_message_set_attribute(m, "logintty", tty ? tty : "");
-
-  owl_message_set_sender(m, longuser);
-  owl_message_set_class(m, "LOGIN");
-  owl_message_set_instance(m, longuser);
-  owl_message_set_recipient(m, "");
-  if (direction==0) {
-    owl_message_set_opcode(m, "USER_LOGIN");
-    owl_message_set_islogin(m);
-  } else if (direction==1) {
-    owl_message_set_opcode(m, "USER_LOGOUT");
-    owl_message_set_islogout(m);
-  }
-
-  if ((ptr=strchr(longuser, '@'))!=NULL) {
-    owl_message_set_realm(m, ptr+1);
-  } else {
-    owl_message_set_realm(m, owl_zephyr_get_realm());
-  }
-
-  owl_message_set_body(m, "<uninitialized>");
-
-  /* save the hostname */
-  owl_function_debugmsg("create_pseudo_login: host is %s", host ? host : "");
-  owl_message_set_hostname(m, host ? host : "");
-  owl_free(longuser);
-}
-
-void owl_message_create_from_zwriteline(owl_message *m, char *line, char *body, char *zsig)
-{
-  owl_zwrite z;
-  int ret;
-  char hostbuff[5000];
-  
-  owl_message_init(m);
-
-  /* create a zwrite for the purpose of filling in other message fields */
-  owl_zwrite_create_from_line(&z, line);
-
-  /* set things */
-  owl_message_set_direction_out(m);
-  owl_message_set_type_zephyr(m);
-  owl_message_set_sender(m, owl_zephyr_get_sender());
-  owl_message_set_class(m, owl_zwrite_get_class(&z));
-  owl_message_set_instance(m, owl_zwrite_get_instance(&z));
-  if (owl_zwrite_get_numrecips(&z)>0) {
-    owl_message_set_recipient(m,
-			      long_zuser(owl_zwrite_get_recip_n(&z, 0))); /* only gets the first user, must fix */
-  }
-  owl_message_set_opcode(m, owl_zwrite_get_opcode(&z));
-  owl_message_set_realm(m, owl_zwrite_get_realm(&z)); /* also a hack, but not here */
-  owl_message_set_zwriteline(m, line);
-  owl_message_set_body(m, body);
-  owl_message_set_zsig(m, zsig);
-  
-  /* save the hostname */
-  ret=gethostname(hostbuff, MAXHOSTNAMELEN);
-  hostbuff[MAXHOSTNAMELEN]='\0';
-  if (ret) {
-    owl_message_set_hostname(m, "localhost");
-  } else {
-    owl_message_set_hostname(m, hostbuff);
-  }
-
-  /* set the "isprivate" attribute if it's a private zephyr. */
-  if (owl_zwrite_is_personal(&z)) {
-    owl_message_set_isprivate(m);
-  }
-
-  owl_zwrite_free(&z);
-}
-
-void owl_message_pretty_zsig(owl_message *m, char *buff)
-{
-  /* stick a one line version of the zsig in buff */
-  char *ptr;
-
-  strcpy(buff, owl_message_get_zsig(m));
-  ptr=strchr(buff, '\n');
-  if (ptr) ptr[0]='\0';
-}
-
-void owl_message_free(owl_message *m)
-{
-  int i, j;
-  owl_pair *p;
-#ifdef HAVE_LIBZEPHYR    
-  if (owl_message_is_type_zephyr(m) && owl_message_is_direction_in(m)) {
-    ZFreeNotice(&(m->notice));
-  }
-#endif
-  if (m->timestr) owl_free(m->timestr);
-
-  /* free all the attributes */
-  j=owl_list_get_size(&(m->attributes));
-  for (i=0; i<j; i++) {
-    p=owl_list_get_element(&(m->attributes), i);
-    owl_free(owl_pair_get_value(p));
-    owl_free(p);
-  }
-
-  owl_list_free_simple(&(m->attributes));
- 
-  owl_message_invalidate_format(m);
-}
Index: ssagelist.c
===================================================================
--- messagelist.c	(revision 0c8ab5eadbb6ecc97a120c91b9a824b33538c764)
+++ 	(revision )
@@ -1,104 +1,0 @@
-#include "owl.h"
-#include <stdlib.h>
-#include <string.h>
-
-static const char fileIdent[] = "$Id$";
-
-int owl_messagelist_create(owl_messagelist *ml)
-{
-  owl_list_create(&(ml->list));
-  return(0);
-}
-
-int owl_messagelist_get_size(owl_messagelist *ml)
-{
-  return(owl_list_get_size(&(ml->list)));
-}
-
-void *owl_messagelist_get_element(owl_messagelist *ml, int n)
-{
-  return(owl_list_get_element(&(ml->list), n));
-}
-
-owl_message *owl_messagelist_get_by_id(owl_messagelist *ml, int target_id)
-{
-  /* return the message with id == 'id'.  If it doesn't exist return NULL. */
-  int first, last, mid, msg_id;
-  owl_message *m;
-
-  first = 0;
-  last = owl_list_get_size(&(ml->list)) - 1;
-  while (first <= last) {
-    mid = (first + last) / 2;
-    m = owl_list_get_element(&(ml->list), mid);
-    msg_id = owl_message_get_id(m);
-    if (msg_id == target_id) {
-      return(m);
-    } else if (msg_id < target_id) {
-      first = mid + 1;
-    } else {
-      last = mid - 1;
-    }
-  }
-  return(NULL);
-}
-
-int owl_messagelist_append_element(owl_messagelist *ml, void *element)
-{
-  return(owl_list_append_element(&(ml->list), element));
-}
-
-/* do we really still want this? */
-int owl_messagelist_delete_element(owl_messagelist *ml, int n)
-{
-  /* mark a message as deleted */
-  owl_message_mark_delete(owl_list_get_element(&(ml->list), n));
-  return(0);
-}
-
-int owl_messagelist_undelete_element(owl_messagelist *ml, int n)
-{
-  /* mark a message as deleted */
-  owl_message_unmark_delete(owl_list_get_element(&(ml->list), n));
-  return(0);
-}
-
-int owl_messagelist_expunge(owl_messagelist *ml)
-{
-  /* expunge deleted messages */
-  int i, j;
-  owl_list newlist;
-  owl_message *m;
-
-  owl_list_create(&newlist);
-  /*create a new list without messages marked as deleted */
-  j=owl_list_get_size(&(ml->list));
-  for (i=0; i<j; i++) {
-    m=owl_list_get_element(&(ml->list), i);
-    if (owl_message_is_delete(m)) {
-      owl_message_free(m);
-    } else {
-      owl_list_append_element(&newlist, m);
-    }
-  }
-
-  /* free the old list */
-  owl_list_free_simple(&(ml->list));
-
-  /* copy the new list to the old list */
-  memcpy(&(ml->list), &newlist, sizeof(owl_list));
-
-  return(0);
-}
-
-void owl_messagelist_invalidate_formats(owl_messagelist *ml)
-{
-  int i, j;
-  owl_message *m;
-
-  j=owl_list_get_size(&(ml->list));
-  for (i=0; i<j; i++) {
-    m=owl_list_get_element(&(ml->list), i);
-    owl_message_invalidate_format(m);
-  }
-}
Index: installdirs
===================================================================
--- mkinstalldirs	(revision 5471a9885a9bc1a848baf5fcc075a0eeea1d83eb)
+++ 	(revision )
@@ -1,40 +1,0 @@
-#! /bin/sh
-# mkinstalldirs --- make directory hierarchy
-# Author: Noah Friedman <friedman@prep.ai.mit.edu>
-# Created: 1993-05-16
-# Public domain
-
-# $Id$
-
-errstatus=0
-
-for file
-do
-   set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
-   shift
-
-   pathcomp=
-   for d
-   do
-     pathcomp="$pathcomp$d"
-     case "$pathcomp" in
-       -* ) pathcomp=./$pathcomp ;;
-     esac
-
-     if test ! -d "$pathcomp"; then
-        echo "mkdir $pathcomp"
-
-        mkdir "$pathcomp" || lasterr=$?
-
-        if test ! -d "$pathcomp"; then
-  	  errstatus=$lasterr
-        fi
-     fi
-
-     pathcomp="$pathcomp/"
-   done
-done
-
-exit $errstatus
-
-# mkinstalldirs ends here
Index: xevents.c
===================================================================
--- muxevents.c	(revision 948b94240edb7210e2db1029e279718ea7fe3aac)
+++ 	(revision )
@@ -1,129 +1,0 @@
-#include <sys/poll.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id $";
-
-#define OWL_MUX_MAX_FD (FD_SETSIZE-1)
-
-static int owl_mux_nexthandle = 5000; /* next handle to hand out */
-static int owl_mux_needgc = 0;	/* number of muxevents needing to be gc'd */
-
-/* returns a handle id or 0 on failure */
-int owl_muxevents_add(owl_muxevents *muxevents, int fd, int eventmask, void (*handler_fn)(int handle, int fd, int eventmask, void *data), void *data)
-{
-  owl_mux *mux;
-  
-  mux = owl_malloc(sizeof(owl_mux));
-  if (!mux) return 0;
-  if (fd > OWL_MUX_MAX_FD) {
-    owl_function_error("owl_muxevents_add: fd %d too large", fd);
-    return 0;
-  }
-  mux->handle = owl_mux_nexthandle++;
-  mux->fd = fd;
-  mux->active = 1;
-  mux->eventmask = eventmask;
-  mux->data = data;
-  mux->handler_fn = handler_fn;
-  if (0!=owl_list_append_element(muxevents, mux)) {
-    owl_free(mux);
-    return(0);
-  }
-  return mux->handle;
-}
-
-/* deactivates a muxevent entry with the given handle */
-void owl_muxevents_remove(owl_muxevents *muxevents, int handle)
-{
-  int max, i;
-  owl_mux *m;
-
-  max = owl_list_get_size(muxevents);
-  for (i=0; i<max; i++) {
-    m = (owl_mux*)owl_list_get_element(muxevents, i);
-    if (m->handle == handle) {
-      m->active=0;
-      owl_mux_needgc++;
-    }
-  }
-}
-
-/* cleans up a muxevents list at a safe time (ie, when it is
-   not being traversed). */
-void owl_muxevents_gc(owl_muxevents *muxevents)
-{
-  int max, i, done=0;
-  owl_mux *m;
-
-  if (!owl_mux_needgc) return;
-  while (!done) {
-    max = owl_list_get_size(muxevents);
-    for (i=0; i<max; i++) {
-      m = (owl_mux*)owl_list_get_element(muxevents, i);
-      if (!m->active) {
-	owl_list_remove_element(muxevents, i);
-	owl_free(m);
-	owl_mux_needgc--;
-	break;
-      }
-    }  
-    if (i==max) done=1;
-  }
-}
-
-/* dispatches out events */
-void owl_muxevents_dispatch(owl_muxevents *muxevents, int timeout_usec)
-{
-  int nevents, i, rv, emask;
-  owl_mux *m;
-  fd_set rfds, wfds, efds;
-  int maxfd=0;
-  struct timeval tv;
-
-  FD_ZERO(&rfds);
-  FD_ZERO(&wfds);
-  FD_ZERO(&efds);
-  nevents = owl_list_get_size(muxevents);
-  for (i=0; i<nevents; i++) {
-      m = (owl_mux*)owl_list_get_element(muxevents, i);
-      if (m->eventmask & OWL_MUX_READ)   FD_SET(m->fd, &rfds);
-      if (m->eventmask & OWL_MUX_WRITE)  FD_SET(m->fd, &wfds);
-      if (m->eventmask & OWL_MUX_EXCEPT) FD_SET(m->fd, &efds);
-      if (m->fd > maxfd) maxfd = m->fd;
-  }
-  tv.tv_sec = 0;
-  tv.tv_usec = timeout_usec;
-  rv = select(maxfd+1, &rfds, &wfds, &efds, &tv);
-  if (rv == 0) return;
-  
-  for (i=0; i<nevents; i++) {
-      m = (owl_mux*)owl_list_get_element(muxevents, i);
-      if (!m->active) continue;
-      emask = 0;
-      if (m->eventmask & OWL_MUX_READ && FD_ISSET(m->fd, &rfds)) {
-	emask |= OWL_MUX_READ;
-      }
-      if (m->eventmask & OWL_MUX_WRITE && FD_ISSET(m->fd, &wfds)) {
-	emask |= OWL_MUX_WRITE;
-      }
-      if (m->eventmask & OWL_MUX_EXCEPT && FD_ISSET(m->fd, &efds)) {
-	emask |= OWL_MUX_EXCEPT;
-      }
-      owl_function_debugmsg("muxevents: dispatching %s%s%s to %d\n",
-			    emask&OWL_MUX_READ?"[read]":"",
-			    emask&OWL_MUX_WRITE?"[write]":"",
-			    emask&OWL_MUX_EXCEPT?"[except]":"",
-			    m->fd);
-      if (emask) {
-	m->handler_fn(m->handle, m->fd, emask, m->data);
-      }
-  }
-
-  owl_function_debugmsg("muxevents: finishing dispatch\n");
-  /* we need to do this here so that the size of muxevents
-  * doesn't change while we're traversing it... */
-  owl_muxevents_gc(muxevents);
-}
Index: array.c
===================================================================
--- obarray.c	(revision af1920fd98d8d860245a197dee998e0e5c337285)
+++ 	(revision )
@@ -1,104 +1,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include "owl.h"
-
-/*
- * At the moment, the obarray is represented as a sorted list of
- * strings. I judge this a reasonable tradeoff between simplicity and
- * reasonable efficient lookup (insertion should be comparatively
- * rare)
- */
-
-/* Helper method: Lookup a key in the obarray. If the key exists,
- * return its index, and the interned value in *val. Otherwise, return
- * the index it should be inserted at.
- */
-int owl_obarray_lookup(owl_obarray *oa, char * key, char ** val) /*noproto*/
-{
-  int first, last, mid;
-  char * str;
-  int cmp;
-
-  mid = 0;
-  first = 0;
-  last = owl_list_get_size(&(oa->strings)) - 1;
-  while(first <= last) {
-    mid = first + (last - first)/2;
-    str = (char*)owl_list_get_element(&(oa->strings), mid);
-    cmp = strcmp(key, str);
-    if(cmp == 0) {
-      *val = str;
-      return mid;
-    } else if(cmp < 0) {
-      first = mid + 1;
-    } else {
-      last = mid - 1;
-    }
-  }
-  *val = NULL;
-  return mid;
-}
-
-/* Returns NULL if the string doesn't exist in the obarray */
-char * owl_obarray_find(owl_obarray *oa, char * string)
-{
-  char *v;
-  owl_obarray_lookup(oa, string, &v);
-  return v;
-}
-
-/* Inserts the string into the obarray if it doesn't exist */
-char * owl_obarray_insert(owl_obarray *oa, char * string)
-{
-  char *v;
-  int i;
-  i = owl_obarray_lookup(oa, string, &v);
-  if(!v) {
-    v = owl_strdup(string);
-    owl_list_insert_element(&(oa->strings), i, v);
-  }
-  return v;
-}
-
-void owl_obarray_init(owl_obarray *oa)
-{
-  owl_list_create(&(oa->strings));
-}
-
-/**************************************************************************/
-/************************* REGRESSION TESTS *******************************/
-/**************************************************************************/
-
-#ifdef OWL_INCLUDE_REG_TESTS
-
-#include "test.h"
-
-int owl_obarray_regtest(void) {
-  int numfailed = 0;
-  char *p,*p2;
-
-  owl_obarray oa;
-  owl_obarray_init(&oa);
-
-  printf("# BEGIN testing owl_obarray\n");
-
-  p = owl_obarray_insert(&oa, "test");
-  FAIL_UNLESS("returned string is equal", p && !strcmp(p, "test"));
-  p2 = owl_obarray_insert(&oa, "test");
-  FAIL_UNLESS("returned string is equal", p2 && !strcmp(p2, "test"));
-  FAIL_UNLESS("returned the same string", p2 && p == p2);
-
-  p = owl_obarray_insert(&oa, "test2");
-  FAIL_UNLESS("returned string is equal", p && !strcmp(p, "test2"));
-  p2 = owl_obarray_find(&oa, "test2");
-  FAIL_UNLESS("returned the same string", p2 && !strcmp(p2, "test2"));
-
-  p = owl_obarray_find(&oa, "nothere");
-  FAIL_UNLESS("Didn't find a string that isn't there", p == NULL);
-
-  printf("# END testing owl_obarray (%d failures)\n", numfailed);
-
-  return numfailed;
-}
-
-#endif /* OWL_INCLUDE_REG_TESTS */
Index: l.c
===================================================================
--- owl.c	(revision 5b37c063d5a6a7a9fdfe3cde5a21e30d94beee7b)
+++ 	(revision )
@@ -1,782 +1,0 @@
-/*  Copyright (c) 2006-2008 The BarnOwl Developers. All rights reserved.
- *  Copyright (c) 2004 James Kretchmar. All rights reserved.
- *
- *  This program is free software. You can redistribute it and/or
- *  modify under the terms of the Sleepycat License. See the COPYING
- *  file included with the distribution for more information.
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-#include <time.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <termios.h>
-#include <sys/stat.h>
-#include <locale.h>
-#include "owl.h"
-
-
-#if OWL_STDERR_REDIR
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_FILIO_H
-#include <sys/filio.h>
-#endif
-int stderr_replace(void);
-#endif
-
-#define STDIN 0
-
-static const char fileIdent[] = "$Id$";
-
-owl_global g;
-
-int main(int argc, char **argv, char **env)
-{
-  WINDOW *recwin, *sepwin, *typwin, *msgwin;
-  owl_editwin *tw;
-  owl_popwin *pw;
-  int ret, initialsubs, debug, argcsave, followlast;
-  int newmsgs, nexttimediff;
-  struct sigaction sigact;
-  char *configfile, *tty, *perlout, *perlerr, **argvsave, buff[LINE], startupmsg[LINE];
-  char *confdir;
-  owl_filter *f;
-  owl_style *s;
-  time_t nexttime, now;
-  struct tm *today;
-  char *dir;
-  struct termios tio;
-  owl_message *m;
-#if OWL_STDERR_REDIR
-  int newstderr;
-#endif
-  
-  if (!GLIB_CHECK_VERSION (2, 12, 0))
-    g_error ("GLib version 2.12.0 or above is needed.");
-
-  argcsave=argc;
-  argvsave=argv;
-  configfile=NULL;
-  confdir = NULL;
-  tty=NULL;
-  debug=0;
-  initialsubs=1;
-
-  setlocale(LC_ALL, "");
-  
-  if (argc>0) {
-    argv++;
-    argc--;
-  }
-  while (argc>0) {
-    if (!strcmp(argv[0], "-n")) {
-      initialsubs=0;
-      argv++;
-      argc--;
-    } else if (!strcmp(argv[0], "-c")) {
-      if (argc<2) {
-        fprintf(stderr, "Too few arguments to -c\n");
-        usage();
-        exit(1);
-      }
-      configfile=argv[1];
-      argv+=2;
-      argc-=2;
-    } else if (!strcmp(argv[0], "-t")) {
-      if (argc<2) {
-        fprintf(stderr, "Too few arguments to -t\n");
-        usage();
-        exit(1);
-      }
-      tty=argv[1];
-      argv+=2;
-      argc-=2;
-    } else if (!strcmp(argv[0], "-s")){
-      if (argc<2) {
-        fprintf(stderr, "Too few arguments to -s\n");
-        usage();
-        exit(1);
-      }
-      confdir = argv[1];
-      argv+=2;
-      argc-=2;
-    } else if (!strcmp(argv[0], "-d")) {
-      debug=1;
-      argv++;
-      argc--;
-    } else if (!strcmp(argv[0], "-D")) {
-      debug=1;
-      unlink(OWL_DEBUG_FILE);
-      argv++;
-      argc--;
-    } else if (!strcmp(argv[0], "-v")) {
-      printf("This is barnowl version %s\n", OWL_VERSION_STRING);
-      exit(0);
-    } else {
-      fprintf(stderr, "Unknown argument\n");
-      usage();	      
-      exit(1);
-    }
-  }
-
-  owl_function_debugmsg("startup: Finished parsing arguments");
-
-  /* signal handler */
-  /*sigact.sa_handler=sig_handler;*/
-  sigact.sa_sigaction=sig_handler;
-  sigemptyset(&sigact.sa_mask);
-  sigact.sa_flags=SA_SIGINFO;
-  sigaction(SIGWINCH, &sigact, NULL);
-  sigaction(SIGALRM, &sigact, NULL);
-  sigaction(SIGPIPE, &sigact, NULL);
-  sigaction(SIGTERM, &sigact, NULL);
-  sigaction(SIGHUP, &sigact, NULL);
-
-  /* save initial terminal settings */
-  tcgetattr(0, owl_global_get_startup_tio(&g));
-
-  /* turn ISTRIP off */
-  tcgetattr(0, &tio);
-  tio.c_iflag &= ~ISTRIP;
-  tcsetattr(0, TCSAFLUSH, &tio);
-
-  /* screen init */
-  if (!getenv("TERMINFO")) {
-    owl_function_debugmsg("startup: Not setting TERMINFO");
-  } else {
-    owl_function_debugmsg("startup: leaving TERMINFO as %s from envrionment", getenv("TERMINFO"));
-  }
-  initscr();
-  start_color();
-#ifdef HAVE_USE_DEFAULT_COLORS
-  use_default_colors();
-#endif
-  raw();
-  noecho();
-
-  /* define simple color pairs */
-  if (has_colors() && COLOR_PAIRS>=8) {
-    int bg = COLOR_BLACK;
-#ifdef HAVE_USE_DEFAULT_COLORS
-    bg = -1;
-#endif
-    init_pair(OWL_COLOR_BLACK,   COLOR_BLACK,   bg);
-    init_pair(OWL_COLOR_RED,     COLOR_RED,     bg);
-    init_pair(OWL_COLOR_GREEN,   COLOR_GREEN,   bg);
-    init_pair(OWL_COLOR_YELLOW,  COLOR_YELLOW,  bg);
-    init_pair(OWL_COLOR_BLUE,    COLOR_BLUE,    bg);
-    init_pair(OWL_COLOR_MAGENTA, COLOR_MAGENTA, bg);
-    init_pair(OWL_COLOR_CYAN,    COLOR_CYAN,    bg);
-    init_pair(OWL_COLOR_WHITE,   COLOR_WHITE,   bg);
-  }
-
-  /* owl global init */
-  owl_global_init(&g);
-  if (debug) owl_global_set_debug_on(&g);
-  if (confdir) owl_global_set_confdir(&g, confdir);
-  owl_function_debugmsg("startup: first available debugging message");
-  owl_global_set_startupargs(&g, argcsave, argvsave);
-  owl_global_set_haveaim(&g);
-
-  /* prepare stdin dispatch */
-  {
-    owl_dispatch *d = owl_malloc(sizeof(owl_dispatch));
-    d->fd = STDIN;
-    d->cfunc = &owl_process_input;
-    d->pfunc = NULL;
-    owl_select_add_dispatch(d);
-  }
-  
-#ifdef HAVE_LIBZEPHYR
-  /* zephyr init */
-  ret=owl_zephyr_initialize();
-  if (!ret) {
-    owl_dispatch *d = owl_malloc(sizeof(owl_dispatch));
-    d->fd = ZGetFD();
-    d->cfunc = &owl_zephyr_process_events;
-    d->pfunc = NULL;
-    owl_select_add_dispatch(d);
-    owl_global_set_havezephyr(&g);
-  }
-
-#endif
-
-#if OWL_STDERR_REDIR
-  /* Do this only after we've started curses up... */
-  owl_function_debugmsg("startup: doing stderr redirection");
-  newstderr = stderr_replace();
-  owl_muxevents_add(owl_global_get_muxevents(&g), newstderr, OWL_MUX_READ,
-		    stderr_redirect_handler, NULL);
-#endif   
-
-  /* create the owl directory, in case it does not exist */
-  owl_function_debugmsg("startup: creating owl directory, if not present");
-  dir=owl_global_get_confdir(&g);
-  mkdir(dir, S_IRWXU);
-
-  /* set the tty, either from the command line, or by figuring it out */
-  owl_function_debugmsg("startup: setting tty name");
-  if (tty) {
-    owl_global_set_tty(&g, tty);
-  } else {
-    owl_global_set_tty(&g, owl_util_get_default_tty());
-  }
-
-  /* Initialize perl */
-  owl_function_debugmsg("startup: processing config file");
-  owl_context_set_readconfig(owl_global_get_context(&g));
-  perlerr=owl_perlconfig_initperl(configfile, &argc, &argv, &env);
-  if (perlerr) {
-    endwin();
-    owl_function_error("Internal perl error: %s\n", perlerr);
-    fprintf(stderr, "Internal perl error: %s\n", perlerr);
-    fflush(stderr);
-    printf("Internal perl error: %s\n", perlerr);
-    fflush(stdout);
-    exit(1);
-  }
-
-  /* setup the default filters */
-  /* the personal filter will need to change again when AIM chat's are
-   *  included.  Also, there should be an %aimme% */
-  owl_function_debugmsg("startup: creating default filters");
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "personal", "isprivate ^true$ and ( not type ^zephyr$"
-                             " or ( class ^message and"
-                             " ( instance ^personal$ or instance ^urgent$ ) ) )");
-  owl_list_append_element(owl_global_get_filterlist(&g), f);
-
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "wordwrap", "not ( type ^admin$ or type ^zephyr$ ) ");
-  owl_list_append_element(owl_global_get_filterlist(&g), f);
-
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "trash", "class ^mail$ or opcode ^ping$ or type ^admin$ or ( not login ^none$ )");
-  owl_list_append_element(owl_global_get_filterlist(&g), f);
-
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "ping", "opcode ^ping$");
-  owl_list_append_element(owl_global_get_filterlist(&g), f);
-
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "auto", "opcode ^auto$");
-  owl_list_append_element(owl_global_get_filterlist(&g), f);
-
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "login", "not login ^none$");
-  owl_list_append_element(owl_global_get_filterlist(&g), f);
-
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "reply-lockout", "class ^noc or class ^mail$");
-  owl_list_append_element(owl_global_get_filterlist(&g), f);
-
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "out", "direction ^out$");
-  owl_list_append_element(owl_global_get_filterlist(&g), f);
-
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "aim", "type ^aim$");
-  owl_list_append_element(owl_global_get_filterlist(&g), f);
-
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "zephyr", "type ^zephyr$");
-  owl_list_append_element(owl_global_get_filterlist(&g), f);
-
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "none", "false");
-  owl_list_append_element(owl_global_get_filterlist(&g), f);
-
-  f=owl_malloc(sizeof(owl_filter));
-  owl_filter_init_fromstring(f, "all", "true");
-  owl_list_append_element(owl_global_get_filterlist(&g), f);
-
-  /* set the current view */
-  owl_function_debugmsg("startup: setting the current view");
-  owl_view_create(owl_global_get_current_view(&g), "main", f, owl_global_get_style_by_name(&g, "default"));
-
-  /* AIM init */
-  owl_function_debugmsg("startup: doing AIM initialization");
-  owl_aim_init();
-
-  /* execute the startup function in the configfile */
-  owl_function_debugmsg("startup: executing perl startup, if applicable");
-  perlout = owl_perlconfig_execute("BarnOwl::Hooks::_startup();");
-  if (perlout) owl_free(perlout);
-
-  /* hold on to the window names for convenience */
-  msgwin=owl_global_get_curs_msgwin(&g);
-  recwin=owl_global_get_curs_recwin(&g);
-  sepwin=owl_global_get_curs_sepwin(&g);
-  typwin=owl_global_get_curs_typwin(&g);
-  tw=owl_global_get_typwin(&g);
-
-  /* welcome message */
-  owl_function_debugmsg("startup: creating splash message");
-  strcpy(startupmsg, "-----------------------------------------------------------------------\n");
-  sprintf(buff,      "Welcome to barnowl version %s.  Press 'h' for on-line help.            \n", OWL_VERSION_STRING);
-  strcat(startupmsg, buff);
-  strcat(startupmsg, "To see a quick introduction, type ':show quickstart'.                  \n");
-  strcat(startupmsg, "                                                                       \n");
-  strcat(startupmsg, "BarnOwl is free software. Type ':show license' for more                \n");
-  strcat(startupmsg, "information.                                                     ^ ^   \n");
-  strcat(startupmsg, "                                                                 OvO   \n");
-  strcat(startupmsg, "Please report any bugs or suggestions to bug-barnowl@mit.edu    (   )  \n");
-  strcat(startupmsg, "-----------------------------------------------------------------m-m---\n");
-  owl_function_adminmsg("", startupmsg);
-  sepbar(NULL);
-
-  /* process the startup file */
-  owl_function_debugmsg("startup: processing startup file");
-  owl_function_source(NULL);
-
-  wrefresh(sepwin);
-
-  /* load zephyr subs */
-  if (initialsubs) {
-    int ret2;
-    owl_function_debugmsg("startup: loading initial zephyr subs");
-
-    /* load default subscriptions */
-    ret=owl_zephyr_loaddefaultsubs();
-    
-    /* load subscriptions from subs file */
-    ret2=owl_zephyr_loadsubs(NULL, 0);
-
-    if (ret || ret2) {
-      owl_function_adminmsg("", "Error loading zephyr subscriptions");
-    } else if (ret2!=-1) {
-      owl_global_add_userclue(&g, OWL_USERCLUE_CLASSES);
-    }
-
-    /* load login subscriptions */
-    if (owl_global_is_loginsubs(&g)) {
-      owl_function_debugmsg("startup: loading login subs");
-      owl_function_loadloginsubs(NULL);
-    }
-  }
-
-  /* First buddy check to sync the list without notifications */
-  owl_function_debugmsg("startup: doing initial zephyr buddy check");
-  /* owl_function_zephyr_buddy_check(0); */
-
-  /* set the startup and default style, based on userclue and presence of a
-   * formatting function */
-  owl_function_debugmsg("startup: setting startup and default style");
-  if (0 != strcmp(owl_global_get_default_style(&g), "__unspecified__")) {
-    /* the style was set by the user: leave it alone */
-  } else {
-    owl_global_set_default_style(&g, "default");
-  }
-
-  /* zlog in if we need to */
-  if (owl_global_is_startuplogin(&g)) {
-    owl_function_debugmsg("startup: doing zlog in");
-    owl_zephyr_zlog_in();
-  }
-
-  owl_function_debugmsg("startup: set style for the view: %s", owl_global_get_default_style(&g));
-  s = owl_global_get_style_by_name(&g, owl_global_get_default_style(&g));
-  if(s)
-      owl_view_set_style(owl_global_get_current_view(&g), s);
-  else
-      owl_function_error("No such style: %s", owl_global_get_default_style(&g));
-
-  owl_function_debugmsg("startup: setting context interactive");
-  owl_context_set_interactive(owl_global_get_context(&g));
-
-  nexttimediff=10;
-  nexttime=time(NULL);
-
-#ifdef HAVE_LIBZEPHYR
-  /* Check for any zephyrs that have come in while we've done init. */
-  owl_zephyr_process_events();
-#endif
-  
-  owl_function_debugmsg("startup: entering main loop");
-  /* main loop */
-  while (1) {
-
-    /* if a resize has been scheduled, deal with it */
-    owl_global_resize(&g, 0, 0);
-
-    /* these are here in case a resize changes the windows */
-    msgwin=owl_global_get_curs_msgwin(&g);
-    recwin=owl_global_get_curs_recwin(&g);
-    sepwin=owl_global_get_curs_sepwin(&g);
-    typwin=owl_global_get_curs_typwin(&g);
-
-    followlast=owl_global_should_followlast(&g);
-    
-    owl_perlconfig_mainloop();
-
-    /* little hack */
-    now=time(NULL);
-    today=localtime(&now);
-    if (today->tm_mon==9 && today->tm_mday==31 && owl_global_get_runtime(&g)<600) {
-      if (time(NULL)>nexttime) {
-	if (nexttimediff==1) {
-	  nexttimediff=10;
-	} else {
-	  nexttimediff=1;
-	}
-	nexttime+=nexttimediff;
-	owl_hack_animate();
-      }
-    }
-
-    /* Grab incoming messages. */
-    newmsgs=0;
-    while(owl_global_messagequeue_pending(&g)) {
-
-      m = owl_global_messagequeue_popmsg(&g);
-
-      if(owl_process_message(m))
-        newmsgs = 1;
-    }
-
-    /* is it time to check zbuddies? */
-    if (owl_global_is_pseudologins(&g)) {
-      if (owl_timer_is_expired(owl_global_get_zephyr_buddycheck_timer(&g))) {
-	owl_function_debugmsg("Doing zephyr buddy check");
-	owl_function_zephyr_buddy_check(1);
-	owl_timer_reset(owl_global_get_zephyr_buddycheck_timer(&g));
-      }
-    }
-
-    /* dispatch any muxevents */
-    owl_muxevents_dispatch(owl_global_get_muxevents(&g), 0);
-
-    /* follow the last message if we're supposed to */
-    if (newmsgs && followlast) {
-      owl_function_lastmsg_noredisplay();
-    }
-
-    /* do the newmsgproc thing */
-    if (newmsgs) {
-      owl_function_do_newmsgproc();
-    }
-    
-    /* redisplay if necessary */
-    /* this should be optimized to not run if the new messages won't be displayed */
-    if (newmsgs) {
-      owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-      sepbar(NULL);
-      if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
-	owl_popwin_refresh(owl_global_get_popwin(&g));
-	/* TODO: this is a broken kludge */
-	if (owl_global_get_viewwin(&g)) {
-	  owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
-	}
-      }
-      owl_global_set_needrefresh(&g);
-    }
-
-    /* if a popwin just came up, refresh it */
-    pw=owl_global_get_popwin(&g);
-    if (owl_popwin_is_active(pw) && owl_popwin_needs_first_refresh(pw)) {
-      owl_popwin_refresh(pw);
-      owl_popwin_no_needs_first_refresh(pw);
-      owl_global_set_needrefresh(&g);
-      /* TODO: this is a broken kludge */
-      if (owl_global_get_viewwin(&g)) {
-	owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
-      }
-    }
-
-    /* update the terminal if we need to */
-    if (owl_global_is_needrefresh(&g)) {
-      /* leave the cursor in the appropriate window */
-      if (owl_global_is_typwin_active(&g)) {
-	owl_function_set_cursor(typwin);
-      } else {
-	owl_function_set_cursor(sepwin);
-      }
-      doupdate();
-      owl_global_set_noneedrefresh(&g);
-    }
-
-    /* select on FDs we know about. */
-    owl_select();
-
-    /* Log any error signals */
-    {
-      siginfo_t si;
-      int signum;
-      if ((signum = owl_global_get_errsignal_and_clear(&g, &si)) > 0) {
-	owl_function_error("Got unexpected signal: %d %s  (code: %d band: %ld  errno: %d)",
-			   signum, signum==SIGPIPE?"SIGPIPE":"SIG????",
-			   si.si_code, si.si_band, si.si_errno);
-      }
-    }
-
-  }
-}
-
-/*
- * Process a new message passed to us on the message queue from some
- * protocol. This includes adding it to the message list, updating the
- * view and scrolling if appropriate, logging it, and so on.
- *
- * Either a pointer is kept to the message internally, or it is freed
- * if unneeded. The caller no longer ``owns'' the message's memory.
- *
- * Returns 1 if the message was added to the message list, and 0 if it
- * was ignored due to user settings or otherwise.
- */
-int owl_process_message(owl_message *m) {
-  owl_filter *f;
-  /* if this message it on the puntlist, nuke it and continue */
-  if (owl_global_message_is_puntable(&g, m)) {
-    owl_message_free(m);
-    return 0;
-  }
-
-  /*  login or logout that should be ignored? */
-  if (owl_global_is_ignorelogins(&g)
-      && owl_message_is_loginout(m)) {
-    owl_message_free(m);
-    return 0;
-  }
-
-  if (!owl_global_is_displayoutgoing(&g)
-      && owl_message_is_direction_out(m)) {
-    owl_message_free(m);
-    return 0;
-  }
-
-  /* add it to the global list */
-  owl_messagelist_append_element(owl_global_get_msglist(&g), m);
-  /* add it to any necessary views; right now there's only the current view */
-  owl_view_consider_message(owl_global_get_current_view(&g), m);
-
-  if(owl_message_is_direction_in(m)) {
-    /* let perl know about it*/
-    owl_perlconfig_getmsg(m, NULL);
-
-    /* do we need to autoreply? */
-    if (owl_global_is_zaway(&g) && !owl_message_get_attribute_value(m, "isauto")) {
-      if (owl_message_is_type_zephyr(m)) {
-        owl_zephyr_zaway(m);
-      } else if (owl_message_is_type_aim(m)) {
-        if (owl_message_is_private(m)) {
-          owl_function_send_aimawymsg(owl_message_get_sender(m), owl_global_get_zaway_msg(&g));
-        }
-      }
-    }
-
-    /* ring the bell if it's a personal */
-    if (!strcmp(owl_global_get_personalbell(&g), "on")) {
-      if (!owl_message_is_loginout(m) &&
-          !owl_message_is_mail(m) &&
-          owl_message_is_personal(m)) {
-        owl_function_beep();
-      }
-    } else if (!strcmp(owl_global_get_personalbell(&g), "off")) {
-      /* do nothing */
-    } else {
-      f=owl_global_get_filter(&g, owl_global_get_personalbell(&g));
-      if (f && owl_filter_message_match(f, m)) {
-        owl_function_beep();
-      }
-    }
-
-    /* if it matches the alert filter, do the alert action */
-    f=owl_global_get_filter(&g, owl_global_get_alert_filter(&g));
-    if (f && owl_filter_message_match(f, m)) {
-      owl_function_command(owl_global_get_alert_action(&g));
-    }
-
-    /* if it's a zephyr login or logout, update the zbuddylist */
-    if (owl_message_is_type_zephyr(m) && owl_message_is_loginout(m)) {
-      if (owl_message_is_login(m)) {
-        owl_zbuddylist_adduser(owl_global_get_zephyr_buddylist(&g), owl_message_get_sender(m));
-      } else if (owl_message_is_logout(m)) {
-        owl_zbuddylist_deluser(owl_global_get_zephyr_buddylist(&g), owl_message_get_sender(m));
-      } else {
-        owl_function_error("Internal error: received login notice that is neither login nor logout");
-      }
-    }
-  }
-
-  /* let perl know about it */
-  owl_perlconfig_newmsg(m, NULL);
-  /* log the message if we need to */
-  owl_log_message(m);
-
-  return 1;
-}
-
-void owl_process_input()
-{
-  int ret;
-  owl_input j;
-  owl_popwin *pw;
-  owl_editwin *tw;
-  WINDOW *typwin;
-
-  typwin = owl_global_get_curs_typwin(&g);
-  while (1) {
-    j.ch = wgetch(typwin);
-    if (j.ch == ERR) return;
-    
-    owl_global_set_lastinputtime(&g, time(NULL));
-    pw=owl_global_get_popwin(&g);
-    tw=owl_global_get_typwin(&g);
-
-    j.uch = '\0';
-    if (j.ch >= KEY_MIN && j.ch <= KEY_MAX) {
-      /* This is a curses control character. */
-    }
-    else if (j.ch > 0x7f && j.ch < 0xfe) {
-      /* Pull in a full utf-8 character. */
-      int bytes, i;
-      char utf8buf[7];
-      memset(utf8buf, '\0', 7);
-      
-      utf8buf[0] = j.ch;
-      
-      if ((j.ch & 0xc0) && (~j.ch & 0x20)) bytes = 2;
-      else if ((j.ch & 0xe0) && (~j.ch & 0x10)) bytes = 3;
-      else if ((j.ch & 0xf0) && (~j.ch & 0x08)) bytes = 4;
-      else if ((j.ch & 0xf8) && (~j.ch & 0x04)) bytes = 5;
-      else if ((j.ch & 0xfc) && (~j.ch & 0x02)) bytes = 6;
-      else bytes = 1;
-      
-      for (i = 1; i < bytes; i++) {
-        int tmp =  wgetch(typwin);
-        /* If what we got was not a byte, or not a continuation byte */
-        if (tmp > 0xff || !(tmp & 0x80 && ~tmp & 0x40)) {
-          /* ill-formed UTF-8 code unit subsequence, put back the
-             char we just got. */
-          ungetch(tmp);
-          j.ch = ERR;
-          break;
-        }
-        utf8buf[i] = tmp;
-      }
-      
-      if (j.ch != ERR) {
-        if (g_utf8_validate(utf8buf, -1, NULL)) {
-          j.uch = g_utf8_get_char(utf8buf);
-        }
-        else {
-          j.ch = ERR;
-        }
-      }
-    }
-    else if (j.ch <= 0x7f) {
-      j.uch = j.ch;
-    }
-    
-    owl_global_set_lastinputtime(&g, time(NULL));
-    /* find and activate the current keymap.
-     * TODO: this should really get fixed by activating
-     * keymaps as we switch between windows... 
-     */
-    if (pw && owl_popwin_is_active(pw) && owl_global_get_viewwin(&g)) {
-      owl_context_set_popless(owl_global_get_context(&g), 
-                              owl_global_get_viewwin(&g));
-      owl_function_activate_keymap("popless");
-    } else if (owl_global_is_typwin_active(&g) 
-               && owl_editwin_get_style(tw)==OWL_EDITWIN_STYLE_ONELINE) {
-      /*
-        owl_context_set_editline(owl_global_get_context(&g), tw);
-        owl_function_activate_keymap("editline");
-      */
-    } else if (owl_global_is_typwin_active(&g) 
-               && owl_editwin_get_style(tw)==OWL_EDITWIN_STYLE_MULTILINE) {
-      owl_context_set_editmulti(owl_global_get_context(&g), tw);
-      owl_function_activate_keymap("editmulti");
-    } else {
-      owl_context_set_recv(owl_global_get_context(&g));
-      owl_function_activate_keymap("recv");
-    }
-    /* now actually handle the keypress */
-    ret = owl_keyhandler_process(owl_global_get_keyhandler(&g), j);
-    if (ret!=0 && ret!=1) {
-      owl_function_makemsg("Unable to handle keypress");
-    }
-  }
-}
-
-void sig_handler(int sig, siginfo_t *si, void *data)
-{
-  if (sig==SIGWINCH) {
-    /* we can't inturrupt a malloc here, so it just sets a flag
-     * schedulding a resize for later
-     */
-    owl_function_resize();
-  } else if (sig==SIGPIPE || sig==SIGCHLD) {
-    /* Set a flag and some info that we got the sigpipe
-     * so we can record that we got it and why... */
-    owl_global_set_errsignal(&g, sig, si);
-  } else if (sig==SIGTERM || sig==SIGHUP) {
-    owl_function_quit();
-  }
-}
-
-void usage()
-{
-  fprintf(stderr, "Barnowl version %s\n", OWL_VERSION_STRING);
-  fprintf(stderr, "Usage: barnowl [-n] [-d] [-D] [-v] [-h] [-c <configfile>] [-s <confdir>] [-t <ttyname>]\n");
-  fprintf(stderr, "  -n      don't load zephyr subscriptions\n");
-  fprintf(stderr, "  -d      enable debugging\n");
-  fprintf(stderr, "  -D      enable debugging and delete previous debug file\n");
-  fprintf(stderr, "  -v      print the Barnowl version number and exit\n");
-  fprintf(stderr, "  -h      print this help message\n");
-  fprintf(stderr, "  -c      specify an alternate config file\n");
-  fprintf(stderr, "  -s      specify an alternate config dir (default ~/.owl)\n");
-  fprintf(stderr, "  -t      set the tty name\n");
-}
-
-#if OWL_STDERR_REDIR
-
-/* Replaces stderr with a pipe so that we can read from it. 
- * Returns the fd of the pipe from which stderr can be read. */
-int stderr_replace(void)
-{
-  int pipefds[2];
-  if (0 != pipe(pipefds)) {
-    perror("pipe");
-    owl_function_debugmsg("stderr_replace: pipe FAILED\n");
-    return -1;
-  }
-    owl_function_debugmsg("stderr_replace: pipe: %d,%d\n", pipefds[0], pipefds[1]);
-  if (-1 == dup2(pipefds[1], 2 /*stderr*/)) {
-    owl_function_debugmsg("stderr_replace: dup2 FAILED (%s)\n", strerror(errno));
-    perror("dup2");
-    return -1;
-  }
-  return pipefds[0];
-}
-
-/* Sends stderr (read from rfd) messages to the error console */
-void stderr_redirect_handler(int handle, int rfd, int eventmask, void *data) 
-{
-  int navail, bread;
-  char *buf;
-  /*owl_function_debugmsg("stderr_redirect: called with rfd=%d\n", rfd);*/
-  if (rfd<0) return;
-  if (-1 == ioctl(rfd, FIONREAD, (void*)&navail)) {
-    return;
-  }
-  /*owl_function_debugmsg("stderr_redirect: navail = %d\n", navail);*/
-  if (navail<=0) return;
-  if (navail>256) { navail = 256; }
-  buf = owl_malloc(navail+1);
-  bread = read(rfd, buf, navail);
-  if (buf[navail-1] != '\0') {
-    buf[navail] = '\0';
-  }
-  owl_function_error("Err: %s", buf);
-  owl_free(buf);
-}
-
-#endif /* OWL_STDERR_REDIR */
Index: l.h
===================================================================
--- owl.h	(revision b940b91e7aa126759387aa2da6dd5b353accdd32)
+++ 	(revision )
@@ -1,616 +1,0 @@
-/*  Copyright (c) 2006-2008 The BarnOwl Developers. All rights reserved.
- *  Copyright (c) 2004 James Kretchmar. All rights reserved.
- *
- *  This program is free software. You can redistribute it and/or
- *  modify under the terms of the Sleepycat License. See the COPYING
- *  file included with the distribution for more information.
- */
-
-#ifndef INC_OWL_H
-#define INC_OWL_H
-
-#ifndef OWL_PERL
-#include <curses.h>
-#endif
-#include <sys/param.h>
-#include <EXTERN.h>
-#include <netdb.h>
-#include <regex.h>
-#include <time.h>
-#include <signal.h>
-#include <termios.h>
-#include "libfaim/aim.h"
-#include <wchar.h>
-#include "config.h"
-#include "glib.h"
-#ifdef HAVE_LIBZEPHYR
-#include <zephyr/zephyr.h>
-#endif
-#ifdef HAVE_COM_ERR_H
-#include <com_err.h>
-#endif
-
-/* Perl and curses don't play nice. */
-#ifdef OWL_PERL
-typedef void WINDOW;
-/* logout is defined in FreeBSD. */
-#define logout logout_
-/* aim.h defines bool */
-#define HAS_BOOL
-#include <perl.h>
-#include "owl_perl.h"
-#undef logout
-#include "XSUB.h"
-#else
-typedef void SV;
-#endif
-
-static const char owl_h_fileIdent[] = "$Id$";
-
-#define BARNOWL_STRINGIFY(x) _STRINGIFY(x)
-#define _STRINGIFY(x) #x
-
-#ifndef OWL_VERSION_STRING
-#define OWL_VERSION_STRING "1.0.4.1"
-#endif
-
-/* Feature that is being tested to redirect stderr through a pipe. 
- * There may still be some portability problems with this. */
-#define OWL_STDERR_REDIR 1
-
-#define OWL_DEBUG 0
-#define OWL_DEBUG_FILE "/var/tmp/owldebug"
-
-#define OWL_CONFIG_DIR "/.owl"             /* this is relative to the user's home directory */
-#define OWL_STARTUP_FILE "/.owl/startup"   /* this is relative to the user's home directory */
-
-#define OWL_FMTEXT_ATTR_NONE      0
-#define OWL_FMTEXT_ATTR_BOLD      1
-#define OWL_FMTEXT_ATTR_REVERSE   2
-#define OWL_FMTEXT_ATTR_UNDERLINE 4
-
-#define OWL_FMTEXT_UC_BASE 0x100000 /* Unicode Plane 16 - Supplementary Private Use Area-B*/
-#define OWL_FMTEXT_UC_ATTR ( OWL_FMTEXT_UC_BASE | 0x800 )
-#define OWL_FMTEXT_UC_ATTR_MASK 0x7
-#define OWL_FMTEXT_UC_COLOR_BASE ( OWL_FMTEXT_UC_BASE | 0x400 )
-#define OWL_FMTEXT_UC_FGCOLOR OWL_FMTEXT_UC_COLOR_BASE
-#define OWL_FMTEXT_UC_BGCOLOR ( OWL_FMTEXT_UC_COLOR_BASE | 0x200 )
-#define OWL_FMTEXT_UC_DEFAULT_COLOR 0x100
-#define OWL_FMTEXT_UC_FGDEFAULT ( OWL_FMTEXT_UC_FGCOLOR | OWL_FMTEXT_UC_DEFAULT_COLOR )
-#define OWL_FMTEXT_UC_BGDEFAULT ( OWL_FMTEXT_UC_BGCOLOR | OWL_FMTEXT_UC_DEFAULT_COLOR )
-#define OWL_FMTEXT_UC_COLOR_MASK 0xFF
-#define OWL_FMTEXT_UC_ALLCOLOR_MASK ( OWL_FMTEXT_UC_COLOR_MASK | OWL_FMTEXT_UC_DEFAULT_COLOR | 0x200)
-#define OWL_FMTEXT_UC_STARTBYTE_UTF8 '\xf4'
-
-#define OWL_FMTEXT_UTF8_ATTR_NONE "\xf4\x80\xa0\x80"
-#define OWL_FMTEXT_UTF8_FGDEFAULT "\xf4\x80\x94\x80"
-#define OWL_FMTEXT_UTF8_BGDEFAULT "\xf4\x80\x9C\x80"
-
-#define OWL_COLOR_BLACK     0
-#define OWL_COLOR_RED       1
-#define OWL_COLOR_GREEN     2
-#define OWL_COLOR_YELLOW    3
-#define OWL_COLOR_BLUE      4
-#define OWL_COLOR_MAGENTA   5
-#define OWL_COLOR_CYAN      6
-#define OWL_COLOR_WHITE     7
-#define OWL_COLOR_DEFAULT   -1
-#define OWL_COLOR_INVALID   -2
-
-#define OWL_EDITWIN_STYLE_MULTILINE 0
-#define OWL_EDITWIN_STYLE_ONELINE   1
-
-#define OWL_PROTOCOL_ZEPHYR         0
-#define OWL_PROTOCOL_AIM            1
-#define OWL_PROTOCOL_JABBER         2
-#define OWL_PROTOCOL_ICQ            3
-#define OWL_PROTOCOL_YAHOO          4
-#define OWL_PROTOCOL_MSN            5
-
-#define OWL_MESSAGE_DIRECTION_NONE  0
-#define OWL_MESSAGE_DIRECTION_IN    1
-#define OWL_MESSAGE_DIRECTION_OUT   2
-
-#define OWL_MUX_READ   1
-#define OWL_MUX_WRITE  2
-#define OWL_MUX_EXCEPT 4
-
-#define OWL_DIRECTION_NONE      0
-#define OWL_DIRECTION_DOWNWARDS 1
-#define OWL_DIRECTION_UPWARDS   2
-
-#define OWL_LOGGING_DIRECTION_BOTH 0
-#define OWL_LOGGING_DIRECTION_IN   1
-#define OWL_LOGGING_DIRECTION_OUT  2
-
-#define OWL_SCROLLMODE_NORMAL      0
-#define OWL_SCROLLMODE_TOP         1
-#define OWL_SCROLLMODE_NEARTOP     2
-#define OWL_SCROLLMODE_CENTER      3
-#define OWL_SCROLLMODE_PAGED       4
-#define OWL_SCROLLMODE_PAGEDCENTER 5
-
-#define OWL_TAB               3  /* This *HAS* to be the size of TABSTR below */
-#define OWL_TABSTR        "   "
-#define OWL_MSGTAB            7
-#define OWL_TYPWIN_SIZE       8
-#define OWL_HISTORYSIZE       50
-
-/* Indicate current state, as well as what is allowed */
-#define OWL_CTX_ANY          0xffff
-/* Only one of these may be active at a time... */
-#define OWL_CTX_MODE_BITS    0x000f
-#define OWL_CTX_STARTUP      0x0001
-#define OWL_CTX_READCONFIG   0x0002
-#define OWL_CTX_INTERACTIVE  0x0004
-/* Only one of these may be active at a time... */
-#define OWL_CTX_ACTIVE_BITS  0xfff0
-#define OWL_CTX_POPWIN       0x00f0
-#define OWL_CTX_POPLESS      0x0010
-#define OWL_CTX_RECWIN       0x0f00
-#define OWL_CTX_RECV         0x0100
-#define OWL_CTX_TYPWIN       0xf000
-#define OWL_CTX_EDIT         0x7000
-#define OWL_CTX_EDITLINE     0x1000
-#define OWL_CTX_EDITMULTI    0x2000
-#define OWL_CTX_EDITRESPONSE 0x4000
-
-#define OWL_USERCLUE_NONE       0
-#define OWL_USERCLUE_CLASSES    1
-#define OWL_USERCLUE_FOOBAR     2
-#define OWL_USERCLUE_BAZ        4
-
-#define OWL_WEBBROWSER_NONE     0
-#define OWL_WEBBROWSER_NETSCAPE 1
-#define OWL_WEBBROWSER_GALEON   2
-#define OWL_WEBBROWSER_OPERA    3
-
-#define OWL_VARIABLE_OTHER      0
-#define OWL_VARIABLE_INT        1
-#define OWL_VARIABLE_BOOL       2
-#define OWL_VARIABLE_STRING     3
-
-#define OWL_FILTER_MAX_DEPTH    300
-
-#define OWL_KEYMAP_MAXSTACK     20
-
-#define OWL_KEYBINDING_COMMAND  1   /* command string */
-#define OWL_KEYBINDING_FUNCTION 2   /* function taking no args */
-
-#define OWL_DEFAULT_ZAWAYMSG    "I'm sorry, but I am currently away from the terminal and am\nnot able to receive your message.\n"
-#define OWL_DEFAULT_AAWAYMSG    "I'm sorry, but I am currently away from the terminal and am\nnot able to receive your message.\n"
-
-#define OWL_INCLUDE_REG_TESTS   1  /* whether to build in regression tests */
-
-#define OWL_CMD_ALIAS_SUMMARY_PREFIX "command alias to: "
-
-#define OWL_WEBZEPHYR_PRINCIPAL "daemon.webzephyr"
-#define OWL_WEBZEPHYR_CLASS     "webzephyr"
-#define OWL_WEBZEPHYR_OPCODE    "webzephyr"
-
-#define OWL_REGEX_QUOTECHARS    "+*.?[]^\\${}()"
-#define OWL_REGEX_QUOTEWITH     "\\"
-
-#if defined(HAVE_DES_STRING_TO_KEY) && defined(HAVE_DES_KEY_SCHED) && defined(HAVE_DES_ECB_ENCRYPT)
-#define OWL_ENABLE_ZCRYPT 1
-#endif
-
-#define OWL_META(key) ((key)|010000)
-/* OWL_CTRL is definied in kepress.c */
-
-#define LINE 2048
-
-typedef struct _owl_variable {
-  char *name;
-  int   type;  /* OWL_VARIABLE_* */
-  void *pval_default;  /* for types other and string */
-  int   ival_default;  /* for types int and bool     */
-  char *validsettings;		/* documentation of valid settings */
-  char *summary;		/* summary of usage */
-  char *description;		/* detailed description */
-  void *val;                    /* current value */
-  int  (*validate_fn)(struct _owl_variable *v, void *newval);
-                                /* returns 1 if newval is valid */
-  int  (*set_fn)(struct _owl_variable *v, void *newval); 
-                                /* sets the variable to a value
-				 * of the appropriate type.
-				 * unless documented, this 
-				 * should make a copy. 
-				 * returns 0 on success. */
-  int  (*set_fromstring_fn)(struct _owl_variable *v, char *newval);
-                                /* sets the variable to a value
-				 * of the appropriate type.
-				 * unless documented, this 
-				 * should make a copy. 
-				 * returns 0 on success. */
-  void *(*get_fn)(struct _owl_variable *v);
-				/* returns a reference to the current value.
-				 * WARNING:  this approach is hard to make
-				 * thread-safe... */
-  int  (*get_tostring_fn)(struct _owl_variable *v, 
-			  char *buf, int bufsize, void *val); 
-                                /* converts val to a string 
-				 * and puts into buf */
-  void  (*free_fn)(struct _owl_variable *v);
-				/* frees val as needed */
-} owl_variable;
-
-typedef struct _owl_input {
-  int ch;
-  gunichar uch;
-} owl_input;
-
-typedef struct _owl_fmtext {
-  int textlen;
-  int bufflen;
-  char *textbuff;
-  char default_attrs;
-  short default_fgcolor;
-  short default_bgcolor;
-} owl_fmtext;
-
-typedef struct _owl_list {
-  int size;
-  int avail;
-  void **list;
-} owl_list;
-
-typedef struct _owl_dict_el {
-  char *k;			/* key   */
-  void *v;			/* value */
-} owl_dict_el;
-
-typedef struct _owl_dict {
-  int size;
-  int avail;
-  owl_dict_el *els;		/* invariant: sorted by k */
-} owl_dict;
-typedef owl_dict owl_vardict;	/* dict of variables */
-typedef owl_dict owl_cmddict;	/* dict of commands */
-
-typedef struct _owl_context {
-  int   mode;
-  void *data;		/* determined by mode */
-} owl_context;
-
-typedef struct _owl_cmd {	/* command */
-  char *name;
-
-  char *summary;		/* one line summary of command */
-  char *usage;			/* usage synopsis */
-  char *description;		/* long description of command */
-
-  int validctx;			/* bitmask of valid contexts */
-
-  /* we should probably have a type here that says which of
-   * the following is valid, and maybe make the below into a union... */
-
-  /* Only one of these may be non-NULL ... */
-
-  char *cmd_aliased_to;		/* what this command is aliased to... */
-  
-  /* These don't take any context */
-  char *(*cmd_args_fn)(int argc, char **argv, char *buff);  
-				/* takes argv and the full command as buff.
-				 * caller must free return value if !NULL */
-  void (*cmd_v_fn)(void);	/* takes no args */
-  void (*cmd_i_fn)(int i);	/* takes an int as an arg */
-
-  /* The following also take the active context if it's valid */
-  char *(*cmd_ctxargs_fn)(void *ctx, int argc, char **argv, char *buff);  
-				/* takes argv and the full command as buff.
-				 * caller must free return value if !NULL */
-  void (*cmd_ctxv_fn)(void *ctx);	        /* takes no args */
-  void (*cmd_ctxi_fn)(void *ctx, int i);	/* takes an int as an arg */
-  SV *cmd_perl;                                /* Perl closure that takes a list of args */
-} owl_cmd;
-
-
-typedef struct _owl_zwrite {
-  char *class;
-  char *inst;
-  char *realm;
-  char *opcode;
-  char *zsig;
-  char *message;
-  owl_list recips;
-  int cc;
-  int noping;
-} owl_zwrite;
-
-typedef struct _owl_pair {
-  char *key;
-  char *value;
-} owl_pair;
-
-struct _owl_fmtext_cache;
-
-typedef struct _owl_message {
-  int id;
-  int direction;
-#ifdef HAVE_LIBZEPHYR
-  ZNotice_t notice;
-#endif
-  struct _owl_fmtext_cache * fmtext;
-  int delete;
-  char *hostname;
-  owl_list attributes;            /* this is a list of pairs */
-  char *timestr;
-  time_t time;
-} owl_message;
-
-#define OWL_FMTEXT_CACHE_SIZE 1000
-/* We cache the saved fmtexts for the last bunch of messages we
-   rendered */
-typedef struct _owl_fmtext_cache {
-    owl_message * message;
-    owl_fmtext fmtext;
-} owl_fmtext_cache;
-
-typedef struct _owl_style {
-  char *name;
-  SV *perlobj;
-} owl_style;
-
-typedef struct _owl_mainwin {
-  int curtruncated;
-  int lasttruncated;
-  int lastdisplayed;
-} owl_mainwin;
-
-typedef struct _owl_viewwin {
-  owl_fmtext fmtext;
-  int textlines;
-  int topline;
-  int rightshift;
-  int winlines, wincols;
-  WINDOW *curswin;
-  void (*onclose_hook) (struct _owl_viewwin *vwin, void *data);
-  void *onclose_hook_data;
-} owl_viewwin;
-  
-typedef struct _owl_popwin {
-  WINDOW *borderwin;
-  WINDOW *popwin;
-  int lines;
-  int cols;
-  int active;
-  int needsfirstrefresh;
-  void (*handler) (int ch);
-} owl_popwin;
-
-typedef struct _owl_popexec {
-  int refcount;
-  owl_viewwin *vwin;
-  int winactive;
-  int pid;			/* or 0 if it has terminated */
-  int rfd;  
-} owl_popexec;
-
-typedef struct _owl_messagelist {
-  owl_list list;
-} owl_messagelist;
-
-typedef struct _owl_regex {
-  int negate;
-  char *string;
-  regex_t re;
-} owl_regex;
-
-typedef struct _owl_filterelement {
-  int (*match_message)(struct _owl_filterelement *fe, owl_message *m);
-  /* Append a string representation of the filterelement onto buf*/
-  void (*print_elt)(struct _owl_filterelement *fe, GString *buf);
-  /* Operands for and,or,not*/
-  struct _owl_filterelement *left, *right;
-  /* For regex filters*/
-  owl_regex re;
-  /* Used by regexes, filter references, and perl */
-  char *field;
-} owl_filterelement;
-
-typedef struct _owl_filter {
-  char *name;
-  int polarity;
-  owl_filterelement * root;
-  int fgcolor;
-  int bgcolor;
-  int cachedmsgid;  /* cached msgid: should move into view eventually */
-} owl_filter;
-
-typedef struct _owl_view {
-  char *name;
-  owl_filter *filter;
-  owl_messagelist ml;
-  owl_style *style;
-} owl_view;
-
-typedef struct _owl_history {
-  owl_list hist;
-  int cur;
-  int touched;
-  int partial;
-  int repeats;
-} owl_history;
-
-typedef struct _owl_editwin {
-  char *buff;
-  owl_history *hist;
-  int bufflen;
-  int allocated;
-  int buffx, buffy;
-  int topline;
-  int winlines, wincols, fillcol, wrapcol;
-  WINDOW *curswin;
-  int style;
-  int lock;
-  int dotsend;
-  int echochar;
-
-  char *command;
-  void (*callback)(struct _owl_editwin*);
-  void *cbdata;
-} owl_editwin;
-
-typedef struct _owl_mux {
-  int handle;			/* for referencing this */
-  int active;			/* has this been deleted? */
-  int fd;		       
-  int eventmask;		/* bitmask of OWL_MUX_* */
-  void (*handler_fn)(int handle, int fd, int eventmask, void *data);
-  void *data;			/* data reference to pass to callback */
-} owl_mux;
-typedef owl_list owl_muxevents;
-
-typedef struct _owl_keybinding {
-  int  *j;			/* keypress stack (0-terminated) */  
-  int   type;			/* command or function? */
-  char *desc;			/* description (or "*user*") */
-  char *command;		/* command, if of type command */
-  void (*function_fn)(void);	/* function ptr, if of type function */
-} owl_keybinding;
-
-typedef struct _owl_keymap {
-  char     *name;		/* name of keymap */
-  char     *desc;		/* description */
-  owl_list  bindings;		/* key bindings */
-  struct _owl_keymap *submap;	/* submap */
-  void (*default_fn)(owl_input j);	/* default action (takes a keypress) */
-  void (*prealways_fn)(owl_input  j);	/* always called before a keypress is received */
-  void (*postalways_fn)(owl_input  j);	/* always called after keypress is processed */
-} owl_keymap;
-
-typedef struct _owl_keyhandler {
-  owl_dict  keymaps;		/* dictionary of keymaps */
-  owl_keymap *active;		/* currently active keymap */
-  int	    in_esc;		/* escape pressed? */
-  int       kpstack[OWL_KEYMAP_MAXSTACK+1]; /* current stack of keypresses */
-  int       kpstackpos;		/* location in stack (-1 = none) */
-} owl_keyhandler;
-
-typedef struct _owl_buddy {
-  int proto;
-  char *name;
-  int isidle;
-  int idlesince;
-} owl_buddy;
-
-typedef struct _owl_buddylist {
-  owl_list buddies;
-} owl_buddylist;
-
-typedef struct _owl_zbuddylist {
-  owl_list zusers;
-} owl_zbuddylist;
-
-typedef struct _owl_timer {
-  int direction;
-  time_t starttime;
-  int start;
-} owl_timer;
-
-typedef struct _owl_errqueue {
-  owl_list errlist;
-} owl_errqueue;
-
-typedef struct _owl_colorpair_mgr {
-  int next;
-  short **pairs;
-} owl_colorpair_mgr;
-
-typedef struct _owl_obarray {
-  owl_list strings;
-} owl_obarray;
-
-typedef struct _owl_dispatch {
-  int fd;           /* FD to watch for dispatch. */
-  void (*cfunc)();  /* C function to dispatch to. */
-  SV *pfunc;        /* Perl function to dispatch to. */
-} owl_dispatch;
-
-typedef struct _owl_global {
-  owl_mainwin mw;
-  owl_popwin pw;
-  owl_history cmdhist;		/* command history */
-  owl_history msghist;		/* outgoing message history */
-  owl_keyhandler kh;
-  owl_list filterlist;
-  owl_list puntlist;
-  owl_muxevents muxevents;	/* fds to dispatch on */
-  owl_vardict vars;
-  owl_cmddict cmds;
-  owl_context ctx;
-  owl_errqueue errqueue;
-  int lines, cols;
-  int curmsg, topmsg;
-  int curmsg_vert_offset;
-  owl_view current_view;
-  owl_messagelist msglist;
-  WINDOW *recwin, *sepwin, *msgwin, *typwin;
-  int needrefresh;
-  int rightshift;
-  int resizepending;
-  int recwinlines;
-  int typwinactive;
-  char *thishost;
-  char *homedir;
-  char *confdir;
-  char *startupfile;
-  int direction;
-  int zaway;
-  char *cur_zaway_msg;
-  int haveconfig;
-  int config_format;
-  void *buffercbdata;
-  owl_editwin tw;
-  owl_viewwin vw;
-  void *perl;
-  int debug;
-  time_t starttime;
-  time_t lastinputtime;
-  char *startupargs;
-  int userclue;
-  int nextmsgid;
-  int hascolors;
-  int colorpairs;
-  owl_colorpair_mgr cpmgr;
-  int searchactive;
-  int newmsgproc_pid;
-  int malloced, freed;
-  char *searchstring;
-  aim_session_t aimsess;
-  aim_conn_t bosconn;
-  owl_timer aim_noop_timer;
-  owl_timer aim_ignorelogin_timer;
-  owl_timer aim_buddyinfo_timer;
-  int aim_loggedin;         /* true if currently logged into AIM */
-  int aim_doprocessing;     /* true if we should process AIM events (like pending login) */
-  char *aim_screenname;     /* currently logged in AIM screen name */
-  char *aim_screenname_for_filters;     /* currently logged in AIM screen name */
-  owl_buddylist buddylist;  /* list of logged in AIM buddies */
-  owl_list messagequeue;    /* for queueing up aim and other messages */
-  owl_dict styledict;       /* global dictionary of available styles */
-  char *response;           /* response to the last question asked */
-  int havezephyr;
-  int haveaim;
-  int got_err_signal;	    /* 1 if we got an unexpected signal */
-  siginfo_t err_signal_info;
-  owl_zbuddylist zbuddies;
-  owl_timer zephyr_buddycheck_timer;
-  struct termios startup_tio;
-  owl_obarray obarray;
-  owl_list dispatchlist;
-} owl_global;
-
-/* globals */
-extern owl_global g;
-
-#include "owl_prototypes.h"
-
-/* these are missing from the zephyr includes for some reason */
-#ifdef HAVE_LIBZEPHYR
-int ZGetSubscriptions(ZSubscription_t *, int *);
-int ZGetLocations(ZLocations_t *,int *);
-#endif
-
-#endif /* INC_OWL_H */
Index: l_perl.h
===================================================================
--- owl_perl.h	(revision 120291c1279afc08f2efbc7c70dd1e069109c9c3)
+++ 	(revision )
@@ -1,55 +1,0 @@
-#ifndef INC_OWL_PERL_H
-#define INC_OWL_PERL_H
-
-#define OWL_PERL_VOID_CALL (void)POPs;
-
-/*
- * This macro defines a convenience wrapper around the boilerplate of
- * calling a method on a perl object (SV*) from C.
- *
- * Arguments are
- * * obj    - the SV* to call the method on
- * * meth   - a char* method name
- * * args   - a code block responsible for pushing args (other than the object)
- * * err    - a string with a %s format specifier to log in case of error
- * * fatalp - if true, perl errors terminate barnowl
- * * ret    - a code block executed if the call succeeded
- *
- * See also: `perldoc perlcall', `perldoc perlapi'
- */
-#define OWL_PERL_CALL_METHOD(obj, meth, args, err, fatalp, ret) { \
-    int count; \
-    dSP; \
-    ENTER; \
-    SAVETMPS; \
-    PUSHMARK(SP); \
-    XPUSHs(obj); \
-    {args} \
-    PUTBACK; \
-    \
-    count = call_method(meth, G_SCALAR|G_EVAL); \
-    \
-    SPAGAIN; \
-    \
-    if(count != 1) { \
-      fprintf(stderr, "perl returned wrong count: %d\n", count); \
-      abort();                                                   \
-    } \
-    if (SvTRUE(ERRSV)) { \
-      if(fatalp) { \
-        printf(err, SvPV_nolen(ERRSV)); \
-        exit(-1); \
-      } else { \
-        owl_function_error(err, SvPV_nolen(ERRSV)); \
-        (void)POPs; \
-        sv_setsv(ERRSV, &PL_sv_undef); \
-      } \
-    } else { \
-      ret; \
-    } \
-    PUTBACK; \
-    FREETMPS; \
-    LEAVE; \
-}
-
-#endif //INC_PERL_PERL_H
Index: ir.c
===================================================================
--- pair.c	(revision de1c8a59c19d33ab73607ff6539f55d51088ec6b)
+++ 	(revision )
@@ -1,22 +1,0 @@
-#include "owl.h"
-
-void owl_pair_create(owl_pair *p, char *key, char *value) {
-  p->key=key;
-  p->value=value;
-}
-
-void owl_pair_set_key(owl_pair *p, char *key) {
-  p->key=key;
-}
-
-void owl_pair_set_value(owl_pair *p, char *value) {
-  p->value=value;
-}
-
-char *owl_pair_get_key(owl_pair *p) {
-  return(p->key);
-}
-
-char *owl_pair_get_value(owl_pair *p) {
-  return(p->value);
-}
Index: rl/lib/BarnOwl/ModuleLoader.pm
===================================================================
--- perl/lib/BarnOwl/ModuleLoader.pm	(revision 41bbb8a6ca458a8596f859362016a37fe22946e2)
+++ 	(revision )
@@ -1,132 +1,0 @@
-use strict;
-use warnings;
-
-package BarnOwl::ModuleLoader;
-
-use lib (BarnOwl::get_data_dir() . "/modules/");
-use PAR (BarnOwl::get_data_dir() . "/modules/*.par");
-use PAR (BarnOwl::get_config_dir() . "/modules/*.par");
-
-our %modules;
-
-sub load_all {
-    my $class = shift;
-    $class->rescan_modules;
-    PAR::reload_libs();
-
-    for my $mod (keys %modules) {
-        if(!defined eval "use BarnOwl::Module::$mod") {
-            BarnOwl::error("Unable to load module $mod: \n$@\n") if $@;
-        }
-    }
-
-    $BarnOwl::Hooks::startup->add(\&register_keybindings);
-}
-
-sub rescan_modules {
-    PAR->import(BarnOwl::get_data_dir() . "/modules/*.par");
-    PAR->import(BarnOwl::get_config_dir() . "/modules/*.par");
-    my @modules;
-
-    %modules = ();
-
-    my @moddirs = ();
-    push @moddirs, BarnOwl::get_data_dir() . "/modules";
-    push @moddirs, BarnOwl::get_config_dir() . "/modules";
-    
-    for my $dir (@moddirs) {
-        opendir(my $dh, $dir) or next;
-        while(defined(my $f = readdir($dh))) {
-            next if $f =~ /^\./;
-            if(-f "$dir/$f" && $f =~ /^(.+)\.par$/) {
-                $modules{$1} = 1;
-            } elsif(-d "$dir/$f" && -d "$dir/$f/lib") {
-                unshift @INC, "$dir/$f/lib" unless grep m{^$dir/$f/lib$}, @INC;
-                $modules{$f} = 1;
-            }
-        }
-        @modules = grep /\.par$/, readdir($dh);
-        closedir($dh);
-        for my $mod (@modules) {
-            my ($class) = ($mod =~ /^(.+)\.par$/);
-            $modules{$class} = 1;
-        }
-    }
-}
-
-sub reload_module {
-    my $class = shift;
-    my $module = shift;
-
-    $class->rescan_modules();
-
-    for my $m (keys %INC) {
-        delete $INC{$m} if $m =~ m{^BarnOwl/Module/$module};
-    }
-
-    my $parfile;
-    for my $p (@PAR::PAR_INC) {
-        if($p =~ m/\Q$module\E[.]par$/) {
-            $parfile = $p;
-            last;
-        }
-    }
-
-    local $SIG{__WARN__} = \&squelch_redefine;
-
-    if(defined $parfile) {
-        PAR::reload_libs($parfile);
-        $class->run_startup_hooks();
-    } elsif(!defined eval "use BarnOwl::Module::$module") {
-        BarnOwl::error("Unable to load module $module: \n$@\n") if $@;
-    }
-}
-
-sub reload_module_cmd {
-    my $class = shift;
-    shift; # Command
-    my $module = shift;
-    unless(defined($module)) {
-        die("Usage: reload-module [MODULE]");
-    };
-    $class->reload_module($module);
-}
-
-sub register_keybindings {
-    BarnOwl::new_command('reload-modules', sub {BarnOwl::ModuleLoader->reload}, {
-                           summary => 'Reload all modules',
-                           usage   => 'reload-modules',
-                           description => q{Reloads all modules located in ~/.owl/modules and the system modules directory}
-                          });
-    BarnOwl::new_command('reload-module', sub {BarnOwl::ModuleLoader->reload_module_cmd(@_)}, {
-                           summary => 'Reload one module',
-                           usage   => 'reload-module [MODULE]',
-                           description => q{Reloads a single module located in ~/.owl/modules or the system modules directory}
-                          });
-}
-
-sub reload {
-    my $class = shift;
-    for my $m (keys %INC) {
-        delete $INC{$m} if $m =~ m{^BarnOwl/};
-    }
-    # Restore core modules from perlwrap.pm
-    $INC{$_} = 1 for (qw(BarnOwl.pm BarnOwl/Hooks.pm
-                         BarnOwl/Message.pm BarnOwl/Style.pm));
-    $class->run_startup_hooks();
-}
-
-sub run_startup_hooks {
-    my $class = shift;
-    local $SIG{__WARN__} = \&squelch_redefine;
-    $class->load_all;
-    $BarnOwl::Hooks::startup->run(1);
-    BarnOwl::startup() if *BarnOwl::startup{CODE};
-}
-
-sub squelch_redefine {
-    my $warning = shift;
-    warn $warning unless $warning =~ /^Subroutine .+ redefined at/;
-}
-
-1;
Index: rl/lib/Module/Install/BarnOwl.pm
===================================================================
--- perl/lib/Module/Install/BarnOwl.pm	(revision 925faaeb6e9cf1e4022d22956f3c21b5412152b5)
+++ 	(revision )
@@ -1,62 +1,0 @@
-use warnings;
-use strict;
-
-=head1 NAME
-
-Module::Install::BarnOwl
-
-=head1 DESCRIPTION
-
-Module::Install::BarnOwl is a M::I module to help building barnowl
-modules,
-
-=head1 SYNOPSIS
-
-    use inc::Module::Install;
-    barnowl_module('Jabber');
-    WriteAll;
-
-This is roughly equivalent to:
-
-    use inc::Module::Install;
-
-    name('BarnOwl-Module-Jabber');
-    all_from('lib/BarnOwl/Module/Jabber.pm');
-    requires_external_bin('barnowl');
-
-    WriteAll;
-
-As well as make rules to generate Jabber.par, and to put some
-additional barnowl-specific information into META.yml
-
-=cut
-
-package Module::Install::BarnOwl;
-
-use base qw(Module::Install::Base);
-
-sub barnowl_module {
-    my $self = shift;
-    my $name = ucfirst shift;
-    my $class = ref $self;
-
-    $self->name("BarnOwl-Module-$name");
-    $self->all_from("lib/BarnOwl/Module/$name.pm");
-
-    $self->postamble(<<"END_MAKEFILE");
-
-# --- $class section:
-
-$name.par: pm_to_blib
-\tcd blib; zip ../$name.par -r arch lib
-
-END_MAKEFILE
-}
-
-=head1 SEE ALSO
-
-L<Module::Install>, L<BarnOwl>
-
-=cut
-
-1;
Index: rl/modules/IRC/Makefile.PL
===================================================================
--- perl/modules/IRC/Makefile.PL	(revision b38b0b2afddb97da1a781f31558c159618326b31)
+++ 	(revision )
@@ -1,8 +1,0 @@
-use strict;
-use warnings;
-
-use inc::Module::Install;
-
-barnowl_module('IRC');
-
-WriteAll;
Index: rl/modules/IRC/inc/Module/Install.pm
===================================================================
--- perl/modules/IRC/inc/Module/Install.pm	(revision 43c62e4f2171c67b269c2b7c681e96dcb936a40c)
+++ 	(revision )
@@ -1,281 +1,0 @@
-#line 1
-package Module::Install;
-
-# For any maintainers:
-# The load order for Module::Install is a bit magic.
-# It goes something like this...
-#
-# IF ( host has Module::Install installed, creating author mode ) {
-#     1. Makefile.PL calls "use inc::Module::Install"
-#     2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install
-#     3. The installed version of inc::Module::Install loads
-#     4. inc::Module::Install calls "require Module::Install"
-#     5. The ./inc/ version of Module::Install loads
-# } ELSE {
-#     1. Makefile.PL calls "use inc::Module::Install"
-#     2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install
-#     3. The ./inc/ version of Module::Install loads
-# }
-
-use 5.004;
-use strict 'vars';
-
-use vars qw{$VERSION};
-BEGIN {
-    # All Module::Install core packages now require synchronised versions.
-    # This will be used to ensure we don't accidentally load old or
-    # different versions of modules.
-    # This is not enforced yet, but will be some time in the next few
-    # releases once we can make sure it won't clash with custom
-    # Module::Install extensions.
-    $VERSION = '0.68';
-}
-
-# Whether or not inc::Module::Install is actually loaded, the
-# $INC{inc/Module/Install.pm} is what will still get set as long as
-# the caller loaded module this in the documented manner.
-# If not set, the caller may NOT have loaded the bundled version, and thus
-# they may not have a MI version that works with the Makefile.PL. This would
-# result in false errors or unexpected behaviour. And we don't want that.
-my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
-unless ( $INC{$file} ) {
-    die <<"END_DIE";
-Please invoke ${\__PACKAGE__} with:
-
-    use inc::${\__PACKAGE__};
-
-not:
-
-    use ${\__PACKAGE__};
-
-END_DIE
-}
-
-# If the script that is loading Module::Install is from the future,
-# then make will detect this and cause it to re-run over and over
-# again. This is bad. Rather than taking action to touch it (which
-# is unreliable on some platforms and requires write permissions)
-# for now we should catch this and refuse to run.
-if ( -f $0 and (stat($0))[9] > time ) {
-	die << "END_DIE";
-Your installer $0 has a modification time in the future.
-
-This is known to create infinite loops in make.
-
-Please correct this, then run $0 again.
-
-END_DIE
-}
-
-use Cwd        ();
-use File::Find ();
-use File::Path ();
-use FindBin;
-
-*inc::Module::Install::VERSION = *VERSION;
-@inc::Module::Install::ISA     = __PACKAGE__;
-
-sub autoload {
-    my $self = shift;
-    my $who  = $self->_caller;
-    my $cwd  = Cwd::cwd();
-    my $sym  = "${who}::AUTOLOAD";
-    $sym->{$cwd} = sub {
-        my $pwd = Cwd::cwd();
-        if ( my $code = $sym->{$pwd} ) {
-            # delegate back to parent dirs
-            goto &$code unless $cwd eq $pwd;
-        }
-        $$sym =~ /([^:]+)$/ or die "Cannot autoload $who - $sym";
-        unshift @_, ($self, $1);
-        goto &{$self->can('call')} unless uc($1) eq $1;
-    };
-}
-
-sub import {
-    my $class = shift;
-    my $self  = $class->new(@_);
-    my $who   = $self->_caller;
-
-    unless ( -f $self->{file} ) {
-        require "$self->{path}/$self->{dispatch}.pm";
-        File::Path::mkpath("$self->{prefix}/$self->{author}");
-        $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
-        $self->{admin}->init;
-        @_ = ($class, _self => $self);
-        goto &{"$self->{name}::import"};
-    }
-
-    *{"${who}::AUTOLOAD"} = $self->autoload;
-    $self->preload;
-
-    # Unregister loader and worker packages so subdirs can use them again
-    delete $INC{"$self->{file}"};
-    delete $INC{"$self->{path}.pm"};
-}
-
-sub preload {
-    my ($self) = @_;
-
-    unless ( $self->{extensions} ) {
-        $self->load_extensions(
-            "$self->{prefix}/$self->{path}", $self
-        );
-    }
-
-    my @exts = @{$self->{extensions}};
-    unless ( @exts ) {
-        my $admin = $self->{admin};
-        @exts = $admin->load_all_extensions;
-    }
-
-    my %seen;
-    foreach my $obj ( @exts ) {
-        while (my ($method, $glob) = each %{ref($obj) . '::'}) {
-            next unless $obj->can($method);
-            next if $method =~ /^_/;
-            next if $method eq uc($method);
-            $seen{$method}++;
-        }
-    }
-
-    my $who = $self->_caller;
-    foreach my $name ( sort keys %seen ) {
-        *{"${who}::$name"} = sub {
-            ${"${who}::AUTOLOAD"} = "${who}::$name";
-            goto &{"${who}::AUTOLOAD"};
-        };
-    }
-}
-
-sub new {
-    my ($class, %args) = @_;
-
-    # ignore the prefix on extension modules built from top level.
-    my $base_path = Cwd::abs_path($FindBin::Bin);
-    unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
-        delete $args{prefix};
-    }
-
-    return $args{_self} if $args{_self};
-
-    $args{dispatch} ||= 'Admin';
-    $args{prefix}   ||= 'inc';
-    $args{author}   ||= ($^O eq 'VMS' ? '_author' : '.author');
-    $args{bundle}   ||= 'inc/BUNDLES';
-    $args{base}     ||= $base_path;
-    $class =~ s/^\Q$args{prefix}\E:://;
-    $args{name}     ||= $class;
-    $args{version}  ||= $class->VERSION;
-    unless ( $args{path} ) {
-        $args{path}  = $args{name};
-        $args{path}  =~ s!::!/!g;
-    }
-    $args{file}     ||= "$args{base}/$args{prefix}/$args{path}.pm";
-
-    bless( \%args, $class );
-}
-
-sub call {
-	my ($self, $method) = @_;
-	my $obj = $self->load($method) or return;
-        splice(@_, 0, 2, $obj);
-	goto &{$obj->can($method)};
-}
-
-sub load {
-    my ($self, $method) = @_;
-
-    $self->load_extensions(
-        "$self->{prefix}/$self->{path}", $self
-    ) unless $self->{extensions};
-
-    foreach my $obj (@{$self->{extensions}}) {
-        return $obj if $obj->can($method);
-    }
-
-    my $admin = $self->{admin} or die <<"END_DIE";
-The '$method' method does not exist in the '$self->{prefix}' path!
-Please remove the '$self->{prefix}' directory and run $0 again to load it.
-END_DIE
-
-    my $obj = $admin->load($method, 1);
-    push @{$self->{extensions}}, $obj;
-
-    $obj;
-}
-
-sub load_extensions {
-    my ($self, $path, $top) = @_;
-
-    unless ( grep { lc $_ eq lc $self->{prefix} } @INC ) {
-        unshift @INC, $self->{prefix};
-    }
-
-    foreach my $rv ( $self->find_extensions($path) ) {
-        my ($file, $pkg) = @{$rv};
-        next if $self->{pathnames}{$pkg};
-
-        local $@;
-        my $new = eval { require $file; $pkg->can('new') };
-        unless ( $new ) {
-            warn $@ if $@;
-            next;
-        }
-        $self->{pathnames}{$pkg} = delete $INC{$file};
-        push @{$self->{extensions}}, &{$new}($pkg, _top => $top );
-    }
-
-    $self->{extensions} ||= [];
-}
-
-sub find_extensions {
-    my ($self, $path) = @_;
-
-    my @found;
-    File::Find::find( sub {
-        my $file = $File::Find::name;
-        return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is;
-        my $subpath = $1;
-        return if lc($subpath) eq lc($self->{dispatch});
-
-        $file = "$self->{path}/$subpath.pm";
-        my $pkg = "$self->{name}::$subpath";
-        $pkg =~ s!/!::!g;
-
-        # If we have a mixed-case package name, assume case has been preserved
-        # correctly.  Otherwise, root through the file to locate the case-preserved
-        # version of the package name.
-        if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
-            open PKGFILE, "<$subpath.pm" or die "find_extensions: Can't open $subpath.pm: $!";
-            my $in_pod = 0;
-            while ( <PKGFILE> ) {
-                $in_pod = 1 if /^=\w/;
-                $in_pod = 0 if /^=cut/;
-                next if ($in_pod || /^=cut/);  # skip pod text
-                next if /^\s*#/;               # and comments
-                if ( m/^\s*package\s+($pkg)\s*;/i ) {
-                    $pkg = $1;
-                    last;
-                }
-            }
-            close PKGFILE;
-        }
-
-        push @found, [ $file, $pkg ];
-    }, $path ) if -d $path;
-
-    @found;
-}
-
-sub _caller {
-    my $depth = 0;
-    my $call  = caller($depth);
-    while ( $call eq __PACKAGE__ ) {
-        $depth++;
-        $call = caller($depth);
-    }
-    return $call;
-}
-
-1;
Index: rl/modules/IRC/inc/Module/Install/BarnOwl.pm
===================================================================
--- perl/modules/IRC/inc/Module/Install/BarnOwl.pm	(revision 43c62e4f2171c67b269c2b7c681e96dcb936a40c)
+++ 	(revision )
@@ -1,31 +1,0 @@
-#line 1
-use warnings;
-use strict;
-
-#line 32
-
-package Module::Install::BarnOwl;
-
-use base qw(Module::Install::Base);
-
-sub barnowl_module {
-    my $self = shift;
-    my $name = ucfirst shift;
-    my $class = ref $self;
-
-    $self->name("BarnOwl-Module-$name");
-    $self->all_from("lib/BarnOwl/Module/$name.pm");
-
-    $self->postamble(<<"END_MAKEFILE");
-
-# --- $class section:
-
-$name.par: pm_to_blib
-\tcd blib; zip ../$name.par -r arch lib
-
-END_MAKEFILE
-}
-
-#line 60
-
-1;
Index: rl/modules/IRC/inc/Module/Install/Base.pm
===================================================================
--- perl/modules/IRC/inc/Module/Install/Base.pm	(revision 43c62e4f2171c67b269c2b7c681e96dcb936a40c)
+++ 	(revision )
@@ -1,70 +1,0 @@
-#line 1
-package Module::Install::Base;
-
-$VERSION = '0.68';
-
-# Suspend handler for "redefined" warnings
-BEGIN {
-	my $w = $SIG{__WARN__};
-	$SIG{__WARN__} = sub { $w };
-}
-
-### This is the ONLY module that shouldn't have strict on
-# use strict;
-
-#line 41
-
-sub new {
-    my ($class, %args) = @_;
-
-    foreach my $method ( qw(call load) ) {
-        *{"$class\::$method"} = sub {
-            shift()->_top->$method(@_);
-        } unless defined &{"$class\::$method"};
-    }
-
-    bless( \%args, $class );
-}
-
-#line 61
-
-sub AUTOLOAD {
-    my $self = shift;
-    local $@;
-    my $autoload = eval { $self->_top->autoload } or return;
-    goto &$autoload;
-}
-
-#line 76
-
-sub _top { $_[0]->{_top} }
-
-#line 89
-
-sub admin {
-    $_[0]->_top->{admin} or Module::Install::Base::FakeAdmin->new;
-}
-
-sub is_admin {
-    $_[0]->admin->VERSION;
-}
-
-sub DESTROY {}
-
-package Module::Install::Base::FakeAdmin;
-
-my $Fake;
-sub new { $Fake ||= bless(\@_, $_[0]) }
-
-sub AUTOLOAD {}
-
-sub DESTROY {}
-
-# Restore warning handler
-BEGIN {
-	$SIG{__WARN__} = $SIG{__WARN__}->();
-}
-
-1;
-
-#line 138
Index: rl/modules/IRC/inc/Module/Install/Can.pm
===================================================================
--- perl/modules/IRC/inc/Module/Install/Can.pm	(revision 43c62e4f2171c67b269c2b7c681e96dcb936a40c)
+++ 	(revision )
@@ -1,82 +1,0 @@
-#line 1
-package Module::Install::Can;
-
-use strict;
-use Module::Install::Base;
-use Config ();
-### This adds a 5.005 Perl version dependency.
-### This is a bug and will be fixed.
-use File::Spec ();
-use ExtUtils::MakeMaker ();
-
-use vars qw{$VERSION $ISCORE @ISA};
-BEGIN {
-	$VERSION = '0.68';
-	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
-}
-
-# check if we can load some module
-### Upgrade this to not have to load the module if possible
-sub can_use {
-	my ($self, $mod, $ver) = @_;
-	$mod =~ s{::|\\}{/}g;
-	$mod .= '.pm' unless $mod =~ /\.pm$/i;
-
-	my $pkg = $mod;
-	$pkg =~ s{/}{::}g;
-	$pkg =~ s{\.pm$}{}i;
-
-	local $@;
-	eval { require $mod; $pkg->VERSION($ver || 0); 1 };
-}
-
-# check if we can run some command
-sub can_run {
-	my ($self, $cmd) = @_;
-
-	my $_cmd = $cmd;
-	return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd));
-
-	for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') {
-		my $abs = File::Spec->catfile($dir, $_[1]);
-		return $abs if (-x $abs or $abs = MM->maybe_command($abs));
-	}
-
-	return;
-}
-
-# can we locate a (the) C compiler
-sub can_cc {
-	my $self   = shift;
-	my @chunks = split(/ /, $Config::Config{cc}) or return;
-
-	# $Config{cc} may contain args; try to find out the program part
-	while (@chunks) {
-		return $self->can_run("@chunks") || (pop(@chunks), next);
-	}
-
-	return;
-}
-
-# Fix Cygwin bug on maybe_command();
-if ( $^O eq 'cygwin' ) {
-	require ExtUtils::MM_Cygwin;
-	require ExtUtils::MM_Win32;
-	if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) {
-		*ExtUtils::MM_Cygwin::maybe_command = sub {
-			my ($self, $file) = @_;
-			if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) {
-				ExtUtils::MM_Win32->maybe_command($file);
-			} else {
-				ExtUtils::MM_Unix->maybe_command($file);
-			}
-		}
-	}
-}
-
-1;
-
-__END__
-
-#line 157
Index: rl/modules/IRC/inc/Module/Install/Fetch.pm
===================================================================
--- perl/modules/IRC/inc/Module/Install/Fetch.pm	(revision 43c62e4f2171c67b269c2b7c681e96dcb936a40c)
+++ 	(revision )
@@ -1,93 +1,0 @@
-#line 1
-package Module::Install::Fetch;
-
-use strict;
-use Module::Install::Base;
-
-use vars qw{$VERSION $ISCORE @ISA};
-BEGIN {
-	$VERSION = '0.68';
-	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
-}
-
-sub get_file {
-    my ($self, %args) = @_;
-    my ($scheme, $host, $path, $file) = 
-        $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return;
-
-    if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) {
-        $args{url} = $args{ftp_url}
-            or (warn("LWP support unavailable!\n"), return);
-        ($scheme, $host, $path, $file) = 
-            $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return;
-    }
-
-    $|++;
-    print "Fetching '$file' from $host... ";
-
-    unless (eval { require Socket; Socket::inet_aton($host) }) {
-        warn "'$host' resolve failed!\n";
-        return;
-    }
-
-    return unless $scheme eq 'ftp' or $scheme eq 'http';
-
-    require Cwd;
-    my $dir = Cwd::getcwd();
-    chdir $args{local_dir} or return if exists $args{local_dir};
-
-    if (eval { require LWP::Simple; 1 }) {
-        LWP::Simple::mirror($args{url}, $file);
-    }
-    elsif (eval { require Net::FTP; 1 }) { eval {
-        # use Net::FTP to get past firewall
-        my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600);
-        $ftp->login("anonymous", 'anonymous@example.com');
-        $ftp->cwd($path);
-        $ftp->binary;
-        $ftp->get($file) or (warn("$!\n"), return);
-        $ftp->quit;
-    } }
-    elsif (my $ftp = $self->can_run('ftp')) { eval {
-        # no Net::FTP, fallback to ftp.exe
-        require FileHandle;
-        my $fh = FileHandle->new;
-
-        local $SIG{CHLD} = 'IGNORE';
-        unless ($fh->open("|$ftp -n")) {
-            warn "Couldn't open ftp: $!\n";
-            chdir $dir; return;
-        }
-
-        my @dialog = split(/\n/, <<"END_FTP");
-open $host
-user anonymous anonymous\@example.com
-cd $path
-binary
-get $file $file
-quit
-END_FTP
-        foreach (@dialog) { $fh->print("$_\n") }
-        $fh->close;
-    } }
-    else {
-        warn "No working 'ftp' program available!\n";
-        chdir $dir; return;
-    }
-
-    unless (-f $file) {
-        warn "Fetching failed: $@\n";
-        chdir $dir; return;
-    }
-
-    return if exists $args{size} and -s $file != $args{size};
-    system($args{run}) if exists $args{run};
-    unlink($file) if $args{remove};
-
-    print(((!exists $args{check_for} or -e $args{check_for})
-        ? "done!" : "failed! ($!)"), "\n");
-    chdir $dir; return !$?;
-}
-
-1;
Index: rl/modules/IRC/inc/Module/Install/Makefile.pm
===================================================================
--- perl/modules/IRC/inc/Module/Install/Makefile.pm	(revision 43c62e4f2171c67b269c2b7c681e96dcb936a40c)
+++ 	(revision )
@@ -1,237 +1,0 @@
-#line 1
-package Module::Install::Makefile;
-
-use strict 'vars';
-use Module::Install::Base;
-use ExtUtils::MakeMaker ();
-
-use vars qw{$VERSION $ISCORE @ISA};
-BEGIN {
-	$VERSION = '0.68';
-	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
-}
-
-sub Makefile { $_[0] }
-
-my %seen = ();
-
-sub prompt {
-	shift;
-
-	# Infinite loop protection
-	my @c = caller();
-	if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) {
-		die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])";
-	}
-
-	# In automated testing, always use defaults
-	if ( $ENV{AUTOMATED_TESTING} and ! $ENV{PERL_MM_USE_DEFAULT} ) {
-		local $ENV{PERL_MM_USE_DEFAULT} = 1;
-		goto &ExtUtils::MakeMaker::prompt;
-	} else {
-		goto &ExtUtils::MakeMaker::prompt;
-	}
-}
-
-sub makemaker_args {
-	my $self = shift;
-	my $args = ($self->{makemaker_args} ||= {});
-	%$args = ( %$args, @_ ) if @_;
-	$args;
-}
-
-# For mm args that take multiple space-seperated args,
-# append an argument to the current list.
-sub makemaker_append {
-	my $self = sShift;
-	my $name = shift;
-	my $args = $self->makemaker_args;
-	$args->{name} = defined $args->{$name}
-		? join( ' ', $args->{name}, @_ )
-		: join( ' ', @_ );
-}
-
-sub build_subdirs {
-	my $self    = shift;
-	my $subdirs = $self->makemaker_args->{DIR} ||= [];
-	for my $subdir (@_) {
-		push @$subdirs, $subdir;
-	}
-}
-
-sub clean_files {
-	my $self  = shift;
-	my $clean = $self->makemaker_args->{clean} ||= {};
-	%$clean = (
-		%$clean, 
-		FILES => join(' ', grep length, $clean->{FILES}, @_),
-	);
-}
-
-sub realclean_files {
-	my $self  = shift;
-	my $realclean = $self->makemaker_args->{realclean} ||= {};
-	%$realclean = (
-		%$realclean, 
-		FILES => join(' ', grep length, $realclean->{FILES}, @_),
-	);
-}
-
-sub libs {
-	my $self = shift;
-	my $libs = ref $_[0] ? shift : [ shift ];
-	$self->makemaker_args( LIBS => $libs );
-}
-
-sub inc {
-	my $self = shift;
-	$self->makemaker_args( INC => shift );
-}
-
-my %test_dir = ();
-
-sub _wanted_t {
-	/\.t$/ and -f $_ and $test_dir{$File::Find::dir} = 1;
-}
-
-sub tests_recursive {
-	my $self = shift;
-	if ( $self->tests ) {
-		die "tests_recursive will not work if tests are already defined";
-	}
-	my $dir = shift || 't';
-	unless ( -d $dir ) {
-		die "tests_recursive dir '$dir' does not exist";
-	}
-	require File::Find;
-	%test_dir = ();
-	File::Find::find( \&_wanted_t, $dir );
-	$self->tests( join ' ', map { "$_/*.t" } sort keys %test_dir );
-}
-
-sub write {
-	my $self = shift;
-	die "&Makefile->write() takes no arguments\n" if @_;
-
-	my $args = $self->makemaker_args;
-	$args->{DISTNAME} = $self->name;
-	$args->{NAME}     = $self->module_name || $self->name || $self->determine_NAME($args);
-	$args->{VERSION}  = $self->version || $self->determine_VERSION($args);
-	$args->{NAME}     =~ s/-/::/g;
-	if ( $self->tests ) {
-		$args->{test} = { TESTS => $self->tests };
-	}
-	if ($] >= 5.005) {
-		$args->{ABSTRACT} = $self->abstract;
-		$args->{AUTHOR}   = $self->author;
-	}
-	if ( eval($ExtUtils::MakeMaker::VERSION) >= 6.10 ) {
-		$args->{NO_META} = 1;
-	}
-	if ( eval($ExtUtils::MakeMaker::VERSION) > 6.17 and $self->sign ) {
-		$args->{SIGN} = 1;
-	}
-	unless ( $self->is_admin ) {
-		delete $args->{SIGN};
-	}
-
-	# merge both kinds of requires into prereq_pm
-	my $prereq = ($args->{PREREQ_PM} ||= {});
-	%$prereq = ( %$prereq,
-		map { @$_ }
-		map { @$_ }
-		grep $_,
-		($self->build_requires, $self->requires)
-	);
-
-	# merge both kinds of requires into prereq_pm
-	my $subdirs = ($args->{DIR} ||= []);
-	if ($self->bundles) {
-		foreach my $bundle (@{ $self->bundles }) {
-			my ($file, $dir) = @$bundle;
-			push @$subdirs, $dir if -d $dir;
-			delete $prereq->{$file};
-		}
-	}
-
-	if ( my $perl_version = $self->perl_version ) {
-		eval "use $perl_version; 1"
-			or die "ERROR: perl: Version $] is installed, "
-			. "but we need version >= $perl_version";
-	}
-
-	$args->{INSTALLDIRS} = $self->installdirs;
-
-	my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_})} keys %$args;
-
-	my $user_preop = delete $args{dist}->{PREOP};
-	if (my $preop = $self->admin->preop($user_preop)) {
-		$args{dist} = $preop;
-	}
-
-	my $mm = ExtUtils::MakeMaker::WriteMakefile(%args);
-	$self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile');
-}
-
-sub fix_up_makefile {
-	my $self          = shift;
-	my $makefile_name = shift;
-	my $top_class     = ref($self->_top) || '';
-	my $top_version   = $self->_top->VERSION || '';
-
-	my $preamble = $self->preamble 
-		? "# Preamble by $top_class $top_version\n"
-			. $self->preamble
-		: '';
-	my $postamble = "# Postamble by $top_class $top_version\n"
-		. ($self->postamble || '');
-
-	local *MAKEFILE;
-	open MAKEFILE, "< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
-	my $makefile = do { local $/; <MAKEFILE> };
-	close MAKEFILE or die $!;
-
-	$makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /;
-	$makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g;
-	$makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g;
-	$makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m;
-	$makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m;
-
-	# Module::Install will never be used to build the Core Perl
-	# Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks
-	# PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist
-	$makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m;
-	#$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m;
-
-	# Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well.
-	$makefile =~ s/("?)-I\$\(PERL_LIB\)\1//g;
-
-	# XXX - This is currently unused; not sure if it breaks other MM-users
-	# $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg;
-
-	open  MAKEFILE, "> $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
-	print MAKEFILE  "$preamble$makefile$postamble" or die $!;
-	close MAKEFILE  or die $!;
-
-	1;
-}
-
-sub preamble {
-	my ($self, $text) = @_;
-	$self->{preamble} = $text . $self->{preamble} if defined $text;
-	$self->{preamble};
-}
-
-sub postamble {
-	my ($self, $text) = @_;
-	$self->{postamble} ||= $self->admin->postamble;
-	$self->{postamble} .= $text if defined $text;
-	$self->{postamble}
-}
-
-1;
-
-__END__
-
-#line 363
Index: rl/modules/IRC/inc/Module/Install/Metadata.pm
===================================================================
--- perl/modules/IRC/inc/Module/Install/Metadata.pm	(revision 43c62e4f2171c67b269c2b7c681e96dcb936a40c)
+++ 	(revision )
@@ -1,336 +1,0 @@
-#line 1
-package Module::Install::Metadata;
-
-use strict 'vars';
-use Module::Install::Base;
-
-use vars qw{$VERSION $ISCORE @ISA};
-BEGIN {
-	$VERSION = '0.68';
-	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
-}
-
-my @scalar_keys = qw{
-    name module_name abstract author version license
-    distribution_type perl_version tests installdirs
-};
-
-my @tuple_keys = qw{
-    build_requires requires recommends bundles
-};
-
-sub Meta            { shift        }
-sub Meta_ScalarKeys { @scalar_keys }
-sub Meta_TupleKeys  { @tuple_keys  }
-
-foreach my $key (@scalar_keys) {
-    *$key = sub {
-        my $self = shift;
-        return $self->{values}{$key} if defined wantarray and !@_;
-        $self->{values}{$key} = shift;
-        return $self;
-    };
-}
-
-foreach my $key (@tuple_keys) {
-    *$key = sub {
-        my $self = shift;
-        return $self->{values}{$key} unless @_;
-
-        my @rv;
-        while (@_) {
-            my $module = shift or last;
-            my $version = shift || 0;
-            if ( $module eq 'perl' ) {
-                $version =~ s{^(\d+)\.(\d+)\.(\d+)}
-                             {$1 + $2/1_000 + $3/1_000_000}e;
-                $self->perl_version($version);
-                next;
-            }
-            my $rv = [ $module, $version ];
-            push @rv, $rv;
-        }
-        push @{ $self->{values}{$key} }, @rv;
-        @rv;
-    };
-}
-
-# configure_requires is currently a null-op
-sub configure_requires { 1 }
-
-# Aliases for build_requires that will have alternative
-# meanings in some future version of META.yml.
-sub test_requires      { shift->build_requires(@_)  }
-sub install_requires   { shift->build_requires(@_)  }
-
-# Aliases for installdirs options
-sub install_as_core    { $_[0]->installdirs('perl')   }
-sub install_as_cpan    { $_[0]->installdirs('site')   }
-sub install_as_site    { $_[0]->installdirs('site')   }
-sub install_as_vendor  { $_[0]->installdirs('vendor') }
-
-sub sign {
-    my $self = shift;
-    return $self->{'values'}{'sign'} if defined wantarray and ! @_;
-    $self->{'values'}{'sign'} = ( @_ ? $_[0] : 1 );
-    return $self;
-}
-
-sub dynamic_config {
-	my $self = shift;
-	unless ( @_ ) {
-		warn "You MUST provide an explicit true/false value to dynamic_config, skipping\n";
-		return $self;
-	}
-	$self->{'values'}{'dynamic_config'} = $_[0] ? 1 : 0;
-	return $self;
-}
-
-sub all_from {
-    my ( $self, $file ) = @_;
-
-    unless ( defined($file) ) {
-        my $name = $self->name
-            or die "all_from called with no args without setting name() first";
-        $file = join('/', 'lib', split(/-/, $name)) . '.pm';
-        $file =~ s{.*/}{} unless -e $file;
-        die "all_from: cannot find $file from $name" unless -e $file;
-    }
-
-    $self->version_from($file)      unless $self->version;
-    $self->perl_version_from($file) unless $self->perl_version;
-
-    # The remaining probes read from POD sections; if the file
-    # has an accompanying .pod, use that instead
-    my $pod = $file;
-    if ( $pod =~ s/\.pm$/.pod/i and -e $pod ) {
-        $file = $pod;
-    }
-
-    $self->author_from($file)   unless $self->author;
-    $self->license_from($file)  unless $self->license;
-    $self->abstract_from($file) unless $self->abstract;
-}
-
-sub provides {
-    my $self     = shift;
-    my $provides = ( $self->{values}{provides} ||= {} );
-    %$provides = (%$provides, @_) if @_;
-    return $provides;
-}
-
-sub auto_provides {
-    my $self = shift;
-    return $self unless $self->is_admin;
-
-    unless (-e 'MANIFEST') {
-        warn "Cannot deduce auto_provides without a MANIFEST, skipping\n";
-        return $self;
-    }
-
-    # Avoid spurious warnings as we are not checking manifest here.
-
-    local $SIG{__WARN__} = sub {1};
-    require ExtUtils::Manifest;
-    local *ExtUtils::Manifest::manicheck = sub { return };
-
-    require Module::Build;
-    my $build = Module::Build->new(
-        dist_name    => $self->name,
-        dist_version => $self->version,
-        license      => $self->license,
-    );
-    $self->provides(%{ $build->find_dist_packages || {} });
-}
-
-sub feature {
-    my $self     = shift;
-    my $name     = shift;
-    my $features = ( $self->{values}{features} ||= [] );
-
-    my $mods;
-
-    if ( @_ == 1 and ref( $_[0] ) ) {
-        # The user used ->feature like ->features by passing in the second
-        # argument as a reference.  Accomodate for that.
-        $mods = $_[0];
-    } else {
-        $mods = \@_;
-    }
-
-    my $count = 0;
-    push @$features, (
-        $name => [
-            map {
-                ref($_) ? ( ref($_) eq 'HASH' ) ? %$_
-                                                : @$_
-                        : $_
-            } @$mods
-        ]
-    );
-
-    return @$features;
-}
-
-sub features {
-    my $self = shift;
-    while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) {
-        $self->feature( $name, @$mods );
-    }
-    return $self->{values}->{features}
-    	? @{ $self->{values}->{features} }
-    	: ();
-}
-
-sub no_index {
-    my $self = shift;
-    my $type = shift;
-    push @{ $self->{values}{no_index}{$type} }, @_ if $type;
-    return $self->{values}{no_index};
-}
-
-sub read {
-    my $self = shift;
-    $self->include_deps( 'YAML', 0 );
-
-    require YAML;
-    my $data = YAML::LoadFile('META.yml');
-
-    # Call methods explicitly in case user has already set some values.
-    while ( my ( $key, $value ) = each %$data ) {
-        next unless $self->can($key);
-        if ( ref $value eq 'HASH' ) {
-            while ( my ( $module, $version ) = each %$value ) {
-                $self->can($key)->($self, $module => $version );
-            }
-        }
-        else {
-            $self->can($key)->($self, $value);
-        }
-    }
-    return $self;
-}
-
-sub write {
-    my $self = shift;
-    return $self unless $self->is_admin;
-    $self->admin->write_meta;
-    return $self;
-}
-
-sub version_from {
-    my ( $self, $file ) = @_;
-    require ExtUtils::MM_Unix;
-    $self->version( ExtUtils::MM_Unix->parse_version($file) );
-}
-
-sub abstract_from {
-    my ( $self, $file ) = @_;
-    require ExtUtils::MM_Unix;
-    $self->abstract(
-        bless(
-            { DISTNAME => $self->name },
-            'ExtUtils::MM_Unix'
-        )->parse_abstract($file)
-     );
-}
-
-sub _slurp {
-    my ( $self, $file ) = @_;
-
-    local *FH;
-    open FH, "< $file" or die "Cannot open $file.pod: $!";
-    do { local $/; <FH> };
-}
-
-sub perl_version_from {
-    my ( $self, $file ) = @_;
-
-    if (
-        $self->_slurp($file) =~ m/
-        ^
-        use \s*
-        v?
-        ([\d_\.]+)
-        \s* ;
-    /ixms
-      )
-    {
-        my $v = $1;
-        $v =~ s{_}{}g;
-        $self->perl_version($1);
-    }
-    else {
-        warn "Cannot determine perl version info from $file\n";
-        return;
-    }
-}
-
-sub author_from {
-    my ( $self, $file ) = @_;
-    my $content = $self->_slurp($file);
-    if ($content =~ m/
-        =head \d \s+ (?:authors?)\b \s*
-        ([^\n]*)
-        |
-        =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s*
-        .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s*
-        ([^\n]*)
-    /ixms) {
-        my $author = $1 || $2;
-        $author =~ s{E<lt>}{<}g;
-        $author =~ s{E<gt>}{>}g;
-        $self->author($author); 
-    }
-    else {
-        warn "Cannot determine author info from $file\n";
-    }
-}
-
-sub license_from {
-    my ( $self, $file ) = @_;
-
-    if (
-        $self->_slurp($file) =~ m/
-        (
-            =head \d \s+
-            (?:licen[cs]e|licensing|copyright|legal)\b
-            .*?
-        )
-        (=head\\d.*|=cut.*|)
-        \z
-    /ixms
-      )
-    {
-        my $license_text = $1;
-        my @phrases      = (
-            'under the same (?:terms|license) as perl itself' => 'perl',        1,
-            'GNU public license'                              => 'gpl',         1,
-            'GNU lesser public license'                       => 'gpl',         1,
-            'BSD license'                                     => 'bsd',         1,
-            'Artistic license'                                => 'artistic',    1,
-            'GPL'                                             => 'gpl',         1,
-            'LGPL'                                            => 'lgpl',        1,
-            'BSD'                                             => 'bsd',         1,
-            'Artistic'                                        => 'artistic',    1,
-            'MIT'                                             => 'mit',         1,
-            'proprietary'                                     => 'proprietary', 0,
-        );
-        while ( my ($pattern, $license, $osi) = splice(@phrases, 0, 3) ) {
-            $pattern =~ s{\s+}{\\s+}g;
-            if ( $license_text =~ /\b$pattern\b/i ) {
-                if ( $osi and $license_text =~ /All rights reserved/i ) {
-                        warn "LEGAL WARNING: 'All rights reserved' may invalidate Open Source licenses. Consider removing it.";
-		}
-                $self->license($license);
-                return 1;
-            }
-        }
-    }
-
-    warn "Cannot determine license info from $file\n";
-    return 'unknown';
-}
-
-1;
Index: rl/modules/IRC/inc/Module/Install/Win32.pm
===================================================================
--- perl/modules/IRC/inc/Module/Install/Win32.pm	(revision 43c62e4f2171c67b269c2b7c681e96dcb936a40c)
+++ 	(revision )
@@ -1,65 +1,0 @@
-#line 1
-package Module::Install::Win32;
-
-use strict;
-use Module::Install::Base;
-
-use vars qw{$VERSION $ISCORE @ISA};
-BEGIN {
-	$VERSION = '0.68';
-	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
-}
-
-# determine if the user needs nmake, and download it if needed
-sub check_nmake {
-	my $self = shift;
-	$self->load('can_run');
-	$self->load('get_file');
-	
-	require Config;
-	return unless (
-		$^O eq 'MSWin32'                     and
-		$Config::Config{make}                and
-		$Config::Config{make} =~ /^nmake\b/i and
-		! $self->can_run('nmake')
-	);
-
-	print "The required 'nmake' executable not found, fetching it...\n";
-
-	require File::Basename;
-	my $rv = $self->get_file(
-		url       => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe',
-		ftp_url   => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe',
-		local_dir => File::Basename::dirname($^X),
-		size      => 51928,
-		run       => 'Nmake15.exe /o > nul',
-		check_for => 'Nmake.exe',
-		remove    => 1,
-	);
-
-	if (!$rv) {
-        die <<'END_MESSAGE';
-
--------------------------------------------------------------------------------
-
-Since you are using Microsoft Windows, you will need the 'nmake' utility
-before installation. It's available at:
-
-  http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe
-      or
-  ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe
-
-Please download the file manually, save it to a directory in %PATH% (e.g.
-C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to
-that directory, and run "Nmake15.exe" from there; that will create the
-'nmake.exe' file needed by this module.
-
-You may then resume the installation process described in README.
-
--------------------------------------------------------------------------------
-END_MESSAGE
-	}
-}
-
-1;
Index: rl/modules/IRC/inc/Module/Install/WriteAll.pm
===================================================================
--- perl/modules/IRC/inc/Module/Install/WriteAll.pm	(revision 43c62e4f2171c67b269c2b7c681e96dcb936a40c)
+++ 	(revision )
@@ -1,43 +1,0 @@
-#line 1
-package Module::Install::WriteAll;
-
-use strict;
-use Module::Install::Base;
-
-use vars qw{$VERSION $ISCORE @ISA};
-BEGIN {
-	$VERSION = '0.68';
-	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
-}
-
-sub WriteAll {
-    my $self = shift;
-    my %args = (
-        meta        => 1,
-        sign        => 0,
-        inline      => 0,
-        check_nmake => 1,
-        @_
-    );
-
-    $self->sign(1)                if $args{sign};
-    $self->Meta->write            if $args{meta};
-    $self->admin->WriteAll(%args) if $self->is_admin;
-
-    if ( $0 =~ /Build.PL$/i ) {
-        $self->Build->write;
-    } else {
-        $self->check_nmake if $args{check_nmake};
-        unless ( $self->makemaker_args->{'PL_FILES'} ) {
-        	$self->makemaker_args( PL_FILES => {} );
-        }
-        if ($args{inline}) {
-            $self->Inline->write;
-        } else {
-            $self->Makefile->write;
-        }
-    }
-}
-
-1;
Index: rl/modules/IRC/lib/BarnOwl/Message/IRC.pm
===================================================================
--- perl/modules/IRC/lib/BarnOwl/Message/IRC.pm	(revision f79d6a2ccedcc7110b1391f385fb739e324562bd)
+++ 	(revision )
@@ -1,89 +1,0 @@
-use warnings;
-use strict;
-
-=head1 NAME
-
-BarnOwl::Message::IRC
-
-=head1 DESCRIPTION
-
-A subclass of BarnOwl::Message for IRC messages
-
-=cut
-
-package BarnOwl::Message::IRC;
-
-use base qw( BarnOwl::Message );
-
-sub smartfilter {
-    my $self = shift;
-    my $inst = shift;
-
-    my $filter;
-    my @filter;
-
-    if($self->is_private) {
-        my $who;
-        if($self->direction eq 'out') {
-            $who = $self->recipient;
-        } else {
-            $who = $self->sender;
-        }
-        $filter = "irc-user-$who";
-        @filter  =
-             (qw{( type ^irc$ and filter personal and },
-              qw{( ( direction ^in$ and sender}, "^\Q$who\E\$",
-              qw{ ) or ( direction ^out$ and recipient}, "^\Q$who\E\$",
-              qw{) ) ) });
-        BarnOwl::command("filter", "$filter", @filter);
-        return $filter;
-    } else {
-        # To a Channel
-        my $network = $self->network;
-        my $channel = $self->channel;
-        my $sender = $self->sender;
-        my ($filter, $ftext);
-        if ($inst && $self->body =~ /^(\S+):/) {
-            $filter = "irc-$network-channel-$channel-$sender-$1";
-            @filter =
-                 (qw{type ^irc$ and network}, "^\Q$network\E\$",
-                  qw{and channel}, "^\Q$channel\E\$",
-                  qw{and ( sender}, "^\Q$sender\E\$",
-                  qw{or sender}, "^\Q$1\E\$",qq{)});
-        } else {
-            $filter = "irc-$network-channel-$channel";
-            @filter = (qw{type ^irc$ and network}, "^\Q$network\E\$",
-                       qw{and channel}, "^\Q$channel\E\$");
-        }
-        BarnOwl::command("filter", "$filter", @filter);
-        return $filter;
-    }
-}
-
-sub server {shift->{server}}
-sub network {shift->{network}}
-sub channel {shift->{channel}}
-sub action {shift->{action}}
-sub reason {shift->{reason}}
-
-# display
-sub context {shift->{network};}
-sub subcontext {shift->{recipient};}
-
-sub long_sender {shift->{from} || ""};
-
-sub login_type {
-    my $self = shift;
-    return " (" . uc $self->action . ")";
-}
-
-sub login_extra { 
-    my $self = shift;
-    if ($self->action eq "quit") {
-        return $self->reason;
-    } else {
-        return $self->channel;
-    }
-}
-
-1;
Index: rl/modules/IRC/lib/BarnOwl/Module/IRC.pm
===================================================================
--- perl/modules/IRC/lib/BarnOwl/Module/IRC.pm	(revision 1c014eece4610d0a5882362dc4eede679792364b)
+++ 	(revision )
@@ -1,353 +1,0 @@
-use strict;
-use warnings;
-
-package BarnOwl::Module::IRC;
-
-=head1 NAME
-
-BarnOwl::Module::IRC
-
-=head1 DESCRIPTION
-
-This module implements IRC support for barnowl.
-
-=cut
-
-use BarnOwl;
-use BarnOwl::Hooks;
-use BarnOwl::Message::IRC;
-use BarnOwl::Module::IRC::Connection qw(is_private);
-
-use Net::IRC;
-use Getopt::Long;
-
-our $VERSION = 0.02;
-
-our $irc;
-
-# Hash alias -> BarnOwl::Module::IRC::Connection object
-our %ircnets;
-our %channels;
-
-sub startup {
-    BarnOwl::new_variable_string('irc:nick', {
-        default     => $ENV{USER},
-        summary     => 'The default IRC nickname',
-        description => 'By default, irc-connect will use this nick '  .
-        'when connecting to a new server. See :help irc-connect for ' .
-        'more information.'
-       });
-
-    BarnOwl::new_variable_string('irc:user', {
-        default => $ENV{USER},
-        summary => 'The IRC "username" field'
-       });
-        BarnOwl::new_variable_string('irc:name', {
-        default => "",
-        summary     => 'A short name field for IRC',
-        description => 'A short (maybe 60 or so chars) piece of text, ' .
-        'originally intended to display your real name, which people '  .
-        'often use for pithy quotes and URLs.'
-       });
-    
-    BarnOwl::new_variable_bool('irc:spew', {
-        default     => 0,
-        summary     => 'Show unhandled IRC events',
-        description => 'If set, display all unrecognized IRC events as ' .
-        'admin messages. Intended for debugging and development use only '
-       });
-    
-    register_commands();
-    register_handlers();
-    BarnOwl::filter('irc type ^IRC$');
-}
-
-sub shutdown {
-    for my $conn (values %ircnets) {
-        $conn->conn->disconnect();
-    }
-}
-
-#sub mainloop_hook {
-#    return unless defined $irc;
-#    eval {
-#        $irc->do_one_loop();
-#    };
-#    return;
-#}
-
-sub OwlProcess {
-    return unless defined $irc;
-    eval {
-        $irc->do_one_loop();
-    };
-    return;
-}
-
-
-sub register_handlers {
-    if(!$irc) {
-        $irc = Net::IRC->new;
-        $irc->timeout(0);
-    }
-}
-
-sub register_commands {
-    BarnOwl::new_command('irc-connect' => \&cmd_connect,
-                       {
-                           summary      => 'Connect to an IRC server',
-                           usage        => 'irc-connect [-a ALIAS ] [-s] [-p PASSWORD] [-n NICK] SERVER [port]',
-                           description  =>
-
-                           "Connect to an IRC server. Supported options are\n\n" .
-                           "-a <alias>          Define an alias for this server\n" .
-                           "-s                  Use SSL\n" .
-                           "-p <password>       Specify the password to use\n" .
-                           "-n <nick>           Use a non-default nick"
-                       });
-    BarnOwl::new_command('irc-disconnect' => \&cmd_disconnect);
-    BarnOwl::new_command('irc-msg'        => \&cmd_msg);
-    BarnOwl::new_command('irc-join'       => \&cmd_join);
-    BarnOwl::new_command('irc-part'       => \&cmd_part);
-    BarnOwl::new_command('irc-nick'       => \&cmd_nick);
-    BarnOwl::new_command('irc-names'      => \&cmd_names);
-    BarnOwl::new_command('irc-whois'      => \&cmd_whois);
-    BarnOwl::new_command('irc-motd'       => \&cmd_motd);
-    BarnOwl::new_command('irc-list'       => \&cmd_list);
-    BarnOwl::new_command('irc-who'        => \&cmd_who);
-    BarnOwl::new_command('irc-stats'      => \&cmd_stats);
-    BarnOwl::new_command('irc-topic'      => \&cmd_topic);
-}
-
-$BarnOwl::Hooks::startup->add('BarnOwl::Module::IRC::startup');
-$BarnOwl::Hooks::shutdown->add('BarnOwl::Module::IRC::shutdown');
-
-################################################################################
-######################## Owl command handlers ##################################
-################################################################################
-
-sub cmd_connect {
-    my $cmd = shift;
-
-    my $nick = BarnOwl::getvar('irc:nick');
-    my $username = BarnOwl::getvar('irc:user');
-    my $ircname = BarnOwl::getvar('irc:name');
-    my $host;
-    my $port;
-    my $alias;
-    my $ssl;
-    my $password = undef;
-
-    {
-        local @ARGV = @_;
-        GetOptions(
-            "alias=s"    => \$alias,
-            "ssl"        => \$ssl,
-            "password=s" => \$password,
-            "nick=s"     => \$nick,
-        );
-        $host = shift @ARGV or die("Usage: $cmd HOST\n");
-        if(!$alias) {
-            if($host =~ /^(?:irc[.])?([\w-]+)[.]\w+$/) {
-                $alias = $1;
-            } else {
-                $alias = $host;
-            }
-        }
-        $ssl ||= 0;
-        $port = shift @ARGV || ($ssl ? 6697 : 6667);
-    }
-
-    if(exists $ircnets{$alias}) {
-        die("Already connected to a server with alias '$alias'. Either disconnect or specify an alias with -a.\n");
-    }
-
-    my $conn = BarnOwl::Module::IRC::Connection->new($irc, $alias,
-        Nick      => $nick,
-        Server    => $host,
-        Port      => $port,
-        Username  => $username,
-        Ircname   => $ircname,
-        Port      => $port,
-        Password  => $password,
-        SSL       => $ssl
-       );
-
-    if ($conn->conn->connected) {
-        BarnOwl::admin_message("IRC", "Connected to $alias as $nick");
-        $ircnets{$alias} = $conn;
-        my $fd = $conn->getSocket()->fileno();
-        BarnOwl::add_dispatch($fd, \&OwlProcess);
-        $conn->{FD} = $fd;
-    } else {
-        die("IRC::Connection->connect failed: $!");
-    }
-
-    return;
-}
-
-sub cmd_disconnect {
-    my $cmd = shift;
-    my $conn = get_connection(\@_);
-    $conn->conn->disconnect;
-    delete $ircnets{$conn->alias};
-}
-
-sub cmd_msg {
-    my $cmd = shift;
-    my $conn = get_connection(\@_);
-    my $to = shift or die("Usage: $cmd NICK\n");
-    # handle multiple recipients?
-    if(@_) {
-        process_msg($conn, $to, join(" ", @_));
-    } else {
-        BarnOwl::start_edit_win("/msg -a " . $conn->alias . " $to", sub {process_msg($conn, $to, @_)});
-    }
-}
-
-sub process_msg {
-    my $conn = shift;
-    my $to = shift;
-    my $body = shift;
-    # Strip whitespace. In the future -- send one message/line?
-    $body =~ tr/\n\r/  /;
-    if ($body =~ /^\/me (.*)/) {
-        $conn->conn->me($to, $1);
-        $body = '* '.$conn->nick.' '.$1;
-    } else {
-        $conn->conn->privmsg($to, $body);
-    }
-    my $msg = BarnOwl::Message->new(
-        type        => 'IRC',
-        direction   => is_private($to) ? 'out' : 'in',
-        server      => $conn->server,
-        network     => $conn->alias,
-        recipient   => $to,
-        body        => $body,
-        sender      => $conn->nick,
-        is_private($to) ?
-          (isprivate  => 'true') : (channel => $to),
-        replycmd    => "irc-msg -a " . $conn->alias . " $to",
-        replysendercmd => "irc-msg -a " . $conn->alias . " $to"
-       );
-    BarnOwl::queue_message($msg);
-}
-
-sub cmd_join {
-    my $cmd = shift;
-    my $conn = get_connection(\@_);
-    my $chan = shift or die("Usage: $cmd channel\n");
-    $channels{$chan} ||= [];
-    push @{$channels{$chan}}, $conn;
-    $conn->conn->join($chan);
-}
-
-sub cmd_part {
-    my $cmd = shift;
-    my $conn = get_connection(\@_);
-    my $chan = get_channel(\@_) || die("Usage: $cmd <channel>\n");
-    $channels{$chan} = [grep {$_ ne $conn} @{$channels{$chan} || []}];
-    $conn->conn->part($chan);
-}
-
-sub cmd_nick {
-    my $cmd = shift;
-    my $conn = get_connection(\@_);
-    my $nick = shift or die("Usage: $cmd <new nick>\n");
-    $conn->conn->nick($nick);
-}
-
-sub cmd_names {
-    my $cmd = shift;
-    my $conn = get_connection(\@_);
-    my $chan = get_channel(\@_) || die("Usage: $cmd <channel>\n");
-    $conn->names_tmp([]);
-    $conn->conn->names($chan);
-}
-
-sub cmd_whois {
-    my $cmd = shift;
-    my $conn = get_connection(\@_);
-    my $who = shift || die("Usage: $cmd <user>\n");
-    $conn->conn->whois($who);
-}
-
-sub cmd_motd {
-    my $cmd = shift;
-    my $conn = get_connection(\@_);
-    $conn->conn->motd;
-}
-
-sub cmd_list {
-    my $cmd = shift;
-    my $message = BarnOwl::Style::boldify('Current IRC networks:') . "\n";
-    while (my ($alias, $conn) = each %ircnets) {
-        $message .= '  ' . $alias . ' => ' . $conn->nick . '@' . $conn->server . "\n";
-    }
-    BarnOwl::popless_ztext($message);
-}
-
-sub cmd_who {
-    my $cmd = shift;
-    my $conn = get_connection(\@_);
-    my $who = shift || die("Usage: $cmd <user>\n");
-    $conn->conn->who($who);
-}
-
-sub cmd_stats {
-    my $cmd = shift;
-    my $conn = get_connection(\@_);
-    my $type = shift || die("Usage: $cmd <chiklmouy> [server] \n");
-    $conn->conn->stats($type, @_);
-}
-
-sub cmd_topic {
-    my $cmd = shift;
-    my $conn = get_connection(\@_);
-    $conn->conn->topic(@_);
-}
-
-################################################################################
-########################### Utilities/Helpers ##################################
-################################################################################
-
-sub get_connection {
-    my $args = shift;
-    if(scalar @$args >= 2 && $args->[0] eq '-a') {
-        shift @$args;
-        return get_connection_by_alias(shift @$args);
-    }
-    my $channel = $args->[-1];
-    if (defined($channel) && $channel =~ /^#/
-        and $channels{$channel} and @{$channels{$channel}} == 1) {
-        return $channels{$channel}[0];
-    }
-    my $m = BarnOwl::getcurmsg();
-    if($m && $m->type eq 'IRC') {
-        return get_connection_by_alias($m->network);
-    }
-    if(scalar keys %ircnets == 1) {
-        return [values(%ircnets)]->[0];
-    }
-    die("You must specify a network with -a\n");
-}
-
-sub get_channel {
-    my $args = shift;
-    if(scalar @$args) {
-        return shift @$args;
-    }
-    my $m = BarnOwl::getcurmsg();
-    if($m && $m->type eq 'IRC') {
-        return $m->channel if !$m->is_private;
-    }
-    return undef;
-}
-
-sub get_connection_by_alias {
-    my $key = shift;
-    die("No such ircnet: $key\n") unless exists $ircnets{$key};
-    return $ircnets{$key};
-}
-
-1;
Index: rl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm
===================================================================
--- perl/modules/IRC/lib/BarnOwl/Module/IRC/Connection.pm	(revision 4789b17987d2032fcf895ce27b81ac613343e169)
+++ 	(revision )
@@ -1,315 +1,0 @@
-use strict;
-use warnings;
-
-package BarnOwl::Module::IRC::Connection;
-
-=head1 NAME
-
-BarnOwl::Module::IRC::Connection
-
-=head1 DESCRIPTION
-
-This module is a wrapper around Net::IRC::Connection for BarnOwl's IRC
-support
-
-=cut
-
-use Net::IRC::Connection;
-
-use base qw(Class::Accessor Exporter);
-__PACKAGE__->mk_accessors(qw(conn alias channels connected motd names_tmp whois_tmp));
-our @EXPORT_OK = qw(&is_private);
-
-use BarnOwl;
-
-BEGIN {
-    no strict 'refs';
-    my @delegate = qw(nick server);
-    for my $meth (@delegate) {
-        *{"BarnOwl::Module::IRC::Connection::$meth"} = sub {
-            shift->conn->$meth(@_);
-        }
-    }
-};
-
-sub new {
-    my $class = shift;
-    my $irc = shift;
-    my $alias = shift;
-    my %args = (@_);
-    my $conn = Net::IRC::Connection->new($irc, %args);
-    my $self = bless({}, $class);
-    $self->conn($conn);
-    $self->alias($alias);
-    $self->channels([]);
-    $self->motd("");
-    $self->connected(0);
-    $self->names_tmp(0);
-    $self->whois_tmp("");
-
-    $self->conn->add_handler(376 => sub { shift; $self->on_connect(@_) });
-    $self->conn->add_default_handler(sub { shift; $self->on_event(@_) });
-    $self->conn->add_handler(['msg', 'notice', 'public', 'caction'],
-            sub { shift; $self->on_msg(@_) });
-    $self->conn->add_handler(['welcome', 'yourhost', 'created',
-                              'luserclient', 'luserop', 'luserchannels', 'luserme',
-                              'error'],
-            sub { shift; $self->on_admin_msg(@_) });
-    $self->conn->add_handler(['myinfo', 'map', 'n_local', 'n_global',
-            'luserconns'],
-            sub { });
-    $self->conn->add_handler(motdstart => sub { shift; $self->on_motdstart(@_) });
-    $self->conn->add_handler(motd      => sub { shift; $self->on_motd(@_) });
-    $self->conn->add_handler(endofmotd => sub { shift; $self->on_endofmotd(@_) });
-    $self->conn->add_handler(join      => sub { shift; $self->on_join(@_) });
-    $self->conn->add_handler(part      => sub { shift; $self->on_part(@_) });
-    $self->conn->add_handler(quit      => sub { shift; $self->on_quit(@_) });
-    $self->conn->add_handler(disconnect => sub { shift; $self->on_disconnect(@_) });
-    $self->conn->add_handler(nicknameinuse => sub { shift; $self->on_nickinuse(@_) });
-    $self->conn->add_handler(cping     => sub { shift; $self->on_ping(@_) });
-    $self->conn->add_handler(topic     => sub { shift; $self->on_topic(@_) });
-    $self->conn->add_handler(topicinfo => sub { shift; $self->on_topicinfo(@_) });
-    $self->conn->add_handler(namreply  => sub { shift; $self->on_namreply(@_) });
-    $self->conn->add_handler(endofnames=> sub { shift; $self->on_endofnames(@_) });
-    $self->conn->add_handler(endofwhois=> sub { shift; $self->on_endofwhois(@_) });
-
-    return $self;
-}
-
-sub getSocket
-{
-    my $self = shift;
-    return $self->conn->socket;
-}
-
-################################################################################
-############################### IRC callbacks ##################################
-################################################################################
-
-sub new_message {
-    my $self = shift;
-    my $evt = shift;
-    return BarnOwl::Message->new(
-        type        => 'IRC',
-        server      => $self->server,
-        network     => $self->alias,
-        sender      => $evt->nick,
-        hostname    => $evt->host,
-        from        => $evt->from,
-        @_
-       );
-}
-
-sub on_msg {
-    my ($self, $evt) = @_;
-    my ($recipient) = $evt->to;
-    my $body = strip_irc_formatting([$evt->args]->[0]);
-    my $nick = $self->nick;
-    BarnOwl::beep() if $body =~ /\b\Q$nick\E\b/;
-    $body = BarnOwl::Style::boldify($evt->nick.' '.$body) if $evt->type eq 'caction';
-    my $msg = $self->new_message($evt,
-        direction   => 'in',
-        recipient   => $recipient,
-        body => $body,
-        $evt->type eq 'notice' ?
-          (notice     => 'true') : (),
-        is_private($recipient) ?
-          (isprivate  => 'true') : (channel => $recipient),
-        replycmd    => 'irc-msg -a ' . $self->alias . ' ' .
-            (is_private($recipient) ? $evt->nick : $recipient),
-        replysendercmd => 'irc-msg -a ' . $self->alias . ' ' . $evt->nick
-       );
-
-    BarnOwl::queue_message($msg);
-}
-
-sub on_ping {
-    my ($self, $evt) = @_;
-    $self->conn->ctcp_reply($evt->nick, join (' ', ($evt->args)));
-}
-
-sub on_admin_msg {
-    my ($self, $evt) = @_;
-    BarnOwl::admin_message("IRC",
-            BarnOwl::Style::boldify('IRC ' . $evt->type . ' message from '
-                . $self->alias) . "\n"
-            . strip_irc_formatting(join ' ', cdr($evt->args)));
-}
-
-sub on_motdstart {
-    my ($self, $evt) = @_;
-    $self->motd(join "\n", cdr($evt->args));
-}
-
-sub on_motd {
-    my ($self, $evt) = @_;
-    $self->motd(join "\n", $self->motd, cdr($evt->args));
-}
-
-sub on_endofmotd {
-    my ($self, $evt) = @_;
-    $self->motd(join "\n", $self->motd, cdr($evt->args));
-    if(!$self->connected) {
-        BarnOwl::admin_message("IRC", "Connected to " .
-                               $self->server . " (" . $self->alias . ")");
-        $self->connected(1);
-        
-    }
-    BarnOwl::admin_message("IRC",
-            BarnOwl::Style::boldify('MOTD for ' . $self->alias) . "\n"
-            . strip_irc_formatting($self->motd));
-}
-
-sub on_join {
-    my ($self, $evt) = @_;
-    my $msg = $self->new_message($evt,
-        loginout   => 'login',
-        action     => 'join',
-        channel    => $evt->to,
-        replycmd => 'irc-msg -a ' . $self->alias . ' ' . join(' ', $evt->to),
-        replysendercmd => 'irc-msg -a ' . $self->alias . ' ' . $evt->nick
-        );
-    BarnOwl::queue_message($msg);
-}
-
-sub on_part {
-    my ($self, $evt) = @_;
-    my $msg = $self->new_message($evt,
-        loginout   => 'logout',
-        action     => 'part',
-        channel    => $evt->to,
-        replycmd => 'irc-msg -a ' . $self->alias . ' ' . join(' ', $evt->to),
-        replysendercmd => 'irc-msg -a ' . $self->alias . ' ' . $evt->nick
-        );
-    BarnOwl::queue_message($msg);
-}
-
-sub on_quit {
-    my ($self, $evt) = @_;
-    my $msg = $self->new_message($evt,
-        loginout   => 'logout',
-        action     => 'quit',
-        from       => $evt->to,
-        reason     => [$evt->args]->[0],
-        replycmd => 'irc-msg -a ' . $self->alias . ' ' . $evt->nick,
-        replysendercmd => 'irc-msg -a ' . $self->alias . ' ' . $evt->nick
-        );
-    BarnOwl::queue_message($msg);
-}
-
-sub on_disconnect {
-    my $self = shift;
-    delete $BarnOwl::Module::IRC::ircnets{$self->alias};
-    BarnOwl::remove_dispatch($self->{FD});
-    BarnOwl::admin_message('IRC',
-                           "[" . $self->alias . "] Disconnected from server");
-}
-
-sub on_nickinuse {
-    my ($self, $evt) = @_;
-    BarnOwl::admin_message("IRC",
-                           "[" . $self->alias . "] " .
-                           [$evt->args]->[1] . ": Nick already in use");
-    unless($self->connected) {
-        $self->conn->disconnect;
-    }
-}
-
-sub on_topic {
-    my ($self, $evt) = @_;
-    my @args = $evt->args;
-    if (scalar @args > 1) {
-        BarnOwl::admin_message("IRC",
-                "Topic for $args[1] on " . $self->alias . " is $args[2]");
-    } else {
-        BarnOwl::admin_message("IRC",
-                "Topic changed to $args[0]");
-    }
-}
-
-sub on_topicinfo {
-    my ($self, $evt) = @_;
-    my @args = $evt->args;
-    BarnOwl::admin_message("IRC",
-        "Topic for $args[1] set by $args[2] at " . localtime($args[3]));
-}
-
-# IRC gives us a bunch of namreply messages, followed by an endofnames.
-# We need to collect them from the namreply and wait for the endofnames message.
-# After this happens, the names_tmp variable is cleared.
-
-sub on_namreply {
-    my ($self, $evt) = @_;
-    return unless $self->names_tmp;
-    $self->names_tmp([@{$self->names_tmp}, split(' ', [$evt->args]->[3])]);
-}
-
-sub on_endofnames {
-    my ($self, $evt) = @_;
-    return unless $self->names_tmp;
-    my $names = BarnOwl::Style::boldify("Members of " . [$evt->args]->[1] . ":\n");
-    for my $name (@{$self->names_tmp}) {
-        $names .= "  $name\n";
-    }
-    BarnOwl::popless_ztext($names);
-    $self->names_tmp(0);
-}
-
-sub on_whois {
-    my ($self, $evt) = @_;
-    $self->whois_tmp(
-      $self->whois_tmp . "\n" . $evt->type . ":\n  " .
-      join("\n  ", cdr(cdr($evt->args))) . "\n"
-    );
-}
-
-sub on_endofwhois {
-    my ($self, $evt) = @_;
-    BarnOwl::popless_ztext(
-        BarnOwl::Style::boldify("/whois for " . [$evt->args]->[1] . ":\n") .
-        $self->whois_tmp
-    );
-    $self->whois_tmp([]);
-}
-
-sub on_event {
-    my ($self, $evt) = @_;
-    return on_whois(@_) if ($evt->type =~ /^whois/);
-    BarnOwl::admin_message("IRC",
-            "[" . $self->alias . "] Unhandled IRC event of type " . $evt->type . ":\n"
-            . strip_irc_formatting(join("\n", $evt->args)))
-        if BarnOwl::getvar('irc:spew') eq 'on';
-}
-
-################################################################################
-########################### Utilities/Helpers ##################################
-################################################################################
-
-sub strip_irc_formatting {
-    my $body = shift;
-    # Strip mIRC colors. If someone wants to write code to convert
-    # these to zephyr colors, be my guest.
-    $body =~ s/\cC\d+(?:,\d+)?//g;
-    $body =~ s/\cO//g;
-    
-    my @pieces = split /\cB/, $body;
-    my $out = '';
-    while(@pieces) {
-        $out .= shift @pieces;
-        $out .= BarnOwl::Style::boldify(shift @pieces) if @pieces;
-    }
-    return $out;
-}
-
-# Determines if the given message recipient is a username, as opposed to
-# a channel that starts with # or &.
-sub is_private {
-    return shift !~ /^[\#\&]/;
-}
-
-sub cdr {
-    shift;
-    return @_;
-}
-
-1;
Index: rl/modules/Jabber/Makefile.PL
===================================================================
--- perl/modules/Jabber/Makefile.PL	(revision 300b4702c05fb4f94af9ee4f55f7c346e3fd60dc)
+++ 	(revision )
@@ -1,8 +1,0 @@
-use strict;
-use warnings;
-
-use inc::Module::Install;
-
-barnowl_module('Jabber');
-
-WriteAll;
Index: rl/modules/Jabber/inc/Module/Install.pm
===================================================================
--- perl/modules/Jabber/inc/Module/Install.pm	(revision 300b4702c05fb4f94af9ee4f55f7c346e3fd60dc)
+++ 	(revision )
@@ -1,281 +1,0 @@
-#line 1
-package Module::Install;
-
-# For any maintainers:
-# The load order for Module::Install is a bit magic.
-# It goes something like this...
-#
-# IF ( host has Module::Install installed, creating author mode ) {
-#     1. Makefile.PL calls "use inc::Module::Install"
-#     2. $INC{inc/Module/Install.pm} set to installed version of inc::Module::Install
-#     3. The installed version of inc::Module::Install loads
-#     4. inc::Module::Install calls "require Module::Install"
-#     5. The ./inc/ version of Module::Install loads
-# } ELSE {
-#     1. Makefile.PL calls "use inc::Module::Install"
-#     2. $INC{inc/Module/Install.pm} set to ./inc/ version of Module::Install
-#     3. The ./inc/ version of Module::Install loads
-# }
-
-use 5.004;
-use strict 'vars';
-
-use vars qw{$VERSION};
-BEGIN {
-    # All Module::Install core packages now require synchronised versions.
-    # This will be used to ensure we don't accidentally load old or
-    # different versions of modules.
-    # This is not enforced yet, but will be some time in the next few
-    # releases once we can make sure it won't clash with custom
-    # Module::Install extensions.
-    $VERSION = '0.65';
-}
-
-# Whether or not inc::Module::Install is actually loaded, the
-# $INC{inc/Module/Install.pm} is what will still get set as long as
-# the caller loaded module this in the documented manner.
-# If not set, the caller may NOT have loaded the bundled version, and thus
-# they may not have a MI version that works with the Makefile.PL. This would
-# result in false errors or unexpected behaviour. And we don't want that.
-my $file = join( '/', 'inc', split /::/, __PACKAGE__ ) . '.pm';
-unless ( $INC{$file} ) {
-    die <<"END_DIE";
-Please invoke ${\__PACKAGE__} with:
-
-    use inc::${\__PACKAGE__};
-
-not:
-
-    use ${\__PACKAGE__};
-
-END_DIE
-}
-
-# If the script that is loading Module::Install is from the future,
-# then make will detect this and cause it to re-run over and over
-# again. This is bad. Rather than taking action to touch it (which
-# is unreliable on some platforms and requires write permissions)
-# for now we should catch this and refuse to run.
-if ( -f $0 and (stat($0))[9] > time ) {
-	die << "END_DIE";
-Your installer $0 has a modification time in the future.
-
-This is known to create infinite loops in make.
-
-Please correct this, then run $0 again.
-
-END_DIE
-}
-
-use Cwd        ();
-use File::Find ();
-use File::Path ();
-use FindBin;
-
-*inc::Module::Install::VERSION = *VERSION;
-@inc::Module::Install::ISA     = __PACKAGE__;
-
-sub autoload {
-    my $self = shift;
-    my $who  = $self->_caller;
-    my $cwd  = Cwd::cwd();
-    my $sym  = "${who}::AUTOLOAD";
-    $sym->{$cwd} = sub {
-        my $pwd = Cwd::cwd();
-        if ( my $code = $sym->{$pwd} ) {
-            # delegate back to parent dirs
-            goto &$code unless $cwd eq $pwd;
-        }
-        $$sym =~ /([^:]+)$/ or die "Cannot autoload $who - $sym";
-        unshift @_, ($self, $1);
-        goto &{$self->can('call')} unless uc($1) eq $1;
-    };
-}
-
-sub import {
-    my $class = shift;
-    my $self  = $class->new(@_);
-    my $who   = $self->_caller;
-
-    unless ( -f $self->{file} ) {
-        require "$self->{path}/$self->{dispatch}.pm";
-        File::Path::mkpath("$self->{prefix}/$self->{author}");
-        $self->{admin} = "$self->{name}::$self->{dispatch}"->new( _top => $self );
-        $self->{admin}->init;
-        @_ = ($class, _self => $self);
-        goto &{"$self->{name}::import"};
-    }
-
-    *{"${who}::AUTOLOAD"} = $self->autoload;
-    $self->preload;
-
-    # Unregister loader and worker packages so subdirs can use them again
-    delete $INC{"$self->{file}"};
-    delete $INC{"$self->{path}.pm"};
-}
-
-sub preload {
-    my ($self) = @_;
-
-    unless ( $self->{extensions} ) {
-        $self->load_extensions(
-            "$self->{prefix}/$self->{path}", $self
-        );
-    }
-
-    my @exts = @{$self->{extensions}};
-    unless ( @exts ) {
-        my $admin = $self->{admin};
-        @exts = $admin->load_all_extensions;
-    }
-
-    my %seen;
-    foreach my $obj ( @exts ) {
-        while (my ($method, $glob) = each %{ref($obj) . '::'}) {
-            next unless $obj->can($method);
-            next if $method =~ /^_/;
-            next if $method eq uc($method);
-            $seen{$method}++;
-        }
-    }
-
-    my $who = $self->_caller;
-    foreach my $name ( sort keys %seen ) {
-        *{"${who}::$name"} = sub {
-            ${"${who}::AUTOLOAD"} = "${who}::$name";
-            goto &{"${who}::AUTOLOAD"};
-        };
-    }
-}
-
-sub new {
-    my ($class, %args) = @_;
-
-    # ignore the prefix on extension modules built from top level.
-    my $base_path = Cwd::abs_path($FindBin::Bin);
-    unless ( Cwd::abs_path(Cwd::cwd()) eq $base_path ) {
-        delete $args{prefix};
-    }
-
-    return $args{_self} if $args{_self};
-
-    $args{dispatch} ||= 'Admin';
-    $args{prefix}   ||= 'inc';
-    $args{author}   ||= ($^O eq 'VMS' ? '_author' : '.author');
-    $args{bundle}   ||= 'inc/BUNDLES';
-    $args{base}     ||= $base_path;
-    $class =~ s/^\Q$args{prefix}\E:://;
-    $args{name}     ||= $class;
-    $args{version}  ||= $class->VERSION;
-    unless ( $args{path} ) {
-        $args{path}  = $args{name};
-        $args{path}  =~ s!::!/!g;
-    }
-    $args{file}     ||= "$args{base}/$args{prefix}/$args{path}.pm";
-
-    bless( \%args, $class );
-}
-
-sub call {
-	my ($self, $method) = @_;
-	my $obj = $self->load($method) or return;
-        splice(@_, 0, 2, $obj);
-	goto &{$obj->can($method)};
-}
-
-sub load {
-    my ($self, $method) = @_;
-
-    $self->load_extensions(
-        "$self->{prefix}/$self->{path}", $self
-    ) unless $self->{extensions};
-
-    foreach my $obj (@{$self->{extensions}}) {
-        return $obj if $obj->can($method);
-    }
-
-    my $admin = $self->{admin} or die <<"END_DIE";
-The '$method' method does not exist in the '$self->{prefix}' path!
-Please remove the '$self->{prefix}' directory and run $0 again to load it.
-END_DIE
-
-    my $obj = $admin->load($method, 1);
-    push @{$self->{extensions}}, $obj;
-
-    $obj;
-}
-
-sub load_extensions {
-    my ($self, $path, $top) = @_;
-
-    unless ( grep { lc $_ eq lc $self->{prefix} } @INC ) {
-        unshift @INC, $self->{prefix};
-    }
-
-    foreach my $rv ( $self->find_extensions($path) ) {
-        my ($file, $pkg) = @{$rv};
-        next if $self->{pathnames}{$pkg};
-
-        local $@;
-        my $new = eval { require $file; $pkg->can('new') };
-        unless ( $new ) {
-            warn $@ if $@;
-            next;
-        }
-        $self->{pathnames}{$pkg} = delete $INC{$file};
-        push @{$self->{extensions}}, &{$new}($pkg, _top => $top );
-    }
-
-    $self->{extensions} ||= [];
-}
-
-sub find_extensions {
-    my ($self, $path) = @_;
-
-    my @found;
-    File::Find::find( sub {
-        my $file = $File::Find::name;
-        return unless $file =~ m!^\Q$path\E/(.+)\.pm\Z!is;
-        my $subpath = $1;
-        return if lc($subpath) eq lc($self->{dispatch});
-
-        $file = "$self->{path}/$subpath.pm";
-        my $pkg = "$self->{name}::$subpath";
-        $pkg =~ s!/!::!g;
-
-        # If we have a mixed-case package name, assume case has been preserved
-        # correctly.  Otherwise, root through the file to locate the case-preserved
-        # version of the package name.
-        if ( $subpath eq lc($subpath) || $subpath eq uc($subpath) ) {
-            open PKGFILE, "<$subpath.pm" or die "find_extensions: Can't open $subpath.pm: $!";
-            my $in_pod = 0;
-            while ( <PKGFILE> ) {
-                $in_pod = 1 if /^=\w/;
-                $in_pod = 0 if /^=cut/;
-                next if ($in_pod || /^=cut/);  # skip pod text
-                next if /^\s*#/;               # and comments
-                if ( m/^\s*package\s+($pkg)\s*;/i ) {
-                    $pkg = $1;
-                    last;
-                }
-            }
-            close PKGFILE;
-        }
-
-        push @found, [ $file, $pkg ];
-    }, $path ) if -d $path;
-
-    @found;
-}
-
-sub _caller {
-    my $depth = 0;
-    my $call  = caller($depth);
-    while ( $call eq __PACKAGE__ ) {
-        $depth++;
-        $call = caller($depth);
-    }
-    return $call;
-}
-
-1;
Index: rl/modules/Jabber/inc/Module/Install/BarnOwl.pm
===================================================================
--- perl/modules/Jabber/inc/Module/Install/BarnOwl.pm	(revision 925faaeb6e9cf1e4022d22956f3c21b5412152b5)
+++ 	(revision )
@@ -1,31 +1,0 @@
-#line 1
-use warnings;
-use strict;
-
-#line 32
-
-package Module::Install::BarnOwl;
-
-use base qw(Module::Install::Base);
-
-sub barnowl_module {
-    my $self = shift;
-    my $name = ucfirst shift;
-    my $class = ref $self;
-
-    $self->name("BarnOwl-Module-$name");
-    $self->all_from("lib/BarnOwl/Module/$name.pm");
-
-    $self->postamble(<<"END_MAKEFILE");
-
-# --- $class section:
-
-$name.par: pm_to_blib
-\tcd blib; zip ../$name.par -r arch lib
-
-END_MAKEFILE
-}
-
-#line 60
-
-1;
Index: rl/modules/Jabber/inc/Module/Install/Base.pm
===================================================================
--- perl/modules/Jabber/inc/Module/Install/Base.pm	(revision 300b4702c05fb4f94af9ee4f55f7c346e3fd60dc)
+++ 	(revision )
@@ -1,70 +1,0 @@
-#line 1
-package Module::Install::Base;
-
-$VERSION = '0.65';
-
-# Suspend handler for "redefined" warnings
-BEGIN {
-	my $w = $SIG{__WARN__};
-	$SIG{__WARN__} = sub { $w };
-}
-
-### This is the ONLY module that shouldn't have strict on
-# use strict;
-
-#line 41
-
-sub new {
-    my ($class, %args) = @_;
-
-    foreach my $method ( qw(call load) ) {
-        *{"$class\::$method"} = sub {
-            shift()->_top->$method(@_);
-        } unless defined &{"$class\::$method"};
-    }
-
-    bless( \%args, $class );
-}
-
-#line 61
-
-sub AUTOLOAD {
-    my $self = shift;
-    local $@;
-    my $autoload = eval { $self->_top->autoload } or return;
-    goto &$autoload;
-}
-
-#line 76
-
-sub _top { $_[0]->{_top} }
-
-#line 89
-
-sub admin {
-    $_[0]->_top->{admin} or Module::Install::Base::FakeAdmin->new;
-}
-
-sub is_admin {
-    $_[0]->admin->VERSION;
-}
-
-sub DESTROY {}
-
-package Module::Install::Base::FakeAdmin;
-
-my $Fake;
-sub new { $Fake ||= bless(\@_, $_[0]) }
-
-sub AUTOLOAD {}
-
-sub DESTROY {}
-
-# Restore warning handler
-BEGIN {
-	$SIG{__WARN__} = $SIG{__WARN__}->();
-}
-
-1;
-
-#line 138
Index: rl/modules/Jabber/inc/Module/Install/Can.pm
===================================================================
--- perl/modules/Jabber/inc/Module/Install/Can.pm	(revision 300b4702c05fb4f94af9ee4f55f7c346e3fd60dc)
+++ 	(revision )
@@ -1,82 +1,0 @@
-#line 1
-package Module::Install::Can;
-
-use strict;
-use Module::Install::Base;
-use Config ();
-### This adds a 5.005 Perl version dependency.
-### This is a bug and will be fixed.
-use File::Spec ();
-use ExtUtils::MakeMaker ();
-
-use vars qw{$VERSION $ISCORE @ISA};
-BEGIN {
-	$VERSION = '0.65';
-	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
-}
-
-# check if we can load some module
-### Upgrade this to not have to load the module if possible
-sub can_use {
-	my ($self, $mod, $ver) = @_;
-	$mod =~ s{::|\\}{/}g;
-	$mod .= '.pm' unless $mod =~ /\.pm$/i;
-
-	my $pkg = $mod;
-	$pkg =~ s{/}{::}g;
-	$pkg =~ s{\.pm$}{}i;
-
-	local $@;
-	eval { require $mod; $pkg->VERSION($ver || 0); 1 };
-}
-
-# check if we can run some command
-sub can_run {
-	my ($self, $cmd) = @_;
-
-	my $_cmd = $cmd;
-	return $_cmd if (-x $_cmd or $_cmd = MM->maybe_command($_cmd));
-
-	for my $dir ((split /$Config::Config{path_sep}/, $ENV{PATH}), '.') {
-		my $abs = File::Spec->catfile($dir, $_[1]);
-		return $abs if (-x $abs or $abs = MM->maybe_command($abs));
-	}
-
-	return;
-}
-
-# can we locate a (the) C compiler
-sub can_cc {
-	my $self   = shift;
-	my @chunks = split(/ /, $Config::Config{cc}) or return;
-
-	# $Config{cc} may contain args; try to find out the program part
-	while (@chunks) {
-		return $self->can_run("@chunks") || (pop(@chunks), next);
-	}
-
-	return;
-}
-
-# Fix Cygwin bug on maybe_command();
-if ( $^O eq 'cygwin' ) {
-	require ExtUtils::MM_Cygwin;
-	require ExtUtils::MM_Win32;
-	if ( ! defined(&ExtUtils::MM_Cygwin::maybe_command) ) {
-		*ExtUtils::MM_Cygwin::maybe_command = sub {
-			my ($self, $file) = @_;
-			if ($file =~ m{^/cygdrive/}i and ExtUtils::MM_Win32->can('maybe_command')) {
-				ExtUtils::MM_Win32->maybe_command($file);
-			} else {
-				ExtUtils::MM_Unix->maybe_command($file);
-			}
-		}
-	}
-}
-
-1;
-
-__END__
-
-#line 157
Index: rl/modules/Jabber/inc/Module/Install/Fetch.pm
===================================================================
--- perl/modules/Jabber/inc/Module/Install/Fetch.pm	(revision 300b4702c05fb4f94af9ee4f55f7c346e3fd60dc)
+++ 	(revision )
@@ -1,93 +1,0 @@
-#line 1
-package Module::Install::Fetch;
-
-use strict;
-use Module::Install::Base;
-
-use vars qw{$VERSION $ISCORE @ISA};
-BEGIN {
-	$VERSION = '0.65';
-	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
-}
-
-sub get_file {
-    my ($self, %args) = @_;
-    my ($scheme, $host, $path, $file) = 
-        $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return;
-
-    if ( $scheme eq 'http' and ! eval { require LWP::Simple; 1 } ) {
-        $args{url} = $args{ftp_url}
-            or (warn("LWP support unavailable!\n"), return);
-        ($scheme, $host, $path, $file) = 
-            $args{url} =~ m|^(\w+)://([^/]+)(.+)/(.+)| or return;
-    }
-
-    $|++;
-    print "Fetching '$file' from $host... ";
-
-    unless (eval { require Socket; Socket::inet_aton($host) }) {
-        warn "'$host' resolve failed!\n";
-        return;
-    }
-
-    return unless $scheme eq 'ftp' or $scheme eq 'http';
-
-    require Cwd;
-    my $dir = Cwd::getcwd();
-    chdir $args{local_dir} or return if exists $args{local_dir};
-
-    if (eval { require LWP::Simple; 1 }) {
-        LWP::Simple::mirror($args{url}, $file);
-    }
-    elsif (eval { require Net::FTP; 1 }) { eval {
-        # use Net::FTP to get past firewall
-        my $ftp = Net::FTP->new($host, Passive => 1, Timeout => 600);
-        $ftp->login("anonymous", 'anonymous@example.com');
-        $ftp->cwd($path);
-        $ftp->binary;
-        $ftp->get($file) or (warn("$!\n"), return);
-        $ftp->quit;
-    } }
-    elsif (my $ftp = $self->can_run('ftp')) { eval {
-        # no Net::FTP, fallback to ftp.exe
-        require FileHandle;
-        my $fh = FileHandle->new;
-
-        local $SIG{CHLD} = 'IGNORE';
-        unless ($fh->open("|$ftp -n")) {
-            warn "Couldn't open ftp: $!\n";
-            chdir $dir; return;
-        }
-
-        my @dialog = split(/\n/, <<"END_FTP");
-open $host
-user anonymous anonymous\@example.com
-cd $path
-binary
-get $file $file
-quit
-END_FTP
-        foreach (@dialog) { $fh->print("$_\n") }
-        $fh->close;
-    } }
-    else {
-        warn "No working 'ftp' program available!\n";
-        chdir $dir; return;
-    }
-
-    unless (-f $file) {
-        warn "Fetching failed: $@\n";
-        chdir $dir; return;
-    }
-
-    return if exists $args{size} and -s $file != $args{size};
-    system($args{run}) if exists $args{run};
-    unlink($file) if $args{remove};
-
-    print(((!exists $args{check_for} or -e $args{check_for})
-        ? "done!" : "failed! ($!)"), "\n");
-    chdir $dir; return !$?;
-}
-
-1;
Index: rl/modules/Jabber/inc/Module/Install/Makefile.pm
===================================================================
--- perl/modules/Jabber/inc/Module/Install/Makefile.pm	(revision 300b4702c05fb4f94af9ee4f55f7c346e3fd60dc)
+++ 	(revision )
@@ -1,212 +1,0 @@
-#line 1
-package Module::Install::Makefile;
-
-use strict 'vars';
-use Module::Install::Base;
-use ExtUtils::MakeMaker ();
-
-use vars qw{$VERSION $ISCORE @ISA};
-BEGIN {
-	$VERSION = '0.65';
-	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
-}
-
-sub Makefile { $_[0] }
-
-my %seen = ();
-
-sub prompt {
-    shift;
-
-    # Infinite loop protection
-    my @c = caller();
-    if ( ++$seen{"$c[1]|$c[2]|$_[0]"} > 3 ) {
-        die "Caught an potential prompt infinite loop ($c[1]|$c[2]|$_[0])";
-    }
-
-    # In automated testing, always use defaults
-    if ( $ENV{AUTOMATED_TESTING} and ! $ENV{PERL_MM_USE_DEFAULT} ) {
-        local $ENV{PERL_MM_USE_DEFAULT} = 1;
-        goto &ExtUtils::MakeMaker::prompt;
-    } else {
-        goto &ExtUtils::MakeMaker::prompt;
-    }
-}
-
-sub makemaker_args {
-    my $self = shift;
-    my $args = ($self->{makemaker_args} ||= {});
-    %$args = ( %$args, @_ ) if @_;
-    $args;
-}
-
-# For mm args that take multiple space-seperated args,
-# append an argument to the current list.
-sub makemaker_append {
-    my $self = shift;
-    my $name = shift;
-    my $args = $self->makemaker_args;
-    $args->{name} = defined $args->{$name}
-    	? join( ' ', $args->{name}, @_ )
-    	: join( ' ', @_ );
-}
-
-sub build_subdirs {
-    my $self    = shift;
-    my $subdirs = $self->makemaker_args->{DIR} ||= [];
-    for my $subdir (@_) {
-        push @$subdirs, $subdir;
-    }
-}
-
-sub clean_files {
-    my $self  = shift;
-    my $clean = $self->makemaker_args->{clean} ||= {};
-    %$clean = (
-        %$clean, 
-        FILES => join(' ', grep length, $clean->{FILES}, @_),
-    );
-}
-
-sub realclean_files {
-    my $self  = shift;
-    my $realclean = $self->makemaker_args->{realclean} ||= {};
-    %$realclean = (
-        %$realclean, 
-        FILES => join(' ', grep length, $realclean->{FILES}, @_),
-    );
-}
-
-sub libs {
-    my $self = shift;
-    my $libs = ref $_[0] ? shift : [ shift ];
-    $self->makemaker_args( LIBS => $libs );
-}
-
-sub inc {
-    my $self = shift;
-    $self->makemaker_args( INC => shift );
-}
-
-sub write {
-    my $self = shift;
-    die "&Makefile->write() takes no arguments\n" if @_;
-
-    my $args = $self->makemaker_args;
-    $args->{DISTNAME} = $self->name;
-    $args->{NAME}     = $self->module_name || $self->name || $self->determine_NAME($args);
-    $args->{VERSION}  = $self->version || $self->determine_VERSION($args);
-    $args->{NAME}     =~ s/-/::/g;
-    if ( $self->tests ) {
-        $args->{test} = { TESTS => $self->tests };
-    }
-    if ($] >= 5.005) {
-        $args->{ABSTRACT} = $self->abstract;
-        $args->{AUTHOR}   = $self->author;
-    }
-    if ( eval($ExtUtils::MakeMaker::VERSION) >= 6.10 ) {
-        $args->{NO_META} = 1;
-    }
-    if ( eval($ExtUtils::MakeMaker::VERSION) > 6.17 and $self->sign ) {
-        $args->{SIGN} = 1;
-    }
-    unless ( $self->is_admin ) {
-        delete $args->{SIGN};
-    }
-
-    # merge both kinds of requires into prereq_pm
-    my $prereq = ($args->{PREREQ_PM} ||= {});
-    %$prereq = ( %$prereq, map { @$_ } map { @$_ } grep $_,
-                 ($self->build_requires, $self->requires) );
-
-    # merge both kinds of requires into prereq_pm
-    my $subdirs = ($args->{DIR} ||= []);
-    if ($self->bundles) {
-        foreach my $bundle (@{ $self->bundles }) {
-            my ($file, $dir) = @$bundle;
-            push @$subdirs, $dir if -d $dir;
-            delete $prereq->{$file};
-        }
-    }
-
-    if ( my $perl_version = $self->perl_version ) {
-        eval "use $perl_version; 1"
-            or die "ERROR: perl: Version $] is installed, "
-                . "but we need version >= $perl_version";
-    }
-
-    $args->{INSTALLDIRS} = $self->installdirs;
-
-    my %args = map { ( $_ => $args->{$_} ) } grep {defined($args->{$_})} keys %$args;
-
-    my $user_preop = delete $args{dist}->{PREOP};
-    if (my $preop = $self->admin->preop($user_preop)) {
-        $args{dist} = $preop;
-    }
-
-    my $mm = ExtUtils::MakeMaker::WriteMakefile(%args);
-    $self->fix_up_makefile($mm->{FIRST_MAKEFILE} || 'Makefile');
-}
-
-sub fix_up_makefile {
-    my $self          = shift;
-    my $makefile_name = shift;
-    my $top_class     = ref($self->_top) || '';
-    my $top_version   = $self->_top->VERSION || '';
-
-    my $preamble = $self->preamble 
-        ? "# Preamble by $top_class $top_version\n"
-            . $self->preamble
-        : '';
-    my $postamble = "# Postamble by $top_class $top_version\n"
-        . ($self->postamble || '');
-
-    local *MAKEFILE;
-    open MAKEFILE, "< $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
-    my $makefile = do { local $/; <MAKEFILE> };
-    close MAKEFILE or die $!;
-
-    $makefile =~ s/\b(test_harness\(\$\(TEST_VERBOSE\), )/$1'inc', /;
-    $makefile =~ s/( -I\$\(INST_ARCHLIB\))/ -Iinc$1/g;
-    $makefile =~ s/( "-I\$\(INST_LIB\)")/ "-Iinc"$1/g;
-    $makefile =~ s/^(FULLPERL = .*)/$1 "-Iinc"/m;
-    $makefile =~ s/^(PERL = .*)/$1 "-Iinc"/m;
-
-    # Module::Install will never be used to build the Core Perl
-    # Sometimes PERL_LIB and PERL_ARCHLIB get written anyway, which breaks
-    # PREFIX/PERL5LIB, and thus, install_share. Blank them if they exist
-    $makefile =~ s/^PERL_LIB = .+/PERL_LIB =/m;
-    #$makefile =~ s/^PERL_ARCHLIB = .+/PERL_ARCHLIB =/m;
-
-    # Perl 5.005 mentions PERL_LIB explicitly, so we have to remove that as well.
-    $makefile =~ s/("?)-I\$\(PERL_LIB\)\1//g;
-
-    # XXX - This is currently unused; not sure if it breaks other MM-users
-    # $makefile =~ s/^pm_to_blib\s+:\s+/pm_to_blib :: /mg;
-
-    open  MAKEFILE, "> $makefile_name" or die "fix_up_makefile: Couldn't open $makefile_name: $!";
-    print MAKEFILE  "$preamble$makefile$postamble" or die $!;
-    close MAKEFILE  or die $!;
-
-    1;
-}
-
-sub preamble {
-    my ($self, $text) = @_;
-    $self->{preamble} = $text . $self->{preamble} if defined $text;
-    $self->{preamble};
-}
-
-sub postamble {
-    my ($self, $text) = @_;
-    $self->{postamble} ||= $self->admin->postamble;
-    $self->{postamble} .= $text if defined $text;
-    $self->{postamble}
-}
-
-1;
-
-__END__
-
-#line 338
Index: rl/modules/Jabber/inc/Module/Install/Metadata.pm
===================================================================
--- perl/modules/Jabber/inc/Module/Install/Metadata.pm	(revision 300b4702c05fb4f94af9ee4f55f7c346e3fd60dc)
+++ 	(revision )
@@ -1,323 +1,0 @@
-#line 1
-package Module::Install::Metadata;
-
-use strict 'vars';
-use Module::Install::Base;
-
-use vars qw{$VERSION $ISCORE @ISA};
-BEGIN {
-	$VERSION = '0.65';
-	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
-}
-
-my @scalar_keys = qw{
-    name module_name abstract author version license
-    distribution_type perl_version tests installdirs
-};
-
-my @tuple_keys = qw{
-    build_requires requires recommends bundles
-};
-
-sub Meta            { shift        }
-sub Meta_ScalarKeys { @scalar_keys }
-sub Meta_TupleKeys  { @tuple_keys  }
-
-foreach my $key (@scalar_keys) {
-    *$key = sub {
-        my $self = shift;
-        return $self->{values}{$key} if defined wantarray and !@_;
-        $self->{values}{$key} = shift;
-        return $self;
-    };
-}
-
-foreach my $key (@tuple_keys) {
-    *$key = sub {
-        my $self = shift;
-        return $self->{values}{$key} unless @_;
-
-        my @rv;
-        while (@_) {
-            my $module = shift or last;
-            my $version = shift || 0;
-            if ( $module eq 'perl' ) {
-                $version =~ s{^(\d+)\.(\d+)\.(\d+)}
-                             {$1 + $2/1_000 + $3/1_000_000}e;
-                $self->perl_version($version);
-                next;
-            }
-            my $rv = [ $module, $version ];
-            push @rv, $rv;
-        }
-        push @{ $self->{values}{$key} }, @rv;
-        @rv;
-    };
-}
-
-sub install_as_core   { $_[0]->installdirs('perl')   }
-sub install_as_cpan   { $_[0]->installdirs('site')   }
-sub install_as_site   { $_[0]->installdirs('site')   }
-sub install_as_vendor { $_[0]->installdirs('vendor') }
-
-sub sign {
-    my $self = shift;
-    return $self->{'values'}{'sign'} if defined wantarray and !@_;
-    $self->{'values'}{'sign'} = ( @_ ? $_[0] : 1 );
-    return $self;
-}
-
-sub dynamic_config {
-	my $self = shift;
-	unless ( @_ ) {
-		warn "You MUST provide an explicit true/false value to dynamic_config, skipping\n";
-		return $self;
-	}
-	$self->{'values'}{'dynamic_config'} = $_[0] ? 1 : 0;
-	return $self;
-}
-
-sub all_from {
-    my ( $self, $file ) = @_;
-
-    unless ( defined($file) ) {
-        my $name = $self->name
-            or die "all_from called with no args without setting name() first";
-        $file = join('/', 'lib', split(/-/, $name)) . '.pm';
-        $file =~ s{.*/}{} unless -e $file;
-        die "all_from: cannot find $file from $name" unless -e $file;
-    }
-
-    $self->version_from($file)      unless $self->version;
-    $self->perl_version_from($file) unless $self->perl_version;
-
-    # The remaining probes read from POD sections; if the file
-    # has an accompanying .pod, use that instead
-    my $pod = $file;
-    if ( $pod =~ s/\.pm$/.pod/i and -e $pod ) {
-        $file = $pod;
-    }
-
-    $self->author_from($file)   unless $self->author;
-    $self->license_from($file)  unless $self->license;
-    $self->abstract_from($file) unless $self->abstract;
-}
-
-sub provides {
-    my $self     = shift;
-    my $provides = ( $self->{values}{provides} ||= {} );
-    %$provides = (%$provides, @_) if @_;
-    return $provides;
-}
-
-sub auto_provides {
-    my $self = shift;
-    return $self unless $self->is_admin;
-
-    unless (-e 'MANIFEST') {
-        warn "Cannot deduce auto_provides without a MANIFEST, skipping\n";
-        return $self;
-    }
-
-    # Avoid spurious warnings as we are not checking manifest here.
-
-    local $SIG{__WARN__} = sub {1};
-    require ExtUtils::Manifest;
-    local *ExtUtils::Manifest::manicheck = sub { return };
-
-    require Module::Build;
-    my $build = Module::Build->new(
-        dist_name    => $self->name,
-        dist_version => $self->version,
-        license      => $self->license,
-    );
-    $self->provides(%{ $build->find_dist_packages || {} });
-}
-
-sub feature {
-    my $self     = shift;
-    my $name     = shift;
-    my $features = ( $self->{values}{features} ||= [] );
-
-    my $mods;
-
-    if ( @_ == 1 and ref( $_[0] ) ) {
-        # The user used ->feature like ->features by passing in the second
-        # argument as a reference.  Accomodate for that.
-        $mods = $_[0];
-    } else {
-        $mods = \@_;
-    }
-
-    my $count = 0;
-    push @$features, (
-        $name => [
-            map {
-                ref($_) ? ( ref($_) eq 'HASH' ) ? %$_
-                                                : @$_
-                        : $_
-            } @$mods
-        ]
-    );
-
-    return @$features;
-}
-
-sub features {
-    my $self = shift;
-    while ( my ( $name, $mods ) = splice( @_, 0, 2 ) ) {
-        $self->feature( $name, @$mods );
-    }
-    return $self->{values}->{features}
-    	? @{ $self->{values}->{features} }
-    	: ();
-}
-
-sub no_index {
-    my $self = shift;
-    my $type = shift;
-    push @{ $self->{values}{no_index}{$type} }, @_ if $type;
-    return $self->{values}{no_index};
-}
-
-sub read {
-    my $self = shift;
-    $self->include_deps( 'YAML', 0 );
-
-    require YAML;
-    my $data = YAML::LoadFile('META.yml');
-
-    # Call methods explicitly in case user has already set some values.
-    while ( my ( $key, $value ) = each %$data ) {
-        next unless $self->can($key);
-        if ( ref $value eq 'HASH' ) {
-            while ( my ( $module, $version ) = each %$value ) {
-                $self->can($key)->($self, $module => $version );
-            }
-        }
-        else {
-            $self->can($key)->($self, $value);
-        }
-    }
-    return $self;
-}
-
-sub write {
-    my $self = shift;
-    return $self unless $self->is_admin;
-    $self->admin->write_meta;
-    return $self;
-}
-
-sub version_from {
-    my ( $self, $file ) = @_;
-    require ExtUtils::MM_Unix;
-    $self->version( ExtUtils::MM_Unix->parse_version($file) );
-}
-
-sub abstract_from {
-    my ( $self, $file ) = @_;
-    require ExtUtils::MM_Unix;
-    $self->abstract(
-        bless(
-            { DISTNAME => $self->name },
-            'ExtUtils::MM_Unix'
-        )->parse_abstract($file)
-     );
-}
-
-sub _slurp {
-    my ( $self, $file ) = @_;
-
-    local *FH;
-    open FH, "< $file" or die "Cannot open $file.pod: $!";
-    do { local $/; <FH> };
-}
-
-sub perl_version_from {
-    my ( $self, $file ) = @_;
-
-    if (
-        $self->_slurp($file) =~ m/
-        ^
-        use \s*
-        v?
-        ([\d_\.]+)
-        \s* ;
-    /ixms
-      )
-    {
-        my $v = $1;
-        $v =~ s{_}{}g;
-        $self->perl_version($1);
-    }
-    else {
-        warn "Cannot determine perl version info from $file\n";
-        return;
-    }
-}
-
-sub author_from {
-    my ( $self, $file ) = @_;
-    my $content = $self->_slurp($file);
-    if ($content =~ m/
-        =head \d \s+ (?:authors?)\b \s*
-        ([^\n]*)
-        |
-        =head \d \s+ (?:licen[cs]e|licensing|copyright|legal)\b \s*
-        .*? copyright .*? \d\d\d[\d.]+ \s* (?:\bby\b)? \s*
-        ([^\n]*)
-    /ixms) {
-        my $author = $1 || $2;
-        $author =~ s{E<lt>}{<}g;
-        $author =~ s{E<gt>}{>}g;
-        $self->author($author); 
-    }
-    else {
-        warn "Cannot determine author info from $file\n";
-    }
-}
-
-sub license_from {
-    my ( $self, $file ) = @_;
-
-    if (
-        $self->_slurp($file) =~ m/
-        (
-            =head \d \s+
-            (?:licen[cs]e|licensing|copyright|legal)\b
-            .*?
-        )
-        (=head\\d.*|=cut.*|)
-        \z
-    /ixms
-      )
-    {
-        my $license_text = $1;
-        my @phrases      = (
-            'under the same (?:terms|license) as perl itself' => 'perl',
-            'GNU public license'                              => 'gpl',
-            'GNU lesser public license'                       => 'gpl',
-            'BSD license'                                     => 'bsd',
-            'Artistic license'                                => 'artistic',
-            'GPL'                                             => 'gpl',
-            'LGPL'                                            => 'lgpl',
-            'BSD'                                             => 'bsd',
-            'Artistic'                                        => 'artistic',
-            'MIT'                                             => 'MIT',
-        );
-        while ( my ( $pattern, $license ) = splice( @phrases, 0, 2 ) ) {
-            $pattern =~ s{\s+}{\\s+}g;
-            if ( $license_text =~ /\b$pattern\b/i ) {
-                $self->license($license);
-                return 1;
-            }
-        }
-    }
-
-    warn "Cannot determine license info from $file\n";
-    return 'unknown';
-}
-
-1;
Index: rl/modules/Jabber/inc/Module/Install/Win32.pm
===================================================================
--- perl/modules/Jabber/inc/Module/Install/Win32.pm	(revision 300b4702c05fb4f94af9ee4f55f7c346e3fd60dc)
+++ 	(revision )
@@ -1,65 +1,0 @@
-#line 1
-package Module::Install::Win32;
-
-use strict;
-use Module::Install::Base;
-
-use vars qw{$VERSION $ISCORE @ISA};
-BEGIN {
-	$VERSION = '0.65';
-	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
-}
-
-# determine if the user needs nmake, and download it if needed
-sub check_nmake {
-	my $self = shift;
-	$self->load('can_run');
-	$self->load('get_file');
-	
-	require Config;
-	return unless (
-		$^O eq 'MSWin32'                     and
-		$Config::Config{make}                and
-		$Config::Config{make} =~ /^nmake\b/i and
-		! $self->can_run('nmake')
-	);
-
-	print "The required 'nmake' executable not found, fetching it...\n";
-
-	require File::Basename;
-	my $rv = $self->get_file(
-		url       => 'http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe',
-		ftp_url   => 'ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe',
-		local_dir => File::Basename::dirname($^X),
-		size      => 51928,
-		run       => 'Nmake15.exe /o > nul',
-		check_for => 'Nmake.exe',
-		remove    => 1,
-	);
-
-	if (!$rv) {
-        die <<'END_MESSAGE';
-
--------------------------------------------------------------------------------
-
-Since you are using Microsoft Windows, you will need the 'nmake' utility
-before installation. It's available at:
-
-  http://download.microsoft.com/download/vc15/Patch/1.52/W95/EN-US/Nmake15.exe
-      or
-  ftp://ftp.microsoft.com/Softlib/MSLFILES/Nmake15.exe
-
-Please download the file manually, save it to a directory in %PATH% (e.g.
-C:\WINDOWS\COMMAND\), then launch the MS-DOS command line shell, "cd" to
-that directory, and run "Nmake15.exe" from there; that will create the
-'nmake.exe' file needed by this module.
-
-You may then resume the installation process described in README.
-
--------------------------------------------------------------------------------
-END_MESSAGE
-	}
-}
-
-1;
Index: rl/modules/Jabber/inc/Module/Install/WriteAll.pm
===================================================================
--- perl/modules/Jabber/inc/Module/Install/WriteAll.pm	(revision 300b4702c05fb4f94af9ee4f55f7c346e3fd60dc)
+++ 	(revision )
@@ -1,43 +1,0 @@
-#line 1
-package Module::Install::WriteAll;
-
-use strict;
-use Module::Install::Base;
-
-use vars qw{$VERSION $ISCORE @ISA};
-BEGIN {
-	$VERSION = '0.65';
-	$ISCORE  = 1;
-	@ISA     = qw{Module::Install::Base};
-}
-
-sub WriteAll {
-    my $self = shift;
-    my %args = (
-        meta        => 1,
-        sign        => 0,
-        inline      => 0,
-        check_nmake => 1,
-        @_
-    );
-
-    $self->sign(1)                if $args{sign};
-    $self->Meta->write            if $args{meta};
-    $self->admin->WriteAll(%args) if $self->is_admin;
-
-    if ( $0 =~ /Build.PL$/i ) {
-        $self->Build->write;
-    } else {
-        $self->check_nmake if $args{check_nmake};
-        unless ( $self->makemaker_args->{'PL_FILES'} ) {
-        	$self->makemaker_args( PL_FILES => {} );
-        }
-        if ($args{inline}) {
-            $self->Inline->write;
-        } else {
-            $self->Makefile->write;
-        }
-    }
-}
-
-1;
Index: rl/modules/Jabber/lib/BarnOwl/Message/Jabber.pm
===================================================================
--- perl/modules/Jabber/lib/BarnOwl/Message/Jabber.pm	(revision 9375f8c6437069cd5e17a476685a9e7b280aa9a5)
+++ 	(revision )
@@ -1,154 +1,0 @@
-use warnings;
-use strict;
-
-=head1 NAME
-
-BarnOwl::Message::Jabber
-
-=head1 DESCRIPTION
-
-A subclass of BarnOwl::Message for Jabber messages
-
-=cut
-
-package BarnOwl::Message::Jabber;
-
-use base qw( BarnOwl::Message );
-
-sub jtype { shift->{jtype} };
-sub from { shift->{from} };
-sub to { shift->{to} };
-sub room { shift->{room} };
-sub subject { shift->{subject} };
-sub status { shift->{status} }
-
-sub login_type {
-    my $self = shift;
-    my $type = $self->jtype;
-    return " ($type)" if $type;
-}
-
-sub login_extra {
-    my $self = shift;
-    my $show = $self->{show};
-    my $status = $self->status;
-    my $s = "";
-    $s .= $show if $show;
-    $s .= ", $status" if $status;
-    return $s;
-}
-
-sub long_sender {
-    my $self = shift;
-    return $self->from;
-}
-
-sub context {
-    return shift->room;
-}
-
-sub subcontext {
-    return shift->subject || "";
-}
-
-sub smartfilter {
-    my $self = shift;
-    my $inst = shift;
-
-    my $filter;
-
-    if($self->jtype eq 'chat') {
-        my $user;
-        if($self->direction eq 'in') {
-            $user = $self->from;
-        } else {
-            $user = $self->to;
-        }
-        return smartfilter_user($user, $inst);
-    } elsif ($self->jtype eq 'groupchat') {
-        my $room = $self->room;
-        $filter = "jabber-room-$room";
-        BarnOwl::command(qw[filter], $filter,
-                         qw[type ^jabber$ and room], "^\Q$room\E\$");
-        return $filter;
-    } elsif ($self->login ne 'none') {
-        return smartfilter_user($self->from, $inst);
-    }
-}
-
-sub smartfilter_user {
-    my $user = shift;
-    my $inst = shift;
-
-    $user   = Net::Jabber::JID->new($user)->GetJID( $inst ? 'full' : 'base' );
-    my $filter = "jabber-user-$user";
-    BarnOwl::command(qw[filter], $filter, qw[type ^jabber$],
-                     qw[and ( ( direction ^in$ and from], "^\Q$user\E(/.*)?\$",
-                     qw[) or ( direction ^out$ and to ], "^\Q$user\E(/.*)?\$",
-                     qw[ ) ) ]);
-    return $filter;
-
-}
-
-sub replycmd {
-    my $self = shift;
-    my ($recip, $account, $subject);
-    if ($self->is_loginout) {
-        $recip   = $self->sender;
-        $account = $self->recipient;
-    } elsif ($self->jtype eq 'chat') {
-        return $self->replysendercmd;
-    } elsif ($self->jtype eq 'groupchat') {
-        $recip = $self->room;
-        if ($self->is_incoming) {
-            $account = $self->to;
-        } else {
-            $account = $self->from;
-        }
-        $subject = $self->subject;
-    } else {
-        # Unknown type
-        return;
-    }
-    return jwrite_cmd($recip, $account, $subject);
-}
-
-sub replysendercmd {
-    my $self = shift;
-    if($self->jtype eq 'groupchat'
-       || $self->jtype eq 'chat') {
-        my ($recip, $account);
-        if ($self->is_incoming) {
-            $recip   = $self->from;
-            $account = $self->to;
-        } else {
-            $recip   = $self->to;
-            $account = $self->from;
-        }
-        return jwrite_cmd($recip, $account);
-    }
-    return $self->replycmd;
-}
-
-sub jwrite_cmd {
-    my ($recip, $account, $subject) = @_;
-    if (defined $recip) {
-        $recip   = BarnOwl::quote($recip);
-        $account = BarnOwl::quote($account);
-        my $cmd = "jwrite $recip -a $account";
-        if (defined $subject) {
-            $cmd .= " -s " . BarnOwl::quote($subject);
-        }
-        return $cmd;
-    } else {
-        return undef;
-    }
-}
-
-=head1 SEE ALSO
-
-L<BarnOwl::Message>
-
-=cut
-
-1;
Index: rl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm
===================================================================
--- perl/modules/Jabber/lib/BarnOwl/Module/Jabber.pm	(revision 799b60ea3145bfa2ad773b09544d31a3e30e77ff)
+++ 	(revision )
@@ -1,1374 +1,0 @@
-use strict;
-use warnings;
-
-package BarnOwl::Module::Jabber;
-
-=head1 NAME
-
-BarnOwl::Module::Jabber
-
-=head1 DESCRIPTION
-
-This module implements Jabber support for barnowl.
-
-=cut
-
-use BarnOwl;
-use BarnOwl::Hooks;
-use BarnOwl::Message::Jabber;
-use BarnOwl::Module::Jabber::Connection;
-use BarnOwl::Module::Jabber::ConnectionManager;
-
-use Authen::SASL qw(Perl);
-use Net::Jabber;
-use Net::Jabber::MUC;
-use Net::DNS;
-use Getopt::Long;
-Getopt::Long::Configure(qw(no_getopt_compat prefix_pattern=-|--));
-
-use utf8;
-
-our $VERSION = 0.1;
-
-BEGIN {
-    if(eval {require IO::Socket::SSL;}) {
-        if($IO::Socket::SSL::VERSION eq "0.97") {
-            BarnOwl::error("You are using IO::Socket:SSL 0.97, which \n" .
-                           "contains bugs causing it not to work with barnowl's\n" .
-                           "jabber support. We recommend updating to the latest\n" .
-                           "IO::Socket::SSL from CPAN. \n");
-            die("Not loading Jabber.par\n");
-        }
-    }
-}
-
-no warnings 'redefine';
-
-################################################################################
-# owl perl jabber support
-#
-# XXX Todo:
-# Rosters for MUCs
-# More user feedback
-#  * joining MUC
-#  * parting MUC
-#  * presence (Roster and MUC)
-# Implementing formatting and logging callbacks for C
-# Appropriate callbacks for presence subscription messages.
-#
-################################################################################
-
-our $conn;
-$conn ||= BarnOwl::Module::Jabber::ConnectionManager->new;
-our %vars;
-
-sub onStart {
-    if ( *BarnOwl::queue_message{CODE} ) {
-        register_owl_commands();
-        register_keybindings();
-        register_filters();
-        $BarnOwl::Hooks::mainLoop->add("BarnOwl::Module::Jabber::onMainLoop");
-        $BarnOwl::Hooks::getBuddyList->add("BarnOwl::Module::Jabber::onGetBuddyList");
-        $BarnOwl::Hooks::getQuickstart->add("BarnOwl::Module::Jabber::onGetQuickstart");
-        $vars{show} = '';
-	BarnOwl::new_variable_bool("jabber:show_offline_buddies",
-				   { default => 1,
-				     summary => 'Show offline or pending buddies.'});
-	BarnOwl::new_variable_bool("jabber:show_logins",
-				   { default => 0,
-				     summary => 'Show login/logout messages.'});
-	BarnOwl::new_variable_bool("jabber:spew",
-				   { default => 0,
-				     summary => 'Display unrecognized Jabber messages.'});
-	BarnOwl::new_variable_int("jabber:auto_away_timeout",
-				  { default => 5,
-				    summary => 'After minutes idle, auto away.',
-				  });
-	BarnOwl::new_variable_int("jabber:auto_xa_timeout",
-				  { default => 15,
-				    summary => 'After minutes idle, auto extended away.'
-				});
-        # Force these. Reload can screw them up.
-        # Taken from Net::Jabber::Protocol.
-        $Net::XMPP::Protocol::NEWOBJECT{'iq'}       = "Net::Jabber::IQ";
-        $Net::XMPP::Protocol::NEWOBJECT{'message'}  = "Net::Jabber::Message";
-        $Net::XMPP::Protocol::NEWOBJECT{'presence'} = "Net::Jabber::Presence";
-        $Net::XMPP::Protocol::NEWOBJECT{'jid'}      = "Net::Jabber::JID";
-    } else {
-        # Our owl doesn't support queue_message. Unfortunately, this
-        # means it probably *also* doesn't support BarnOwl::error. So just
-        # give up silently.
-    }
-}
-
-$BarnOwl::Hooks::startup->add("BarnOwl::Module::Jabber::onStart");
-
-sub onMainLoop {
-    return if ( !$conn->connected() );
-
-    $vars{status_changed} = 0;
-    my $auto_away = BarnOwl::getvar('jabber:auto_away_timeout');
-    my $auto_xa = BarnOwl::getvar('jabber:auto_xa_timeout');
-    my $idletime = BarnOwl::getidletime();
-    if ($auto_xa != 0 && $idletime >= (60 * $auto_xa) && ($vars{show} eq 'away' || $vars{show} eq '' )) {
-        $vars{show} = 'xa';
-        $vars{status} = 'Auto extended-away after '.$auto_xa.' minute'.($auto_xa == 1 ? '' : 's').' idle.';
-        $vars{status_changed} = 1;
-    } elsif ($auto_away != 0 && $idletime >= (60 * $auto_away) && $vars{show} eq '') {
-        $vars{show} = 'away';
-        $vars{status} = 'Auto away after '.$auto_away.' minute'.($auto_away == 1 ? '' : 's').' idle.';
-        $vars{status_changed} = 1;
-    } elsif ($idletime == 0 && $vars{show} ne '') {
-        $vars{show} = '';
-        $vars{status} = '';
-        $vars{status_changed} = 1;
-    }
-
-    foreach my $jid ( $conn->getJIDs() ) {
-        my $client = $conn->getConnectionFromJID($jid);
-
-        unless($client) {
-            $conn->removeConnection($jid);
-            BarnOwl::error("Connection for $jid undefined -- error in reload?");
-        }
-        # We keep this in the mainloop hook for keep-alives
-        my $status = $client->Process(0);
-        if ( !defined($status) ) {
-            BarnOwl::error("Jabber account $jid disconnected!");
-            do_logout($jid);
-        }
-        if ($::shutdown) {
-            do_logout($jid);
-            next;
-        }
-
-        if ($vars{status_changed}) {
-            my $p = new Net::Jabber::Presence;
-            $p->SetShow($vars{show}) if $vars{show};
-            $p->SetStatus($vars{status}) if $vars{status};
-            $client->Send($p);
-        }
-    }
-}
-
-our $showOffline = 0;
-
-sub blist_listBuddy {
-    my $roster = shift;
-    my $buddy  = shift;
-    my $blistStr .= "    ";
-    my %jq  = $roster->query($buddy);
-    my $res = $roster->resource($buddy);
-
-    my $name = $jq{name} || $buddy->GetUserID();
-
-    $blistStr .= sprintf '%-15s %s', $name, $buddy->GetJID();
-
-    if ($res) {
-        my %rq = $roster->resourceQuery( $buddy, $res );
-        $blistStr .= " [" . ( $rq{show} ? $rq{show} : 'online' ) . "]";
-        $blistStr .= " " . $rq{status} if $rq{status};
-        $blistStr = BarnOwl::Style::boldify($blistStr) if $showOffline;
-    }
-    else {
-        return '' unless $showOffline;
-	if ($jq{ask}) {
-            $blistStr .= " [pending]";
-	}
-	elsif ($jq{subscription} eq 'none' || $jq{subscription} eq 'from') {
-	    $blistStr .= " [not subscribed]";
-	}
-	else {
-	    $blistStr .= " [offline]";
-	}
-    }
-    return $blistStr . "\n";
-}
-
-sub getSingleBuddyList {
-    my $jid = shift;
-    $jid = resolveConnectedJID($jid);
-    return "" unless $jid;
-    my $blist = "";
-    my $roster = $conn->getRosterFromJID($jid);
-    if ($roster) {
-        $blist .= "\n" . BarnOwl::Style::boldify("Jabber Roster for $jid\n");
-
-        foreach my $group ( $roster->groups() ) {
-            $blist .= "  Group: $group\n";
-            my @buddies = $roster->jids( 'group', $group );
-            foreach my $buddy ( @buddies ) {
-                $blist .= blist_listBuddy( $roster, $buddy );
-            }
-        }
-
-        my @unsorted = $roster->jids('nogroup');
-        if (@unsorted) {
-            $blist .= "  [unsorted]\n";
-            foreach my $buddy (@unsorted) {
-                $blist .= blist_listBuddy( $roster, $buddy );
-            }
-        }
-    }
-    return $blist;
-}
-
-sub onGetBuddyList {
-    $showOffline = BarnOwl::getvar('jabber:show_offline_buddies') eq 'on';
-    my $blist = "";
-    foreach my $jid ($conn->getJIDs()) {
-        $blist .= getSingleBuddyList($jid);
-    }
-    return $blist;
-}
-
-sub onGetQuickstart {
-    return <<'EOF'
-@b(Jabber:)
-Type ':jabberlogin @b(username@mit.edu)' to log in to Jabber. The command
-':jroster sub @b(somebody@gmail.com)' will request that they let you message
-them. Once you get a message saying you are subscribed, you can message
-them by typing ':jwrite @b(somebody@gmail.com)' or just 'j @b(somebody)'.
-EOF
-}
-
-################################################################################
-### Owl Commands
-sub register_owl_commands() {
-    BarnOwl::new_command(
-        jabberlogin => \&cmd_login,
-        {
-            summary => "Log into jabber",
-            usage   => "jabberlogin JID [PASSWORD]"
-        }
-    );
-    BarnOwl::new_command(
-        jabberlogout => \&cmd_logout,
-        { summary => "Log out of jabber" }
-    );
-    BarnOwl::new_command(
-        jwrite => \&cmd_jwrite,
-        {
-            summary => "Send a Jabber Message",
-            usage   => "jwrite JID [-t thread] [-s subject]"
-        }
-    );
-    BarnOwl::new_command(
-        jaway => \&cmd_jaway,
-        {
-            summary => "Set Jabber away / presence information",
-            usage   => "jaway [-s online|dnd|...] [<message>]"
-        }
-    );
-    BarnOwl::new_command(
-        jlist => \&cmd_jlist,
-        {
-            summary => "Show your Jabber roster.",
-            usage   => "jlist"
-        }
-    );
-    BarnOwl::new_command(
-        jmuc => \&cmd_jmuc,
-        {
-            summary     => "Jabber MUC related commands.",
-            description => "jmuc sends jabber commands related to muc.\n\n"
-              . "The following commands are available\n\n"
-              . "join <muc>  Join a muc.\n\n"
-              . "part <muc>  Part a muc.\n"
-              . "            The muc is taken from the current message if not supplied.\n\n"
-              . "invite <jid> <muc>\n"
-              . "            Invite <jid> to <muc>.\n"
-              . "            The muc is taken from the current message if not supplied.\n\n"
-              . "configure <muc>\n"
-              . "            Configures a MUC.\n"
-              . "            Necessary to initalize a new MUC.\n"
-              . "            At present, only the default configuration is supported.\n"
-              . "            The muc is taken from the current message if not supplied.\n\n"
-              . "presence <muc>\n"
-              . "            Shows the roster for <muc>.\n"
-              . "            The muc is taken from the current message if not supplied.\n\n"
-              . "presence -a\n"
-              . "            Shows rosters for all MUCs you're participating in.\n\n",
-            usage => "jmuc COMMAND ARGS"
-        }
-    );
-    BarnOwl::new_command(
-        jroster => \&cmd_jroster,
-        {
-            summary     => "Jabber Roster related commands.",
-            description => "jroster sends jabber commands related to rosters.\n\n"
-              . "The following commands are available\n\n"
-              . "sub <jid>     Subscribe to <jid>'s presence. (implicit add)\n\n"
-              . "add <jid>     Adds <jid> to your roster.\n\n"
-              . "unsub <jid>   Unsubscribe from <jid>'s presence.\n\n"
-              . "remove <jid>  Removes <jid> to your roster. (implicit unsub)\n\n"
-              . "auth <jid>    Authorizes <jid> to subscribe to your presence.\n\n"
-              . "deauth <jid>  De-authorizes <jid>'s subscription to your presence.\n\n"
-              . "The following arguments are supported for all commands\n\n"
-              . "-a <jid>      Specify which account to make the roster changes on.\n"
-              . "              Required if you're signed into more than one account.\n\n"
-              . "The following arguments only work with the add and sub commands.\n\n"
-              . "-g <group>    Add <jid> to group <group>.\n"
-              . "              May be specified more than once, will not remove <jid> from any groups.\n\n"
-              . "-p            Purge. Removes <jid> from all groups.\n"
-              . "              May be combined with -g completely alter <jid>'s groups.\n\n"
-              . "-n <name>     Sets <name> as <jid>'s short name.\n\n"
-              . "Note: Unless -n is used, you can specify multiple <jid> arguments.\n",
-            usage       => "jroster COMMAND ARGS"
-        }
-    );
-}
-
-sub register_keybindings {
-    BarnOwl::bindkey("recv j command start-command jwrite ");
-}
-
-sub register_filters {
-    BarnOwl::filter('jabber type ^jabber$');
-}
-
-sub cmd_login {
-    my $cmd = shift;
-    my $jid = new Net::Jabber::JID;
-    $jid->SetJID(shift);
-    my $password = '';
-    $password = shift if @_;
-
-    my $uid           = $jid->GetUserID();
-    my $componentname = $jid->GetServer();
-    my $resource      = $jid->GetResource() || 'owl';
-    $jid->SetResource($resource);
-    my $jidStr = $jid->GetJID('full');
-
-    if ( !$uid || !$componentname ) {
-        BarnOwl::error("usage: $cmd JID");
-        return;
-    }
-
-    if ( $conn->jidExists($jidStr) ) {
-        BarnOwl::error("Already logged in as $jidStr.");
-        return;
-    }
-
-    my ( $server, $port ) = getServerFromJID($jid);
-
-    $vars{jlogin_jid} = $jidStr;
-    $vars{jlogin_connhash} = {
-        hostname      => $server,
-        tls           => 1,
-        port          => $port,
-        componentname => $componentname
-    };
-    $vars{jlogin_authhash} =
-      { username => $uid,
-        resource => $resource,
-    };
-
-    return do_login($password);
-}
-
-sub do_login {
-    $vars{jlogin_password} = shift;
-    $vars{jlogin_authhash}->{password} = sub { return $vars{jlogin_password} || '' };
-    my $jidStr = $vars{jlogin_jid};
-    if ( !$jidStr && $vars{jlogin_havepass}) {
-        BarnOwl::error("Got password but have no jid!");
-    }
-    else
-    {
-        my $client = $conn->addConnection($jidStr);
-
-        #XXX Todo: Add more callbacks.
-        # * MUC presence handlers
-        # We use the anonymous subrefs in order to have the correct behavior
-        # when we reload
-        $client->SetMessageCallBacks(
-            chat      => sub { BarnOwl::Module::Jabber::process_incoming_chat_message(@_) },
-            error     => sub { BarnOwl::Module::Jabber::process_incoming_error_message(@_) },
-            groupchat => sub { BarnOwl::Module::Jabber::process_incoming_groupchat_message(@_) },
-            headline  => sub { BarnOwl::Module::Jabber::process_incoming_headline_message(@_) },
-            normal    => sub { BarnOwl::Module::Jabber::process_incoming_normal_message(@_) }
-        );
-        $client->SetPresenceCallBacks(
-            available    => sub { BarnOwl::Module::Jabber::process_presence_available(@_) },
-            unavailable  => sub { BarnOwl::Module::Jabber::process_presence_available(@_) },
-            subscribe    => sub { BarnOwl::Module::Jabber::process_presence_subscribe(@_) },
-            subscribed   => sub { BarnOwl::Module::Jabber::process_presence_subscribed(@_) },
-            unsubscribe  => sub { BarnOwl::Module::Jabber::process_presence_unsubscribe(@_) },
-            unsubscribed => sub { BarnOwl::Module::Jabber::process_presence_unsubscribed(@_) },
-            error        => sub { BarnOwl::Module::Jabber::process_presence_error(@_) });
-
-        my $status = $client->Connect( %{ $vars{jlogin_connhash} } );
-        if ( !$status ) {
-            $conn->removeConnection($jidStr);
-            BarnOwl::error("We failed to connect");
-        } else {
-            my @result = $client->AuthSend( %{ $vars{jlogin_authhash} } );
-
-            if ( !@result || $result[0] ne 'ok' ) {
-                if ( !$vars{jlogin_havepass} && ( !@result || $result[0] eq '401' || $result[0] eq 'error') ) {
-                    $vars{jlogin_havepass} = 1;
-                    $conn->removeConnection($jidStr);
-                    BarnOwl::start_password("Password for $jidStr: ", \&do_login );
-                    return "";
-                }
-                $conn->removeConnection($jidStr);
-                BarnOwl::error( "Error in connect: " . join( " ", @result ) );
-            } else {
-                $conn->getRosterFromJID($jidStr)->fetch();
-                $client->PresenceSend( priority => 1 );
-		my $fullJid = $client->{SESSION}->{FULLJID} || $jidStr;
-		$conn->renameConnection($jidStr, $fullJid);
-                queue_admin_msg("Connected to jabber as $fullJid");
-                # The remove_dispatch() method is called from the
-                # ConnectionManager's removeConnection() method.
-                $client->{fileno} = $client->getSocket()->fileno();
-                #queue_admin_msg("Connected to jabber as $fullJid ($client->{fileno})");
-                BarnOwl::add_dispatch($client->{fileno}, sub { $client->OwlProcess() });
-            }
-        }
-    }
-    delete $vars{jlogin_jid};
-    $vars{jlogin_password} =~ tr/\0-\377/x/ if $vars{jlogin_password};
-    delete $vars{jlogin_password};
-    delete $vars{jlogin_havepass};
-    delete $vars{jlogin_connhash};
-    delete $vars{jlogin_authhash};
-
-    return "";
-}
-
-sub do_logout {
-    my $jid = shift;
-    my $disconnected = $conn->removeConnection($jid);
-    queue_admin_msg("Jabber disconnected ($jid).") if $disconnected;
-}
-
-sub cmd_logout {
-    # Logged into multiple accounts
-    if ( $conn->connected() > 1 ) {
-        # Logged into multiple accounts, no accout specified.
-        if ( !$_[1] ) {
-            my $errStr =
-              "You are logged into multiple accounts. Please specify an account to log out of.\n";
-            foreach my $jid ( $conn->getJIDs() ) {
-                $errStr .= "\t$jid\n";
-            }
-            queue_admin_msg($errStr);
-        }
-        # Logged into multiple accounts, account specified.
-        else {
-            if ( $_[1] eq '-a' )    #All accounts.
-            {
-                foreach my $jid ( $conn->getJIDs() ) {
-                    do_logout($jid);
-                }
-            }
-            else                    #One account.
-            {
-                my $jid = resolveConnectedJID( $_[1] );
-                do_logout($jid) if ( $jid ne '' );
-            }
-        }
-    }
-    else                            # Only one account logged in.
-    {
-        do_logout( ( $conn->getJIDs() )[0] );
-    }
-    return "";
-}
-
-sub cmd_jlist {
-    if ( !( scalar $conn->getJIDs() ) ) {
-        BarnOwl::error("You are not logged in to Jabber.");
-        return;
-    }
-    BarnOwl::popless_ztext( onGetBuddyList() );
-}
-
-sub cmd_jwrite {
-    if ( !$conn->connected() ) {
-        BarnOwl::error("You are not logged in to Jabber.");
-        return;
-    }
-
-    my $jwrite_to      = "";
-    my $jwrite_from    = "";
-    my $jwrite_sid     = "";
-    my $jwrite_thread  = "";
-    my $jwrite_subject = "";
-    my ($to, $from);
-    my $jwrite_type    = "chat";
-
-    my @args = @_;
-    shift;
-    local @ARGV = @_;
-    my $gc;
-    GetOptions(
-        'thread=s'  => \$jwrite_thread,
-        'subject=s' => \$jwrite_subject,
-        'account=s' => \$from,
-        'id=s'     =>  \$jwrite_sid,
-    ) or die("Usage: jwrite JID [-t thread] [-s 'subject'] [-a account]\n");
-    $jwrite_type = 'groupchat' if $gc;
-
-    if ( scalar @ARGV != 1 ) {
-        BarnOwl::error(
-            "Usage: jwrite JID [-t thread] [-s 'subject'] [-a account]");
-        return;
-    }
-    else {
-      $to = shift @ARGV;
-    }
-
-    my @candidates = guess_jwrite($from, $to);
-
-    unless(scalar @candidates) {
-        die("Unable to resolve JID $to");
-    }
-
-    @candidates = grep {defined $_->[0]} @candidates;
-
-    unless(scalar @candidates) {
-        if(!$from) {
-            die("You must specify an account with -a");
-        } else {
-            die("Unable to resolve account $from");
-        }
-    }
-
-
-    ($jwrite_from, $jwrite_to, $jwrite_type) = @{$candidates[0]};
-
-    $vars{jwrite} = {
-        to      => $jwrite_to,
-        from    => $jwrite_from,
-        sid     => $jwrite_sid,
-        subject => $jwrite_subject,
-        thread  => $jwrite_thread,
-        type    => $jwrite_type
-    };
-
-    if(scalar @candidates > 1) {
-        BarnOwl::message(
-            "Warning: Guessing account and/or destination JID"
-           );
-    } else  {
-        BarnOwl::message(
-            "Type your message below.  End with a dot on a line by itself.  ^C will quit."
-           );
-    }
-
-    my $cmd = "jwrite $jwrite_to -a $jwrite_from";
-    $cmd .= " -t $jwrite_thread" if $jwrite_thread;
-    $cmd .= " -s $jwrite_subject" if $jwrite_subject;
-
-    BarnOwl::start_edit_win($cmd, \&process_owl_jwrite );
-}
-
-sub cmd_jmuc {
-    die "You are not logged in to Jabber" unless $conn->connected();
-    my $ocmd = shift;
-    my $cmd  = shift;
-    if ( !$cmd ) {
-
-        #XXX TODO: Write general usage for jmuc command.
-        return;
-    }
-
-    my %jmuc_commands = (
-        join      => \&jmuc_join,
-        part      => \&jmuc_part,
-        invite    => \&jmuc_invite,
-        configure => \&jmuc_configure,
-        presence  => \&jmuc_presence
-    );
-    my $func = $jmuc_commands{$cmd};
-    if ( !$func ) {
-        BarnOwl::error("jmuc: Unknown command: $cmd");
-        return;
-    }
-
-    {
-        local @ARGV = @_;
-        my $jid;
-        my $muc;
-        my $m = BarnOwl::getcurmsg();
-        if ( $m && $m->is_jabber && $m->{jtype} eq 'groupchat' ) {
-            $muc = $m->{room};
-            $jid = $m->{to};
-        }
-
-        my $getopt = Getopt::Long::Parser->new;
-        $getopt->configure('pass_through', 'no_getopt_compat');
-        $getopt->getoptions( 'account=s' => \$jid );
-        $jid ||= defaultJID();
-        if ($jid) {
-            $jid = resolveConnectedJID($jid);
-            return unless $jid;
-        }
-        else {
-            BarnOwl::error('You must specify an account with -a {jid}');
-        }
-        return $func->( $jid, $muc, @ARGV );
-    }
-}
-
-sub jmuc_join {
-    my ( $jid, $muc, @args ) = @_;
-    local @ARGV = @args;
-    my $password;
-    GetOptions( 'password=s' => \$password );
-
-    $muc = shift @ARGV
-      or die("Usage: jmuc join MUC [-p password] [-a account]");
-
-    die("Error: Must specify a fully-qualified MUC name (e.g. barnowl\@conference.mit.edu)\n")
-        unless $muc =~ /@/;
-    $muc = Net::Jabber::JID->new($muc);
-    $jid = Net::Jabber::JID->new($jid);
-    $muc->SetResource($jid->GetJID('full')) unless length $muc->GetResource();
-
-    $conn->getConnectionFromJID($jid)->MUCJoin(JID      => $muc,
-                                               Password => $password,
-                                               History  => {
-                                                   MaxChars => 0
-                                                  });
-    return;
-}
-
-sub jmuc_part {
-    my ( $jid, $muc, @args ) = @_;
-
-    $muc = shift @args if scalar @args;
-    die("Usage: jmuc part MUC [-a account]") unless $muc;
-
-    if($conn->getConnectionFromJID($jid)->MUCLeave(JID => $muc)) {
-        queue_admin_msg("$jid has left $muc.");
-    } else {
-        die("Error: Not joined to $muc");
-    }
-}
-
-sub jmuc_invite {
-    my ( $jid, $muc, @args ) = @_;
-
-    my $invite_jid = shift @args;
-    $muc = shift @args if scalar @args;
-
-    die('Usage: jmuc invite JID [muc] [-a account]')
-      unless $muc && $invite_jid;
-
-    my $message = Net::Jabber::Message->new();
-    $message->SetTo($muc);
-    my $x = $message->NewChild('http://jabber.org/protocol/muc#user');
-    $x->AddInvite();
-    $x->GetInvite()->SetTo($invite_jid);
-    $conn->getConnectionFromJID($jid)->Send($message);
-    queue_admin_msg("$jid has invited $invite_jid to $muc.");
-}
-
-sub jmuc_configure {
-    my ( $jid, $muc, @args ) = @_;
-    $muc = shift @args if scalar @args;
-    die("Usage: jmuc configure [muc]") unless $muc;
-    my $iq = Net::Jabber::IQ->new();
-    $iq->SetTo($muc);
-    $iq->SetType('set');
-    my $query = $iq->NewQuery("http://jabber.org/protocol/muc#owner");
-    my $x     = $query->NewChild("jabber:x:data");
-    $x->SetType('submit');
-
-    $conn->getConnectionFromJID($jid)->Send($iq);
-    queue_admin_msg("Accepted default instant configuration for $muc");
-}
-
-sub jmuc_presence_single {
-    my $m = shift;
-    my @jids = $m->Presence();
-
-    my $presence = "JIDs present in " . $m->BaseJID;
-    if($m->Anonymous) {
-        $presence .= " [anonymous MUC]";
-    }
-    $presence .= "\n\t";
-    $presence .= join("\n\t", map {pp_jid($m, $_);} @jids) . "\n";
-    return $presence;
-}
-
-sub pp_jid {
-    my ($m, $jid) = @_;
-    my $nick = $jid->GetResource;
-    my $full = $m->GetFullJID($jid);
-    if($full && $full ne $nick) {
-        return "$nick ($full)";
-    } else {
-        return "$nick";
-    }
-}
-
-sub jmuc_presence {
-    my ( $jid, $muc, @args ) = @_;
-
-    $muc = shift @args if scalar @args;
-    die("Usage: jmuc presence MUC") unless $muc;
-
-    if ($muc eq '-a') {
-        my $str = "";
-        foreach my $jid ($conn->getJIDs()) {
-            $str .= BarnOwl::Style::boldify("Conferences for $jid:\n");
-            my $connection = $conn->getConnectionFromJID($jid);
-            foreach my $muc ($connection->MUCs) {
-                $str .= jmuc_presence_single($muc)."\n";
-            }
-        }
-        BarnOwl::popless_ztext($str);
-    }
-    else {
-        my $m = $conn->getConnectionFromJID($jid)->FindMUC(jid => $muc);
-        die("No such muc: $muc") unless $m;
-        BarnOwl::popless_ztext(jmuc_presence_single($m));
-    }
-}
-
-
-#XXX TODO: Consider merging this with jmuc and selecting off the first two args.
-sub cmd_jroster {
-    die "You are not logged in to Jabber" unless $conn->connected();
-    my $ocmd = shift;
-    my $cmd  = shift;
-    if ( !$cmd ) {
-
-        #XXX TODO: Write general usage for jroster command.
-        return;
-    }
-
-    my %jroster_commands = (
-        sub      => \&jroster_sub,
-        unsub    => \&jroster_unsub,
-        add      => \&jroster_add,
-        remove   => \&jroster_remove,
-        auth     => \&jroster_auth,
-        deauth   => \&jroster_deauth
-    );
-    my $func = $jroster_commands{$cmd};
-    if ( !$func ) {
-        BarnOwl::error("jroster: Unknown command: $cmd");
-        return;
-    }
-
-    {
-        local @ARGV = @_;
-        my $jid;
-        my $name;
-        my @groups;
-        my $purgeGroups;
-        my $getopt = Getopt::Long::Parser->new;
-        $getopt->configure('pass_through', 'no_getopt_compat');
-        $getopt->getoptions(
-            'account=s' => \$jid,
-            'group=s' => \@groups,
-            'purgegroups' => \$purgeGroups,
-            'name=s' => \$name
-        );
-        $jid ||= defaultJID();
-        if ($jid) {
-            $jid = resolveConnectedJID($jid);
-            return unless $jid;
-        }
-        else {
-            BarnOwl::error('You must specify an account with -a {jid}');
-        }
-        return $func->( $jid, $name, \@groups, $purgeGroups,  @ARGV );
-    }
-}
-
-sub cmd_jaway {
-    my $cmd = shift;
-    local @ARGV = @_;
-    my $getopt = Getopt::Long::Parser->new;
-    my ($jid, $show);
-    my $p = new Net::Jabber::Presence;
-
-    $getopt->configure('pass_through', 'no_getopt_compat');
-    $getopt->getoptions(
-        'account=s' => \$jid,
-        'show=s'    => \$show
-    );
-    $jid ||= defaultJID();
-    if ($jid) {
-        $jid = resolveConnectedJID($jid);
-        return unless $jid;
-    }
-    else {
-        BarnOwl::error('You must specify an account with -a {jid}');
-    }
-
-    $p->SetShow($show eq "online" ? "" : $show) if $show;
-    $p->SetStatus(join(' ', @ARGV)) if @ARGV;
-    $conn->getConnectionFromJID($jid)->Send($p);
-}
-
-
-sub jroster_sub {
-    my $jid = shift;
-    my $name = shift;
-    my @groups = @{ shift() };
-    my $purgeGroups = shift;
-    my $baseJID = baseJID($jid);
-
-    my $roster = $conn->getRosterFromJID($jid);
-
-    # Adding lots of users with the same name is a bad idea.
-    $name = "" unless (1 == scalar(@ARGV));
-
-    my $p = new Net::Jabber::Presence;
-    $p->SetType('subscribe');
-
-    foreach my $to (@ARGV) {
-        jroster_add($jid, $name, \@groups, $purgeGroups, ($to)) unless ($roster->exists($to));
-
-        $p->SetTo($to);
-        $conn->getConnectionFromJID($jid)->Send($p);
-        queue_admin_msg("You ($baseJID) have requested a subscription to ($to)'s presence.");
-    }
-}
-
-sub jroster_unsub {
-    my $jid = shift;
-    my $name = shift;
-    my @groups = @{ shift() };
-    my $purgeGroups = shift;
-    my $baseJID = baseJID($jid);
-
-    my $p = new Net::Jabber::Presence;
-    $p->SetType('unsubscribe');
-    foreach my $to (@ARGV) {
-        $p->SetTo($to);
-        $conn->getConnectionFromJID($jid)->Send($p);
-        queue_admin_msg("You ($baseJID) have unsubscribed from ($to)'s presence.");
-    }
-}
-
-sub jroster_add {
-    my $jid = shift;
-    my $name = shift;
-    my @groups = @{ shift() };
-    my $purgeGroups = shift;
-    my $baseJID = baseJID($jid);
-
-    my $roster = $conn->getRosterFromJID($jid);
-
-    # Adding lots of users with the same name is a bad idea.
-    $name = "" unless (1 == scalar(@ARGV));
-
-    foreach my $to (@ARGV) {
-        my %jq  = $roster->query($to);
-        my $iq = new Net::Jabber::IQ;
-        $iq->SetType('set');
-        my $item = new XML::Stream::Node('item');
-        $iq->NewChild('jabber:iq:roster')->AddChild($item);
-
-        my %allGroups = ();
-
-        foreach my $g (@groups) {
-            $allGroups{$g} = $g;
-        }
-
-        unless ($purgeGroups) {
-            foreach my $g (@{$jq{groups}}) {
-                $allGroups{$g} = $g;
-            }
-        }
-
-        foreach my $g (keys %allGroups) {
-            $item->add_child('group')->add_cdata($g);
-        }
-
-        $item->put_attrib(jid => $to);
-        $item->put_attrib(name => $name) if $name;
-        $conn->getConnectionFromJID($jid)->Send($iq);
-        my $msg = "$baseJID: "
-          . ($name ? "$name ($to)" : "($to)")
-          . " is on your roster in the following groups: { "
-          . join(" , ", keys %allGroups)
-          . " }";
-        queue_admin_msg($msg);
-    }
-}
-
-sub jroster_remove {
-    my $jid = shift;
-    my $name = shift;
-    my @groups = @{ shift() };
-    my $purgeGroups = shift;
-    my $baseJID = baseJID($jid);
-
-    my $iq = new Net::Jabber::IQ;
-    $iq->SetType('set');
-    my $item = new XML::Stream::Node('item');
-    $iq->NewChild('jabber:iq:roster')->AddChild($item);
-    $item->put_attrib(subscription=> 'remove');
-    foreach my $to (@ARGV) {
-        $item->put_attrib(jid => $to);
-        $conn->getConnectionFromJID($jid)->Send($iq);
-        queue_admin_msg("You ($baseJID) have removed ($to) from your roster.");
-    }
-}
-
-sub jroster_auth {
-    my $jid = shift;
-    my $name = shift;
-    my @groups = @{ shift() };
-    my $purgeGroups = shift;
-    my $baseJID = baseJID($jid);
-
-    my $p = new Net::Jabber::Presence;
-    $p->SetType('subscribed');
-    foreach my $to (@ARGV) {
-        $p->SetTo($to);
-        $conn->getConnectionFromJID($jid)->Send($p);
-        queue_admin_msg("($to) has been subscribed to your ($baseJID) presence.");
-    }
-}
-
-sub jroster_deauth {
-    my $jid = shift;
-    my $name = shift;
-    my @groups = @{ shift() };
-    my $purgeGroups = shift;
-    my $baseJID = baseJID($jid);
-
-    my $p = new Net::Jabber::Presence;
-    $p->SetType('unsubscribed');
-    foreach my $to (@ARGV) {
-        $p->SetTo($to);
-        $conn->getConnectionFromJID($jid)->Send($p);
-        queue_admin_msg("($to) has been unsubscribed from your ($baseJID) presence.");
-    }
-}
-
-################################################################################
-### Owl Callbacks
-sub process_owl_jwrite {
-    my $body = shift;
-
-    my $j = new Net::Jabber::Message;
-    $body =~ s/\n\z//;
-    $j->SetMessage(
-        to   => $vars{jwrite}{to},
-        from => $vars{jwrite}{from},
-        type => $vars{jwrite}{type},
-        body => $body
-    );
-
-    $j->SetThread( $vars{jwrite}{thread} )   if ( $vars{jwrite}{thread} );
-    $j->SetSubject( $vars{jwrite}{subject} ) if ( $vars{jwrite}{subject} );
-
-    my $m = j2o( $j, { direction => 'out' } );
-    if ( $vars{jwrite}{type} ne 'groupchat') {
-        BarnOwl::queue_message($m);
-    }
-
-    $j->RemoveFrom(); # Kludge to get around gtalk's random bits after the resource.
-    if ($vars{jwrite}{sid} && $conn->sidExists( $vars{jwrite}{sid} )) {
-        $conn->getConnectionFromSid($vars{jwrite}{sid})->Send($j);
-    }
-    else {
-        $conn->getConnectionFromJID($vars{jwrite}{from})->Send($j);
-    }
-
-    delete $vars{jwrite};
-    BarnOwl::message("");   # Kludge to make the ``type your message...'' message go away
-}
-
-### XMPP Callbacks
-
-sub process_incoming_chat_message {
-    my ( $sid, $j ) = @_;
-    if ($j->DefinedBody()) {
-        BarnOwl::queue_message( j2o( $j, { direction => 'in',
-                                           sid => $sid } ) );
-    }
-}
-
-sub process_incoming_error_message {
-    my ( $sid, $j ) = @_;
-    my %jhash = j2hash( $j, { direction => 'in',
-                              sid => $sid } );
-    $jhash{type} = 'admin';
-    
-    BarnOwl::queue_message( BarnOwl::Message->new(%jhash) );
-}
-
-sub process_incoming_groupchat_message {
-    my ( $sid, $j ) = @_;
-
-    # HACK IN PROGRESS (ignoring delayed messages)
-    return if ( $j->DefinedX('jabber:x:delay') && $j->GetX('jabber:x:delay') );
-    BarnOwl::queue_message( j2o( $j, { direction => 'in',
-                                   sid => $sid } ) );
-}
-
-sub process_incoming_headline_message {
-    my ( $sid, $j ) = @_;
-    BarnOwl::queue_message( j2o( $j, { direction => 'in',
-                                   sid => $sid } ) );
-}
-
-sub process_incoming_normal_message {
-    my ( $sid, $j ) = @_;
-    my %jhash = j2hash( $j, { direction => 'in',
-                              sid => $sid } );
-
-    # XXX TODO: handle things such as MUC invites here.
-
-    #    if ($j->HasX('http://jabber.org/protocol/muc#user'))
-    #    {
-    #	my $x = $j->GetX('http://jabber.org/protocol/muc#user');
-    #	if ($x->HasChild('invite'))
-    #	{
-    #	    $props
-    #	}
-    #    }
-    #
-    if(BarnOwl::getvar('jabber:spew') eq 'on') {
-        BarnOwl::queue_message( BarnOwl::Message->new(%jhash) );
-    }
-}
-
-sub process_muc_presence {
-    my ( $sid, $p ) = @_;
-    return unless ( $p->HasX('http://jabber.org/protocol/muc#user') );
-}
-
-
-sub process_presence_available {
-    return unless (BarnOwl::getvar('jabber:show_logins') eq 'on');
-    my ( $sid, $p ) = @_;
-    my $from = $p->GetFrom('jid')->GetJID('base');
-    my $to = $p->GetTo();
-    my $type = $p->GetType();
-    my %props = (
-        to => $to,
-        from => $p->GetFrom(),
-        recipient => $to,
-        sender => $from,
-        type => 'jabber',
-        jtype => $p->GetType(),
-        status => $p->GetStatus(),
-        show => $p->GetShow(),
-        xml => $p->GetXML(),
-        direction => 'in');
-
-    if ($type eq '' || $type eq 'available') {
-        $props{body} = "$from is now online. ";
-        $props{loginout} = 'login';
-    }
-    else {
-        $props{body} = "$from is now offline. ";
-        $props{loginout} = 'logout';
-    }
-    BarnOwl::queue_message(BarnOwl::Message->new(%props));
-}
-
-sub process_presence_subscribe {
-    my ( $sid, $p ) = @_;
-    my $from = $p->GetFrom();
-    my $to = $p->GetTo();
-    my %props = (
-        to => $to,
-        from => $from,
-        xml => $p->GetXML(),
-        type => 'admin',
-        adminheader => 'Jabber presence: subscribe',
-        direction => 'in');
-
-    $props{body} = "Allow user ($from) to subscribe to your ($to) presence?\n" .
-                   "(Answer with the `yes' or `no' commands)";
-    $props{yescommand} = "jroster auth $from -a $to";
-    $props{nocommand} = "jroster deauth $from -a $to";
-    $props{question} = "true";
-    BarnOwl::queue_message(BarnOwl::Message->new(%props));
-}
-
-sub process_presence_unsubscribe {
-    my ( $sid, $p ) = @_;
-    my $from = $p->GetFrom();
-    my $to = $p->GetTo();
-    my %props = (
-        to => $to,
-        from => $from,
-        xml => $p->GetXML(),
-        type => 'admin',
-        adminheader => 'Jabber presence: unsubscribe',
-        direction => 'in');
-
-    $props{body} = "The user ($from) has been unsubscribed from your ($to) presence.\n";
-    BarnOwl::queue_message(BarnOwl::Message->new(%props));
-
-    # Find a connection to reply with.
-    foreach my $jid ($conn->getJIDs()) {
-	my $cJID = new Net::Jabber::JID;
-	$cJID->SetJID($jid);
-	if ($to eq $cJID->GetJID('base') ||
-            $to eq $cJID->GetJID('full')) {
-	    my $reply = $p->Reply(type=>"unsubscribed");
-	    $conn->getConnectionFromJID($jid)->Send($reply);
-	    return;
-	}
-    }
-}
-
-sub process_presence_subscribed {
-    my ( $sid, $p ) = @_;
-    queue_admin_msg("ignoring:".$p->GetXML());
-    # RFC 3921 says we should respond to this with a "subscribe"
-    # but this causes a flood of sub/sub'd presence packets with
-    # some servers, so we won't. We may want to detect this condition
-    # later, and have per-server settings.
-    return;
-}
-
-sub process_presence_unsubscribed {
-    my ( $sid, $p ) = @_;
-    queue_admin_msg("ignoring:".$p->GetXML());
-    # RFC 3921 says we should respond to this with a "subscribe"
-    # but this causes a flood of unsub/unsub'd presence packets with
-    # some servers, so we won't. We may want to detect this condition
-    # later, and have per-server settings.
-    return;
-}
-
-sub process_presence_error {
-    my ( $sid, $p ) = @_;
-    my $code = $p->GetErrorCode();
-    my $error = $p->GetError();
-    BarnOwl::error("Jabber: $code $error");
-}
-
-
-### Helper functions
-
-sub j2hash {
-    my $j   = shift;
-    my %props = (type => 'jabber',
-                 dir  => 'none',
-                 %{$_[0]});
-
-    my $dir = $props{direction};
-
-    my $jtype = $props{jtype} = $j->GetType();
-    my $from = $j->GetFrom('jid');
-    my $to   = $j->GetTo('jid');
-
-    $props{from} = $from->GetJID('full');
-    $props{to}   = $to->GetJID('full');
-
-    $props{recipient}  = $to->GetJID('base');
-    $props{sender}     = $from->GetJID('base');
-    $props{subject}    = $j->GetSubject() if ( $j->DefinedSubject() );
-    $props{thread}     = $j->GetThread() if ( $j->DefinedThread() );
-    if ( $j->DefinedBody() ) {
-        $props{body}   = $j->GetBody();
-        $props{body}  =~ s/\xEF\xBB\xBF//g; # Strip stray Byte-Order-Marks.
-    }
-    $props{error}      = $j->GetError() if ( $j->DefinedError() );
-    $props{error_code} = $j->GetErrorCode() if ( $j->DefinedErrorCode() );
-    $props{xml}        = $j->GetXML();
-
-    if ( $jtype eq 'chat' ) {
-        $props{private} = 1;
-
-        my $connection;
-        if ($dir eq 'in') {
-            $connection = $conn->getConnectionFromSid($props{sid});
-        }
-        else {
-            $connection = $conn->getConnectionFromJID($props{from});
-        }
-
-        # Check to see if we're doing personals with someone in a muc.
-        # If we are, show the full jid because the base jid is the room.
-        if ($connection) {
-            $props{sender} = $props{from}
-              if ($connection->FindMUC(jid => $from));
-            $props{recipient} = $props{to}
-              if ($connection->FindMUC(jid => $to));
-        }
-    }
-    elsif ( $jtype eq 'groupchat' ) {
-        my $nick = $props{nick} = $from->GetResource();
-        my $room = $props{room} = $from->GetJID('base');
-
-        $props{sender} = $nick || $room;
-        $props{recipient} = $room;
-
-        if ( $props{subject} && !$props{body} ) {
-            $props{body} =
-              '[' . $nick . " has set the topic to: " . $props{subject} . "]";
-        }
-    }
-    elsif ( $jtype eq 'normal' ) {
-        $props{private} = 1;
-    }
-    elsif ( $jtype eq 'headline' ) {
-    }
-    elsif ( $jtype eq 'error' ) {
-        $props{body}     = "Error "
-          . $props{error_code}
-          . " sending to "
-          . $props{from} . "\n"
-          . $props{error};
-    }
-
-    return %props;
-}
-
-sub j2o {
-    return BarnOwl::Message->new( j2hash(@_) );
-}
-
-sub queue_admin_msg {
-    my $err = shift;
-    BarnOwl::admin_message("Jabber", $err);
-}
-
-sub getServerFromJID {
-    my $jid = shift;
-    my $res = new Net::DNS::Resolver;
-    my $packet =
-      $res->search( '_xmpp-client._tcp.' . $jid->GetServer(), 'srv' );
-
-    if ($packet)    # Got srv record.
-    {
-        my @answer = $packet->answer;
-        return $answer[0]{target}, $answer[0]{port};
-    }
-
-    return $jid->GetServer(), 5222;
-}
-
-sub defaultJID {
-    return ( $conn->getJIDs() )[0] if ( $conn->connected() == 1 );
-    return;
-}
-
-sub baseJID {
-    my $givenJIDStr = shift;
-    my $givenJID    = new Net::Jabber::JID;
-    $givenJID->SetJID($givenJIDStr);
-    return $givenJID->GetJID('base');
-}
-
-sub resolveConnectedJID {
-    my $givenJIDStr = shift;
-    my $givenJID    = new Net::Jabber::JID;
-    $givenJID->SetJID($givenJIDStr);
-
-    # Account fully specified.
-    if ( $givenJID->GetResource() ) {
-        # Specified account exists
-        return $givenJIDStr if ($conn->jidExists($givenJIDStr) );
-        die("Invalid account: $givenJIDStr");
-    }
-
-    # Disambiguate.
-    else {
-        my $matchingJID = "";
-        my $errStr =
-          "Ambiguous account reference. Please specify a resource.\n";
-        my $ambiguous = 0;
-
-        foreach my $jid ( $conn->getJIDs() ) {
-            my $cJID = new Net::Jabber::JID;
-            $cJID->SetJID($jid);
-            if ( $givenJIDStr eq $cJID->GetJID('base') ) {
-                $ambiguous = 1 if ( $matchingJID ne "" );
-                $matchingJID = $jid;
-                $errStr .= "\t$jid\n";
-            }
-        }
-
-        # Need further disambiguation.
-        if ($ambiguous) {
-            die($errStr);
-        }
-
-        # Not one of ours.
-        elsif ( $matchingJID eq "" ) {
-            die("Invalid account: $givenJIDStr");
-        }
-
-        # It's this one.
-        else {
-            return $matchingJID;
-        }
-    }
-    return "";
-}
-
-sub resolveDestJID {
-    my ($to, $from) = @_;
-    my $jid = Net::Jabber::JID->new($to);
-
-    my $roster = $conn->getRosterFromJID($from);
-    my @jids = $roster->jids('all');
-    for my $j (@jids) {
-        if(($roster->query($j, 'name') || $j->GetUserID()) eq $to) {
-            return $j->GetJID('full');
-        } elsif($j->GetJID('base') eq baseJID($to)) {
-            return $jid->GetJID('full');
-        }
-    }
-
-    # If we found nothing being clever, check to see if our input was
-    # sane enough to look like a jid with a UserID.
-    return $jid->GetJID('full') if $jid->GetUserID();
-    return undef;
-}
-
-sub resolveType {
-    my $to = shift;
-    my $from = shift;
-    return unless $from;
-    my @mucs = $conn->getConnectionFromJID($from)->MUCs;
-    if(grep {$_->BaseJID eq $to } @mucs) {
-        return 'groupchat';
-    } else {
-        return 'chat';
-    }
-}
-
-sub guess_jwrite {
-    # Heuristically guess what jids a jwrite was meant to be going to/from
-    my ($from, $to) = (@_);
-    my ($from_jid, $to_jid);
-    my @matches;
-    if($from) {
-        $from_jid = resolveConnectedJID($from);
-        die("Unable to resolve account $from") unless $from_jid;
-        $to_jid = resolveDestJID($to, $from_jid);
-        push @matches, [$from_jid, $to_jid] if $to_jid;
-    } else {
-        for my $f ($conn->getJIDs) {
-            $to_jid = resolveDestJID($to, $f);
-            if(defined($to_jid)) {
-                push @matches, [$f, $to_jid];
-            }
-        }
-        if($to =~ /@/) {
-            push @matches, [$_, $to]
-               for ($conn->getJIDs);
-        }
-    }
-
-    for my $m (@matches) {
-        my $type = resolveType($m->[1], $m->[0]);
-        push @$m, $type;
-    }
-
-    return @matches;
-}
-
-1;
Index: rl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm
===================================================================
--- perl/modules/Jabber/lib/BarnOwl/Module/Jabber/Connection.pm	(revision 6b580b05f6e84a05297c835e3ff724e1e3187e1c)
+++ 	(revision )
@@ -1,158 +1,0 @@
-use warnings;
-use strict;
-use utf8;
-
-=head1 NAME
-
-BarnOwl::Module::Jabber::Connection
-
-=head1 DESCRIPTION
-
-A subclass of L<Net::Jabber::Client> used in the BarnOwl jabber module
-
-=cut
-
-package BarnOwl::Module::Jabber::Connection;
-
-use base qw(Net::Jabber::Client);
-
-use Net::Jabber;
-
-sub new {
-    my $class = shift;
-
-    my %args = ();
-    if(BarnOwl::getvar('debug') eq 'on') {
-        $args{debuglevel} = 1;
-        $args{debugfile} = 'jabber.log';
-    }
-    my $self = $class->SUPER::new(%args);
-    $self->{_BARNOWL_MUCS} = [];
-    return $self;
-}
-
-=head2 MUCJoin
-
-Extends MUCJoin to keep track of the MUCs we're joined to as
-Net::Jabber::MUC objects. Takes the same arguments as
-L<Net::Jabber::MUC/new> and L<Net::Jabber::MUC/Connect>
-
-=cut
-
-sub MUCJoin {
-    my $self = shift;
-    my $muc = Net::Jabber::MUC->new(connection => $self, @_);
-    $muc->Join(@_);
-
-    # Add MUC to list of MUCs, unless we're just changing nicks.
-    push @{$self->MUCs}, $muc unless grep {$_->BaseJID eq $muc->BaseJID} $self->MUCs;
-}
-
-=head2 MUCLeave ARGS
-
-Leave a MUC. The MUC is specified in the same form as L</FindMUC>
-
-Returns true if successful, false if this connection was not in the
-named MUC.
-
-=cut
-
-sub MUCLeave {
-    my $self = shift;
-    my $muc = $self->FindMUC(@_);
-    return unless $muc;
-
-    $muc->Leave();
-    $self->{_BARNOWL_MUCS} = [grep {$_->BaseJID ne $muc->BaseJID} $self->MUCs];
-    return 1;
-}
-
-=head2 FindMUC ARGS
-
-Return the Net::Jabber::MUC object representing a specific MUC we're
-joined to, undef if it doesn't exists. ARGS can be either JID => $JID,
-or Room => $room, Server => $server.
-
-=cut
-
-sub FindMUC {
-    my $self = shift;
-
-    my %args;
-    while($#_ >= 0) { $args{ lc(pop(@_)) } = pop(@_); }
-
-    my $jid;
-    if($args{jid}) {
-        $jid = $args{jid};
-    } elsif($args{room} && $args{server}) {
-        $jid = Net::Jabber::JID->new(userid => $args{room},
-                                     server => $args{server});
-    }
-    $jid = $jid->GetJID('base') if UNIVERSAL::isa($jid, 'Net::XMPP::JID');
-
-    foreach my $muc ($self->MUCs) {
-        return $muc if $muc->BaseJID eq $jid;
-    }
-    return undef;
-}
-
-=head2 MUCs
-
-Returns a list (or arrayref in scalar context) of Net::Jabber::MUC
-objects we believe ourself to be connected to.
-
-=cut
-
-sub MUCs {
-    my $self = shift;
-    my $mucs = $self->{_BARNOWL_MUCS};
-    return wantarray ? @$mucs : $mucs;
-}
-
-
-=head2 getSID
-
-Returns the StreamID for this connection.
-
-=cut
-
-sub getStreamID {
-    my $self = shift;
-    return $self->{SESSION}->{id} || "";
-}
-
-=head2 getSocket
-
-Returns the IO::Socket for this connection.
-
-=cut
-
-sub getSocket {
-    my $self = shift;
-    my $sid = getStreamID($self);
-    return $self->{STREAM}->GetSock($sid) || -1;
-}
-
-=head2 OwlProcess
-
-Non-blocking connection processing. For use in a select loop.
-
-=cut
-
-sub OwlProcess {
-    my $self = shift;
-    my $status = $self->Process(0);
-    if ( !defined($status) ) {
-        my $jid = $self->{SESSION}->{FULLJID};
-        BarnOwl::error("Jabber account $jid disconnected!");
-        BarnOwl::Module::Jabber::do_logout($jid);
-    }
-}
-
-=head1 SEE ALSO
-
-L<Net::Jabber::Client>, L<BarnOwl::Module::Jabber>
-
-=cut
-
-1;
Index: rl/modules/Jabber/lib/BarnOwl/Module/Jabber/ConnectionManager.pm
===================================================================
--- perl/modules/Jabber/lib/BarnOwl/Module/Jabber/ConnectionManager.pm	(revision 6b580b05f6e84a05297c835e3ff724e1e3187e1c)
+++ 	(revision )
@@ -1,118 +1,0 @@
-use warnings;
-use strict;
-
-=head1 NAME
-
-BarnOwl::Module::Jabber::ConnectionManager
-
-=head1 DESCRIPTION
-
-A class to keep track of all the active connection in the barnowl
-jabber module
-
-=cut
-
-package BarnOwl::Module::Jabber::ConnectionManager;
-
-sub new {
-    my $class = shift;
-    return bless { }, $class;
-}
-
-sub addConnection {
-    my $self = shift;
-    my $jidStr = shift;
-
-    my $client = BarnOwl::Module::Jabber::Connection->new;
-
-    $self->{$jidStr}->{Client} = $client;
-    $self->{$jidStr}->{Roster} = $client->Roster();
-    $self->{$jidStr}->{Status} = "available";
-    return $client;
-}
-
-sub removeConnection {
-    my $self = shift;
-    my $jidStr = shift;
-    return 0 unless exists $self->{$jidStr};
-
-    BarnOwl::remove_dispatch($self->{$jidStr}->{Client}->{fileno}) if $self->{$jidStr}->{Client}->{fileno};
-    $self->{$jidStr}->{Client}->Disconnect()
-      if $self->{$jidStr}->{Client};
-    delete $self->{$jidStr};
-
-    return 1;
-}
-
-sub renameConnection {
-    my $self = shift;
-    my $oldJidStr = shift;
-    my $newJidStr = shift;
-    return 0 unless exists $self->{$oldJidStr};
-    return 0 if $oldJidStr eq $newJidStr;
-
-    $self->{$newJidStr} = $self->{$oldJidStr};
-    delete $self->{$oldJidStr};
-    return 1;
-}
-
-sub connected {
-    my $self = shift;
-    return scalar keys %{ $self };
-}
-
-sub getJIDs {
-    my $self = shift;
-    return keys %{ $self };
-}
-
-sub jidExists {
-    my $self = shift;
-    my $jidStr = shift;
-    return exists $self->{$jidStr};
-}
-
-sub sidExists {
-    my $self = shift;
-    my $sid = shift || "";
-    foreach my $c ( values %{ $self } ) {
-        return 1 if ($c->{Client}->{SESSION}->{id} eq $sid);
-    }
-    return 0;
-}
-
-sub getConnectionFromSid {
-    my $self = shift;
-    my $sid = shift;
-    foreach my $c (values %{ $self }) {
-        return $c->{Client} if $c->{Client}->{SESSION}->{id} eq $sid;
-    }
-    return undef;
-}
-
-sub getConnectionFromJID {
-    my $self = shift;
-    my $jid = shift;
-    $jid = $jid->GetJID('full') if UNIVERSAL::isa($jid, 'Net::XMPP::JID');
-    return $self->{$jid}->{Client} if exists $self->{$jid};
-}
-
-sub getRosterFromSid {
-    my $self = shift;
-    my $sid = shift;
-    foreach my $c (values %{ $self }) {
-        return $c->{Roster}
-          if $c->{Client}->{SESSION}->{id} eq $sid;
-    }
-    return undef;
-}
-
-sub getRosterFromJID {
-    my $self = shift;
-    my $jid = shift;
-    $jid = $jid->GetJID('full') if UNIVERSAL::isa($jid, 'Net::XMPP::JID');
-    return $self->{$jid}->{Roster} if exists $self->{$jid};
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,182 +1,0 @@
-###############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-###############################################################################
-
-package Net::Jabber;
-
-=head1 NAME
-
-Net::Jabber - Jabber Perl Library
-
-=head1 SYNOPSIS
-
-  Net::Jabber provides a Perl user with access to the Jabber Instant
-  Messaging protocol.
-
-  For more information about Jabber visit:
-
-    http://www.jabber.org
-
-=head1 DESCRIPTION
-
-  Net::Jabber is a convenient tool to use for any perl script that would
-  like to utilize the Jabber Instant Messaging protocol.  While not a
-  client in and of itself, it provides all of the necessary back-end
-  functions to make a CGI client or command-line perl client feasible and
-  easy to use.  Net::Jabber is a wrapper around the rest of the official
-  Net::Jabber::xxxxxx packages.
-
-  There is are example scripts in the example directory that provide you
-  with examples of very simple Jabber programs.
-
-
-  NOTE: The parser that XML::Stream::Parser provides, as are most Perl
-  parsers, is synchronous.  If you are in the middle of parsing a packet
-  and call a user defined callback, the Parser is blocked until your
-  callback finishes.  This means you cannot be operating on a packet,
-  send out another packet and wait for a response to that packet.  It
-  will never get to you.  Threading might solve this, but as of the
-  writing of this, threading in Perl is not quite up to par yet.  This
-  issue will be revisted in the future.
-
-=head1 EXAMPLES
-
-    For a client:
-      use Net::Jabber;
-      my $client = Net::Jabber::Client->new();
-
-    For a component:
-      use Net::Jabber;
-      my $component = Net::Jabber::Component->new();
-
-=head1 METHODS
-
-  The Net::Jabber module does not define any methods that you will call
-  directly in your code.  Instead you will instantiate objects that call
-  functions from this module to do work.  The three main objects that
-  you will work with are the Message, Presence, and IQ modules.  Each one
-  corresponds to the Jabber equivilant and allows you get and set all
-  parts of those packets.
-
-=head1 PACKAGES
-
-  For more information on each of these packages, please see the man page
-  for each one.
-
-=head2 Net::Jabber::Client
-
-  This package contains the code needed to communicate with a Jabber
-  server: login, wait for messages, send messages, and logout.  It uses
-  XML::Stream to read the stream from the server and based on what kind
-  of tag it encounters it calls a function to handle the tag.
-
-=head2 Net::Jabber::Component
-
-  This package contains the code needed to write a server component.  A
-  component is a program tha handles the communication between a jabber
-  server and some outside program or communications pacakge (IRC, talk,
-  email, etc...)  With this module you can write a full component in just
-  a few lines of Perl.  It uses XML::Stream to communicate with its host
-  server and based on what kind of tag it encounters it calls a function
-  to handle the tag.
-
-=head2 Net::Jabber::Protocol
-
-  A collection of high-level functions that Client and Component use to
-  make their lives easier through inheritance.
-
-=head2 Net::Jabber::JID
-
-  The Jabber IDs consist of three parts: user id, server, and resource.
-  This module gives you access to those components without having to
-  parse the string yourself.
-
-=head2 Net::Jabber::Message
-
-  Everything needed to create and read a <message/> received from the
-  server.
-
-=head2 Net::Jabber::Presence
-
-  Everything needed to create and read a <presence/> received from the
-  server.
-
-=head2 Net::Jabber::IQ
-
-  IQ is a wrapper around a number of modules that provide support for the
-  various Info/Query namespaces that Jabber recognizes.
-
-=head2 Net::Jabber::Stanza
-
-  This module represents a namespaced stanza that is used to extend a
-  <message/>, <presence/>, and <iq/>.  Ultimately each namespace is
-  documented in a JEP of some kind.  http://jabber.org/jeps/
-
-  The man page for Net::Jabber::Stanza contains a listing of all
-  supported namespaces, and the methods that are supported by the objects
-  that represent those namespaces.
-
-=head2 Net::Jabber::Namespaces
-
-  Jabber allows for any stanza to be extended by any bit of XML.  This
-  module contains all of the internals for defining the Jabber based
-  extensions defined by the JEPs.  The documentation for this module
-  explains more about how to add your own custom namespace and have it be
-  supported.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software, you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.005;
-use strict;
-use Carp;
-use POSIX;
-use Net::XMPP 1.0;
-
-use base qw( Net::XMPP );
-
-use vars qw( $VERSION );
-
-$VERSION = "2.0";
-
-use Net::Jabber::Debug;
-use Net::Jabber::JID;
-use Net::Jabber::Namespaces;
-use Net::Jabber::Stanza;
-use Net::Jabber::Message;
-use Net::Jabber::IQ;
-use Net::Jabber::Presence;
-use Net::Jabber::Protocol;
-use Net::Jabber::Client;
-use Net::Jabber::Component;
-
-sub GetTimeStamp { return &Net::XMPP::GetTimeStamp(@_); }
-sub printData    { return &Net::XMPP::printData(@_);    }
-sub sprintData   { return &Net::XMPP::sprintData(@_);   }
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Client.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Client.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,76 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Client;
-
-=head1 NAME
-
-Net::Jabber::Client - Jabber Client Library
-
-=head1 SYNOPSIS
-
-  Net::Jabber::Client is a module that provides a developer easy access
-  to the Jabber Instant Messaging protocol.
-
-=head1 DESCRIPTION
-
-  Client.pm inherits its methods from Net::XMPP::Client,
-  Net::XMPP::Protocol and Net::Jabber::Protocol.  The Protocol modules
-  provide enough high level APIs and automation of the low level APIs
-  that writing a Jabber Client in Perl is trivial.  For those that wish
-  to work with the low level you can do that too, but those functions are
-  covered in the documentation for each module.
-
-  Net::Jabber::Client provides functions to connect to a Jabber server,
-  login, send and receive messages, set personal information, create a
-  new user account, manage the roster, and disconnect.  You can use all
-  or none of the functions, there is no requirement.
-
-  For more information on how the details for how Net::Jabber is written
-  please see the help for Net::Jabber itself.
-
-  For a full list of high level functions available please see:
-
-    Net::XMPP::Client
-    Net::XMPP::Protocol
-    Net::Jabber::Protocol
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use Carp;
-use Net::XMPP::Client;
-use Net::Jabber::Protocol;
-use base qw( Net::XMPP::Client Net::Jabber::Protocol );
-use vars qw( $VERSION ); 
-
-$VERSION = "2.0";
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Component.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Component.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,264 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Component;
-
-=head1 NAME
-
-Net::Jabber::Component - Jabber Component Library
-
-=head1 SYNOPSIS
-
-  Net::Jabber::Component is a module that provides a developer easy
-  access to developing server components in the Jabber Instant Messaging
-  protocol.
-
-=head1 DESCRIPTION
-
-  Component.pm seeks to provide enough high level APIs and automation of
-  the low level APIs that writing a Jabber Component in Perl is trivial.
-  For those that wish to work with the low level you can do that too,
-  but those functions are covered in the documentation for each module.
-
-  Net::Jabber::Component provides functions to connect to a Jabber
-  server, login, send and receive messages, operate as a server side
-  component, and disconnect.  You can use all or none of the functions,
-  there is no requirement.
-
-  For more information on how the details for how Net::Jabber is written
-  please see the help for Net::Jabber itself.
-
-  For a full list of high level functions available please see
-  Net::Jabber::Protocol and Net::XMPP::Protocol.
-
-=head2 Basic Functions
-
-    use Net::Jabber;
-
-    $Con = Net::Jabber::Component->new();
-
-    $Con->Execute(hostname=>"jabber.org",
-                  componentname=>"service.jabber.org",
-                  secret=>"XXXX"
-                 );
-
-    #
-    # For the list of available functions see Net::XMPP::Protocol.
-    #
-
-    $Con->Disconnect();
-
-=head1 METHODS
-
-=head2 Basic Functions
-
-    new(debuglevel=>0|1|2, - creates the Component object.  debugfile
-        debugfile=>string,   should be set to the path for the debug
-        debugtime=>0|1)      log to be written.  If set to "stdout"
-                             then the debug will go there.  debuglevel
-                             controls the amount of debug.  For more
-                             information about the valid setting for
-                             debuglevel, debugfile, and debugtime see
-                             Net::Jabber::Debug.
-
-    AuthSend(secret=>string) - Perform the handshake and authenticate
-                               with the server.
-
-    Connect(hostname=>string,       - opens a connection to the server
-	        port=>integer,            based on the value of
-	        componentname=>string,    connectiontype.  The only valid
-	        connectiontype=>string)   setting is:
-	                                    accept - TCP/IP remote connection
-                                      In the future this might be used
-                                      again by offering new features.
-                                      If accept then it connects to the
-                                      server listed in the hostname
-                                      value, on the port listed.  The
-                                      defaults for the two are localhost
-                                      and 5269.
-                                      
-                                      Note: A change from previous
-                                      versions is that Component now
-                                      shares its core with Client.  To
-                                      that end, the secret should no
-                                      longer be used.  Call AuthSend
-                                      after connecting.  Better yet,
-                                      use Execute.
-
-    Connected() - returns 1 if the Component is connected to the server,
-                  and 0 if not.
-
-    Disconnect() - closes the connection to the server.
-
-    Execute(hostname=>string,       - Generic inner loop to handle
-	        port=>int,                connecting to the server, calling
-	        secret=>string,           Process, and reconnecting if the
-	        componentname=>string,    connection is lost.  There are four
-	        connectiontype=>string,   callbacks available that are called
-            connectattempts=>int,     at various places in the loop.
-            connectsleep=>int)          onconnect - when the component
-                                                    connects to the
-                                                    server.
-                                        onauth - when the component has
-                                                 completed its handshake
-                                                 with the server this
-                                                 will be called.
-                                        onprocess - this is the most
-                                                    inner loop and so
-                                                    gets called the most.
-                                                    Be very very careful
-                                                    what you put here
-                                                    since it can
-                                                    *DRASTICALLY* affect
-                                                    performance.
-                                        ondisconnect - when connection is
-                                                       lost.
-                                        onexit - when the function gives
-                                                 up trying to connect and
-                                                 exits.
-                                      The arguments are passed straight
-                                      on to the Connect function, except
-                                      for connectattempts and
-                                      connectsleep.  connectattempts is
-                                      the number of time that the
-                                      Component should try to connect
-                                      before giving up.  -1 means try
-                                      forever.  The default is -1.
-                                      connectsleep is the number of
-                                      seconds to sleep between each
-                                      connection attempt.
-
-    Process(integer) - takes the timeout period as an argument.  If no
-                       timeout is listed then the function blocks until
-                       a packet is received.  Otherwise it waits that
-                       number of seconds and then exits so your program
-                       can continue doing useful things.  NOTE: This is
-                       important for GUIs.  You need to leave time to
-                       process GUI commands even if you are waiting for
-                       packets.  The following are the possible return
-                       values, and what they mean:
-
-                           1   - Status ok, data received.
-                           0   - Status ok, no data received.
-                         undef - Status not ok, stop processing.
-                       
-                       IMPORTANT: You need to check the output of every
-                       Process.  If you get an undef then the connection
-                       died and you should behave accordingly.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use Carp;
-use Net::XMPP::Connection;
-use Net::Jabber::Protocol;
-use base qw( Net::XMPP::Connection Net::Jabber::Protocol );
-use vars qw( $VERSION );
-
-$VERSION = "2.0";
-
-use Net::Jabber::XDB;
-
-sub new
-{
-    srand( time() ^ ($$ + ($$ << 15)));
-
-    my $proto = shift;
-    my $self = { };
-
-    bless($self, $proto);
-    $self->init(@_);
-    
-    $self->{SERVER}->{port} = 5269;
-    $self->{SERVER}->{namespace} = "jabber:component:accept";
-    $self->{SERVER}->{allow_register} = 0;
-    
-    return $self;
-}
-
-
-sub AuthSend
-{
-    my $self = shift;
-
-    $self->_auth(@_);
-}
-
-
-sub _auth
-{
-    my $self = shift;
-    my (%args) = @_;
-    
-    $self->{STREAM}->SetCallBacks(node=>undef);
-
-    $self->Send("<handshake>".Digest::SHA1::sha1_hex($self->{SESSION}->{id}.$args{secret})."</handshake>");
-    my $handshake = $self->Process();
-
-    if (!defined($handshake) ||
-        ($#{$handshake} == -1) ||
-            (ref($handshake->[0]) ne "XML::Stream::Node") ||
-                ($handshake->[0]->get_tag() ne "handshake"))
-    {
-        $self->SetErrorCode("Bad handshake.");
-        return ("fail","Bad handshake.");
-    }
-    shift(@{$handshake});
-
-    foreach my $node (@{$handshake})
-    {
-        $self->CallBack($self->{SESSION}->{id},$node);
-    }
-
-    $self->{STREAM}->SetCallBacks(node=>sub{ $self->CallBack(@_) });
-
-    return ("ok","");
-}
-
-
-sub _connection_args
-{
-    my $self = shift;
-    my (%args) = @_;
-    
-    my %connect;
-    $connect{componentname}  = $args{componentname};
-    $connect{hostname}       = $args{hostname};
-    $connect{port}           = $args{port}           if exists($args{port});
-    $connect{connectiontype} = $args{connectiontype} if exists($args{connectiontype});
-    $connect{timeout}        = $args{connecttimeout} if exists($args{connecttimeout});
-    $connect{tls}            = $args{tls}            if exists($args{tls});
-
-    
-    return %connect;
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Data.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Data.pm	(revision cdd3959ca8040d068d22c13fc707f1c7b9033bc7)
+++ 	(revision )
@@ -1,367 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Data;
-
-=head1 NAME
-
-Net::Jabber::Data - Jabber Data Library
-
-=head1 SYNOPSIS
-
-  Net::Jabber::Data is a companion to the Net::Jabber::XDB module. It
-  provides the user a simple interface to set and retrieve all
-  parts of a Jabber XDB Data.
-
-=head1 DESCRIPTION
-
-  Net::Jabber::Data differs from the other modules in that its behavior
-  and available functions are based off of the XML namespace that is
-  set in it.  The current list of supported namespaces is:
-
-    jabber:iq:auth
-    jabber:iq:auth:0k
-    jabber:iq:register
-    jabber:iq:roster
-
-  For more information on what these namespaces are for, visit 
-  http://www.jabber.org and browse the Jabber Programmers Guide.
-
-  Each of these namespaces provide Net::Jabber::Data with the functions
-  to access the data.  By using the AUTOLOAD function the functions for
-  each namespace is used when that namespace is active.
-
-  To access a Data object you must create an XDB object and use the
-  access functions there to get to the Data.  To initialize the XDB with
-  a Jabber <xdb/> you must pass it the XML::Stream hash from the
-  Net::Jabber::Client module.
-
-    my $xdb = Net::Jabber::XDB->new(%hash);
-
-  There has been a change from the old way of handling the callbacks.
-  You no longer have to do the above yourself, a Net::Jabber::XDB
-  object is passed to the callback function for the message.  Also,
-  the first argument to the callback functions is the session ID from
-  XML::Streams.  There are some cases where you might want this
-  information, like if you created a Client that connects to two servers
-  at once, or for writing a mini server.
-
-    use Net::Jabber qw(Client);
-
-    sub xdbCB {
-      my ($sid,$XDB) = @_;
-      my $data = $XDB->GetData();
-      .
-      .
-      .
-    }
-
-  You now have access to all of the retrieval functions available for
-  that namespace.
-
-  To create a new xdb to send to the server:
-
-    use Net::Jabber;
-
-    my $xdb = Net::Jabber::XDB->new();
-    $data = $xdb->NewData("jabber:iq:auth");
-
-  Now you can call the creation functions for the Data as defined in the
-  proper namespaces.  See below for the general <data/> functions, and
-  in each data module for those functions.
-
-  For more information about the array format being passed to the
-  CallBack please read the Net::Jabber::Client documentation.
-
-=head1 METHODS
-
-=head2 Retrieval functions
-
-  GetXMLNS() - returns a string with the namespace of the data that
-               the <xdb/> contains.
-
-               $xmlns  = $XDB->GetXMLNS();
-
-  GetData() - since the behavior of this module depends on the
-               namespace, a Data object may contain Data objects.
-               This helps to leverage code reuse by making children
-               behave in the same manner.  More than likely this
-               function will never be called.
-
-               @data = GetData()
-
-=head2 Creation functions
-
-  SetXMLNS(string) - sets the xmlns of the <data/> to the string.
-
-                     $data->SetXMLNS("jabber:xdb:roster");
-
-
-In an effort to make maintaining this document easier, I am not going
-to go into full detail on each of these functions.  Rather I will
-present the functions in a list with a type in the first column to
-show what they return, or take as arguments.  Here is the list of
-types I will use:
-
-  string  - just a string
-  array   - array of strings
-  flag    - this means that the specified child exists in the
-            XML <child/> and acts like a flag.  get will return
-            0 or 1.
-  JID     - either a string or Net::Jabber::JID object.
-  objects - creates new objects, or returns an array of
-            objects.
-  special - this is a special case kind of function.  Usually
-            just by calling Set() with no arguments it will
-            default the value to a special value, like OS or time.
-            Sometimes it will modify the value you set, like
-            in jabber:xdb:version SetVersion() the function
-            adds on the Net::Jabber version to the string
-            just for advertisement purposes. =)
-  master  - this desribes a function that behaves like the
-            SetMessage() function in Net::Jabber::Message.
-            It takes a hash and sets all of the values defined,
-            and the Set returns a hash with the values that
-            are defined in the object.
-
-=head1 jabber:iq:
-
-  Type     Get               Set               Defined
-  =======  ================  ================  ==================
-
-
-=head1 jabber:iq:
-
-  Type     Get               Set               Defined
-  =======  ================  ================  ==================
-
-
-=head1 jabber:iq:
-
-  Type     Get               Set               Defined
-  =======  ================  ================  ==================
-
-
-=head1 jabber:iq:
-
-  Type     Get               Set               Defined
-  =======  ================  ================  ==================
-
-
-=head1 jabber:iq:
-
-  Type     Get               Set               Defined
-  =======  ================  ================  ==================
-
-
-=head1 CUSTOM NAMESPACES
-
-  Part of the flexability of this module is that you can define your own
-  namespace.  For more information on this topic, please read the
-  Net::Jabber::Namespaces man page.
-
-=head1 AUTHOR
-
-By Ryan Eatmon in May of 2001 for http://jabber.org..
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-use vars qw($VERSION $AUTOLOAD %FUNCTIONS %NAMESPACES);
-
-$VERSION = "2.0";
-
-sub new
-{
-    my $proto = shift;
-    my $class = ref($proto) || $proto;
-    my $self = { };
-
-    $self->{VERSION} = $VERSION;
-
-    bless($self, $proto);
-
-    $self->{DEBUGHEADER} = "Data";
-
-    $self->{DATA} = {};
-    $self->{CHILDREN} = {};
-
-    $self->{TAG} = "data";
-
-    if ("@_" ne (""))
-    {
-        if (ref($_[0]) eq "Net::Jabber::Data")
-        {
-            return $_[0];
-        }
-        else
-        {
-            $self->{TREE} = shift;
-            $self->{TAG} = $self->{TREE}->get_tag();
-            $self->ParseXMLNS();
-            $self->ParseTree();
-        }
-    }
-
-    return $self;
-}
-
-
-##############################################################################
-#
-# AUTOLOAD - This function calls the main AutoLoad function in Jabber.pm
-#
-##############################################################################
-sub AUTOLOAD
-{
-    my $self = shift;
-    &Net::Jabber::AutoLoad($self,$AUTOLOAD,@_);
-}
-
-$FUNCTIONS{XMLNS}->{Get}     = "xmlns";
-$FUNCTIONS{XMLNS}->{Set}     = ["scalar","xmlns"];
-$FUNCTIONS{XMLNS}->{Defined} = "xmlns";
-$FUNCTIONS{XMLNS}->{Hash}    = "att";
-
-$FUNCTIONS{Data}->{Get}     = "__netjabber__:children:data";
-$FUNCTIONS{Data}->{Defined} = "__netjabber__:children:data";
-
-#-----------------------------------------------------------------------------
-# jabber:iq:auth
-#-----------------------------------------------------------------------------
-$NAMESPACES{"jabber:iq:auth"}->{Password}->{Get}     = "password";
-$NAMESPACES{"jabber:iq:auth"}->{Password}->{Set}     = ["scalar","password"];
-$NAMESPACES{"jabber:iq:auth"}->{Password}->{Defined} = "password";
-$NAMESPACES{"jabber:iq:auth"}->{Password}->{Hash}    = "data";
-
-$NAMESPACES{"jabber:iq:auth"}->{Auth}->{Get} = "__netjabber__:master";
-$NAMESPACES{"jabber:iq:auth"}->{Auth}->{Set} = ["master"];
-
-$NAMESPACES{"jabber:iq:auth"}->{"__netjabber__"}->{Tag} = "password";
-
-#-----------------------------------------------------------------------------
-# jabber:iq:auth:0k
-#-----------------------------------------------------------------------------
-$NAMESPACES{"jabber:iq:auth:0k"}->{Hash}->{Get}     = "hash";
-$NAMESPACES{"jabber:iq:auth:0k"}->{Hash}->{Set}     = ["scalar","hash"];
-$NAMESPACES{"jabber:iq:auth:0k"}->{Hash}->{Defined} = "hash";
-$NAMESPACES{"jabber:iq:auth:0k"}->{Hash}->{Hash}    = "child-data";
-
-$NAMESPACES{"jabber:iq:auth:0k"}->{Sequence}->{Get}     = "sequence";
-$NAMESPACES{"jabber:iq:auth:0k"}->{Sequence}->{Set}     = ["scalar","sequence"];
-$NAMESPACES{"jabber:iq:auth:0k"}->{Sequence}->{Defined} = "sequence";
-$NAMESPACES{"jabber:iq:auth:0k"}->{Sequence}->{Hash}    = "child-data";
-
-$NAMESPACES{"jabber:iq:auth:0k"}->{Token}->{Get}     = "token";
-$NAMESPACES{"jabber:iq:auth:0k"}->{Token}->{Set}     = ["scalar","token"];
-$NAMESPACES{"jabber:iq:auth:0k"}->{Token}->{Defined} = "token";
-$NAMESPACES{"jabber:iq:auth:0k"}->{Token}->{Hash}    = "child-data";
-
-$NAMESPACES{"jabber:iq:auth:0k"}->{ZeroK}->{Get} = "__netjabber__:master";
-$NAMESPACES{"jabber:iq:auth:0k"}->{ZeroK}->{Set} = ["master"];
-
-$NAMESPACES{"jabber:iq:auth:0k"}->{"__netjabber__"}->{Tag} = "zerok";
-
-#-----------------------------------------------------------------------------
-# jabber:iq:last
-#-----------------------------------------------------------------------------
-$NAMESPACES{"jabber:iq:last"}->{Message}->{Get}     = "message";
-$NAMESPACES{"jabber:iq:last"}->{Message}->{Set}     = ["scalar","message"];
-$NAMESPACES{"jabber:iq:last"}->{Message}->{Defined} = "message";
-$NAMESPACES{"jabber:iq:last"}->{Message}->{Hash}    = "data";
-
-$NAMESPACES{"jabber:iq:last"}->{Seconds}->{Get}     = "last";
-$NAMESPACES{"jabber:iq:last"}->{Seconds}->{Set}     = ["scalar","last"];
-$NAMESPACES{"jabber:iq:last"}->{Seconds}->{Defined} = "last";
-$NAMESPACES{"jabber:iq:last"}->{Seconds}->{Hash}    = "att";
-
-$NAMESPACES{"jabber:iq:last"}->{Last}->{Get} = "__netjabber__:master";
-$NAMESPACES{"jabber:iq:last"}->{Last}->{Set} = ["master"];
-
-$NAMESPACES{"jabber:iq:last"}->{"__netjabber__"}->{Tag} = "query";
-
-#-----------------------------------------------------------------------------
-# jabber:iq:roster
-#-----------------------------------------------------------------------------
-$NAMESPACES{"jabber:iq:roster"}->{Item}->{Get}     = "";
-$NAMESPACES{"jabber:iq:roster"}->{Item}->{Set}     = ["add","Data","__netjabber__:iq:roster:item"];
-$NAMESPACES{"jabber:iq:roster"}->{Item}->{Defined} = "__netjabber__:children:data";
-$NAMESPACES{"jabber:iq:roster"}->{Item}->{Hash}    = "child-add";
-
-$NAMESPACES{"jabber:iq:roster"}->{Item}->{Add} = ["Data","__netjabber__:iq:roster:item","Item","item"];
-
-$NAMESPACES{"jabber:iq:roster"}->{Items}->{Get} = ["__netjabber__:children:data","__netjabber__:iq:roster:item"];
-
-$NAMESPACES{"jabber:iq:roster"}->{"__netjabber__"}->{Tag} = "query";
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:roster:item
-#-----------------------------------------------------------------------------
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Ask}->{Get}     = "ask";
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Ask}->{Set}     = ["scalar","ask"];
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Ask}->{Defined} = "ask";
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Ask}->{Hash}    = "att";
-
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Group}->{Get}     = "group";
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Group}->{Set}     = ["array","group"];
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Group}->{Defined} = "group";
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Group}->{Hash}    = "child-data";
-
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{JID}->{Get}     = "jid";
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{JID}->{Set}     = ["jid","jid"];
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{JID}->{Defined} = "jid";
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{JID}->{Hash}    = "att";
-
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Name}->{Get}     = "name";
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Name}->{Set}     = ["scalar","name"];
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Name}->{Defined} = "name";
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Name}->{Hash}    = "att";
-
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Subscription}->{Get}     = "subscription";
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Subscription}->{Set}     = ["scalar","subscription"];
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Subscription}->{Defined} = "subscription";
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Subscription}->{Hash}    = "att";
-
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Item}->{Get} = "__netjabber__:master";
-$NAMESPACES{"__netjabber__:iq:roster:item"}->{Item}->{Set} = ["master"];
-
-#-----------------------------------------------------------------------------
-# jabber:x:offline
-#-----------------------------------------------------------------------------
-$NAMESPACES{"jabber:x:offline"}->{Data}->{Get}     = "data";
-$NAMESPACES{"jabber:x:offline"}->{Data}->{Set}     = ["scalar","data"];
-$NAMESPACES{"jabber:x:offline"}->{Data}->{Defined} = "data";
-$NAMESPACES{"jabber:x:offline"}->{Data}->{Hash}    = "data";
-
-$NAMESPACES{"jabber:x:offline"}->{Offline}->{Get} = "__netjabber__:master";
-$NAMESPACES{"jabber:x:offline"}->{Offline}->{Set} = ["master"];
-
-$NAMESPACES{"jabber:x:offline"}->{"__netjabber__"}->{Tag} = "foo";
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Debug.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Debug.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,53 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Debug;
-
-=head1 NAME
-
-Net::Jabber::Debug - Jabber Debug Library
-
-=head1 DESCRIPTION
-
-  Net::Jabber::Debug inherits all of its methods from Net::XMPP::Debug.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use FileHandle;
-use Carp;
-use Net::XMPP::Debug;
-use base qw( Net::XMPP::Debug );
-use vars qw( $VERSION );
-
-$VERSION = "2.0";
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Dialback.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Dialback.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,118 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Dialback;
-
-=head1 NAME
-
-Net::Jabber::Dialback - Jabber Dialback Module
-
-=head1 SYNOPSIS
-
-  Net::Jabber::Dialback is a companion to the Net::Jabber::Server
-  module.  It provides the user a simple interface to set and retrieve
-  all parts of a Jabber Server Dialback.
-
-=head1 DESCRIPTION
-
-  To initialize the Dialback with a Jabber <db:*/> you must pass it
-  the XML::Stream hash.  For example:
-
-    my $dialback = Net::Jabber::Dialback->new(%hash);
-
-  You now have access to all of the retrieval functions available.
-
-  To create a new message to send to the server:
-
-    use Net::Jabber qw(Server);
-
-    $DB = Net::Jabber::Dialback->new("verify");
-    $DB = Net::Jabber::Dialback->new("result");
-
-  Please see the specific documentation for Net::Jabber::Dialback::Result
-  and Net::Jabber::Dialback::Verify.
-
-  For more information about the array format being passed to the
-  CallBack please read the Net::Jabber::Client documentation.
-
-=head1 AUTHOR
-
-By Ryan Eatmon in May of 2001 for http://jabber.org..
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-use vars qw($VERSION $AUTOLOAD %FUNCTIONS);
-
-$VERSION = "2.0";
-
-use Net::Jabber::Dialback::Result;
-($Net::Jabber::Dialback::Result::VERSION < $VERSION) &&
-  die("Net::Jabber::Dialback::Result $VERSION required--this is only version $Net::Jabber::Dialback::Result::VERSION");
-
-use Net::Jabber::Dialback::Verify;
-($Net::Jabber::Dialback::Verify::VERSION < $VERSION) &&
-  die("Net::Jabber::Dialback::Verify $VERSION required--this is only version $Net::Jabber::Dialback::Verify::VERSION");
-
-sub new
-{
-    my $proto = shift;
-    my $class = ref($proto) || $proto;
-    my $self = { };
-
-    bless($self, $proto);
-
-    if ("@_" ne (""))
-    {
-        if (ref($_[0]) =~ /Net::Jabber::Dialback/)
-        {
-            return $_[0];
-        }
-        else
-        {
-            my ($temp) = @_;
-            return Net::Jabber::Dialback::Result->new()
-                if ($temp eq "result");
-            return Net::Jabber::Dialback::Verify->new()
-                if ($temp eq "verify");
-
-            my @temp = @{$temp};
-            return Net::Jabber::Dialback::Result->new(@temp)
-                if ($temp[0] eq "db:result");
-            return Net::Jabber::Dialback::Verify->new(@temp)
-                if ($temp[0] eq "db:verify");
-        }
-    }
-    else
-    {
-        carp "You must specify either \"result\" or \"verify\" as an argument";
-    }
-}
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Dialback/Result.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Dialback/Result.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,242 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Dialback::Result;
-
-=head1 NAME
-
-Net::Jabber::Dialback::Result - Jabber Dialback Result Module
-
-=head1 SYNOPSIS
-
-  Net::Jabber::Dialback::Result is a companion to the Net::Jabber::Dialback
-  module.  It provides the user a simple interface to set and retrieve all
-  parts of a Jabber Dialback Result.
-
-=head1 DESCRIPTION
-
-  To initialize the Result with a Jabber <db:*/> you must pass it
-  the XML::Stream hash.  For example:
-
-    my $dialback = Net::Jabber::Dialback::Result->new(%hash);
-
-  There has been a change from the old way of handling the callbacks.
-  You no longer have to do the above yourself, a NJ::Dialback::Result
-  object is passed to the callback function for the message.  Also,
-  the first argument to the callback functions is the session ID from
-  XML::Streams.  There are some cases where you might want this
-  information, like if you created a Client that connects to two servers
-  at once, or for writing a mini server.
-
-    use Net::Jabber qw(Server);
-
-    sub dialbackResult {
-      my ($sid,$Result) = @_;
-      .
-      .
-      .
-    }
-
-  You now have access to all of the retrieval functions available.
-
-  To create a new dialback to send to the server:
-
-    use Net::Jabber qw(Server);
-
-    $Result = Net::Jabber::Dialback::Result->new();
-
-  Now you can call the creation functions below to populate the tag before
-  sending it.
-
-  For more information about the array format being passed to the CallBack
-  please read the Net::Jabber::Client documentation.
-
-=head2 Retrieval functions
-
-    $to         = $Result->GetTo();
-    $from       = $Result->GetFrom();
-    $type       = $Result->GetType();
-
-    $data       = $Result->GetData();
-
-    $str        = $Result->GetXML();
-    @dialback   = $Result->GetTree();
-
-=head2 Creation functions
-
-    $Result->SetResult(from=>"jabber.org",
-		       to=>"jabber.com",
-		       data=>key);
-    $Result->SetTo("jabber.org");
-    $Result->SetFrom("jabber.com");
-    $Result->SetType("valid");
-    $Result->SetData(key);
-
-=head2 Test functions
-
-    $test = $Result->DefinedTo();
-    $test = $Result->DefinedFrom();
-    $test = $Result->DefinedType();
-
-=head1 METHODS
-
-=head2 Retrieval functions
-
-  GetTo() -  returns a string with server that the <db:result/> is being
-             sent to.
-
-  GetFrom() -  returns a string with server that the <db:result/> is being
-               sent from.
-
-  GetType() - returns a string with the type <db:result/> this is.
-
-  GetData() - returns a string with the cdata of the <db:result/>.
-
-  GetXML() - returns the XML string that represents the <db:result/>.
-             This is used by the Send() function in Server.pm to send
-             this object as a Jabber Dialback Result.
-
-  GetTree() - returns an array that contains the <db:result/> tag
-              in XML::Parser::Tree format.
-
-=head2 Creation functions
-
-  SetResult(to=>string,   - set multiple fields in the <db:result/>
-            from=>string,   at one time.  This is a cumulative
-            type=>string,   and over writing action.  If you set
-            data=>string)   the "from" attribute twice, the second
-                            setting is what is used.  If you set
-                            the type, and then set the data
-                            then both will be in the <db:result/>
-                            tag.  For valid settings read the
-                            specific Set functions below.
-
-  SetTo(string) - sets the to attribute.
-
-  SetFrom(string) - sets the from attribute.
-
-  SetType(string) - sets the type attribute.  Valid settings are:
-
-                    valid
-                    invalid
-
-  SetData(string) - sets the cdata of the <db:result/>.
-
-=head2 Test functions
-
-  DefinedTo() - returns 1 if the to attribute is defined in the 
-                <db:result/>, 0 otherwise.
-
-  DefinedFrom() - returns 1 if the from attribute is defined in the 
-                  <db:result/>, 0 otherwise.
-
-  DefinedType() - returns 1 if the type attribute is defined in the 
-                  <db:result/>, 0 otherwise.
-
-=head1 AUTHOR
-
-By Ryan Eatmon in May of 2001 for http://jabber.org..
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-use vars qw($VERSION $AUTOLOAD %FUNCTIONS);
-
-$VERSION = "2.0";
-
-sub new
-{
-    my $proto = shift;
-    my $class = ref($proto) || $proto;
-    my $self = { };
-
-    $self->{VERSION} = $VERSION;
-
-    bless($self, $proto);
-
-    $self->{DEBUGHEADER} = "DB:Result";
-
-    $self->{DATA} = {};
-    $self->{CHILDREN} = {};
-
-    $self->{TAG} = "db:result";
-
-    if ("@_" ne (""))
-    {
-        if (ref($_[0]) eq "Net::Jabber::Dialback::Result")
-        {
-            return $_[0];
-        }
-        else
-        {
-            $self->{TREE} = shift;
-            $self->ParseTree();
-        }
-    }
-
-    return $self;
-}
-
-
-##############################################################################
-#
-# AUTOLOAD - This function calls the main AutoLoad function in Jabber.pm
-#
-##############################################################################
-sub AUTOLOAD
-{
-    my $self = shift;
-    &Net::Jabber::AutoLoad($self,$AUTOLOAD,@_);
-}
-
-$FUNCTIONS{From}->{Get}        = "from";
-$FUNCTIONS{From}->{Set}        = ["jid","from"];
-$FUNCTIONS{From}->{Defined}    = "from";
-$FUNCTIONS{From}->{Hash}       = "att";
-
-$FUNCTIONS{Data}->{Get}        = "data";
-$FUNCTIONS{Data}->{Set}        = ["scalar","data"];
-$FUNCTIONS{Data}->{Defined}    = "data";
-$FUNCTIONS{Data}->{Hash}       = "data";
-
-$FUNCTIONS{To}->{Get}        = "to";
-$FUNCTIONS{To}->{Set}        = ["jid","to"];
-$FUNCTIONS{To}->{Defined}    = "to";
-$FUNCTIONS{To}->{Hash}       = "att";
-
-$FUNCTIONS{Type}->{Get}        = "type";
-$FUNCTIONS{Type}->{Set}        = ["scalar","type"];
-$FUNCTIONS{Type}->{Defined}    = "type";
-$FUNCTIONS{Type}->{Hash}       = "att";
-
-$FUNCTIONS{Result}->{Get} = "__netjabber__:master";
-$FUNCTIONS{Result}->{Set} = ["master"];
-
-1;
-
Index: rl/modules/Jabber/lib/Net/Jabber/Dialback/Verify.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Dialback/Verify.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,256 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Dialback::Verify;
-
-=head1 NAME
-
-Net::Jabber::Dialback::Verify - Jabber Dialback Verify Module
-
-=head1 SYNOPSIS
-
-  Net::Jabber::Dialback::Verify is a companion to the Net::Jabber::Dialback
-  module.  It provides the user a simple interface to set and retrieve all
-  parts of a Jabber Dialback Verify.
-
-=head1 DESCRIPTION
-
-  To initialize the Verify with a Jabber <db:*/> you must pass it
-  the XML::Stream hash.  For example:
-
-    my $dialback = Net::Jabber::Dialback::Verify->new(%hash);
-
-  There has been a change from the old way of handling the callbacks.
-  You no longer have to do the above yourself, a NJ::Dialback::Verify
-  object is passed to the callback function for the message.  Also,
-  the first argument to the callback functions is the session ID from
-  XML::Streams.  There are some cases where you might want this
-  information, like if you created a Client that connects to two servers
-  at once, or for writing a mini server.
-
-    use Net::Jabber qw(Server);
-
-    sub dialbackVerify {
-      my ($sid,$Verify) = @_;
-      .
-      .
-      .
-    }
-
-  You now have access to all of the retrieval functions available.
-
-  To create a new dialback to send to the server:
-
-    use Net::Jabber qw(Server);
-
-    $Verify = Net::Jabber::Dialback::Verify->new();
-
-  Now you can call the creation functions below to populate the tag before
-  sending it.
-
-  For more information about the array format being passed to the CallBack
-  please read the Net::Jabber::Client documentation.
-
-=head2 Retrieval functions
-
-    $to         = $Verify->GetTo();
-    $from       = $Verify->GetFrom();
-    $type       = $Verify->GetType();
-    $id         = $Verify->GetID();
-    $data       = $Verify->GetData();
-
-    $str        = $Verify->GetXML();
-    @dialback   = $Verify->GetTree();
-
-=head2 Creation functions
-
-    $Verify->SetVerify(from=>"jabber.org",
-		       to=>"jabber.com",
-		       id=>id,
-		       data=>key);
-    $Verify->SetTo("jabber.org");
-    $Verify->SetFrom("jabber.com");
-    $Verify->SetType("valid");
-    $Verify->SetID(id);
-    $Verify->SetData(key);
-
-=head2 Test functions
-
-    $test = $Verify->DefinedTo();
-    $test = $Verify->DefinedFrom();
-    $test = $Verify->DefinedType();
-    $test = $Verify->DefinedID();
-
-=head1 METHODS
-
-=head2 Retrieval functions
-
-  GetTo() -  returns a string with server that the <db:verify/> is being
-             sent to.
-
-  GetFrom() -  returns a string with server that the <db:verify/> is being
-               sent from.
-
-  GetType() - returns a string with the type <db:verify/> this is.
-
-  GetID() - returns a string with the id <db:verify/> this is.
-
-  GetData() - returns a string with the cdata of the <db:verify/>.
-
-  GetXML() - returns the XML string that represents the <db:verify/>.
-             This is used by the Send() function in Server.pm to send
-             this object as a Jabber Dialback Verify.
-
-  GetTree() - returns an array that contains the <db:verify/> tag
-              in XML::Parser::Tree format.
-
-=head2 Creation functions
-
-  SetVerify(to=>string,   - set multiple fields in the <db:verify/>
-            from=>string,   at one time.  This is a cumulative
-            type=>string,   and over writing action.  If you set
-            id=>string,     the "from" attribute twice, the second
-            data=>string)   setting is what is used.  If you set
-                            the type, and then set the data
-                            then both will be in the <db:verify/>
-                            tag.  For valid settings read the
-                            specific Set functions below.
-
-  SetTo(string) - sets the to attribute.
-
-  SetFrom(string) - sets the from attribute.
-
-  SetType(string) - sets the type attribute.  Valid settings are:
-
-                    valid
-                    invalid
-
-  SetID(string) - sets the id attribute.
-
-  SetData(string) - sets the cdata of the <db:verify/>.
-
-=head2 Test functions
-
-  DefinedTo() - returns 1 if the to attribute is defined in the 
-                <db:verify/>, 0 otherwise.
-
-  DefinedFrom() - returns 1 if the from attribute is defined in the 
-                  <db:verify/>, 0 otherwise.
-
-  DefinedType() - returns 1 if the type attribute is defined in the 
-                  <db:verify/>, 0 otherwise.
-
-  DefinedID() - returns 1 if the id attribute is defined in the 
-                  <db:verify/>, 0 otherwise.
-
-=head1 AUTHOR
-
-By Ryan Eatmon in May of 2001 for http://jabber.org..
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-use vars qw($VERSION $AUTOLOAD %FUNCTIONS);
-
-$VERSION = "2.0";
-
-sub new
-{
-    my $proto = shift;
-    my $class = ref($proto) || $proto;
-    my $self = { };
-
-    $self->{VERSION} = $VERSION;
-
-    bless($self, $proto);
-
-    $self->{DEBUGHEADER} = "DB:Verify";
-
-    $self->{DATA} = {};
-    $self->{CHILDREN} = {};
-
-    $self->{TAG} = "db:verify";
-
-    if ("@_" ne (""))
-    {
-        if (ref($_[0]) eq "Net::Jabber::Dialback::Verify")
-        {
-            return $_[0];
-        }
-        else
-        {
-            $self->{TREE} = shift;
-            $self->ParseTree();
-        }
-    }
-
-    return $self;
-}
-
-
-##############################################################################
-#
-# AUTOLOAD - This function calls the main AutoLoad function in Jabber.pm
-#
-##############################################################################
-sub AUTOLOAD
-{
-    my $self = shift;
-    &Net::Jabber::AutoLoad($self,$AUTOLOAD,@_);
-}
-
-$FUNCTIONS{From}->{Get}        = "from";
-$FUNCTIONS{From}->{Set}        = ["jid","from"];
-$FUNCTIONS{From}->{Defined}    = "from";
-$FUNCTIONS{From}->{Hash}       = "att";
-
-$FUNCTIONS{Data}->{Get}        = "data";
-$FUNCTIONS{Data}->{Set}        = ["scalar","data"];
-$FUNCTIONS{Data}->{Defined}    = "data";
-$FUNCTIONS{Data}->{Hash}       = "data";
-
-$FUNCTIONS{ID}->{Get}        = "id";
-$FUNCTIONS{ID}->{Set}        = ["scalar","id"];
-$FUNCTIONS{ID}->{Defined}    = "id";
-$FUNCTIONS{ID}->{Hash}       = "child-data";
-
-$FUNCTIONS{To}->{Get}        = "to";
-$FUNCTIONS{To}->{Set}        = ["jid","to"];
-$FUNCTIONS{To}->{Defined}    = "to";
-$FUNCTIONS{To}->{Hash}       = "att";
-
-$FUNCTIONS{Type}->{Get}        = "type";
-$FUNCTIONS{Type}->{Set}        = ["scalar","type"];
-$FUNCTIONS{Type}->{Defined}    = "type";
-$FUNCTIONS{Type}->{Hash}       = "att";
-
-$FUNCTIONS{Verify}->{Get} = "__netjabber__:master";
-$FUNCTIONS{Verify}->{Set} = ["master"];
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/IQ.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/IQ.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,69 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::IQ;
-
-=head1 NAME
-
-Net::Jabber::IQ - Jabber Info/Query Library
-
-=head1 DESCRIPTION
-
-  Net::Jabber::IQ inherits all of its methods from Net::XMPP::IQ.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-use Net::XMPP::IQ;
-use base qw( Net::XMPP::IQ );
-
-use vars qw( $VERSION );
-
-$VERSION = "2.0";
-
-sub GetQuery     { my $self = shift; $self->GetChild(@_);     }
-sub DefinedQuery { my $self = shift; $self->DefinedChild(@_); }
-sub NewQuery     { my $self = shift; $self->RemoveFirstChild(); $self->NewFirstChild(@_);     }
-sub AddQuery     { my $self = shift; $self->AddChild(@_);     } 
-sub RemoveQuery  { my $self = shift; $self->RemoveFirstChild(@_);  }
-
-sub GetX     { my $self = shift; $self->GetChild(@_);     }
-sub DefinedX { my $self = shift; $self->DefinedChild(@_); }
-sub NewX     { my $self = shift; $self->NewChild(@_);     }
-sub AddX     { my $self = shift; $self->AddChild(@_);     } 
-sub RemoveX  { my $self = shift; $self->RemoveChild(@_);  }
-
-sub _new_jid    { my $self = shift; return Net::Jabber::JID->new(@_);    }
-sub _new_packet { my $self = shift; return Net::Jabber::Stanza->new(@_); }
-sub _iq         { my $self = shift; return Net::Jabber::IQ->new(@_);     }
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/JID.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/JID.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,54 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::JID;
-
-=head1 NAME
-
-Net::Jabber::JID - Jabber JID Module
-
-=head1 DESCRIPTION
-
-  Net::Jabber::JID inherits all of its methods from Net::XMPP::JID.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-
-use Net::XMPP::JID;
-use base qw( Net::XMPP::JID );
-
-use vars qw($VERSION);
-
-$VERSION = "2.0";
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Key.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Key.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,176 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Key;
-
-=head1 NAME
-
-Net::Jabber::Key - Jabber Key Library
-
-=head1 SYNOPSIS
-
-  Net::Jabber::Key is a module that provides a developer easy access
-  to generating, caching, and comparing keys.
-
-=head1 DESCRIPTION
-
-  Key.pm is a helper module for the Net::Jabber::Transport.  When the
-  Transport talks to a Client it sends a key and expects to get that
-  key back from the Client.  This module provides an API to generate,
-  cache, and then compare the key send from the Client.
-
-=head2 Basic Functions
-
-    $Key = Net::Jabber::Key->new();
-
-    $key = $Key->Generate();
-
-    $key = $Key->Create("bob\@jabber.org");
-
-    $test = $Key->Compare("bob\@jabber.org","some key");
-
-=head1 METHODS
-
-=head2 Basic Functions
-
-    new(debug=>string,       - creates the Key object.  debug should
-        debugfh=>FileHandle,   be set to the path for the debug
-        debuglevel=>integer)   log to be written.  If set to "stdout" 
-                               then the debug will go there.  Also, you
-                               can specify a filehandle that already
-                               exists and use that.  debuglevel controls
-                               the amount of debug.  0 is none, 1 is
-                               normal, 2 is all.
-
-    Generate() - returns a key in Digest SHA1 form based on the current
-                 time and the PID.
-
-    Create(cacheString) - generates a key and caches it with the key 
-                          of cacheString.  Create returns the key.
-
-    Compare(cacheString, - compares the key stored in the cache under
-            keyString)     cacheString with the keyString.  Returns 1
-                           if they match, and 0 otherwise.
-
-=head1 AUTHOR
-
-By Ryan Eatmon in May of 2000 for http://jabber.org.
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use FileHandle;
-use vars qw($VERSION);
-
-$VERSION = "2.0";
-
-sub new
-{
-    srand( time() ^ ($$ + ($$ << 15)));
-
-    my $proto = shift;
-    my $self = { };
-
-    $self->{DEBUG} = Net::Jabber::Debug->new(usedefault=>1,
-                                             header=>"NJ::Key");
-
-    $self->{VERSION} = $VERSION;
-    
-    $self->{CACHE} = {};
-
-    if (eval "require Digest::SHA1")
-    {
-        $self->{DIGEST} = 1;
-        Digest::SHA1->import(qw(sha1 sha1_hex sha1_base64));
-    }
-    else
-    {
-        print "ERROR:  You cannot use Key.pm unless you have Digest::SHA1 installed.\n";
-        exit(0);
-    }
-
-    bless($self, $proto);
-    return $self;
-}
-
-
-###########################################################################
-#
-# Generate - returns a random string based on the PID and time and a 
-#            random number.  Then it creates an SHA1 Digest of that 
-#            string and returns it.
-#
-###########################################################################
-sub Generate
-{
-    my $self = shift;
-
-    my $string = $$.time.rand(1000000);
-    $string = Digest::SHA1::sha1_hex($string);
-    $self->{DEBUG}->Log1("Generate: key($string)");
-    return $string;
-}
-
-
-##############################################################################
-#
-# Create - Creates a key and caches the id for comparison later.
-#
-##############################################################################
-sub Create
-{
-    my $self = shift;
-    my ($cacheString) = @_;
-
-    $self->{DEBUG}->Log1("Create: cacheString($cacheString)");
-    my $key = $self->Generate();
-    $self->{DEBUG}->Log1("Create: key($key)");
-    $self->{CACHE}->{$cacheString} = $key;
-    return $key;
-}
-
-
-##############################################################################
-#
-# Compare - Compares the key with the key in the cache.
-#
-##############################################################################
-sub Compare
-{
-    my $self = shift;
-    my ($cacheString,$key) = @_;
-
-    $self->{DEBUG}->Log1("Compare: cacheString($cacheString) key($key)");
-    my $cacheKey = delete($self->{CACHE}->{$cacheString});
-    $self->{DEBUG}->Log1("Compare: cacheKey($cacheKey)");
-    return ($key eq $cacheKey);
-}
-
-
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Log.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Log.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,303 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Log;
-
-=head1 NAME
-
-Net::Jabber::Log - Jabber Log Module
-
-=head1 SYNOPSIS
-
-  Net::Jabber::Log is a companion to the Net::Jabber module.
-  It provides the user a simple interface to set and retrieve all 
-  parts of a Jabber Log.
-
-=head1 DESCRIPTION
-
-  To initialize the Log with a Jabber <log/> you must pass it the 
-  XML::Parser Tree array.  For example:
-
-    my $log = Net::Jabber::Log->new(@tree);
-
-  There has been a change from the old way of handling the callbacks.
-  You no longer have to do the above, a Net::Jabber::Log object is passed
-  to the callback function for the log:
-
-    use Net::Jabber;
-
-    sub log {
-      my ($Log) = @_;
-      .
-      .
-      .
-    }
-
-  You now have access to all of the retrieval functions available.
-
-  To create a new log to send to the server:
-
-    use Net::Jabber;
-
-    $Log = Net::Jabber::Log->new();
-
-  Now you can call the creation functions below to populate the tag before
-  sending it.
-
-  For more information about the array format being passed to the CallBack
-  please read the Net::Jabber::Client documentation.
-
-=head2 Retrieval functions
-
-    $from       = $Log->GetFrom();
-    $fromJID    = $Log->GetFrom("jid");
-    $type       = $Log->GetType();
-    $data       = $Log->GetData();
-
-    $str        = $Log->GetXML();
-    @log        = $Log->GetTree();
-
-=head2 Creation functions
-
-    $Log->SetLog(type=>"error",
-		 from=>"users.jabber.org",
-		 data=>"The moon is full... I can't run anymore.");
-    $Log->SetFrom("foo.jabber.org");
-    $Log->SetType("warn");
-    $Log->SetData("I can't find a config file.  Using defaults.");
-
-=head2 Test functions
-
-    $test = $Log->DefinedFrom();
-    $test = $Log->DefinedType();
-
-=head1 METHODS
-
-=head2 Retrieval functions
-
-  GetFrom()      -  returns either a string with the Jabber Identifier,
-  GetFrom("jid")    or a Net::Jabber::JID object for the person who
-                    sent the <log/>.  To get the JID object set 
-                    the string to "jid", otherwise leave blank for the 
-                    text string.
-
-  GetType() - returns a string with the type <log/> this is.
-
-  GetData() - returns a string with the cdata of the <log/>.
-
-  GetXML() - returns the XML string that represents the <log/>.
-             This is used by the Send() function in Client.pm to send
-             this object as a Jabber Log.
-
-  GetTree() - returns an array that contains the <log/> tag
-              in XML::Parser Tree format.
-
-=head2 Creation functions
-
-  SetLog(from=>string|JID, - set multiple fields in the <log/>
-         type=>string,       at one time.  This is a cumulative
-         data=>string)       and over writing action.  If you set
-                             the "from" attribute twice, the second
-                             setting is what is used.  If you set
-                             the type, and then set the data
-                             then both will be in the <log/>
-                             tag.  For valid settings read the
-                             specific Set functions below.
-
-  SetFrom(string) - sets the from attribute.  You can either pass a string
-  SetFrom(JID)      or a JID object.  They must be valid Jabber 
-                    Identifiers or the server will return an error log.
-                    (ie.  jabber:bob@jabber.org/Silent Bob, etc...)
-
-  SetType(string) - sets the type attribute.  Valid settings are:
-
-                    notice     general logging
-                    warn       warning
-                    alert      critical error (can still run but not 
-                               correctly)
-                    error      fatal error (cannot run anymore)
-
-  SetData(string) - sets the cdata of the <log/>.
-
-=head2 Test functions
-
-  DefinedFrom() - returns 1 if the from attribute is defined in the 
-                  <log/>, 0 otherwise.
-
-  DefinedType() - returns 1 if the type attribute is defined in the 
-                  <log/>, 0 otherwise.
-
-=head1 AUTHOR
-
-By Ryan Eatmon in May of 2000 for http://jabber.org..
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-use vars qw($VERSION $AUTOLOAD %FUNCTIONS);
-
-$VERSION = "2.0";
-
-sub new
-{
-    my $proto = shift;
-    my $class = ref($proto) || $proto;
-    my $self = { };
-    
-    $self->{VERSION} = $VERSION;
-    $self->{TIMESTAMP} = &Net::Jabber::GetTimeStamp("local");
-
-    bless($self, $proto);
-
-    $self->{DEBUG} = Net::Jabber::Debug->new(usedefault=>1,
-                                             header=>"NJ::Log");
-
-    if ("@_" ne (""))
-    {
-        if (ref($_[0]) eq "Net::Jabber::Log")
-        {
-            return $_[0];
-        }
-        else
-        {
-            my @temp = @_;
-            $self->{LOG} = \@temp;
-        }
-    }
-    else
-    {
-        $self->{LOG} = [ "log" , [{}]];
-    }
-
-    return $self;
-}
-
-
-##############################################################################
-#
-# AUTOLOAD - This function calls the delegate with the appropriate function
-#            name and argument list.
-#
-##############################################################################
-sub AUTOLOAD
-{
-    my $self = shift;
-    return if ($AUTOLOAD =~ /::DESTROY$/);
-    $AUTOLOAD =~ s/^.*:://;
-    my ($type,$value) = ($AUTOLOAD =~ /^(Get|Set|Defined)(.*)$/);
-    $type = "" unless defined($type);
-    my $treeName = "LOG";
-    
-    return "log" if ($AUTOLOAD eq "GetTag");
-    return &XML::Stream::BuildXML(@{$self->{$treeName}}) if ($AUTOLOAD eq "GetXML");
-    return @{$self->{$treeName}} if ($AUTOLOAD eq "GetTree");
-    return &Net::Jabber::Get($self,$self,$value,$treeName,$FUNCTIONS{get}->{$value},@_) if ($type eq "Get");
-    return &Net::Jabber::Set($self,$self,$value,$treeName,$FUNCTIONS{set}->{$value},@_) if ($type eq "Set");
-    return &Net::Jabber::Defined($self,$self,$value,$treeName,$FUNCTIONS{defined}->{$value},@_) if ($type eq "Defined");
-    return &Net::Jabber::debug($self,$treeName) if ($AUTOLOAD eq "debug");
-    &Net::Jabber::MissingFunction($self,$AUTOLOAD);
-}
-
-
-$FUNCTIONS{get}->{From} = ["value","","from"];
-$FUNCTIONS{get}->{Type} = ["value","","type"];
-$FUNCTIONS{get}->{Data} = ["value","",""];
-
-$FUNCTIONS{set}->{Type} = ["single","","","type","*"];
-$FUNCTIONS{set}->{Data} = ["single","","*","",""];
-
-$FUNCTIONS{defined}->{From} = ["existence","","from"];
-$FUNCTIONS{defined}->{Type} = ["existence","","type"];
-
-
-##############################################################################
-#
-# GetXML -  returns the XML string that represents the data in the XML::Parser
-#          Tree.
-#
-##############################################################################
-sub GetXML
-{
-    my $self = shift;
-    $self->MergeX();
-    return &XML::Stream::BuildXML(@{$self->{LOG}});
-}
-
-
-##############################################################################
-#
-# GetTree - returns the XML::Parser Tree that is stored in the guts of
-#              the object.
-#
-##############################################################################
-sub GetTree
-{
-    my $self = shift;
-    $self->MergeX();
-    return %{$self->{LOG}};
-}
-
-
-##############################################################################
-#
-# SetLog - takes a hash of all of the things you can set on a <log/>
-#              and sets each one.
-#
-##############################################################################
-sub SetLog
-{
-    my $self = shift;
-    my %log;
-    while($#_ >= 0) { $log{ lc pop(@_) } = pop(@_); }
-
-    $self->SetFrom($log{from}) if exists($log{from});
-    $self->SetType($log{type}) if exists($log{type});
-    $self->SetData($log{data}) if exists($log{data});
-}
-
-
-##############################################################################
-#
-# SetFrom - sets the from attribute in the <log/>
-#
-##############################################################################
-sub SetFrom
-{
-    my $self = shift;
-    my ($from) = @_;
-    if (ref($from) eq "Net::Jabber::JID")
-    {
-        $from = $from->GetJID("full");
-    }
-    return unless ($from ne "");
-    &XML::Stream::SetXMLData("single",$self->{LOG},"","",{from=>$from});
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/MUC.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/MUC.pm	(revision 892568bf6e3ceea8724cef719078e5f6c2455b16)
+++ 	(revision )
@@ -1,258 +1,0 @@
-package Net::Jabber::MUC;
-
-=head1 NAME
-
-Net::Jabber::Roster - Jabber Multi-User Chat Object
-
-=head1 SYNOPSIS
-
-  my $Client = Net::XMPP:Client->new(...);
-
-  my $muc = Net::Jabber::MUC(connection => $Client,
-                             room   => "jabber",
-                             server => "conference.jabber.org",
-                             nick   => "nick");
-   or
-  my $muc = Net::Jabber::MUC(connection => $Client,
-                             jid    =>  'jabber@conference.jabber.org/nick');
-
-
-  $muc->Join(Password => "secret", History => {MaxChars => 0});
-
-  if( $muc->Contains($JID) ) { ... }
-  my @jids = $muc->Presence();
-
-  $muc->Leave();
-
-=head1 DESCRIPTION
-
-The MUC object seeks to provide a simple API for interfacing with
-Jabber multi-user chats (as defined in XEP 0045). It automatically
-registers callbacks with the connections to keep track of presence in
-the MUC.
-
-
-=cut
-
-use strict;
-use warnings;
-
-sub new {
-    my $class = shift;
-    my $self = { };
-
-    my %args;
-    while($#_ >= 0) { $args{ lc(pop(@_)) } = pop(@_); }
-
-    if (!exists($args{connection}) ||
-        !$args{connection}->isa("Net::XMPP::Connection"))
-    {
-        croak("You must pass Net::Jabber::MUC a valid connection object.");
-    }
-
-    if($args{jid}) {
-        my $jid = $args{jid};
-        $jid = Net::Jabber::JID->new($jid) unless UNIVERSAL::isa($jid, 'Net::Jabber::JID');
-        $args{jid} = $jid;
-    } elsif($args{room} && $args{server} && $args{nick}) {
-        $args{jid} = New::Jabber::JID->new($args{room}."@".$args{server}."/".$args{nick});
-    } else {
-        croak("You must specify either a jid or room,server,nick.");
-    }
-
-    $self->{CONNECTION} = $args{connection};
-    $self->{JID} = $args{jid};
-    $self->{PRESENCE} = { };
-    $self->{ANONYMOUS} = 1;
-
-    bless($self, $class);
-
-    $self->_init;
-
-    return $self;
-}
-
-=head2 JID
-
-Returns the Net::Jabber::JID object representing this MUC's JID
-(room@host/nick)
-
-=cut
-
-sub JID {
-    my $self = shift;
-    return $self->{JID};
-}
-
-=head2 BaseJID
-
-Returns the base JID of this MUC as a string
-
-=cut
-
-sub BaseJID {
-    my $self = shift;
-    return $self->JID->GetJID('base');
-}
-
-
-=head2 _init
-
-Add callbacks to our connection to receive the appropriate packets.
-
-=cut
-
-sub _init {
-    my $self = shift;
-
-    $self->{CONNECTION}->SetXPathCallBacks('/presence' => sub { $self->_handler(@_) });
-}
-
-=head2 Join
-
-Sends the appropriate presence packet to join us to the MUC.
-
-=cut
-
-sub Join {
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc(pop(@_)) } = pop(@_); }
-
-    my $presence = Net::Jabber::Presence->new;
-    $presence->SetTo($self->JID);
-    my $x = $presence->NewChild('http://jabber.org/protocol/muc');
-    if($args{password}) {
-        $x->SetPassword($args{password});
-    }
-    if($args{history}) {
-        my $h = $x->AddHistory();
-        if($args{history}{MaxChars}) {
-            $h->SetMaxChars($args{history}{MaxChars});
-        } elsif($args{history}{MaxStanzas}) {
-            $h->SetMaxStanzas($args{history}{MaxStanzas});
-        } elsif($args{history}{Seconds}) {
-            $h->SetSeconds($args{history}{Seconds});
-        } elsif($args{history}{Since}) {
-            $h->SetSince($args{history}{Since});
-        }
-    }
-    $self->{CONNECTION}->Send($presence);
-}
-
-=head2 Leave
-
-Leaves the MUC
-
-=cut
-
-sub Leave {
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc(pop(@_)) } = pop(@_); }
-
-    $self->{CONNECTION}->PresenceSend(to => $self->JID, type => 'unavailable');
-    $self->{PRESENCE} = {};
-}
-
-
-=head2 _handler
-
-Central dispatch point for handling incoming packets.
-
-=cut
-
-sub _handler {
-    my $self = shift;
-    my $sid = shift;
-    my $packet = shift;
-
-    $self->_handlePresence($packet) if $packet->GetTag() eq "presence";
-}
-
-=head2 handlePresence
-
-Handle an incoming presence packet.
-
-=cut
-
-sub _handlePresence {
-    my $self = shift;
-    my $presence = shift;
-
-    my $type = $presence->GetType() || "available";
-    my $from = Net::Jabber::JID->new($presence->GetFrom());
-
-    return unless $from->GetJID('base') eq $self->BaseJID;
-
-    if($type eq 'unavailable') {
-        delete $self->{PRESENCE}->{$from->GetJID('full')};
-    } elsif($type eq 'available') {
-        $self->{PRESENCE}->{$from->GetJID('full')} = {ROOMNICK => $from};
-        my $x = $presence->GetX('http://jabber.org/protocol/muc#user');
-        if($x && $x->DefinedItem()) {
-            my $item = $x->GetItem();
-            if($item->DefinedJID()) {
-                $self->{PRESENCE}->{$from->GetJID('full')}->{FULLJID} = $item->GetJID();
-                $self->{ANONYMOUS} = 0;
-            }
-        }
-    }
-}
-
-=head2 Contains JID
-
-Returns true iff the MUC contains the specified full JID
-
-=cut
-
-sub Contains {
-    my $self = shift;
-    my $jid = shift;
-
-    $jid = $jid->GetJID('full') if UNIVERSAL::isa($jid, 'Net::Jabber::JID');
-
-    return exists $self->{PRESENCE}->{$jid};
-}
-
-=head2 GetFullJID roomjid
-
-Given the roomnick of a user in the MUC, return their full NIC if the
-MUC makes it available. If the MUC is anonymous or the user does not
-exist in the MUC, return undef.
-
-=cut
-
-sub GetFullJID {
-    my $self = shift;
-    my $jid = shift;
-
-    $jid = $jid->GetJID('full') if UNIVERSAL::isa($jid, 'Net::Jabber::JID');
-    my $pres = $self->{PRESENCE}->{$jid};
-    return unless $pres;
-    return $pres->{FULLJID};
-}
-
-=head2 Presence
-
-Returns a list of JIDS in the MUC, as Net::Jabber::JID objects
-
-=cut
-
-sub Presence {
-    my $self = shift;
-    return map {$_->{ROOMNICK}} values %{$self->{PRESENCE}};
-}
-
-=head2 Anonymous
-
-Returns true if the MUC is anonymous (hides participants real JIDs)
-
-=cut
-
-sub Anonymous {
-    my $self = shift;
-    return $self->{ANONYMOUS};
-}
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Message.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Message.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,64 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Message;
-
-=head1 NAME
-
-Net::Jabber::Message - Jabber Message Module
-
-=head1 DESCRIPTION
-
-  Net::Jabber::Message inherits all of its methods from
-  Net::XMPP::Message.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software, you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-use Net::XMPP::Message;
-use base qw( Net::XMPP::Message );
-
-use vars qw( $VERSION );
-
-$VERSION = "2.0";
-
-sub GetX     { my $self = shift; $self->GetChild(@_);    } 
-sub DefinedX { my $self = shift; $self->DefinedChild(@_); }
-sub NewX     { my $self = shift; $self->NewChild(@_);    }
-sub AddX     { my $self = shift; $self->AddChild(@_);    } 
-sub RemoveX  { my $self = shift; $self->RemoveChild(@_); }
-
-sub _new_jid    { my $self = shift; return Net::Jabber::JID->new(@_);     }
-sub _new_packet { my $self = shift; return Net::Jabber::Stanza->new(@_);  }
-sub _message    { my $self = shift; return Net::Jabber::Message->new(@_); }
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Namespaces.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Namespaces.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,2241 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Namespaces;
-
-=head1 NAME
-
-Net::Jabber::Namespaces
-
-=head1 SYNOPSIS
-
-  Net::Jabber::Namespaces is a pure documentation
-  module.  It provides no code for execution, just
-  documentation on how the Net::Jabber modules handle
-  namespaces.
-
-=head1 DESCRIPTION
-
-  Net::Jabber::Namespaces is fully documented by Net::XMPP::Namesapces.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use Net::XMPP::Namespaces;
-
-$Net::XMPP::Namespaces::SKIPNS{'__netjabber__'} = 1;
-
-#-----------------------------------------------------------------------------
-# jabber:iq:agent
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:agent',
-            tag   => 'query',
-            xpath => {
-                      Agents      => {
-                                      type => 'flag',
-                                      path => 'agents',
-                                     },
-                      Description => { path => 'description/text()' },
-                      JID         => {
-                                      type => 'jid',
-                                      path => '@jid',
-                                     },
-                      Name        => { path => 'name/text()' },
-                      GroupChat   => {
-                                      type => 'flag',
-                                      path => 'groupchat',
-                                     },
-                      Register    => {
-                                      type => 'flag',
-                                      path => 'register',
-                                     },
-                      Search      => {
-                                      type => 'flag',
-                                      path => 'search',
-                                     },
-                      Service     => { path => 'service/text()' },
-                      Transport   => { path => 'transport/text()' },
-                      URL         => { path => 'url/text()' },
-                      Agent       => { type => 'master' },
-                     },
-            docs  => {
-                      module     => 'Net::Jabber',
-                      deprecated => 1,
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:agents
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:agents',
-            tag   => 'query',
-            xpath => {
-                      Agent  => {
-                                 type  => 'child',
-                                 path  => 'agent',
-                                 child => {
-                                           ns         => 'jabber:iq:agent',
-                                           skip_xmlns => 1,
-                                          },
-                                 calls => [ 'Add' ],
-                                },
-                      Agents => {
-                                 type  => 'child',
-                                 path  => 'agent',
-                                 child => { ns => 'jabber:iq:agent' },
-                                },
-                     },
-            docs  => {
-                      module     => 'Net::Jabber',
-                      deprecated => 1,
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:autoupdate
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:autoupdate',
-            tag   => 'query',
-            xpath => {
-                      Beta     => {
-                                   type  => 'child',
-                                   path  => 'beta',
-                                   child => { ns => '__netjabber__:iq:autoupdate:release' },
-                                   calls => [ 'Add' ],
-                                  },
-                      Dev      => {
-                                   type  => 'child',
-                                   path  => 'dev',
-                                   child => { ns => '__netjabber__:iq:autoupdate:release' },
-                                   calls => [ 'Add' ],
-                                  },
-                      Release  => {
-                                   type  => 'child',
-                                   path  => 'release',
-                                   child => { ns => '__netjabber__:iq:autoupdate:release' },
-                                   calls => [ 'Add' ],
-                                  },
-                      Releases => {
-                                   type  => 'child',
-                                   path  => '*',
-                                   child => { ns => '__netjabber__:iq:autoupdate:release' },
-                                  },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:autoupdate:release
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:autoupdate:release',
-            xpath => {
-                      Desc     => { path => 'desc/text()' },
-                      Priority => { path => '@priority' },
-                      URL      => { path => 'url/text()' },
-                      Version  => { path => 'version/text()' },
-                      Release  => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:iq:autoupdate - release objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:browse
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:browse',
-            tag   => 'item',
-            xpath => {
-                      Category => { path => '@category' },
-                      Item     => {
-                                   type  => 'child',
-                                   path  => '*[name() != "ns"]',
-                                   child => { ns           => '__netjabber__:iq:browse:item',
-                                              specify_name => 1,
-                                              tag          => 'item',
-                                            },
-                                   calls => [ 'Add' ],
-                                  },
-                      Items    => {
-                                   type  => 'child',
-                                   path  => '*[name() != "ns"]',
-                                   child => { ns => '__netjabber__:iq:browse:item' },
-                                  },
-                      JID      => {
-                                   type => 'jid',
-                                   path => '@jid',
-                                  },
-                      Name     => { path => '@name' },
-                      NS       => {
-                                   type => 'array',
-                                   path => 'ns/text()',
-                                  },
-                      Type     => { path => '@type' },
-                      Browse   => { type => 'master' }
-                     },
-            docs  => {
-                      module     => 'Net::Jabber',
-                      deprecated => 1,
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:browse:item
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:browse:item',
-            tag   => 'item',
-            xpath => {
-                      Category => { path => '@category' },
-                      Item     => {
-                                   type  => 'child',
-                                   path  => '*[name() != "ns"]',
-                                   child => { ns           => '__netjabber__:iq:browse:item',
-                                              specify_name => 1,
-                                              tag          => 'item',
-                                            },
-                                   calls => [ 'Add' ],
-                                  },
-                      Items    => {
-                                   type  => 'child',
-                                   path  => '*[name() != "ns"]',
-                                   child => { ns => '__netjabber__:iq:browse:item' },
-                                  },
-                      JID      => {
-                                   type => 'jid',
-                                   path => '@jid',
-                                  },
-                      Name     => { path => '@name' },
-                      NS       => {
-                                   type => 'array',
-                                   path => 'ns/text()',
-                                  },
-                      Type     => { path => '@type' },
-                      Browse   => { type => 'master' }
-                     },
-            docs  => {
-                      module     => 'Net::Jabber',
-                      name       => 'jabber:iq:browse - item objects',
-                      deprecated => 1,
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:conference
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:conference',
-            tag   => 'query',
-            xpath => {
-                      ID         => { path => 'id/text()' },
-                      Name       => { path => 'name/text()' },
-                      Nick       => { path => 'nick/text()' },
-                      Privacy    => {
-                                     type => 'flag',
-                                     path => 'privacy',
-                                    },
-                      Secret     => { path => 'secret/text()' },
-                      Conference => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:filter
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:filter',
-            tag   => 'query',
-            xpath => {
-                      Rule  => {
-                                type  => 'child',
-                                path  => 'rule',
-                                child => { ns => '__netjabber__:iq:filter:rule' },
-                                calls => [ 'Add' ],
-                               },
-                      Rules => {
-                                type  => 'child',
-                                path  => 'rule',
-                                child => { ns => '__netjabber__:iq:filter:rule' },
-                               },
-                     },
-            docs  => {
-                      module     => 'Net::Jabber',
-                      deprecated => 1,
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:filter:rule
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns     => '__netjabber__:iq:filter:rule',
-            xpath  => {
-                       Body        => { path => 'body/text()' },
-                       Continued   => { path => 'continued/text()' },
-                       Drop        => { path => 'drop/text()' },
-                       Edit        => { path => 'edit/text()' },
-                       Error       => { path => 'error/text()' },
-                       From        => { path => 'from/text()' },
-                       Offline     => { path => 'offline/text()' },
-                       Reply       => { path => 'reply/text()' },
-                       Resource    => { path => 'resource/text()' },
-                       Show        => { path => 'show/text()' },
-                       Size        => { path => 'size/text()' },
-                       Subject     => { path => 'subject/text()' },
-                       Time        => { path => 'time/text()' },
-                       Type        => { path => 'type/text()' },
-                       Unavailable => { path => 'unavailable/text()' },
-                       Rule        => { type => 'master' },
-                      },
-            docs  => {
-                      module     => 'Net::Jabber',
-                      name       => 'jabber:iq:filter - rule objects',
-                      deprecated => 1,
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:gateway
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:gateway',
-            tag   => 'query',
-            xpath => {
-                      Desc    => { path => 'desc/text()' },
-                      JID     => {
-                                  type => 'jid',
-                                  path => 'jid/text()',
-                                 },
-                      Prompt  => { path => 'prompt/text()' },
-                      Gateway => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:last
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:last',
-            tag   => 'query',
-            xpath => {
-                      Message => { path => 'text()' },
-                      Seconds => { path => '@seconds' },
-                      Last    => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:oob
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:oob',
-            tag   => 'query',
-            xpath => {
-                      Desc => { path => 'desc/text()' },
-                      URL  => { path => 'url/text()' },
-                      Oob  => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:pass
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:pass',
-            tag   => 'query',
-            xpath => {
-                      Client     => { path => 'client/text()' },
-                      ClientPort => { path => 'client/@port' },
-                      Close      => {
-                                     type => 'flag',
-                                     path => 'close',
-                                    },
-                      Expire     => { path => 'expire/text()' },
-                      OneShot    => {
-                                     type => 'flag',
-                                     path => 'oneshot',
-                                    },
-                      Proxy      => { path => 'proxy/text()' },
-                      ProxyPort  => { path => 'proxy/@port' },
-                      Server     => { path => 'server/text()' },
-                      ServerPort => { path => 'server/@port' },
-                      Pass       => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:rpc
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:rpc',
-            tag   => 'query',
-            xpath => {
-                      MethodCall     => {
-                                         type  => 'child',
-                                         path  => 'methodCall',
-                                         child => { ns => '__netjabber__:iq:rpc:methodCall' },
-                                         calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                        },
-                      MethodResponse => {
-                                         type  => 'child',
-                                         path  => 'methodResponse',
-                                         child => { ns => '__netjabber__:iq:rpc:methodResponse' },
-                                         calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                        },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:rpc:methodCall
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:rpc:methodCall',
-            xpath => {
-                      MethodName => { path => 'methodName/text()' },
-                      Params     => {
-                                     type  => 'child',
-                                     path  => 'params',
-                                     child => { ns => '__netjabber__:iq:rpc:params' },
-                                     calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                     },
-                      MethodCall => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:iq:rpc - methodCall objects',
-                     },
-
-           );
-}
-       
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:rpc:methodResponse
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:rpc:methodResponse',
-            xpath => {
-                      Fault  => {
-                                 type  => 'child',
-                                 path  => 'fault',
-                                 child => { ns => '__netjabber__:iq:rpc:fault' },
-                                 calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                },
-                      Params => {
-                                 type  => 'child',
-                                 path  => 'params',
-                                 child => { ns => '__netjabber__:iq:rpc:params' },
-                                 calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:iq:rpc - methodResponse objects',
-                     },
-
-           );
-}
-       
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:rpc:fault
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    =>'__netjabber__:iq:rpc:fault',
-            xpath => {
-                      Value => {
-                                type  => 'child',
-                                path  => 'value',
-                                child => { ns => '__netjabber__:iq:rpc:value' },
-                                calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                               },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:iq:rpc - fault objects',
-                     },
-
-           );
-}
-       
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:rpc:params
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:rpc:params',
-            xpath => {
-                      Param  => {
-                                 type  => 'child',
-                                 path  => 'param',
-                                 child => { ns => '__netjabber__:iq:rpc:param' },
-                                 calls => [ 'Add' ],
-                                },
-                      Params => {
-                                 type  => 'child',
-                                 path  => 'param',
-                                 child => { ns => '__netjabber__:iq:rpc:param' },
-                                },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:iq:rpc - params objects',
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:rpc:param
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    =>'__netjabber__:iq:rpc:param',
-            xpath => {
-                      Value => {
-                                type  => 'child',
-                                path  => 'value',
-                                child => { ns => '__netjabber__:iq:rpc:value' },
-                                calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                               },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:iq:rpc - param objects',
-                     },
-           );
-}
-       
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:rpc:value
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:rpc:value',
-            xpath => {
-                      Array    => {
-                                   type  => 'child',
-                                   path  => 'array',
-                                   child => { ns => '__netjabber__:iq:rpc:array' },
-                                   calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                  },
-                      Base64   => { path => 'base64/text()' },
-                      Boolean  => { path => 'boolean/text()' },
-                      DateTime => { path => 'dateTime.iso8601/text()' },
-                      Double   => { path => 'double/text()' },
-                      I4       => { path => 'i4/text()' },
-                      Int      => { path => 'int/text()' },
-                      String   => { path => 'string/text()' },
-                      Struct   => {
-                                   type  => 'child',
-                                   path  => 'struct',
-                                   child => { ns => '__netjabber__:iq:rpc:struct' },
-                                   calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                  },
-                      Value    => { path => 'value/text()' },
-                      RPCValue => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:iq:rpc - value objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:rpc:struct
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:rpc:struct',
-            xpath => {
-                      Member   => {
-                                  type  => 'child',
-                                  path  => 'member',
-                                  child => { ns => '__netjabber__:iq:rpc:struct:member' },
-                                  calls => [ 'Add' ],
-                                 },
-                      Members => {
-                                  type  => 'child',
-                                  path  => 'member',
-                                  child => { ns => '__netjabber__:iq:rpc:struct:member' },
-                                 },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:iq:rpc - struct objects',
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:rpc:struct:member
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    =>'__netjabber__:iq:rpc:struct:member',
-            xpath => {
-                      Name   => { path => 'name/text()' },
-                      Value  => {
-                                 type  => 'child',
-                                 path  => 'value',
-                                 child => { ns => '__netjabber__:iq:rpc:value' },
-                                 calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                },
-                      Member => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:iq:rpc - member objects',
-                     },
-
-          );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:rpc:array
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:rpc:array',
-            xpath => {
-                      Data  => {
-                                type  => 'child',
-                                path  => 'data',
-                                child => { ns => '__netjabber__:iq:rpc:array:data' },
-                                calls => [ 'Add' ],
-                               },
-                      Datas => {
-                                type  => 'child',
-                                path  => 'data',
-                                child => { ns => '__netjabber__:iq:rpc:array:data' },
-                               },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:iq:rpc - array objects',
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:rpc:array:data
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    =>'__netjabber__:iq:rpc:array:data',
-            xpath => {
-                      Value => {
-                                type  => 'child',
-                                path  => 'value',
-                                child => { ns => '__netjabber__:iq:rpc:value' },
-                                calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                               },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:iq:rpc - data objects',
-                     },
-
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:search
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:search',
-            tag   => 'query',
-            xpath => {
-                      Email        => { path => 'email/text()' },
-                      Family       => { path => 'family/text()' },
-                      First        => { path => 'first/text()' },
-                      Given        => { path => 'given/text()' },
-                      Instructions => { path => 'instructions/text()' },
-                      Item         => {
-                                       type  => 'child',
-                                       path  => 'item',
-                                       child => { ns => '__netjabber__:iq:search:item' },
-                                       calls => [ 'Add' ],
-                                      },
-                      Items        => {
-                                       type  => 'child',
-                                       path  => 'item',
-                                       child => { ns => '__netjabber__:iq:search:item', },
-                                      },
-                      Key          => { path => 'key/text()' },
-                      Last         => { path => 'last/text()' },
-                      Name         => { path => 'name/text()' },
-                      Nick         => { path => 'nick/text()' },
-                      Truncated    => {
-                                       type => 'flag',
-                                       path => 'truncated',
-                                      },
-                      Search       => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:search:item
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:search:item',
-            xpath => {
-                      Email  => { path => 'email/text()' },
-                      Family => { path => 'family/text()' },
-                      First  => { path => 'first/text()' },
-                      Given  => { path => 'given/text()' },
-                      JID    => {
-                                 type => 'jid',
-                                 path => '@jid',
-                                },
-                      Key    => { path => 'key/text()' },
-                      Last   => { path => 'last/text()' },
-                      Name   => { path => 'name/text()' },
-                      Nick   => { path => 'nick/text()' },
-                      Item   => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:iq:search - item objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:time
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:time',
-            tag   => 'query',
-            xpath => {
-                      Display => {
-                                  type  => ['special','time-display'],
-                                  path  => 'display/text()',
-                                 },
-                      TZ      => {
-                                  type  => ['special','time-tz'],
-                                  path  => 'tz/text()',
-                                 },
-                      UTC     => {
-                                  type  => ['special','time-utc'],
-                                  path  => 'utc/text()',
-                                 },
-                      Time    => { type => [ 'master', 'all' ] }
-                      },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-                                   
-#-----------------------------------------------------------------------------
-# jabber:iq:version
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:version',
-            tag   => 'query',
-            xpath => {
-                      Name    => { path => 'name/text()' },
-                      OS      => {
-                                  type => [ 'special', 'version-os' ],
-                                  path => 'os/text()',
-                                 },
-                      Ver     => {
-                                  type => [ 'special' ,'version-version' ],
-                                  path => 'version/text()',
-                                 },
-                      Version => { type => [ 'master', 'all' ] }
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:x:autoupdate
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:x:autoupdate',
-            tag   => 'x',
-            xpath => {
-                      JID => {
-                              type => 'jid',
-                              path => '@jid',
-                             },
-                      Autoupdate => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-                  
-#-----------------------------------------------------------------------------
-# jabber:x:conference
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:x:conference',
-            tag   => 'x',
-            xpath => {
-                      JID => {
-                              type => 'jid',
-                              path => '@jid',
-                             },
-                      Conference => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:x:data
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:x:data',
-            tag   => 'x',
-            xpath => {
-                      Field        => {
-                                       type  => 'child',
-                                       path  => 'field',
-                                       child => { ns => '__netjabber__:x:data:field' },
-                                       calls => [ 'Add' ],
-                                      },
-                      Fields       => {
-                                       type  => 'child',
-                                       path  => 'field',
-                                       child => { ns => '__netjabber__:x:data:field', },
-                                      },
-                      Form         => { path => '@form' },
-                      Instructions => { path => 'instructions/text()' },
-                      Item         => {
-                                       type  => 'child',
-                                       path  => 'item',
-                                       child => { ns => '__netjabber__:x:data:item' },
-                                       calls => [ 'Add' ],
-                                      },
-                      Items        => {
-                                       type  => 'child',
-                                       path  => 'item',
-                                       child => { ns => '__netjabber__:x:data:item', },
-                                      },
-                      Reported     => {
-                                       type  => 'child',
-                                       path  => 'reported',
-                                       child => { ns => '__netjabber__:x:data:reported' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Title        => { path => 'title/text()' },
-                      Type         => { path => '@type' },
-                      Data         => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:x:data:field
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:x:data:field',
-            xpath => {
-                      Desc     => { path => 'desc/text()' },
-                      Label    => { path => '@label' },
-                      Option   => {
-                                   type  => 'child',
-                                   path  => 'option',
-                                   child => { ns => '__netjabber__:x:data:field:option' },
-                                   calls => [ 'Add' ],
-                                  },
-                      Options  => {
-                                   type  => 'child',
-                                   path  => 'option',
-                                   child => { ns => '__netjabber__:x:data:field:option', },
-                                  },
-                      Required => {
-                                   type => 'flag',
-                                   path => 'required',
-                                  },
-                      Type     => { path => '@type' },
-                      Value    => {
-                                   type => 'array',
-                                   path => 'value/text()',
-                                  },
-                      Var      => { path => '@var' },
-                      Field  => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:x:data - field objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:x:data:field:option
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:x:data:field:option',
-            xpath => {
-                      Label  => { path => '@label' },
-                      Value  => { path => 'value/text()' },
-                      Option => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:x:data - option objects',
-                     },
-           );
-}
-       
-#-----------------------------------------------------------------------------
-# __netjabber__:x:data:item
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:x:data:item',
-            xpath => {
-                      Field        => {
-                                       type  => 'child',
-                                       path  => 'field',
-                                       child => { ns => '__netjabber__:x:data:field' },
-                                       calls => [ 'Add' ],
-                                      },
-                      Fields       => {
-                                       type  => 'child',
-                                       path  => 'field',
-                                       child => { ns => '__netjabber__:x:data:field', },
-                                      },
-                      Item         => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:x:data - item objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:x:data:reported
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:x:data:reported',
-            xpath => {
-                      Field        => {
-                                       type  => 'child',
-                                       path  => 'field',
-                                       child => { ns => '__netjabber__:x:data:field' },
-                                       calls => [ 'Add' ],
-                                      },
-                      Fields       => {
-                                       type  => 'child',
-                                       path  => 'field',
-                                       child => { ns => '__netjabber__:x:data:field', },
-                                      },
-                      Reported     => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:x:data - reported objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:x:delay
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:x:delay',
-            tag   => 'x',
-            xpath => {
-                      From    => {
-                                  type => 'jid',
-                                  path => '@from',
-                                 },
-                      Message => { path => 'text()' },
-                      Stamp   => {
-                                  type => 'timestamp',
-                                  path => '@stamp',
-                                 },
-                      Delay   => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:x:encrypted
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:x:encrypted',
-            tag   => 'x',
-            xpath => {
-                      Message   => { path => 'text()' },
-                      Encrypted => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-       
-#-----------------------------------------------------------------------------
-# jabber:x:event
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:x:event',
-            tag   => 'x',
-            xpath => {
-                      Composing => {
-                                    type => 'flag',
-                                    path => 'composing',
-                                   },
-                      Delivered => {
-                                    type => 'flag',
-                                    path => 'delivered',
-                                   },
-                      Displayed => {
-                                    type => 'flag',
-                                    path => 'displayed',
-                                   },
-                      ID        => { path => 'id/text()' },
-                      Offline   => {
-                                    type => 'flag',
-                                    path => 'offline',
-                                   },
-                      Event     => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:x:expire
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:x:expire',
-            tag   => 'x',
-            xpath => {
-                      Seconds => { path => '@seconds' },
-                      Expire  => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:x:oob
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:x:oob',
-            tag   => 'x',
-            xpath => {
-                      Desc => { path => 'desc/text()' },
-                      URL  => { path => 'url/text()' },
-                      Oob  => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:x:roster
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:x:roster',
-            tag   => 'x',
-            xpath => {
-                      Item  => {
-                                type  => 'child',
-                                path  => 'item',
-                                child => { ns => '__netjabber__:x:roster:item' },
-                                calls => [ 'Add' ],
-                               },
-                      Items => {
-                                type  => 'child',
-                                path  => 'item',
-                                child => { ns => '__netjabber__:x:roster:item', },
-                               },
-                      Roster => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-       
-#-----------------------------------------------------------------------------
-# __netjabber__:x:roster:item
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:x:roster:item',
-            xpath => {
-                      Ask          => { path => '@ask' },
-                      Group        => {
-                                       type => 'array',
-                                       path => 'group/text()',
-                                      },
-                      JID          => {
-                                       type => 'jid',
-                                       path => '@jid',
-                                      },
-                      Name         => { path => '@name' },
-                      Subscription => { path => '@subscription' },
-                      Item         => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'jabber:x:roster - item objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:x:signed
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:x:signed',
-            tag   => 'x',
-            xpath => {
-                      Signature => { path => 'text()' },
-                      Signed    => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/bytestreams
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/bytestreams',
-            tag   => 'query',
-            xpath => {
-                      Activate => { path => 'activate/text()' },
-                      SID               => { path => '@sid' },
-                      StreamHost        => {
-                                            type  => 'child',
-                                            path  => 'streamhost',
-                                            child => { ns => '__netjabber__:iq:bytestreams:streamhost' },
-                                            calls => [ 'Add' ],
-                                           },
-                      StreamHosts       => {
-                                            type  => 'child',
-                                            path  => 'streamhost',
-                                            child => { ns  => '__netjabber__:iq:bytestreams:streamhost', },
-                                           },
-                      StreamHostUsedJID => {
-                                            type => 'jid',
-                                            path => 'streamhost-used/@jid',
-                                           },
-                      ByteStreams       => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:bytestreams:streamhost
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:bytestreams:streamhost',
-            xpath => {
-                      Host       => { path => '@host' },
-                      JID        => {
-                                     type => 'jid',
-                                     path => '@jid',
-                                    },
-                      Port       => { path => '@port' },
-                      ZeroConf   => { path => '@zeroconf' },
-                      StreamHost => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/bytestreams - streamhost objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/commands
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/commands',
-            tag   => 'command',
-            xpath => {
-                      Action    => { path => '@action' },
-                      Node      => { path => '@node' },
-                      Note      => {
-                                    type  => 'child',
-                                    path  => 'note',
-                                    child => { ns  => '__netjabber__:iq:commands:note' },
-                                    calls => [ 'Add' ],
-                                   },
-                      Notes     => {
-                                    type  => 'child',
-                                    path  => 'note',
-                                    child => { ns => '__netjabber__:iq:commands:note', },
-                                   },
-                      SessionID => { path => '@sessionid' },
-                      Status    => { path => '@status' },
-                      Command   => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-# xxx xml:lang
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:commands:note
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:commands:note',
-            xpath => {
-                      Type    => { path => '@type' },
-                      Message => { path => 'text()' },
-                      Note    => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/commands - note objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/disco#info
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/disco#info',
-            tag   => 'query',
-            xpath => {
-                      Feature    => {
-                                     type  => 'child',
-                                     path  => 'feature',
-                                     child => { ns => '__netjabber__:iq:disco:info:feature' },
-                                     calls => [ 'Add' ],
-                                    },
-                      Features   => {
-                                     type  => 'child',
-                                     path  => 'feature',
-                                     child => { ns => '__netjabber__:iq:disco:info:feature' },
-                                    },
-                      Identity   => {
-                                     type  => 'child',
-                                     path  => 'identity',
-                                     child => { ns => '__netjabber__:iq:disco:info:identity' },
-                                     calls => [ 'Add' ],
-                                    },
-                      Identities => {
-                                     type  => 'child',
-                                     path  => 'identity',
-                                     child => { ns => '__netjabber__:iq:disco:info:identity' },
-                                    },
-                      Node       => { path => '@node' },
-                      DiscoInfo  => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:disco:info:feature
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:disco:info:feature',
-            xpath => {
-                      Var     => { path => '@var' },
-                      Feature => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/disco#info - feature objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:disco:info:identity
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:disco:info:identity',
-            xpath => {
-                      Category => { path => '@category' },
-                      Name     => { path => '@name' },
-                      Type     => { path => '@type' },
-                      Identity => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/disco#info - identity objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/disco#items
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/disco#items',
-            tag   => 'query',
-            xpath => {
-                      Item       => {
-                                     type  => 'child',
-                                     path  => 'item',
-                                     child => { ns => '__netjabber__:iq:disco:items:item' },
-                                     calls => [ 'Add' ],
-                                    },
-                      Items      => {
-                                     type  => 'child',
-                                     path  => 'item',
-                                     child => { ns => '__netjabber__:iq:disco:items:item' },
-                                    },
-                      Node       => { path => '@node' },
-                      DiscoItems => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-       
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:disco:items:item
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:disco:items:item',
-            xpath => {
-                      Action => { path => '@action' },
-                      JID    => {
-                                 type => 'jid',
-                                 path => '@jid',
-                                },
-                      Name   => { path => '@name' },
-                      Node   => { path => '@node' },
-                      Item   => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/disco#items - item objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/feature-neg
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/feature-neg',
-            tag   => 'feature',
-            xpath => {
-                      FeatureNeg => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-       
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/muc
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/muc',
-            tag   => 'x',
-            xpath => {
-                      Password => { path => 'password/text()' },
-                      History  => {
-                                    type  => 'child',
-                                    path  => 'history',
-                                    child => { ns => '__netjabber__:iq:muc:history' },
-                                    calls => ['Add', 'Get', 'Set', 'Defined' ],
-                                   },
-                      MUC      => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:muc:history
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:muc:history',
-            tag   => 'history',
-            xpath => {
-                      MaxChars   => { path => '@maxchars' },
-                      MaxStanzas => { path => '@maxstanzas' },
-                      Seconds    => { path => '@seconds' },
-                      Since      => { path => '@since' }
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-                   
-}
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/muc#admin
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/muc#admin',
-            tag   => 'query',
-            xpath => {
-                      Item  => {
-                                type  => 'child',
-                                path  => 'item',
-                                child => { ns => '__netjabber__:iq:muc:admin:item' },
-                                calls => [ 'Add' ],
-                               },
-                      Items => {
-                                type  => 'child',
-                                path  => 'item',
-                                child => { ns => '__netjabber__:iq:muc:admin:item' },
-                               },
-                      Admin => { type => 'master' },
-                    },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:muc:admin:item
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:muc:admin:item',
-            xpath => {
-                      ActorJID    => {
-                                      type => 'jid',
-                                      path => 'actor/@jid',
-                                     },
-                      Affiliation => { path => '@affiliation' },
-                      JID         => {
-                                      type => 'jid',
-                                      path => '@jid',
-                                     },
-                      Nick        => { path => '@nick' },
-                      Reason      => { path => 'reason/text()' },
-                      Role        => { path => '@role' },
-                      Item        => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/muc#admin - item objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/muc#user
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/muc#user',
-            tag   => 'x',
-            xpath => {
-                      Alt        => { path => 'alt/text()' },
-                      Invite     => {
-                                     type  => 'child',
-                                     path  => 'invite',
-                                     child => { ns => '__netjabber__:x:muc:invite' },
-                                     calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                    },
-                      Item       => {
-                                     type  => 'child',
-                                     path  => 'item',
-                                     child => { ns => '__netjabber__:x:muc:item' },
-                                     calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                    },
-                      Password   => { path => 'password/text()' },
-                      StatusCode => { path => 'status/@code' },
-                      User       => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:x:muc:invite
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:x:muc:invite',
-            xpath => {
-                      From   => {
-                                 type => 'jid',
-                                 path => '@from',
-                                },
-                      Reason => { path => 'reason/text()' },
-                      To     => {
-                                 type => 'jid',
-                                 path => '@to',
-                                },
-                      Invite => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/muc#user - invite objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:x:muc:item
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:x:muc:item',
-            xpath => {
-                      ActorJID    => {
-                                      type => 'jid',
-                                      path => 'actor/@jid',
-                                     },
-                      Affiliation => { path => '@affiliation' },
-                      JID         => {
-                                      type => 'jid',
-                                      path => '@jid',
-                                     },
-                      Nick        => { path => '@nick' },
-                      Reason      => { path => 'reason/text()' },
-                      Role        => { path => '@role' },
-                      Item        => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/muc#user - item objects',
-                     },
-           );
-}
-
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/muc#owner
-#-----------------------------------------------------------------------------
-
-{
-        &add_ns(
-                ns  => "http://jabber.org/protocol/muc#owner",
-                tag => 'query',
-               );
-}
-
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/pubsub
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/pubsub',
-            tag   => 'pubsub',
-            xpath => {
-                      Affiliations => {
-                                       type  => 'child',
-                                       path  => 'affiliations',
-                                       child => { ns => '__netjabber__:iq:pubsub:affiliations' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Configure    => {
-                                       type  => 'child',
-                                       path  => 'configure',
-                                       child => { ns => '__netjabber__:iq:pubsub:configure' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Create       => {
-                                       type  => 'child',
-                                       path  => 'create',
-                                       child => { ns => '__netjabber__:iq:pubsub:create' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Delete       => {
-                                       type  => 'child',
-                                       path  => 'delete',
-                                       child => { ns => '__netjabber__:iq:pubsub:delete' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Entities     => {
-                                       type  => 'child',
-                                       path  => 'entities',
-                                       child => { ns => '__netjabber__:iq:pubsub:entities' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Entity       => {
-                                       type  => 'child',
-                                       path  => 'entity',
-                                       child => { ns => '__netjabber__:iq:pubsub:entity' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Items        => {
-                                       type  => 'child',
-                                       path  => 'items',
-                                       child => { ns => '__netjabber__:iq:pubsub:items' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Item         => {
-                                       type  => 'child',
-                                       path  => 'item',
-                                       child => { ns => '__netjabber__:iq:pubsub:item' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Options      => {
-                                       type  => 'child',
-                                       path  => 'options',
-                                       child => { ns => '__netjabber__:iq:pubsub:options' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Publish      => {
-                                       type  => 'child',
-                                       path  => 'publish',
-                                       child => { ns => '__netjabber__:iq:pubsub:publish' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Purge        => {
-                                       type  => 'child',
-                                       path  => 'purge',
-                                       child => { ns => '__netjabber__:iq:pubsub:purge' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Retract      => {
-                                       type  => 'child',
-                                       path  => 'retract',
-                                       child => { ns => '__netjabber__:iq:pubsub:retract' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Subscribe    => {
-                                       type  => 'child',
-                                       path  => 'subscribe',
-                                       child => { ns => '__netjabber__:iq:pubsub:subscribe' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Unsubscribe  => {
-                                       type  => 'child',
-                                       path  => 'unsubscribe',
-                                       child => { ns => '__netjabber__:iq:pubsub:unsubscribe' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      PubSub       => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:affiliations
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:affiliations',
-            xpath => {
-                      Entity       => {
-                                       type  => 'child',
-                                       path  => 'entity',
-                                       child => { ns => '__netjabber__:iq:pubsub:entity' },
-                                       calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                      },
-                      Affiliations => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - affiliations objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:configure
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:configure',
-            xpath => {
-                      Node      => { path => '@node' },
-                      Configure => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - configure objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:create
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:create',
-            xpath => {
-                      Node   => { path => '@node' },
-                      Create => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - create objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:delete
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:delete',
-            xpath => {
-                      Node   => { path => '@node' },
-                      Delete => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - delete objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:entities
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:entities',
-            xpath => {
-                      Entity   => {
-                                   type  => 'child',
-                                   path  => 'entity',
-                                   child => { ns => '__netjabber__:iq:pubsub:entity' },
-                                   calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                  },
-                      Entities => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - entities objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:entity
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:entity',
-            xpath => {
-                      Affiliation      => { path => '@affiliation' },
-                      JID              => {
-                                           type => 'jid',
-                                           path => '@jid',
-                                          },
-                      Node             => { path => '@node' },
-                      Subscription     => { path => '@subscription' },
-                      SubscribeOptions => {
-                                           type  => 'child',
-                                           path  => 'subscribe-options',
-                                           child => { ns => '__netjabber__:iq:pubsub:subscribe-options' },
-                                           calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                          },
-                      Entity           => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - entity objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:items
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:items',
-            xpath => {
-                      Item     => {
-                                   type  => 'child',
-                                   path  => 'item',
-                                   child => { ns => '__netjabber__:iq:pubsub:item' },
-                                   calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                  },
-                      Node     => { path => '@node' },
-                      MaxItems => { path => '@max_items' },
-                      Items    => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - items objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:item
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:item',
-            xpath => {
-                      ID      => { path => '@id' },
-                      Payload => { type => 'raw' },
-                      Item    => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - item objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:options
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:options',
-            xpath => {
-                      JID     => {
-                                  type => 'jid',
-                                  path => '@jid',
-                                 },
-                      Node    => { path => '@node' },
-                      Options => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - options objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:publish
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:publish',
-            xpath => {
-                      Item    => {
-                                  type  => 'child',
-                                  path  => 'item',
-                                  child => { ns => '__netjabber__:iq:pubsub:item' },
-                                  calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                 },
-                      Node    => { path => '@node' },
-                      Publish => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - publish objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:purge
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:purge',
-            xpath => {
-                      Node  => { path => '@node' },
-                      Purge => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - purge objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:retract
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:retract',
-            xpath => {
-                      Item    => {
-                                  type  => 'child',
-                                  path  => 'item',
-                                  child => { ns => '__netjabber__:iq:pubsub:item' },
-                                  calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                 },
-                      Node    => { path => '@node' },
-                      Retract => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - retract objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:subscribe
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:subscribe',
-            xpath => {
-                      JID       => {
-                                    type => 'jid',
-                                    path => '@jid',
-                                   },
-                      Node      => { path => '@node' },
-                      Subscribe => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - subscribe objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:subscribe-options
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:subscribe-options',
-            xpath => {
-                      Required         => {
-                                           type => 'flag',
-                                           path => 'required',
-                                          },
-                      SubscribeOptions => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - subscribe-options objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:unsubscribe
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:unsubscribe',
-            xpath => {
-                      JID         => {
-                                      type => 'jid',
-                                      path => '@jid',
-                                     },
-                      Node        => { path => '@node' },
-                      Unsubscribe => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub - unsubscribe objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/pubsub#event
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/pubsub#event',
-            tag   => 'event',
-            xpath => {
-                      Delete => {
-                                 type  => 'child',
-                                 path  => 'delete',
-                                 child => { ns => '__netjabber__:iq:pubsub:event:delete' },
-                                 calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                },
-                      Items  => {
-                                 type  => 'child',
-                                 path  => 'items',
-                                 child => { ns => '__netjabber__:iq:pubsub:event:items' },
-                                 calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                },
-                      Event  => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:event:delete
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:event:delete',
-            xpath => {
-                      Node   => { path => '@node' },
-                      Delete => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub#event - delete objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:event:items
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:event:items',
-            xpath => {
-                      Item  => {
-                                type  => 'child',
-                                path  => 'item',
-                                child => { ns => '__netjabber__:iq:pubsub:event:item' },
-                                calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                               },
-                      Node  => { path => '@node' },
-                      Items => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub#event - items objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:event:item
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:event:item',
-            xpath => {
-                      ID      => { path => '@id' },
-                      Payload => { type => 'raw' },
-                      Item    => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub#event - item objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/pubsub#owner
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/pubsub#owner',
-            tag   => 'pubsub',
-            xpath => {
-                      Action    => { path => '@action' },
-                      Configure => {
-                                    type  => 'child',
-                                    path  => 'configure',
-                                    child => { ns => '__netjabber__:iq:pubsub:owner:configure' },
-                                    calls => [ 'Get', 'Defined', 'Add', 'Remove' ],
-                                   },
-                      Owner     => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:pubsub:owner:configure
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netjabber__:iq:pubsub:owner:configure',
-            xpath => {
-                      Node      => { path => '@node' },
-                      Configure => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                      name   => 'http://jabber.org/protocol/pubsub#owner - configure objects',
-                     },
-           );
-}
-
-#XXX pubsub#errors
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/si
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/si',
-            tag   => 'si',
-            xpath => {
-                      ID       => { path => '@id' },
-                      MimeType => { path => '@mime-type' },
-                      Profile  => { path => '@profile' },
-                      Stream   => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/si/profile/file-transfer
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'http://jabber.org/protocol/si/profile/file-transfer',
-            tag   => 'file',
-            xpath => {
-                      Date        => { path => '@date' },
-                      Desc        => { path => 'desc/text()' },
-                      Hash        => { path => '@hash' },
-                      Name        => { path => '@name' },
-                      Range       => {
-                                      type => 'flag',
-                                      path => 'range',
-                                     },
-                      RangeOffset => { path => 'range/@offset' },
-                      RangeLength => { path => 'range/@length' },
-                      Size        => { path => '@size' },
-                      File        => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::Jabber',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# http://jabber.org/protocol/si/profile/tree-transfer
-#-----------------------------------------------------------------------------
-# XXX do later
-$ns = 'http://jabber.org/protocol/si/profile/tree-transfer';
-
-$TAGS{$ns} = "tree";
-
-$NAMESPACES{$ns}->{Directory}->{XPath}->{Type} = 'child';
-$NAMESPACES{$ns}->{Directory}->{XPath}->{Path} = 'directory';
-$NAMESPACES{$ns}->{Directory}->{XPath}->{Child} = ['Query','__netjabber__:iq:si:profile:tree:directory'];
-$NAMESPACES{$ns}->{Directory}->{XPath}->{Calls} = ['Add','Get'];
-
-$NAMESPACES{$ns}->{Numfiles}->{XPath}->{Path} = '@numfiles';
-
-$NAMESPACES{$ns}->{Size}->{XPath}->{Path} = '@size';
-
-$NAMESPACES{$ns}->{Tree}->{XPath}->{Type} = 'master';
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:si:profile:tree:directory
-#-----------------------------------------------------------------------------
-$ns = '__netjabber__:iq:si:profile:tree:directory';
-
-$NAMESPACES{$ns}->{Directory}->{XPath}->{Type} = 'child';
-$NAMESPACES{$ns}->{Directory}->{XPath}->{Path} = 'directory';
-$NAMESPACES{$ns}->{Directory}->{XPath}->{Child} = ['Query','__netjabber__:iq:si:profile:tree:directory'];
-$NAMESPACES{$ns}->{Directory}->{XPath}->{Calls} = ['Add','Get'];
-
-$NAMESPACES{$ns}->{File}->{XPath}->{Type} = 'child';
-$NAMESPACES{$ns}->{File}->{XPath}->{Path} = 'file';
-$NAMESPACES{$ns}->{File}->{XPath}->{Child} = ['Query','__netjabber__:iq:si:profile:tree:file'];
-$NAMESPACES{$ns}->{File}->{XPath}->{Calls} = ['Add','Get'];
-
-$NAMESPACES{$ns}->{Name}->{XPath}->{Path} = '@name';
-
-$NAMESPACES{$ns}->{Dir}->{XPath}->{Type} = 'master';
-
-#-----------------------------------------------------------------------------
-# __netjabber__:iq:si:profile:tree:file
-#-----------------------------------------------------------------------------
-$ns = '__netjabber__:iq:si:profile:tree:file';
-
-$NAMESPACES{$ns}->{Name}->{XPath}->{Path} = '@name';
-
-$NAMESPACES{$ns}->{SID}->{XPath}->{Path} = '@sid';
-
-$NAMESPACES{$ns}->{File}->{XPath}->{Type} = 'master';
-
-sub add_ns
-{
-    &Net::XMPP::Namespaces::add_ns(@_);
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Presence.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Presence.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,64 +1,0 @@
-#############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Presence;
-
-=head1 NAME
-
-Net::Jabber::Presence - Jabber Presence Module
-
-=head1 DESCRIPTION
-
-  Net::Jabber::Presence inherits all of its methods from
-  Net::XMPP::Presence.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-use Net::XMPP::Presence;
-use base qw( Net::XMPP::Presence );
-
-use vars qw( $VERSION );
-
-$VERSION = "2.0";
-
-sub GetX     { my $self = shift; $self->GetChild(@_);    } 
-sub DefinedX { my $self = shift; $self->DefinedChild(@_); }
-sub NewX     { my $self = shift; $self->NewChild(@_);    }
-sub AddX     { my $self = shift; $self->AddChild(@_);    } 
-sub RemoveX  { my $self = shift; $self->RemoveChild(@_); }
-
-sub _new_jid    { my $self = shift; return Net::Jabber::JID->new(@_);      }
-sub _new_packet { my $self = shift; return Net::Jabber::Stanza->new(@_);   }
-sub _presence   { my $self = shift; return Net::Jabber::Presence->new(@_); }
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Protocol.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Protocol.pm	(revision cdd3959ca8040d068d22c13fc707f1c7b9033bc7)
+++ 	(revision )
@@ -1,3082 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Protocol;
-
-=head1 NAME
-
-Net::Jabber::Protocol - Jabber Protocol Library
-
-=head1 SYNOPSIS
-
-  Net::Jabber::Protocol is a module that provides a developer easy
-  access to the Jabber Instant Messaging protocol.  It provides high
-  level functions to the Net::Jabber Client, Component, and Server
-  objects.  These functions are automatically indluded in those modules
-  through AUTOLOAD and delegates.
-
-=head1 DESCRIPTION
-
-  Protocol.pm seeks to provide enough high level APIs and automation of
-  the low level APIs that writing a Jabber Client/Transport in Perl is
-  trivial.  For those that wish to work with the low level you can do
-  that too, but those functions are covered in the documentation for
-  each module.
-
-  Net::Jabber::Protocol provides functions to login, send and receive
-  messages, set personal information, create a new user account, manage
-  the roster, and disconnect.  You can use all or none of the functions,
-  there is no requirement.
-
-  For more information on how the details for how Net::Jabber is written
-  please see the help for Net::Jabber itself.
-
-  For more information on writing a Client see Net::Jabber::Client.
-
-  For more information on writing a Transport see Net::Jabber::Transport.
-
-=head2 Modes
-
-  Several of the functions take a mode argument that let you specify how
-  the function should behave:
-
-    block - send the packet with an ID, and then block until an answer
-            comes back.  You can optionally specify a timeout so that
-            you do not block forever.
-           
-    nonblock - send the packet with an ID, but then return that id and
-               control to the master program.  Net::Jabber is still
-               tracking this packet, so you must use the CheckID function
-               to tell when it comes in.  (This might not be very
-               useful...)
-
-    passthru - send the packet with an ID, but do NOT register it with
-               Net::Jabber, then return the ID.  This is useful when
-               combined with the XPath function because you can register
-               a one shot function tied to the id you get back.
-               
-
-=head2 Basic Functions
-
-    use Net::Jabber qw( Client );
-    $Con = Net::Jabber::Client->new();                # From
-    $status = $Con->Connect(hostname=>"jabber.org"); # Net::Jabber::Client
-
-      or
-
-    use Net::Jabber qw( Component );
-    $Con = Net::Jabber::Component->new();             #
-    $status = $Con->Connect(hostname=>"jabber.org",  # From
-                            secret=>"bob");          # Net::Jabber::Component
-
-
-    #
-    # For callback setup, see Net::XMPP::Protocol
-    #
-
-    $Con->Info(name=>"Jarl",
-               version=>"v0.6000");
-
-=head2 ID Functions
-
-    $id         = $Con->SendWithID($sendObj);
-    $id         = $Con->SendWithID("<tag>XML</tag>");
-    $receiveObj = $Con->SendAndReceiveWithID($sendObj);
-    $receiveObj = $Con->SendAndReceiveWithID($sendObj,
-                                             10);
-    $receiveObj = $Con->SendAndReceiveWithID("<tag>XML</tag>");
-    $receiveObj = $Con->SendAndReceiveWithID("<tag>XML</tag>",
-                                             5);
-    $yesno      = $Con->ReceivedID($id);
-    $receiveObj = $Con->GetID($id);
-    $receiveObj = $Con->WaitForID($id);
-    $receiveObj = $Con->WaitForID($id,
-                                  20);
-
-=head2 IQ  Functions
-
-=head2 Agents Functions
-
-    %agents = $Con->AgentsGet();
-    %agents = $Con->AgentsGet(to=>"transport.jabber.org");
-
-=head2 Browse Functions
-
-    %hash = $Con->BrowseRequest(jid=>"jabber.org");
-    %hash = $Con->BrowseRequest(jid=>"jabber.org",
-                                timeout=>10);
-
-    $id = $Con->BrowseRequest(jid=>"jabber.org",
-                              mode=>"nonblock");
-
-    $id = $Con->BrowseRequest(jid=>"jabber.org",
-                              mode=>"passthru");
-
-=head2 Browse DB Functions
-
-    $Con->BrowseDBDelete("jabber.org");
-    $Con->BrowseDBDelete(Net::Jabber::JID);
-
-    $presence  = $Con->BrowseDBQuery(jid=>"bob\@jabber.org");
-    $presence  = $Con->BrowseDBQuery(jid=>Net::Jabber::JID);
-    $presence  = $Con->BrowseDBQuery(jid=>"users.jabber.org",
-                                     timeout=>10);
-    $presence  = $Con->BrowseDBQuery(jid=>"conference.jabber.org",
-                                     refresh=>1);
-
-=head2 Bystreams Functions
-
-    %hash = $Con->ByteStreamsProxyRequest(jid=>"proxy.server"); 
-    %hash = $Con->ByteStreamsProxyRequest(jid=>"proxy.server",
-                                          timeout=>10); 
-
-    $id = $Con->ByteStreamsProxyRequest(jid=>"proxy.server",
-                                        mode=>"nonblock");
-
-    $id = $Con->ByteStreamsProxyRequest(jid=>"proxy.server",
-                                        mode=>"passthru");
-
-    
-    %hash = $Con->ByteStreamsProxyParse($query);
-
-    
-    $status = $Con->ByteStreamsProxyActivate(sid=>"stream_id",
-                                             jid=>"proxy.server"); 
-    $status = $Con->ByteStreamsProxyActivate(sid=>"stream_id",
-                                             jid=>"proxy.server",
-                                            timeout=>10); 
-
-    $id = $Con->ByteStreamsProxyActivate(sid=>"stream_id",
-                                         jid=>"proxy.server",
-                                        mode=>"nonblock");
-
-    $id = $Con->ByteStreamsProxyActivate(sid=>"stream_id",
-                                         jid=>"proxy.server",
-                                        mode=>"passthru"); 
-
-
-    $jid = $Con->ByteStreamsOffer(sid=>"stream_id",
-                                  streamhosts=>[{jid=>"jid",
-                                                 host=>"host",
-                                                 port=>"port",
-                                                 zeroconf=>"zero",
-                                                },
-                                                ...
-                                               ],
-                                  jid=>"bob\@jabber.org"); 
-    $jid = $Con->ByteStreamsOffer(sid=>"stream_id",
-                                  streamhosts=>[{},{},...],
-                                  jid=>"bob\@jabber.org",
-                                  timeout=>10); 
-
-    $id = $Con->ByteStreamsOffer(sid=>"stream_id",
-                                 streamhosts=>[{},{},...],
-                                 jid=>"bob\@jabber.org",
-                                 mode=>"nonblock");
-
-    $id = $Con->ByteStreamsOffer(sid=>"stream_id",
-                                 streamhosts=>[{},{},...],
-                                 jid=>"bob\@jabber.org",
-                                 mode=>"passthru");
- 
-=head2 Disco Functions
-
-    %hash = $Con->DiscoInfoRequest(jid=>"jabber.org");
-    %hash = $Con->DiscoInfoRequest(jid=>"jabber.org",
-                                   node=>"node...");
-    %hash = $Con->DiscoInfoRequest(jid=>"jabber.org",
-                                   node=>"node...",
-                                   timeout=>10);
-
-    $id = $Con->DiscoInfoRequest(jid=>"jabber.org",
-                                 mode=>"nonblock");
-    $id = $Con->DiscoInfoRequest(jid=>"jabber.org",
-                                 node=>"node...",
-                                 mode=>"nonblock");
-
-    $id = $Con->DiscoInfoRequest(jid=>"jabber.org",
-                                 mode=>"passthru");
-    $id = $Con->DiscoInfoRequest(jid=>"jabber.org",
-                                 node=>"node...",
-                                 mode=>"passthru");
-
-    
-    %hash = $Con->DiscoInfoParse($query);
-
-
-    %hash = $Con->DiscoItemsRequest(jid=>"jabber.org");
-    %hash = $Con->DiscoItemsRequest(jid=>"jabber.org",
-                                    timeout=>10);
-
-    $id = $Con->DiscoItemsRequest(jid=>"jabber.org",
-                                  mode=>"nonblock");
-
-    $id = $Con->DiscoItemsRequest(jid=>"jabber.org",
-                                  mode=>"passthru");
-
-    
-    %hash = $Con->DiscoItemsParse($query);
-
-=head2 Feature Negotiation Functions
-
-  
-    %hash = $Con->FeatureNegRequest(jid=>"jabber.org",
-                                    features=>{ feat1=>["opt1","opt2",...],
-                                                feat2=>["optA","optB",...]
-                                              }
-                                   );
-    %hash = $Con->FeatureNegRequest(jid=>"jabber.org",
-                                    features=>{ ... },
-                                    timeout=>10);
-
-    $id = $Con->FeatureNegRequest(jid=>"jabber.org",
-                                  features=>{ ... },
-                                  mode=>"nonblock");
-
-    $id = $Con->FeatureNegRequest(jid=>"jabber.org",
-                                  features=>{ ... },
-                                  mode=>"passthru");
-
-    my $query = $self->FeatureNegQuery(\{ ... });
-    $iq->AddQuery($query);
-
-    %hash = $Con->FeatureNegParse($query);  
-
-=head2 File Transfer Functions
-
-    $method = $Con->FileTransferOffer(jid=>"bob\@jabber.org",
-                                      sid=>"stream_id",
-                                      filename=>"/path/to/file",
-                                      methods=>["http://jabber.org/protocol/si/profile/bytestreams",
-                                                "jabber:iq:oob",
-                                                ...
-                                               ]
-                                     );
-    $method = $Con->FileTransferOffer(jid=>"bob\@jabber.org",
-                                      sid=>"stream_id",
-                                      filename=>"/path/to/file",
-                                      methods=>\@methods,
-                                      timeout=>"10");
-
-    $id = $Con->FileTransferOffer(jid=>"bob\@jabber.org",
-                                  sid=>"stream_id",
-                                  filename=>"/path/to/file",
-                                  methods=>\@methods,
-                                  mode=>"nonblock");
-
-    $id = $Con->FileTransferOffer(jid=>"bob\@jabber.org",
-                                  sid=>"stream_id",
-                                  filename=>"/path/to/file",
-                                  methods=>\@methods,
-                                  mode=>"passthru");
-
-=head2 Last Functions
-
-    $Con->LastQuery();
-    $Con->LastQuery(to=>"bob@jabber.org");
-
-    %result = $Con->LastQuery(mode=>"block");
-    %result = $Con->LastQuery(to=>"bob@jabber.org",
-                              mode=>"block");
-
-    %result = $Con->LastQuery(to=>"bob@jabber.org",
-                              mode=>"block",
-                              timeout=>10);
-    %result = $Con->LastQuery(mode=>"block",
-                              timeout=>10);
-
-    $Con->LastSend(to=>"bob@jabber.org");
-
-    $seconds = $Con->LastActivity();
-
-=head2 Multi-User Chat Functions
-
-    $Con->MUCJoin(room=>"jabber",
-                  server=>"conference.jabber.org",
-                  nick=>"nick");
-
-    $Con->MUCJoin(room=>"jabber",
-                  server=>"conference.jabber.org",
-                  nick=>"nick",
-                  password=>"secret");
-
-=head2 Register Functions
-
-    @result = $Con->RegisterSendData("users.jabber.org",
-                                     first=>"Bob",
-                                     last=>"Smith",
-                                     nick=>"bob",
-                                     email=>"foo@bar.net");
-
-
-=head2 RPC Functions
-
-    $query = $Con->RPCEncode(type=>"methodCall",
-                             methodName=>"methodName",
-                             params=>[param,param,...]);
-    $query = $Con->RPCEncode(type=>"methodResponse",
-                             params=>[param,param,...]);
-    $query = $Con->RPCEncode(type=>"methodResponse",
-                             faultCode=>4,
-                             faultString=>"Too many params");
-
-    @response = $Con->RPCParse($iq);
-
-    @response = $Con->RPCCall(to=>"dataHouse.jabber.org",
-                              methodname=>"numUsers",
-                              params=>[ param,param,... ]
-                             );
-
-    $Con->RPCResponse(to=>"you\@jabber.org",
-                      params=>[ param,param,... ]);
-
-    $Con->RPCResponse(to=>"you\@jabber.org",
-                      faultCode=>"4",
-                      faultString=>"Too many parameters"
-                     );
-
-    $Con->RPCSetCallBacks(myMethodA=>\&methoda,
-                          myMethodB=>\&do_somthing,
-                          etc...
-                         );
-
-=head2 Search Functions
-
-    %fields = $Con->SearchRequest();
-    %fields = $Con->SearchRequest(to=>"users.jabber.org");
-    %fields = $Con->SearchRequest(to=>"users.jabber.org",
-                                  timeout=>10);
-
-    $Con->SearchSend(to=>"somewhere",
-                     name=>"",
-                     first=>"Bob",
-                     last=>"",
-                     nick=>"bob",
-                     email=>"",
-                     key=>"some key");
-
-    $Con->SearchSendData("users.jabber.org",
-                         first=>"Bob",
-                         last=>"",
-                         nick=>"bob",
-                         email=>"");
-
-=head2 Time Functions
-
-    $Con->TimeQuery();
-    $Con->TimeQuery(to=>"bob@jabber.org");
-
-    %result = $Con->TimeQuery(mode=>"block");
-    %result = $Con->TimeQuery(to=>"bob@jabber.org",
-                              mode=>"block");
-
-    $Con->TimeSend(to=>"bob@jabber.org");
-
-=head2 Version Functions
-
-    $Con->VersionQuery();
-    $Con->VersionQuery(to=>"bob@jabber.org");
-
-    %result = $Con->VersionQuery(mode=>"block");
-    %result = $Con->VersionQuery(to=>"bob@jabber.org",
-                                 mode=>"block");
-
-    $Con->VersionSend(to=>"bob@jabber.org",
-                      name=>"Net::Jabber",
-                      ver=>"1.0a",
-                      os=>"Perl");
-
-=head1 METHODS
-
-=head2 Basic Functions
-
-    Info(name=>string,    - Set some information so that Net::Jabber
-         version=>string)   can auto-reply to some packets for you to
-                            reduce the work you have to do.
-
-                            NOTE: This requires that you use the
-                            SetIQCallBacks methodology and not the
-                            SetCallBacks for <iq/> packets.
-
-=head2 IQ Functions
-
-=head2 Agents Functions
-
-    ********************************
-    *                              *
-    * Deprecated in favor of Disco *
-    *                              *
-    ********************************
-
-    AgentsGet(to=>string, - takes all of the information and
-    AgentsGet()             builds a Net::Jabber::IQ::Agents packet.
-                            It then sends that packet either to the
-                            server, or to the specified transport,
-                            with an ID and waits for that ID to return.
-                            Then it looks in the resulting packet and
-                            builds a hash that contains the values
-                            of the agent list.  The hash is layed out
-                            like this:  (NOTE: the jid is the key to
-                            distinguish the various agents)
-
-                              $hash{<JID>}->{order} = 4
-                                          ->{name} = "ICQ Transport"
-                                          ->{transport} = "ICQ #"
-                                          ->{description} = "ICQ..blah.."
-                                          ->{service} = "icq"
-                                          ->{register} = 1
-                                          ->{search} = 1
-                                        etc...
-
-                            The order field determines the order that
-                            it came from the server in... in case you
-                            care.  For more info on the valid fields
-                            see the Net::Jabber::Query jabber:iq:agent
-                            namespace.
-
-=head2 Browse Functions
-
-    ********************************
-    *                              *
-    * Deprecated in favor of Disco *
-    *                              *
-    ********************************
-
-    BrowseRequest(jid=>string, - sends a jabber:iq:browse request to
-                  mode=>string,  the jid passed as an argument.
-                  timeout=>int)  Returns a hash with the resulting
-                                 tree if mode is set to "block":
-
-                $browse{'category'} = "conference"
-                $browse{'children'}->[0]
-                $browse{'children'}->[1]
-                $browse{'children'}->[11]
-                $browse{'jid'} = "conference.jabber.org"
-                $browse{'name'} = "Jabber.org Conferencing Center"
-                $browse{'ns'}->[0]
-                $browse{'ns'}->[1]
-                $browse{'type'} = "public"
-
-                                 The ns array is an array of the
-                                 namespaces that this jid supports.
-                                 The children array points to hashs
-                                 of this form, and represent the fact
-                                 that they can be browsed to.
-
-                                 See MODES above for using the mode
-                                 and timeout.
-
-=head2 Browse DB Functions
-
-    BrowseDBDelete(string|Net::Jabber::JID) - delete thes JID browse
-                                              data from the DB.
-
-    BrowseDBQuery(jid=>string | NJ::JID, - returns the browse data
-                  timeout=>integer,        for the requested JID.  If
-                  refresh=>0|1)            the DB does not contain
-                                           the data for the JID, then
-                                           it attempts to fetch the
-                                           data via BrowseRequest().
-                                           The timeout is passed to
-                                           the BrowseRequest() call,
-                                           and refresh tells the DB
-                                           to request the data, even
-                                           if it already has some.
-
-=head2 Bytestreams Functions
-
-    ByteStreamsProxyRequest(jid=>string, - sends a bytestreams request
-                            mode=>string,  to the jid passed as an
-                            timeout=>int)  argument.  Returns an array
-                                           ref with the resulting tree
-                                           if mode is set to "block".
-
-                                           See ByteStreamsProxyParse
-                                           for the format of the
-                                           resulting tree.
-
-                                           See MODES above for using
-                                           the mode and timeout.
-
-    ByteStreamsProxyParse(Net::Jabber::Query) - parses the query and
-                                                returns an array ref
-                                                to the resulting tree:
-
-                $host[0]->{jid} = "bytestreams1.proxy.server";
-                $host[0]->{host} = "proxy1.server";
-                $host[0]->{port} = "5006";
-                $host[1]->{jid} = "bytestreams2.proxy.server";
-                $host[1]->{host} = "proxy2.server";
-                $host[1]->{port} = "5007";
-                ...
-
-    ByteStreamsProxyActivate(jid=>string, - sends a bytestreams activate
-                             sid=>string,   to the jid passed as an
-                             mode=>string,  argument.  Returns 1 if the
-                             timeout=>int)  proxy activated (undef if
-                                            it did not) if mode is set
-                                            to "block".
-
-                                            sid is the stream id that
-                                            is being used to talk about
-                                            this stream.
-
-                                            See MODES above for using
-                                            the mode and timeout.
-
-    ByteStreamsOffer(jid=>string,         - sends a bytestreams offer
-                     sid=>string,           to the jid passed as an
-                     streamhosts=>arrayref  argument.  Returns the jid
-                     mode=>string,          of the streamhost that the
-                     timeout=>int)          user selected if mode is set
-                                            to "block".
-
-                                            streamhosts is the same
-                                            format as the array ref
-                                            returned from
-                                            ByteStreamsProxyParse.
-
-                                            See MODES above for using
-                                            the mode and timeout.
-
-=head2 Disco Functions
-
-    DiscoInfoRequest(jid=>string, - sends a disco#info request to
-                     node=>string,  the jid passed as an argument,
-                     mode=>string,  and the node if specified.
-                     timeout=>int)  Returns a hash with the resulting
-                                    tree if mode is set to "block".
-
-                                    See DiscoInfoParse for the format
-                                    of the resulting tree.
-                                    
-                                    See MODES above for using the mode
-                                    and timeout.
-
-    DiscoInfoParse(Net::Jabber::Query) - parses the query and
-                                         returns a hash ref
-                                         to the resulting tree:
-
-             $info{identity}->[0]->{category} = "groupchat";
-             $info{identity}->[0]->{name} = "Public Chatrooms";
-             $info{identity}->[0]->{type} = "public";
-
-             $info{identity}->[1]->{category} = "groupchat";
-             $info{identity}->[1]->{name} = "Private Chatrooms";
-             $info{identity}->[1]->{type} = "private";
-
-             $info{feature}->{http://jabber.org/protocol/disco#info} = 1;
-             $info{feature}->{http://jabber.org/protocol/muc#admin} = 1;
-                                    
-    DiscoItemsRequest(jid=>string, - sends a disco#items request to
-                      mode=>string,  the jid passed as an argument.
-                      timeout=>int)  Returns a hash with the resulting
-                                     tree if mode is set to "block".
-
-                                     See DiscoItemsParse for the format
-                                     of the resulting tree.
-                                    
-                                     See MODES above for using the mode
-                                     and timeout.
-
-    DiscoItemsParse(Net::Jabber::Query) - parses the query and
-                                          returns a hash ref
-                                          to the resulting tree:
-
-             $items{jid}->{node} = name;
-
-             $items{"proxy.server"}->{""} = "Bytestream Proxy Server";
-             $items{"conf.server"}->{"public"} = "Public Chatrooms";
-             $items{"conf.server"}->{"private"} = "Private Chatrooms";
-
-=head2 Feature Negotiation Functions
-
-    FeatureNegRequest(jid=>string,       - sends a feature negotiation to
-                      features=>hash ref,  the jid passed as an argument,
-                      mode=>string,        using the features specified.
-                      timeout=>int)        Returns a hash with the resulting
-                                           tree if mode is set to "block".
-
-                                           See DiscoInfoQuery for the format
-                                           of the features hash ref.
-                                    
-                                           See DiscoInfoParse for the format
-                                           of the resulting tree.
-                                    
-                                           See MODES above for using the mode
-                                           and timeout.
-
-    FeatureNegParse(Net::Jabber::Query) - parses the query and
-                                          returns a hash ref
-                                          to the resulting tree:
-
-             $features->{feat1} = ["opt1","opt2",...];
-             $features->{feat2} = ["optA","optB",...];
-             ....
-
-                                          If this is a result:
-
-             $features->{feat1} = "opt2";
-             $features->{feat2} = "optA";
-             ....
-
-    FeatureNeqQuery(hash ref) - takes a hash ref and turns it into a
-                                feature negotiation query that you can
-                                AddQuery into your packaet.  The format
-                                of the hash ref is as follows:
-
-             $features->{feat1} = ["opt1","opt2",...];
-             $features->{feat2} = ["optA","optB",...];
-             ....
-
-=head2 File Transfer Functions
-
-    FileTransferOffer(jid=>string,         - sends a file transfer stream
-                      sid=>string,           initiation to the jid passed
-                      filename=>string,      as an argument.  Returns the
-                      mode=>string,          method (if the users accepts),
-                      timeout=>int)          undef (if the user declines),
-                                             if the mode is set to "block".
-
-                                             See MODES above for using
-                                             the mode and timeout.
-
-=head2 Last Functions
-
-    LastQuery(to=>string,     - asks the jid specified for its last
-              mode=>string,     activity.  If the to is blank, then it
-              timeout=>int)     queries the server.  Returns a hash with
-    LastQuery()                 the various items set if mode is set to
-                                "block":
-
-                                  $last{seconds} - Seconds since activity
-                                  $last{message} - Message for activity
-
-                                See MODES above for using the mode
-                                and timeout.
-
-    LastSend(to=>string, - sends the specified last to the specified jid.
-             hash)         the hash is the seconds and message as shown
-                           in the Net::Jabber::Query man page.
-
-    LastActivity() - returns the number of seconds since the last activity
-                     by the user.
-
-=head2 Multi-User Chat Functions
-
-    MUCJoin(room=>string,    - Sends the appropriate MUC protocol to join
-            server=>string,    the specified room with the specified nick.
-            nick=>string,
-            password=>string)
-
-=head2 Register Functions
-
-    RegisterSendData(string|JID, - takes the contents of the hash and
-                     hash)         builds a jabebr:x:data return packet
-                                   which it sends in a Net::Jabber::Query
-                                   jabber:iq:register namespace packet.
-                                   The first argument is the JID to send
-                                   the packet to.  This function returns
-                                   an array that looks like this:
-
-                                     [ type , message ]
-
-                                   If type is "ok" then registration was
-                                   successful, otherwise message contains
-                                   a little more detail about the error.
-
-=head2 RPC Functions
-
-    RPCParse(IQ object) - returns an array.  The first argument tells
-                          the status "ok" or "fault".  The second
-                          argument is an array if "ok", or a hash if
-                          "fault".
-
-    RPCCall(to=>jid|string,     - takes the methodName and params,
-            methodName=>string,   builds the RPC calls and sends it
-            params=>array,        to the specified address.  Returns
-            mode=>string,         the above data from RPCParse.
-            timeout=>int)         
-                                  See MODES above for using the mode
-                                  and timeout.
-
-    RPCResponse(to=>jid|string,      - generates a response back to
-                params=>array,         the caller.  If any part of
-                faultCode=>int,        fault is specified, then it
-                faultString=>string)   wins.
-
-
-    Note: To ensure that you get the correct type for a param sent
-          back, you can specify the type by prepending the type to
-          the value:
-
-            "i4:5" or "int:5"
-            "boolean:0"
-            "string:56"
-            "double:5.0"
-            "datetime:20020415T11:11:11"
-            "base64:...."
-
-    RPCSetCallBacks(method=>function, - sets the callback functions
-                    method=>function,   for the specified methods.
-                    etc...)             The method comes from the
-                                        <methodName/> and is case
-                                        sensitive.  The single
-                                        arguemnt is a ref to an
-                                        array that contains the
-                                        <params/>.  The function you
-                                        write should return one of two
-                                        things:
-
-                                          ["ok", [...] ]
-
-                                        The [...] is a list of the
-                                        <params/> you want to return.
-
-                                          ["fault", {faultCode=>1,
-                                                     faultString=>...} ]
-
-                                        If you set the function to undef,
-                                        then the method is removed from
-                                        the list.
-
-=head2 Search Functions
-
-    SearchRequest(to=>string,  - send an <iq/> request to the specified
-                  mode=>string,  server/transport, if not specified it
-                  timeout=>int)  sends to the current active server.
-    SearchRequest()              The function returns a hash that
-                                 contains the required fields.   Here
-                                 is an example of the hash:
-
-                                 $hash{fields}    - The raw fields from
-                                                    the iq:register.  To
-                                                    be used if there is
-                                                    no x:data in the
-                                                    packet.
-                                 $hash{instructions} - How to fill out
-                                                       the form.
-                                 $hash{form}   - The new dynamic forms.
-
-                                 In $hash{form}, the fields that are
-                                 present are the required fields the
-                                 server needs.
-                                
-                                 See MODES above for using the mode
-                                 and timeout.
-
-    SearchSend(to=>string|JID, - takes the contents of the hash and
-               hash)             passes it to the SetSearch function
-                                 in the Net::Jabber::Query
-                                 jabber:iq:search namespace.  And then
-                                 sends the packet.
-
-    SearchSendData(string|JID, - takes the contents of the hash and
-                   hash)         builds a jabebr:x:data return packet
-                                 which it sends in a Net::Jabber::Query
-                                 jabber:iq:search namespace packet.
-                                 The first argument is the JID to send
-                                 the packet to.
-
-=head2 Time Functions
-
-    TimeQuery(to=>string,     - asks the jid specified for its localtime.
-              mode=>string,     If the to is blank, then it queries the
-              timeout=>int)     server.  Returns a hash with the various
-    TimeQuery()                 items set if mode is set to "block":
-
-                                  $time{utc}     - Time in UTC
-                                  $time{tz}      - Timezone
-                                  $time{display} - Display string
-
-                                See MODES above for using the mode
-                                and timeout.
-
-    TimeSend(to=>string) - sends the current UTC time to the specified
-                           jid.
-
-=head2 Version Functions
-
-    VersionQuery(to=>string,     - asks the jid specified for its
-                 mode=>string,     client version information.  If the
-                 timeout=>int)     to is blank, then it queries the
-    VersionQuery()                 server.  Returns ahash with the
-                                   various items set if mode is set to
-                                   "block":
-
-                                     $version{name} - Name
-                                     $version{ver}  - Version
-                                     $version{os}   - Operating System/
-                                                        Platform
-
-                                  See MODES above for using the mode
-                                  and timeout.
-
-    VersionSend(to=>string,   - sends the specified version information
-                name=>string,   to the jid specified in the to.
-                ver=>string,
-                os=>string)
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use Carp;
-use vars qw($VERSION);
-
-$VERSION = "2.0";
-
-##############################################################################
-# BuildObject takes a root tag and builds the correct object.  NEWOBJECT is
-# the table that maps tag to package.  Override these, or provide new ones.
-#-----------------------------------------------------------------------------
-$Net::XMPP::Protocol::NEWOBJECT{'iq'}       = "Net::Jabber::IQ";
-$Net::XMPP::Protocol::NEWOBJECT{'message'}  = "Net::Jabber::Message";
-$Net::XMPP::Protocol::NEWOBJECT{'presence'} = "Net::Jabber::Presence";
-$Net::XMPP::Protocol::NEWOBJECT{'jid'}      = "Net::Jabber::JID";
-##############################################################################
-
-###############################################################################
-#+-----------------------------------------------------------------------------
-#|
-#| Base API
-#|
-#+-----------------------------------------------------------------------------
-###############################################################################
-
-###############################################################################
-#
-# Info - set the base information about this Jabber Client/Component for
-#        use in a default response.
-#
-###############################################################################
-sub Info
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    foreach my $arg (keys(%args))
-    {
-        $self->{INFO}->{$arg} = $args{$arg};
-    }
-}
-
-
-###############################################################################
-#
-# DefineNamespace - adds the namespace and corresponding functions onto the
-#                   of available functions based on namespace.
-#
-#     Deprecated in favor of AddNamespace
-#
-###############################################################################
-sub DefineNamespace
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    croak("You must specify xmlns=>'' for the function call to DefineNamespace")
-        if !exists($args{xmlns});
-    croak("You must specify type=>'' for the function call to DefineNamespace")
-        if !exists($args{type});
-    croak("You must specify functions=>'' for the function call to DefineNamespace")
-        if !exists($args{functions});
-    
-    my %xpath;
-
-    my $tag;
-    if (exists($args{tag}))
-    {
-        $tag = $args{tag};
-    }
-    else
-    {
-        $tag = "x" if ($args{type} eq "X");
-        $tag = "query" if ($args{type} eq "Query");
-    }
-
-    foreach my $function (@{$args{functions}})
-    {
-        my %tempHash = %{$function};
-        my %funcHash;
-        foreach my $func (keys(%tempHash))
-        {
-            $funcHash{lc($func)} = $tempHash{$func};
-        }
-
-        croak("You must specify name=>'' for each function in call to DefineNamespace")
-            if !exists($funcHash{name});
-
-        my $name = delete($funcHash{name});
-
-        if (!exists($funcHash{set}) && exists($funcHash{get}))
-        {
-            croak("The DefineNamespace arguments have changed, and I cannot determine the\nnew values automatically for name($name).  Please read the man page\nfor Net::Jabber::Namespaces.  I apologize for this incompatability.\n");
-        }
-
-        if (exists($funcHash{type}) || exists($funcHash{path}) ||
-            exists($funcHash{child}) || exists($funcHash{calls}))
-        {
-
-            foreach my $type (keys(%funcHash))
-            {
-                if ($type eq "child")
-                {
-                    $xpath{$name}->{$type}->{ns} = $funcHash{$type}->[1];
-                    my $i = 2;
-                    while( $i <= $#{$funcHash{$type}} )
-                    {
-                        if ($funcHash{$type}->[$i] eq "__netjabber__:skip_xmlns")
-                        {
-                            $xpath{$name}->{$type}->{skip_xmlns} = 1;
-                        }
-                        
-                        if ($funcHash{$type}->[$i] eq "__netjabber__:specifyname")
-                        {
-                            $xpath{$name}->{$type}->{specify_name} = 1;
-                            $i++;
-                            $xpath{$name}->{$type}->{tag} = $funcHash{$type}->[$i+1];
-                        }
-
-                        $i++;
-                    }
-                }
-                else
-                {
-                    $xpath{$name}->{$type} = $funcHash{$type};
-                }
-            }
-            next;
-        }
-        
-        my $type = $funcHash{set}->[0];
-        my $xpath = $funcHash{set}->[1];
-        if (exists($funcHash{hash}))
-        {
-            $xpath = "text()" if ($funcHash{hash} eq "data");
-            $xpath .= "/text()" if ($funcHash{hash} eq "child-data");
-            $xpath = "\@$xpath" if ($funcHash{hash} eq "att");
-            $xpath = "$1/\@$2" if ($funcHash{hash} =~ /^att-(\S+)-(.+)$/);
-        }
-
-        if ($type eq "master")
-        {
-            $xpath{$name}->{type} = $type;
-            next;
-        }
-        
-        if ($type eq "scalar")
-        {
-            $xpath{$name}->{path} = $xpath;
-            next;
-        }
-        
-        if ($type eq "flag")
-        {
-            $xpath{$name}->{type} = 'flag';
-            $xpath{$name}->{path} = $xpath;
-            next;
-        }
-
-        if (($funcHash{hash} eq "child-add") && exists($funcHash{add}))
-        {
-            $xpath{$name}->{type} = "node";
-            $xpath{$name}->{path} = $funcHash{add}->[3];
-            $xpath{$name}->{child}->{ns} = $funcHash{add}->[1];
-            $xpath{$name}->{calls} = [ 'Add' ];
-            next;
-        }
-    }
-
-    $self->AddNamespace(ns => $args{xmlns},
-                        tag => $tag,
-                        xpath => \%xpath );
-}
-
-###############################################################################
-#
-# AgentsGet - Sends an empty IQ to the server/transport to request that the
-#             list of supported Agents be sent to them.  Returns a hash
-#             containing the values for the agents.
-#
-###############################################################################
-sub AgentsGet
-{
-    my $self = shift;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(@_);
-    $iq->SetIQ(type=>"get");
-    my $query = $iq->NewQuery("jabber:iq:agents");
-
-    $iq = $self->SendAndReceiveWithID($iq);
-
-    return unless defined($iq);
-
-    $query = $iq->GetQuery();
-    my @agents = $query->GetAgents();
-
-    my %agents;
-    my $count = 0;
-    foreach my $agent (@agents)
-    {
-        my $jid = $agent->GetJID();
-        $agents{$jid}->{name} = $agent->GetName();
-        $agents{$jid}->{description} = $agent->GetDescription();
-        $agents{$jid}->{transport} = $agent->GetTransport();
-        $agents{$jid}->{service} = $agent->GetService();
-        $agents{$jid}->{register} = $agent->DefinedRegister();
-        $agents{$jid}->{search} = $agent->DefinedSearch();
-        $agents{$jid}->{groupchat} = $agent->DefinedGroupChat();
-        $agents{$jid}->{agents} = $agent->DefinedAgents();
-        $agents{$jid}->{order} = $count++;
-    }
-
-    return %agents;
-}
-
-
-###############################################################################
-#
-# BrowseRequest - requests the browse information from the specified JID.
-#
-###############################################################################
-sub BrowseRequest
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "block";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>$args{jid},
-               type=>"get");
-    my $query = $iq->NewQuery("jabber:iq:browse");
-
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    #--------------------------------------------------------------------------
-    # Check if there was an error.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    if ($iq->GetType() eq "error")
-    {
-        $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError());
-        return;
-    }
-
-    $query = $iq->GetQuery();
-
-    if (defined($query))
-    {
-        my %browse = %{$self->BrowseParse($query)};
-        return %browse;
-    }
-    else
-    {
-        return;
-    }
-}
-
-
-###############################################################################
-#
-# BrowseParse - helper function for BrowseRequest to convert the object
-#               tree into a hash for better consumption.
-#
-###############################################################################
-sub BrowseParse
-{ 
-    my $self = shift;
-    my $item = shift;
-    my %browse;
-
-    if ($item->DefinedCategory())
-    {
-        $browse{category} = $item->GetCategory();
-    }
-    else
-    {
-        $browse{category} = $item->GetTag();
-    }
-    $browse{type} = $item->GetType();
-    $browse{name} = $item->GetName();
-    $browse{jid} = $item->GetJID();
-    $browse{ns} = [ $item->GetNS() ];
-
-    foreach my $subitem ($item->GetItems())
-    {
-        my ($subbrowse) = $self->BrowseParse($subitem);
-        push(@{$browse{children}},$subbrowse);
-    }
-
-    return \%browse;
-}
-
-
-###############################################################################
-#
-# BrowseDBDelete - delete the JID from the DB completely.
-#
-###############################################################################
-sub BrowseDBDelete
-{
-    my $self = shift;
-    my ($jid) = @_;
-
-    my $indexJID = $jid;
-    $indexJID = $jid->GetJID() if (ref($jid) eq "Net::Jabber::JID");
-
-    return if !exists($self->{BROWSEDB}->{$indexJID});
-    delete($self->{BROWSEDB}->{$indexJID});
-    $self->{DEBUG}->Log1("BrowseDBDelete: delete ",$indexJID," from the DB");
-}
-
-
-###############################################################################
-#
-# BrowseDBQuery - retrieve the last Net::Jabber::Browse received with
-#                  the highest priority.
-#
-###############################################################################
-sub BrowseDBQuery
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $args{timeout} = 10 unless exists($args{timeout});
-
-    my $indexJID = $args{jid};
-    $indexJID = $args{jid}->GetJID() if (ref($args{jid}) eq "Net::Jabber::JID");
-
-    if ((exists($args{refresh}) && ($args{refresh} eq "1")) ||
-        (!exists($self->{BROWSEDB}->{$indexJID})))
-    {
-        my %browse = $self->BrowseRequest(jid=>$args{jid},
-                                          timeout=>$args{timeout});
-
-        $self->{BROWSEDB}->{$indexJID} = \%browse;
-    }
-    return %{$self->{BROWSEDB}->{$indexJID}};
-}
-
-
-###############################################################################
-#
-# ByteStreamsProxyRequest - This queries a proxy server to get a list of 
-#
-###############################################################################
-sub ByteStreamsProxyRequest
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "block";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>$args{jid},
-               type=>"get");
-    my $query = $iq->NewQuery("http://jabber.org/protocol/bytestreams");
-
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    #--------------------------------------------------------------------------
-    # Check if there was an error.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    if ($iq->GetType() eq "error")
-    {
-        $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError());
-        return;
-    }
-
-    $query = $iq->GetQuery();
-
-    if (defined($query))
-    {
-        my @hosts = @{$self->ByteStreamsProxyParse($query)};
-        return @hosts;
-    }
-    else
-    {
-        return;
-    }
-}
-
-
-###############################################################################
-#
-# ByteStreamsProxyParse - helper function for ByteStreamProxyRequest to convert
-#                         the object tree into a hash for better consumption.
-#
-###############################################################################
-sub ByteStreamsProxyParse
-{
-    my $self = shift;
-    my $item = shift;
-
-    my @hosts;
-
-    foreach my $host ($item->GetStreamHosts())
-    {
-        my %host;
-        $host{jid} = $host->GetJID();
-        $host{host} = $host->GetHost() if $host->DefinedHost();
-        $host{port} = $host->GetPort() if $host->DefinedPort();
-        $host{zeroconf} = $host->GetZeroConf() if $host->DefinedZeroConf();
-
-        push(@hosts,\%host);
-    }
-    
-    return \@hosts;
-}
-
-
-###############################################################################
-#
-# ByteStreamsProxyActivate - This tells a proxy to activate the connection 
-#
-###############################################################################
-sub ByteStreamsProxyActivate
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "block";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>$args{jid},
-               type=>"set");
-    my $query = $iq->NewQuery("http://jabber.org/protocol/bytestreams");
-    $query->SetByteStreams(sid=>$args{sid},
-                           activate=>(ref($args{recipient}) eq "Net::Jabber::JID" ? $args{recipient}->GetJID("full") : $args{recipient})
-                         );
-    
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-    
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    #--------------------------------------------------------------------------
-    # Check if there was an error.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    if ($iq->GetType() eq "error")
-    {
-        $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError());
-        return;
-    }
-
-    return 1;
-}
-
-
-###############################################################################
-#
-# ByteStreamsOffer - This offers a recipient a list of stream hosts to pick
-#                    from.
-#
-###############################################################################
-sub ByteStreamsOffer
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "block";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>$args{jid},
-               type=>"set");
-    my $query = $iq->NewQuery("http://jabber.org/protocol/bytestreams");
-
-    $query->SetByteStreams(sid=>$args{sid});
-
-    foreach my $host (@{$args{streamhosts}})
-    {
-        $query->AddStreamHost(jid=>$host->{jid},
-                              (exists($host->{host}) ? (host=>$host->{host}) : ()),
-                              (exists($host->{port}) ? (port=>$host->{port}) : ()),
-                              (exists($host->{zeroconf}) ? (zeroconf=>$host->{zeroconf}) : ()),
-                             );
-    }
-
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    #--------------------------------------------------------------------------
-    # Check if there was an error.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    if ($iq->GetType() eq "error")
-    {
-        $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError());
-        return;
-    }
-
-    $query = $iq->GetQuery();
-
-    if (defined($query))
-    {
-        return $query->GetStreamHostUsedJID();
-    }
-    else
-    {
-        return;
-    }
-}
-
-
-###############################################################################
-#
-# DiscoInfoRequest - requests the disco information from the specified JID.
-#
-###############################################################################
-sub DiscoInfoRequest
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "block";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>$args{jid},
-               type=>"get");
-    my $query = $iq->NewQuery("http://jabber.org/protocol/disco#info");
-    $query->SetDiscoInfo(node=>$args{node}) if exists($args{node});
-
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    #--------------------------------------------------------------------------
-    # Check if there was an error.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    if ($iq->GetType() eq "error")
-    {
-        $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError());
-        return;
-    }
-    return unless $iq->DefinedQuery();
-
-    $query = $iq->GetQuery();
-
-    return %{$self->DiscoInfoParse($query)};
-}
-
-
-###############################################################################
-#
-# DiscoInfoParse - helper function for DiscoInfoRequest to convert the object
-#                  tree into a hash for better consumption.
-#
-###############################################################################
-sub DiscoInfoParse
-{
-    my $self = shift;
-    my $item = shift;
-
-    my %disco;
-
-    foreach my $ident ($item->GetIdentities())
-    {
-        my %identity;
-        $identity{category} = $ident->GetCategory();
-        $identity{name} = $ident->GetName();
-        $identity{type} = $ident->GetType();
-        push(@{$disco{identity}},\%identity);
-    }
-
-    foreach my $feat ($item->GetFeatures())
-    {
-        $disco{feature}->{$feat->GetVar()} = 1;
-    }
-    
-    return \%disco;
-}
-
-
-###############################################################################
-#
-# DiscoItemsRequest - requests the disco information from the specified JID.
-#
-###############################################################################
-sub DiscoItemsRequest
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "block";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>$args{jid},
-               type=>"get");
-    my $query = $iq->NewQuery("http://jabber.org/protocol/disco#items");
-    $query->SetDiscoItems(node=>$args{node}) if exists($args{node});
-
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    #--------------------------------------------------------------------------
-    # Check if there was an error.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    if ($iq->GetType() eq "error")
-    {
-        $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError());
-        return;
-    }
-
-    $query = $iq->GetQuery();
-
-    if (defined($query))
-    {
-        my %disco = %{$self->DiscoItemsParse($query)};
-        return %disco;
-    }
-    else
-    {
-        return;
-    }
-}
-
-
-###############################################################################
-#
-# DiscoItemsParse - helper function for DiscoItemsRequest to convert the object
-#                   tree into a hash for better consumption.
-#
-###############################################################################
-sub DiscoItemsParse
-{
-    my $self = shift;
-    my $item = shift;
-
-    my %disco;
-
-    foreach my $item ($item->GetItems())
-    {
-        $disco{$item->GetJID()}->{$item->GetNode()} = $item->GetName();
-    }
-    
-    return \%disco;
-}
-
-
-###############################################################################
-#
-# FeatureNegRequest - requests a feature negotiation from the specified JID.
-#
-###############################################################################
-sub FeatureNegRequest
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "block";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>$args{jid},
-               type=>"get");
-
-    my $query = $self->FeatureNegQuery($args{features});
-
-    $iq->AddQuery($query);
-    
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    #--------------------------------------------------------------------------
-    # Check if there was an error.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    if ($iq->GetType() eq "error")
-    {
-        $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError());
-        return;
-    }
-
-    $query = $iq->GetQuery();
-
-    if (defined($query))
-    {
-        my %feats = %{$self->FeatureNegParse($query)};
-        return %feats;
-    }
-    else
-    {
-        return;
-    }
-}
-
-#xxx fneg needs to reutrn a type='submit' on the x:data in a result
-
-
-###############################################################################
-#
-# FeatureNegQuery - given a feature hash, return a query that contains it.
-#
-###############################################################################
-sub FeatureNegQuery
-{
-    my $self = shift;
-    my $features = shift;
-
-    my $tag = "query";
-    $tag = $Net::Jabber::Query::TAGS{'http://jabber.org/protocol/feature-neg'}
-        if exists($Net::Jabber::Query::TAGS{'http://jabber.org/protocol/feature-neg'});
-    
-    my $query = Net::Jabber::Query->new($tag);
-    $query->SetXMLNS("http://jabber.org/protocol/feature-neg");
-    my $xdata = $query->NewX("jabber:x:data");
-    
-    foreach my $feature (keys(%{$features}))
-    {
-        my $field = $xdata->AddField(type=>"list-single",
-                                     var=>$feature);
-        foreach my $value (@{$features->{$feature}})
-        {
-            $field->AddOption(value=>$value);
-        }
-    }
-
-    return $query;
-}
-
-
-###############################################################################
-#
-# FeatureNegParse - helper function for FeatureNegRequest to convert the object
-#                   tree into a hash for better consumption.
-#
-###############################################################################
-sub FeatureNegParse
-{
-    my $self = shift;
-    my $item = shift;
-
-    my %feats;
-
-    my $xdata = $item->GetX("jabber:x:data");
-    
-    foreach my $field ($xdata->GetFields())
-    {
-        my @options;
-        
-        foreach my $option ($field->GetOptions())
-        {
-            push(@options,$option->GetValue());
-        }
-
-        if ($#options == -1)
-        {
-            
-            $feats{$field->GetVar()} = $field->GetValue();
-        }
-        else
-        {
-            $feats{$field->GetVar()} = \@options;
-        }
-    }
-    
-    return \%feats;
-}
-
-#XXX - need a feature-neg answer function...
-
-###############################################################################
-#
-# FileTransferOffer - offer a file transfer JEP-95
-#
-###############################################################################
-sub FileTransferOffer
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "block";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>$args{jid},
-               type=>"set");
-    my $query = $iq->NewQuery("http://jabber.org/protocol/si");
-    my $profile = $query->NewQuery("http://jabber.org/protocol/si/profile/file-transfer");
-
-    # XXX support hashing via MD5
-    # XXX support date via JEP-82
-
-    my ($filename) = ($args{filename} =~ /\/?([^\/]+)$/);
-
-    $profile->SetFile(name=>$filename,
-                      size=>(-s $args{filename})
-                     );
-
-    $profile->SetFile(desc=>$args{desc}) if exists($args{desc});
-
-    $query->SetStream(mimetype=>(-B $args{filename} ? 
-                                    "application/octect-stream" :
-                                    "text/plain"
-                                ),
-                      id=>$args{sid},
-                      profile=>"http://jabber.org/protocol/si/profile/file-transfer"
-                     );
-
-    if (!exists($args{skip_methods}))
-    {
-        if ($#{$args{methods}} == -1)
-        {
-            print STDERR "You did not provide any valid methods for file transfer.\n";
-            return;
-        }
-
-        my $fneg = $self->FeatureNegQuery({'stream-method'=>$args{methods}});
-
-        $query->AddQuery($fneg);
-    }
-
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    #--------------------------------------------------------------------------
-    # Check if there was an error.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    if ($iq->GetType() eq "error")
-    {
-        $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError());
-        return;
-    }
-
-    $query = $iq->GetQuery();
-
-    if (defined($query))
-    {
-        my @fneg = $query->GetQuery("http://jabber.org/protocol/feature-neg");
-        my @xdata = $fneg[0]->GetX("jabber:x:data");
-        my @fields = $xdata[0]->GetFields();
-        return $fields[0]->GetValue();
-        # XXX need better error handling
-    }
-    else
-    {
-        return;
-    }
-}
-
-
-###############################################################################
-#
-# TreeTransferOffer - offer a file transfer JEP-95
-#
-###############################################################################
-sub TreeTransferOffer
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "block";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>$args{jid},
-               type=>"set");
-    my $query = $iq->NewQuery("http://jabber.org/protocol/si");
-    my $profile = $query->NewQuery("http://jabber.org/protocol/si/profile/tree-transfer");
-
-    my ($root) = ($args{directory} =~ /\/?([^\/]+)$/);
-
-    my $rootDir = $profile->AddDirectory(name=>$root);
-
-    my %tree;
-    $tree{counter} = 0;
-    $self->TreeTransferDescend($args{sidbase},
-                               $args{directory},
-                               $rootDir,
-                               \%tree
-                              );
-
-    $profile->SetTree(numfiles=>$tree{counter},
-                      size=>$tree{size}
-                     );
-
-    $query->SetStream(id=>$args{sidbase},
-                      profile=>"http://jabber.org/protocol/si/profile/tree-transfer"
-                     );
-
-    if ($#{$args{methods}} == -1)
-    {
-        print STDERR "You did not provide any valid methods for the tree transfer.\n";
-        return;
-    }
-
-    my $fneg = $self->FeatureNegQuery({'stream-method'=>$args{methods}});
-
-    $query->AddQuery($fneg);
-
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        $tree{id} = $id;
-        return %tree;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    #--------------------------------------------------------------------------
-    # Check if there was an error.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    if ($iq->GetType() eq "error")
-    {
-        $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError());
-        return;
-    }
-
-    $query = $iq->GetQuery();
-
-    if (defined($query))
-    {
-        my @fneg = $query->GetQuery("http://jabber.org/protocol/feature-neg");
-        my @xdata = $fneg[0]->GetX("jabber:x:data");
-        my @fields = $xdata[0]->GetFields();
-        return $fields[0]->GetValue();
-        # XXX need better error handling
-    }
-    else
-    {
-        return;
-    }
-}
-
-
-###############################################################################
-#
-# TreeTransferDescend - descend a directory structure and build the packet.
-#
-###############################################################################
-sub TreeTransferDescend
-{
-    my $self = shift;
-    my $sidbase = shift;
-    my $path = shift;
-    my $parent = shift;
-    my $tree = shift;
-
-    $tree->{size} += (-s $path);
-            
-    opendir(DIR, $path);
-    foreach my $file ( sort {$a cmp $b} readdir(DIR) )
-    {
-        next if ($file =~ /^\.\.?$/);
-
-        if (-d "$path/$file")
-        {
-            my $tempParent = $parent->AddDirectory(name=>$file);
-            $self->TreeTransferDescend($sidbase,
-                                       "$path/$file",
-                                       $tempParent,
-                                       $tree
-                                      );
-        }
-        else
-        {
-            $tree->{size} += (-s "$path/$file");
-            
-            $tree->{tree}->{"$path/$file"}->{order} = $tree->{counter};
-            $tree->{tree}->{"$path/$file"}->{sid} =
-                $sidbase."-".$tree->{counter};
-            $tree->{tree}->{"$path/$file"}->{name} = $file;
-
-            $parent->AddFile(name=>$tree->{tree}->{"$path/$file"}->{name},
-                             sid=>$tree->{tree}->{"$path/$file"}->{sid});
-            $tree->{counter}++;
-        }
-    }
-    closedir(DIR);
-}
-
-
-###############################################################################
-#
-# LastQuery - Sends an iq:last query to either the server or the specified
-#             JID.
-#
-###############################################################################
-sub LastQuery
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "passthru";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $args{waitforid} = 0 unless exists($args{waitforid});
-    my $waitforid = delete($args{waitforid});
-    $args{mode} = "block" if $waitforid;
-    
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>delete($args{to})) if exists($args{to});
-    $iq->SetIQ(type=>'get');
-    my $last = $iq->NewQuery("jabber:iq:last");
-
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    return unless defined($iq);
-
-    $last = $iq->GetQuery();
-
-    return unless defined($last);
-
-    return $last->GetLast();
-}
-
-
-###############################################################################
-#
-# LastSend - sends an iq:last packet to the specified user.
-#
-###############################################################################
-sub LastSend
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $args{ignoreactivity} = 0 unless exists($args{ignoreactivity});
-    my $ignoreActivity = delete($args{ignoreactivity});
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>delete($args{to}),
-             type=>'result');
-    my $last = $iq->NewQuery("jabber:iq:last");
-    $last->SetLast(%args);
-
-    $self->Send($iq,$ignoreActivity);
-}
-
-
-###############################################################################
-#
-# LastActivity - returns number of seconds since the last activity.
-#
-###############################################################################
-sub LastActivity
-{
-    my $self = shift;
-
-    return (time - $self->{STREAM}->LastActivity($self->{SESSION}->{id}));
-}
-
-
-###############################################################################
-#
-# RegisterSendData - This is a self contained function to send a register iq
-#                    tag with an id.  It uses the jabber:x:data method to
-#                    return the data.
-#
-###############################################################################
-sub RegisterSendData
-{
-    my $self = shift;
-    my $to = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    #--------------------------------------------------------------------------
-    # Create a Net::Jabber::IQ object to send to the server
-    #--------------------------------------------------------------------------
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>$to) if (defined($to) && ($to ne ""));
-    $iq->SetIQ(type=>"set");
-    my $iqRegister = $iq->NewQuery("jabber:iq:register");
-    my $xForm = $iqRegister->NewX("jabber:x:data");
-    foreach my $var (keys(%args))
-    {
-        next if ($args{$var} eq "");
-        $xForm->AddField(var=>$var,
-                         value=>$args{$var}
-                        );
-    }
-
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    $iq = $self->SendAndReceiveWithID($iq);
-
-    #--------------------------------------------------------------------------
-    # From the reply IQ determine if we were successful or not.  If yes then
-    # return "".  If no then return error string from the reply.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    return ( $iq->GetErrorCode() , $iq->GetError() )
-        if ($iq->GetType() eq "error");
-    return ("ok","");
-}
-
-
-###############################################################################
-#
-# RPCSetCallBacks - place to register a callback for RPC calls.  This is
-#                   used in conjunction with the default IQ callback.
-#
-###############################################################################
-sub RPCSetCallBacks
-{
-    my $self = shift;
-    while($#_ >= 0) {
-        my $func = pop(@_);
-        my $method = pop(@_);
-        $self->{DEBUG}->Log2("RPCSetCallBacks: method($method) func($func)");
-        if (defined($func))
-        {
-            $self->{RPCCB}{$method} = $func;
-        }
-        else
-        {
-            delete($self->{RPCCB}{$method});
-        }
-    }
-}
-
-
-###############################################################################
-#
-# RPCCall - Make an RPC call to the specified JID.
-#
-###############################################################################
-sub RPCCall
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "block";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(type=>"set",
-               to=>delete($args{to}));
-    $iq->AddQuery($self->RPCEncode(type=>"methodCall",
-                                   %args));
-
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    return unless defined($iq);
-
-    return $self->RPCParse($iq);
-}
-
-
-###############################################################################
-#
-# RPCResponse - Send back an RPC response, or fault, to the specified JID.
-#
-###############################################################################
-sub RPCResponse
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(type=>"result",
-               to=>delete($args{to}));
-    $iq->AddQuery($self->RPCEncode(type=>"methodResponse",
-                                   %args));
-
-    $iq = $self->SendAndReceiveWithID($iq);
-    return unless defined($iq);
-
-    return $self->RPCParse($iq);
-}
-
-
-###############################################################################
-#
-# RPCEncode - Returns a Net::Jabber::Query with the arguments encoded for the
-#             RPC packet.
-#
-###############################################################################
-sub RPCEncode
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $query = Net::Jabber::Stanza->new("query");
-    $query->SetXMLNS("jabber:iq:rpc");
-
-    my $source;
-
-    if ($args{type} eq "methodCall")
-    {
-        $source = $query->AddMethodCall();
-        $source->SetMethodName($args{methodname});
-    }
-
-    if ($args{type} eq "methodResponse")
-    {
-        $source = $query->AddMethodResponse();
-    }
-
-    if (exists($args{faultcode}) || exists($args{faultstring}))
-    {
-        my $struct = $source->AddFault()->AddValue()->AddStruct();
-        $struct->AddMember(name=>"faultCode")->AddValue(i4=>$args{faultcode});
-        $struct->AddMember(name=>"faultString")->AddValue(string=>$args{faultstring});
-    }
-    elsif (exists($args{params}))
-    {
-        my $params = $source->AddParams();
-        foreach my $param (@{$args{params}})
-        {
-            $self->RPCEncode_Value($params->AddParam(),$param);
-        }
-    }
-
-    return $query;
-}
-
-
-###############################################################################
-#
-# RPCEncode_Value - Run through the value, and encode it into XML.
-#
-###############################################################################
-sub RPCEncode_Value
-{
-    my $self = shift;
-    my $obj = shift;
-    my $value = shift;
-
-    if (ref($value) eq "ARRAY")
-    {
-        my $array = $obj->AddValue()->AddArray();
-        foreach my $data (@{$value})
-        {
-            $self->RPCEncode_Value($array->AddData(),$data);
-        }
-    }
-    elsif (ref($value) eq "HASH")
-    {
-        my $struct = $obj->AddValue()->AddStruct();
-        foreach my $key (keys(%{$value}))
-        {
-            $self->RPCEncode_Value($struct->AddMember(name=>$key),$value->{$key});
-        }
-    }
-    else
-    {
-        if ($value =~ /^(int|i4|boolean|string|double|datetime|base64):/i)
-        {
-            my $type = $1;
-            my($val) = ($value =~ /^$type:(.*)$/);
-            $obj->AddValue($type=>$val);
-        }
-        elsif ($value =~ /^[+-]?\d+$/)
-        {
-            $obj->AddValue(i4=>$value);
-        }
-        elsif ($value =~ /^(-?(?:\d+(?:\.\d*)?|\.\d+)|([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?)$/)
-        {
-            $obj->AddValue(double=>$value);
-        }
-        else
-        {
-            $obj->AddValue(string=>$value);
-        }
-    }
-}
-
-
-###############################################################################
-#
-# RPCParse - Returns an array of the params sent in the RPC packet.
-#
-###############################################################################
-sub RPCParse
-{
-    my $self = shift;
-    my($iq) = @_;
-
-    my $query = $iq->GetQuery();
-
-    my $source;
-    $source = $query->GetMethodCall() if $query->DefinedMethodCall();
-    $source = $query->GetMethodResponse() if $query->DefinedMethodResponse();
-
-    if (defined($source))
-    {
-        if (($source->GetTag() eq "methodResponse") && ($source->DefinedFault()))
-        {
-            my %response =
-                $self->RPCParse_Struct($source->GetFault()->GetValue()->GetStruct());
-            return ("fault",\%response);
-        }
-
-        if ($source->DefinedParams())
-        {
-            #------------------------------------------------------------------
-            # The <param/>s part
-            #------------------------------------------------------------------
-            my @response;
-            foreach my $param ($source->GetParams()->GetParams())
-            {
-                push(@response,$self->RPCParse_Value($param->GetValue()));
-            }
-            return ("ok",\@response);
-        }
-    }
-    else
-    {
-        print "AAAAHHHH!!!!\n";
-    }
-}
-
-
-###############################################################################
-#
-# RPCParse_Value - Takes a <value/> and returns the data it represents
-#
-###############################################################################
-sub RPCParse_Value
-{
-    my $self = shift;
-    my($value) = @_;
-
-    if ($value->DefinedStruct())
-    {
-        my %struct = $self->RPCParse_Struct($value->GetStruct());
-        return \%struct;
-    }
-
-    if ($value->DefinedArray())
-    {
-        my @array = $self->RPCParse_Array($value->GetArray());
-        return \@array;
-    }
-
-    return $value->GetI4() if $value->DefinedI4();
-    return $value->GetInt() if $value->DefinedInt();
-    return $value->GetBoolean() if $value->DefinedBoolean();
-    return $value->GetString() if $value->DefinedString();
-    return $value->GetDouble() if $value->DefinedDouble();
-    return $value->GetDateTime() if $value->DefinedDateTime();
-    return $value->GetBase64() if $value->DefinedBase64();
-
-    return $value->GetValue();
-}
-
-
-###############################################################################
-#
-# RPCParse_Struct - Takes a <struct/> and returns the hash of values.
-#
-###############################################################################
-sub RPCParse_Struct
-{
-    my $self = shift;
-    my($struct) = @_;
-
-    my %struct;
-    foreach my $member ($struct->GetMembers())
-    {
-        $struct{$member->GetName()} = $self->RPCParse_Value($member->GetValue());
-    }
-
-    return %struct;
-}
-
-
-###############################################################################
-#
-# RPCParse_Array - Takes a <array/> and returns the hash of values.
-#
-###############################################################################
-sub RPCParse_Array
-{
-    my $self = shift;
-    my($array) = @_;
-
-    my @array;
-    foreach my $data ($array->GetDatas())
-    {
-        push(@array,$self->RPCParse_Value($data->GetValue()));
-    }
-
-    return @array;
-}
-
-
-###############################################################################
-#
-# SearchRequest - This is a self contained function to send an iq tag
-#                 an id that requests the target address to send back
-#                 the required fields.  It waits for a reply what the
-#                 same id to come back and tell the caller what the
-#                 fields are.
-#
-###############################################################################
-sub SearchRequest
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "block";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    #--------------------------------------------------------------------------
-    # Create a Net::Jabber::IQ object to send to the server
-    #--------------------------------------------------------------------------
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>delete($args{to})) if exists($args{to});
-    $iq->SetIQ(type=>"get");
-    my $query = $iq->NewQuery("jabber:iq:search");
-
-    $self->{DEBUG}->Log1("SearchRequest: sent(",$iq->GetXML(),")");
-
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    $self->{DEBUG}->Log1("SearchRequest: received(",$iq->GetXML(),")")
-        if defined($iq);
-
-    #--------------------------------------------------------------------------
-    # Check if there was an error.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    if ($iq->GetType() eq "error")
-    {
-        $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError());
-        $self->{DEBUG}->Log1("SearchRequest: error(",$self->GetErrorCode(),")");
-        return;
-    }
-
-    my %search;
-    #--------------------------------------------------------------------------
-    # From the reply IQ determine what fields are required and send a hash
-    # back with the fields and any values that are already defined (like key)
-    #--------------------------------------------------------------------------
-    $query = $iq->GetQuery();
-    $search{fields} = { $query->GetSearch() };
-
-    #--------------------------------------------------------------------------
-    # Get any forms so that we have the option of showing a nive dynamic form
-    # to the user and not just a bunch of fields.
-    #--------------------------------------------------------------------------
-    &ExtractForms(\%search,$query->GetX("jabber:x:data"));
-
-    #--------------------------------------------------------------------------
-    # Get any oobs so that we have the option of sending the user to the http
-    # form and not a dynamic one.
-    #--------------------------------------------------------------------------
-    &ExtractOobs(\%search,$query->GetX("jabber:x:oob"));
-
-    return %search;
-}
-
-
-###############################################################################
-#
-# SearchSend - This is a self contained function to send a search
-#              iq tag with an id.  Then wait for a reply what the same
-#              id to come back and tell the caller what the result was.
-#
-###############################################################################
-sub SearchSend
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    #--------------------------------------------------------------------------
-    # Create a Net::Jabber::IQ object to send to the server
-    #--------------------------------------------------------------------------
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>delete($args{to})) if exists($args{to});
-    $iq->SetIQ(type=>"set");
-    my $iqSearch = $iq->NewQuery("jabber:iq:search");
-    $iqSearch->SetSearch(%args);
-
-    #--------------------------------------------------------------------------
-    # Send the IQ.
-    #--------------------------------------------------------------------------
-    $self->Send($iq);
-}
-
-
-###############################################################################
-#
-# SearchSendData - This is a self contained function to send a search iq tag
-#                  with an id.  It uses the jabber:x:data method to return the
-#                  data.
-#
-###############################################################################
-sub SearchSendData
-{
-    my $self = shift;
-    my $to = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    #--------------------------------------------------------------------------
-    # Create a Net::Jabber::IQ object to send to the server
-    #--------------------------------------------------------------------------
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>$to) if (defined($to) && ($to ne ""));
-    $iq->SetIQ(type=>"set");
-    my $iqSearch = $iq->NewQuery("jabber:iq:search");
-    my $xForm = $iqSearch->NewX("jabber:x:data");
-    foreach my $var (keys(%args))
-    {
-        next if ($args{$var} eq "");
-        $xForm->AddField(var=>$var,
-                         value=>$args{$var}
-                        );
-    }
-
-    #--------------------------------------------------------------------------
-    # Send the IQ.
-    #--------------------------------------------------------------------------
-    $self->Send($iq);
-}
-
-
-###############################################################################
-#
-# TimeQuery - Sends an iq:time query to either the server or the specified
-#             JID.
-#
-###############################################################################
-sub TimeQuery
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "passthru";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $args{waitforid} = 0 unless exists($args{waitforid});
-    my $waitforid = delete($args{waitforid});
-    $args{mode} = "block" if $waitforid;
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>delete($args{to})) if exists($args{to});
-    $iq->SetIQ(type=>'get',%args);
-    my $time = $iq->NewQuery("jabber:iq:time");
-
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    return unless defined($iq);
-
-    my $query = $iq->GetQuery();
-
-    return unless defined($query);
-
-    my %result;
-    $result{utc} = $query->GetUTC();
-    $result{display} = $query->GetDisplay();
-    $result{tz} = $query->GetTZ();
-    return %result;
-}
-
-
-###############################################################################
-#
-# TimeSend - sends an iq:time packet to the specified user.
-#
-###############################################################################
-sub TimeSend
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>delete($args{to}),
-               type=>'result');
-    my $time = $iq->NewQuery("jabber:iq:time");
-    $time->SetTime(%args);
-
-    $self->Send($iq);
-}
-
-
-
-###############################################################################
-#
-# VersionQuery - Sends an iq:version query to either the server or the
-#                specified JID.
-#
-###############################################################################
-sub VersionQuery
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "passthru";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $args{waitforid} = 0 unless exists($args{waitforid});
-    my $waitforid = delete($args{waitforid});
-    $args{mode} = "block" if $waitforid;
-    
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>delete($args{to})) if exists($args{to});
-    $iq->SetIQ(type=>'get',%args);
-    my $version = $iq->NewQuery("jabber:iq:version");
-
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    return unless defined($iq);
-
-    my $query = $iq->GetQuery();
-
-    return unless defined($query);
-
-    my %result;
-    $result{name} = $query->GetName();
-    $result{ver} = $query->GetVer();
-    $result{os} = $query->GetOS();
-    return %result;
-}
-
-
-###############################################################################
-#
-# VersionSend - sends an iq:version packet to the specified user.
-#
-###############################################################################
-sub VersionSend
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>delete($args{to}),
-               type=>'result');
-    my $version = $iq->NewQuery("jabber:iq:version");
-    $version->SetVersion(%args);
-
-    $self->Send($iq);
-}
-
-
-###############################################################################
-#
-# MUCJoin - join a MUC room
-#
-###############################################################################
-sub MUCJoin
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $presence = $self->_presence();
-    $presence->SetTo($args{room}.'@'.$args{server}.'/'.$args{nick});
-    my $x = $presence->NewChild("http://jabber.org/protocol/muc");
-
-    if (exists($args{password}) && ($args{password} ne ""))
-    {
-        $x->SetMUC(password=>$args{password});
-    }
-    
-    return $presence->GetXML() if exists($args{'__netjabber__:test'});
-    $self->Send($presence);
-}
-
-
-###############################################################################
-#+-----------------------------------------------------------------------------
-#|
-#| Helper Functions
-#|
-#+-----------------------------------------------------------------------------
-###############################################################################
-
-
-###############################################################################
-#
-# ExtractForms - Helper function to make extracting jabber:x:data for forms
-#                more centrally definable.
-#
-###############################################################################
-sub ExtractForms
-{
-    my ($target,@xForms) = @_;
-
-    my $tempVar = "1";
-    foreach my $xForm (@xForms) {
-        $target->{instructions} = $xForm->GetInstructions();
-        my $order = 0;
-        foreach my $field ($xForm->GetFields())
-        {
-            $target->{form}->[$order]->{type} = $field->GetType()
-                if $field->DefinedType();
-            $target->{form}->[$order]->{label} = $field->GetLabel()
-                if $field->DefinedLabel();
-            $target->{form}->[$order]->{desc} = $field->GetDesc()
-                if $field->DefinedDesc();
-            $target->{form}->[$order]->{var} = $field->GetVar()
-                if $field->DefinedVar();
-            $target->{form}->[$order]->{var} = "__netjabber__:tempvar:".$tempVar++
-                if !$field->DefinedVar();
-            if ($field->DefinedValue())
-            {
-                if ($field->GetType() eq "list-multi")
-                {
-                    $target->{form}->[$order]->{value} = [ $field->GetValue() ];
-                }
-                else
-                {
-                    $target->{form}->[$order]->{value} = ($field->GetValue())[0];
-                }
-            }  
-            my $count = 0;
-            foreach my $option ($field->GetOptions())
-            {
-                $target->{form}->[$order]->{options}->[$count]->{value} =
-                    $option->GetValue();
-                $target->{form}->[$order]->{options}->[$count]->{label} =
-                    $option->GetLabel();
-                $count++;
-            }
-            $order++;
-        }
-        foreach my $reported ($xForm->GetReported())
-        {
-            my $order = 0;
-            foreach my $field ($reported->GetFields())
-            {
-                $target->{reported}->[$order]->{label} = $field->GetLabel();
-                $target->{reported}->[$order]->{var} = $field->GetVar();
-                $order++;
-            }
-        }
-    }
-}
-
-
-###############################################################################
-#
-# ExtractOobs - Helper function to make extracting jabber:x:oob for forms
-#               more centrally definable.
-#
-###############################################################################
-sub ExtractOobs
-{
-    my ($target,@xOobs) = @_;
-
-    foreach my $xOob (@xOobs)
-    {
-        $target->{oob}->{url} = $xOob->GetURL();
-        $target->{oob}->{desc} = $xOob->GetDesc();
-    }
-}
-
-
-###############################################################################
-#+-----------------------------------------------------------------------------
-#|
-#| Default CallBacks
-#|
-#+-----------------------------------------------------------------------------
-###############################################################################
-
-
-###############################################################################
-#
-# callbackInit - initialize the default callbacks
-#
-###############################################################################
-sub callbackInit
-{
-    my $self = shift;
-
-    $self->SUPER::callbackInit();
-
-    $self->SetIQCallBacks("jabber:iq:last"=>
-                          {
-                            get=>sub{ $self->callbackGetIQLast(@_) },
-                            result=>sub{ $self->callbackResultIQLast(@_) }
-                          },
-                          "jabber:iq:rpc"=>
-                          {
-                            set=>sub{ $self->callbackSetIQRPC(@_) },
-                          },
-                          "jabber:iq:time"=>
-                          {
-                            get=>sub{ $self->callbackGetIQTime(@_) },
-                            result=>sub{ $self->callbackResultIQTime(@_) }
-                          },
-                          "jabber:iq:version"=>
-                          {
-                            get=>sub{ $self->callbackGetIQVersion(@_) },
-                            result=>sub{ $self->callbackResultIQVersion(@_) }
-                          },
-                         );
-}
-
-
-###############################################################################
-#
-# callbackSetIQRPC - callback to handle auto-replying to an iq:rpc by calling
-#                    the user registered functions.
-#
-###############################################################################
-sub callbackSetIQRPC
-{
-    my $self = shift;
-    my $sid = shift;
-    my $iq = shift;
-
-    my $query = $iq->GetQuery();
-
-    my $reply = $iq->Reply(type=>"result");
-    my $replyQuery = $reply->GetQuery();
-
-    if (!$query->DefinedMethodCall())
-    {
-        my $methodResponse = $replyQuery->AddMethodResponse();
-        my $struct = $methodResponse->AddFault()->AddValue()->AddStruct();
-        $struct->AddMember(name=>"faultCode")->AddValue(int=>400);
-        $struct->AddMember(name=>"faultString")->AddValue(string=>"Missing methodCall.");
-        $self->Send($reply,1);
-        return;
-    }
-
-    if (!$query->GetMethodCall()->DefinedMethodName())
-    {
-        my $methodResponse = $replyQuery->AddMethodResponse();
-        my $struct = $methodResponse->AddFault()->AddValue()->AddStruct();
-        $struct->AddMember(name=>"faultCode")->AddValue(int=>400);
-        $struct->AddMember(name=>"faultString")->AddValue(string=>"Missing methodName.");
-        $self->Send($reply,1);
-        return;
-    }
-
-    my $methodName = $query->GetMethodCall()->GetMethodName();
-
-    if (!exists($self->{RPCCB}->{$methodName}))
-    {
-        my $methodResponse = $replyQuery->AddMethodResponse();
-        my $struct = $methodResponse->AddFault()->AddValue()->AddStruct();
-        $struct->AddMember(name=>"faultCode")->AddValue(int=>404);
-        $struct->AddMember(name=>"faultString")->AddValue(string=>"methodName $methodName not defined.");
-        $self->Send($reply,1);
-        return;
-    }
-
-    my @params = $self->RPCParse($iq);
-
-    my @return = &{$self->{RPCCB}->{$methodName}}($iq,$params[1]);
-
-    if ($return[0] ne "ok") {
-        my $methodResponse = $replyQuery->AddMethodResponse();
-        my $struct = $methodResponse->AddFault()->AddValue()->AddStruct();
-        $struct->AddMember(name=>"faultCode")->AddValue(int=>$return[1]->{faultCode});
-        $struct->AddMember(name=>"faultString")->AddValue(string=>$return[1]->{faultString});
-        $self->Send($reply,1);
-        return;
-    }
-    $reply->RemoveQuery();
-    $reply->AddQuery($self->RPCEncode(type=>"methodResponse",
-                                      params=>$return[1]));
-
-    $self->Send($reply,1);
-}
-
-
-###############################################################################
-#
-# callbackGetIQTime - callback to handle auto-replying to an iq:time get.
-#
-###############################################################################
-sub callbackGetIQTime
-{
-    my $self = shift;
-    my $sid = shift;
-    my $iq = shift;
-
-    my $query = $iq->GetQuery();
-
-    my $reply = $iq->Reply(type=>"result");
-    my $replyQuery = $reply->GetQuery();
-    $replyQuery->SetTime();
-
-    $self->Send($reply,1);
-}
-
-
-###############################################################################
-#
-# callbackResultIQTime - callback to handle formatting iq:time result into
-#                        a message.
-#
-###############################################################################
-sub callbackResultIQTime
-{
-    my $self = shift;
-    my $sid = shift;
-    my $iq = shift;
-
-    my $fromJID = $iq->GetFrom("jid");
-    my $query = $iq->GetQuery();
-
-    my $body = "UTC: ".$query->GetUTC()."\n";
-    $body .=   "Time: ".$query->GetDisplay()."\n";
-    $body .=   "Timezone: ".$query->GetTZ()."\n";
-    
-    my $message = $self->_message();
-    $message->SetMessage(to=>$iq->GetTo(),
-                         from=>$iq->GetFrom(),
-                         subject=>"CTCP: Time",
-                         body=>$body);
-
-
-    $self->CallBack($sid,$message);
-}
-
-
-###############################################################################
-#
-# callbackGetIQVersion - callback to handle auto-replying to an iq:time
-#                        get.
-#
-###############################################################################
-sub callbackGetIQVersion
-{
-    my $self = shift;
-    my $sid = shift;
-    my $iq = shift;
-
-    my $query = $iq->GetQuery();
-
-    my $reply = $iq->Reply(type=>"result");
-    my $replyQuery = $reply->GetQuery();
-    $replyQuery->SetVersion(name=>$self->{INFO}->{name},
-                            ver=>$self->{INFO}->{version},
-                            os=>"");
-
-    $self->Send($reply,1);
-}
-
-
-###############################################################################
-#
-# callbackResultIQVersion - callback to handle formatting iq:time result
-#                           into a message.
-#
-###############################################################################
-sub callbackResultIQVersion
-{
-    my $self = shift;
-    my $sid = shift;
-    my $iq = shift;
-
-    my $query = $iq->GetQuery();
-
-    my $body = "Program: ".$query->GetName()."\n";
-    $body .=   "Version: ".$query->GetVer()."\n";
-    $body .=   "OS: ".$query->GetOS()."\n";
-
-    my $message = $self->_message();
-    $message->SetMessage(to=>$iq->GetTo(),
-                         from=>$iq->GetFrom(),
-                         subject=>"CTCP: Version",
-                         body=>$body);
-
-    $self->CallBack($sid,$message);
-}
-
-
-###############################################################################
-#
-# callbackGetIQLast - callback to handle auto-replying to an iq:last get.
-#
-###############################################################################
-sub callbackGetIQLast
-{
-    my $self = shift;
-    my $sid = shift;
-    my $iq = shift;
-
-    my $query = $iq->GetQuery();
-    my $reply = $iq->Reply(type=>"result");
-    my $replyQuery = $reply->GetQuery();
-    $replyQuery->SetLast(seconds=>$self->LastActivity());
-
-    $self->Send($reply,1);
-}
-
-
-###############################################################################
-#
-# callbackResultIQLast - callback to handle formatting iq:last result into
-#                        a message.
-#
-###############################################################################
-sub callbackResultIQLast
-{
-    my $self = shift;
-    my $sid = shift;
-    my $iq = shift;
-
-    my $fromJID = $iq->GetFrom("jid");
-    my $query = $iq->GetQuery();
-    my $seconds = $query->GetSeconds();
-
-    my $lastTime = &Net::Jabber::GetTimeStamp("local",(time - $seconds),"long");
-
-    my $elapsedTime = &Net::Jabber::GetHumanTime($seconds);
-
-    my $body;
-    if ($fromJID->GetUserID() eq "")
-    {
-        $body  = "Start Time: $lastTime\n";
-        $body .= "Up time: $elapsedTime\n";
-        $body .= "Message: ".$query->GetMessage()."\n"
-            if ($query->DefinedMessage());
-    }
-    elsif ($fromJID->GetResource() eq "")
-    {
-        $body  = "Logout Time: $lastTime\n";
-        $body .= "Elapsed time: $elapsedTime\n";
-        $body .= "Message: ".$query->GetMessage()."\n"
-            if ($query->DefinedMessage());
-    }
-    else
-    {
-        $body  = "Last activity: $lastTime\n";
-        $body .= "Elapsed time: $elapsedTime\n";
-        $body .= "Message: ".$query->GetMessage()."\n"
-            if ($query->DefinedMessage());
-    }
-    
-    my $message = $self->_message();
-    $message->SetMessage(from=>$iq->GetFrom(),
-                         subject=>"Last Activity",
-                         body=>$body);
-
-    $self->CallBack($sid,$message);
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Server.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Server.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,393 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Server;
-
-=head1 NAME
-
-Net::Jabber::Server - Jabber Server Library
-
-=head1 SYNOPSIS
-
-  Net::Jabber::Server is a module that provides a developer easy access
-  to developing applications that need an embedded Jabber server.
-
-=head1 DESCRIPTION
-
-  Server.pm seeks to provide enough high level APIs and automation of
-  the low level APIs that writing and spawning a Jabber Server in Perl
-  is trivial.  For those that wish to work with the low level you can
-  do that too, but those functions are covered in the documentation for
-  each module.
-
-  Net::Jabber::Server provides functions to run a full Jabber server that
-  accepts incoming connections and delivers packets to external Jabber
-  servers.  You can use all or none of the functions, there is no requirement.
-
-  For more information on how the details for how Net::Jabber is written
-  please see the help for Net::Jabber itself.
-
-  For a full list of high level functions available please see
-  Net::Jabber::Protocol.
-
-=head2 Basic Functions
-
-    use Net::Jabber qw(Server);
-
-    $Server = Net::Jabber::Server->new();
-
-    $Server->Start();
-    $Server->Start(jabberxml=>"custom_jabber.xml",
-	           hostname=>"foobar.net");
-
-    %status = $Server->Process();
-    %status = $Server->Process(5);
-    
-    $Server->Stop();
-
-=head1 METHODS
-
-=head2 Basic Functions
-
-    new(debuglevel=>0|1|2, - creates the Server object.  debugfile
-        debugfile=>string,   should be set to the path for the debug
-        debugtime=>0|1)      log to be written.  If set to "stdout"
-                             then the debug will go there.  debuglevel
-                             controls the amount of debug.  For more
-                             information about the valid setting for
-                             debuglevel, debugfile, and debugtime see
-                             Net::Jabber::Debug.
-
-    Start(hostname=>string, - starts the server listening on the proper
-	  jaberxml=>string)   ports.  hostname is a quick way of telling
-                              the server the hostname to listen on.
-                              jabberxml defines the path to a different
-                              jabberd configuration file (default is
-                              "./jabber.xml").
-
-    Process(integer) - takes the timeout period as an argument.  If no
-                       timeout is listed then the function blocks until
-                       a packet is received.  Otherwise it waits that
-                       number of seconds and then exits so your program
-                       can continue doing useful things.  NOTE: This is
-                       important for GUIs.  You need to leave time to
-                       process GUI commands even if you are waiting for
-                       packets.  The following are the possible return
-                       values for each hash entry, and what they mean:
-
-                           1   - Status ok, data received.
-                           0   - Status ok, no data received.
-                         undef - Status not ok, stop processing.
-                       
-                       IMPORTANT: You need to check the output of every
-                       Process.  If you get an undef then the connection
-                       died and you should behave accordingly.
-
-    Stop() - stops the server from running and shuts down all sub programs.
-
-=head1 AUTHOR
-
-By Ryan Eatmon in January of 2001 for http://jabber.org.
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use Carp;
-use base qw( Net::Jabber::Protocol );
-use vars qw( $VERSION );
-
-$VERSION = "2.0";
-
-use Net::Jabber::Data;
-($Net::Jabber::Data::VERSION < $VERSION) &&
-  die("Net::Jabber::Data $VERSION required--this is only version $Net::Jabber::Data::VERSION");
-
-use Net::Jabber::XDB;
-($Net::Jabber::XDB::VERSION < $VERSION) &&
-  die("Net::Jabber::XDB $VERSION required--this is only version $Net::Jabber::XDB::VERSION");
-
-#use Net::Jabber::Log;
-#($Net::Jabber::Log::VERSION < $VERSION) &&
-#  die("Net::Jabber::Log $VERSION required--this is only version $Net::Jabber::Log::VERSION");
-
-use Net::Jabber::Dialback;
-($Net::Jabber::Dialback::VERSION < $VERSION) &&
-  die("Net::Jabber::Dialback $VERSION required--this is only version $Net::Jabber::Dialback::VERSION");
-
-use Net::Jabber::Key;
-($Net::Jabber::Key::VERSION < $VERSION) &&
-  die("Net::Jabber::Key $VERSION required--this is only version $Net::Jabber::Key::VERSION");
-
-sub new
-{
-    srand( time() ^ ($$ + ($$ << 15)));
-
-    my $proto = shift;
-    my $self = { };
-
-    my %args;
-    while($#_ >= 0) { $args{ lc(pop(@_)) } = pop(@_); }
-
-    bless($self, $proto);
-
-    $self->{KEY} = Net::Jabber::Key->new();
-
-    $self->{DEBUG} =
-        Net::Jabber::Debug->new(level=>exists($args{debuglevel}) ? $args{debuglevel} : -1,
-                                file=>exists($args{debugfile}) ? $args{debugfile} : "stdout",
-                                time=>exists($args{debugtime}) ? $args{debugtime} : 0,
-                                setdefault=>1,
-                                header=>"NJ::Server"
-                               );
-
-    $self->{SERVER} = { hostname => "localhost",
-                        port => 5269,
-                        servername => ""};
-
-    $self->{STREAM} = new XML::Stream(style=>"node",
-                                      debugfh=>$self->{DEBUG}->GetHandle(),
-                                      debuglevel=>$self->{DEBUG}->GetLevel(),
-                                      debugtime=>$self->{DEBUG}->GetTime());
-
-    $self->{STREAM}->SetCallBacks(node=>sub{ $self->CallBack(@_) },
-                                  sid=>sub{ return $self->{KEY}->Generate()});
-
-    $self->{VERSION} = $VERSION;
-
-    return $self;
-}
-
-
-##############################################################################
-#
-# Start - starts the server running
-#
-##############################################################################
-sub Start
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $self->{STOP} = 0;
-
-    $self->SetCallBacks('message'=>sub{ $self->messageHandler(@_); },
-                        'presence'=>sub{ $self->presenceHandler(@_); },
-                        'iq'=>sub{ $self->iqHandler(@_); },
-                        'db:result'=>sub{ $self->dbresultHandler(@_); },
-                        'db:verify'=>sub{ $self->dbverifyHandler(@_); },
-                       );
-
-    my $hostname = $self->{SERVER}->{hostname};
-    $hostname = $args{hostname} if exists($args{hostname});
-
-    my $status = $self->{STREAM}->Listen(hostname=>$hostname,
-                         port=>$self->{SERVER}->{port},
-                         namespace=>"jabber:server");
-
-    while($self->{STOP} == 0) {
-        while(($self->{STOP} == 0) && defined($self->{STREAM}->Process())) {
-        }
-    }
-}
-
-
-###############################################################################
-#
-#  Process - If a timeout value is specified then the function will wait
-#            that long before returning.  This is useful for apps that
-#            need to handle other processing while still waiting for
-#            packets.  If no timeout is listed then the function waits
-#            until a packet is returned.  Either way the function exits
-#            as soon as a packet is returned.
-#
-###############################################################################
-sub Process
-{
-    my $self = shift;
-    my ($timeout) = @_;
-    my %status;
-
-    if (exists($self->{PROCESSERROR}) && ($self->{PROCESSERROR} == 1))
-    {
-        croak("You should always check the output of the Process call.  If it was undef\nthen there was a fatal error that you need to check.  There is an error in your\nprogram.");
-    }
-
-    $self->{DEBUG}->Log1("Process: timeout($timeout)") if defined($timeout);
-
-    if (!defined($timeout) || ($timeout eq ""))
-    {
-        while(1)
-        {
-            %status = $self->{STREAM}->Process();
-            $self->{DEBUG}->Log1("Process: status($status{$self->{SESSION}->{id}})");
-            last if ($status{$self->{SESSION}->{id}} != 0);
-            select(undef,undef,undef,.25);
-        }
-        $self->{DEBUG}->Log1("Process: return($status{$self->{SESSION}->{id}})");
-        if ($status{$self->{SESSION}->{id}} == -1)
-        {
-            $self->{PROCESSERROR} = 1;
-            return;
-        }
-        else
-        {
-            return $status{$self->{SESSION}->{id}};
-        }
-    }
-    else
-    {
-        %status = $self->{STREAM}->Process($timeout);
-        if ($status{$self->{SESSION}->{id}} == -1)
-        {
-            $self->{PROCESSERROR} = 1;
-            return;
-        }
-        else
-        {
-            return $status{$self->{SESSION}->{id}};
-        }
-    }
-}
-
-
-##############################################################################
-#
-# Stop - shuts down the server
-#
-##############################################################################
-sub Stop
-{
-    my $self = shift;
-    $self->{STOP} = 1;
-}
-
-
-sub messageHandler
-{
-    my $self = shift;
-    my $sid = shift;
-    my ($message) = @_;
-
-    $self->{DEBUG}->Log2("messageHandler: message(",$message->GetXML(),")");
-
-    my $reply = $message->Reply();
-    $self->Send($reply);
-}
-
-
-sub presenceHandler
-{
-    my $self = shift;
-    my $sid = shift;
-    my ($presence) = @_;
-
-    $self->{DEBUG}->Log2("presenceHandler: presence(",$presence->GetXML(),")");
-}
-
-
-sub iqHandler
-{
-    my $self = shift;
-    my $sid = shift;
-    my ($iq) = @_;
-
-    $self->{DEBUG}->Log2("iqHandler: iq(",$iq->GetXML(),")");
-}
-
-
-sub dbresultHandler
-{
-    my $self = shift;
-    my $sid = shift;
-    my ($dbresult) = @_;
-
-    $self->{DEBUG}->Log2("dbresultHandler: dbresult(",$dbresult->GetXML(),")");
-
-    my $dbverify = Net::Jabber::Dialback::Verify->new();
-    $dbverify->SetVerify(to=>$dbresult->GetFrom(),
-                         from=>$dbresult->GetTo(),
-                         id=>$self->{STREAM}->GetRoot($sid)->{id},
-                         data=>$dbresult->GetData());
-    $self->Send($dbverify);
-}
-
-
-sub dbverifyHandler
-{
-    my $self = shift;
-    my $sid = shift;
-    my ($dbverify) = @_;
-
-    $self->{DEBUG}->Log2("dbverifyHandler: dbverify(",$dbverify->GetXML(),")");
-}
-
-
-sub Send
-{
-    my $self = shift;
-    my $object = shift;
-
-    if (ref($object) eq "")
-    {
-        my ($server) = ($object =~ /to=[\"\']([^\"\']+)[\"\']/);
-        $server =~ s/^\S*\@?(\S+)\/?.*$/$1/;
-        $self->SendXML($server,$object);
-    }
-    else
-    {
-        $self->SendXML($object->GetTo("jid")->GetServer(),$object->GetXML());
-    }
- }
-
-
-sub SendXML {
-    my $self = shift;
-    my $server = shift;
-    my $xml = shift;
-    $self->{DEBUG}->Log1("SendXML: server($server) sent($xml)");
-
-    my $sid = $self->{STREAM}->Host2SID($server);
-    if (!defined($sid)) {
-        $self->{STREAM}->Connect(hostname=>$server,
-                     port=>5269,
-                     connectiontype=>"tcpip",
-                     namespace=>"jabber:server");
-        $sid = $self->{STREAM}->Host2SID($server);
-    }
-    $self->{DEBUG}->Log1("SendXML: sid($sid)");
-    &{$self->{CB}->{send}}($sid,$xml) if exists($self->{CB}->{send});
-    $self->{STREAM}->Send($sid,$xml);
-}
-
-
-#
-# by not send xmlns:db='jabber:server:dialback' to a server, we operate in
-# legacy mode, and do not have to do dialback.
-#
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/Stanza.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/Stanza.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,1844 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::Stanza;
-
-=head1 NAME
-
-Net::Jabber::Stanza - Jabber Stanza Module
-
-=head1 SYNOPSIS
-
-  Net::Jabber::Stanza is a private package that serves as a basis
-  for all Jabber stanzas generated by Net::Jabber.
-
-=head1 DESCRIPTION
-
-  This module is not meant to be used directly.  You should be using
-  either Net::Jabber::IQ, Net::Jabber::Message, Net::Jabber::Presence, or
-  another package that inherits from Net::Jabber::Stanza.
-
-  That said, this is where all of the namespaced methods are defined.
-
-  The current supported namespaces are:
-
-=cut
-
-# NS_BEGIN
-
-=pod
-
-    http://jabber.org/protocol/bytestreams
-    http://jabber.org/protocol/commands
-    http://jabber.org/protocol/disco#info
-    http://jabber.org/protocol/disco#items
-    http://jabber.org/protocol/feature-neg
-    http://jabber.org/protocol/muc
-    http://jabber.org/protocol/muc#admin
-    http://jabber.org/protocol/muc#user
-    http://jabber.org/protocol/pubsub
-    http://jabber.org/protocol/pubsub#event
-    http://jabber.org/protocol/pubsub#owner
-    http://jabber.org/protocol/si
-    http://jabber.org/protocol/si/profile/file-transfer
-    jabber:iq:agent - DEPRECATED
-    jabber:iq:agents - DEPRECATED
-    jabber:iq:autoupdate
-    jabber:iq:browse - DEPRECATED
-    jabber:iq:conference
-    jabber:iq:filter - DEPRECATED
-    jabber:iq:gateway
-    jabber:iq:last
-    jabber:iq:oob
-    jabber:iq:pass
-    jabber:iq:rpc
-    jabber:iq:search
-    jabber:iq:time
-    jabber:iq:version
-    jabber:x:autoupdate
-    jabber:x:conference
-    jabber:x:data
-    jabber:x:delay
-    jabber:x:encrypted
-    jabber:x:event
-    jabber:x:expire
-    jabber:x:oob
-    jabber:x:roster
-    jabber:x:signed
-
-=cut
-
-# NS_END
-
-=pod
-    
-  For more information on what these namespaces are for, visit 
-  http://www.jabber.org and browse the Jabber Programmers Guide.
-
-  The following tables can be read as follows:
-
-  ny:private:ns
-  
-  Name                        Type     Get  Set  Remove  Defined  Add
-  ==========================  =======  ===  ===  ======  =======  ===
-  Foo                         scalar    X    X     X        X
-  Bar                         child                                X 
-  Bars                        child     X
-  Test                        master    X    X
-
-  Withing the my:private:ns namespace, there exists the functions:
-
-    GetFoo(), SetFoo(), RemoveFoo(), DefinedFoo()
-    
-    AddBar()
-    
-    GetBars(), DefinedBars()
-    
-    GetTest(), SetMaster()
-
-  Hopefully it should be obvious how this all works.  If not feel free to
-  contact me and I'll work on adding more documentation.
-
-=cut
-
-# DOC_BEGIN
-=head1 http://jabber.org/protocol/bytestreams
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Activate                    scalar      X    X     X        X        
-  SID                         scalar      X    X     X        X        
-  StreamHostUsedJID           jid         X    X     X        X        
-  StreamHost                  child                                  X 
-  StreamHosts                 child       X          X        X        
-  ByteStreams                 master      X    X                       
-
-=head1 http://jabber.org/protocol/bytestreams - streamhost objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Host                        scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Port                        scalar      X    X     X        X        
-  ZeroConf                    scalar      X    X     X        X        
-  StreamHost                  master      X    X                       
-
-=head1 http://jabber.org/protocol/commands
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Action                      scalar      X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  SessionID                   scalar      X    X     X        X        
-  Status                      scalar      X    X     X        X        
-  Note                        child                                  X 
-  Notes                       child       X          X        X        
-  Command                     master      X    X                       
-
-=head1 http://jabber.org/protocol/commands - note objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Message                     scalar      X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Note                        master      X    X                       
-
-=head1 http://jabber.org/protocol/disco#info
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Feature                     child                                  X 
-  Features                    child       X          X        X        
-  Identities                  child       X          X        X        
-  Identity                    child                                  X 
-  DiscoInfo                   master      X    X                       
-
-=head1 http://jabber.org/protocol/disco#info - feature objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Var                         scalar      X    X     X        X        
-  Feature                     master      X    X                       
-
-=head1 http://jabber.org/protocol/disco#info - identity objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Category                    scalar      X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Identity                    master      X    X                       
-
-=head1 http://jabber.org/protocol/disco#items
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  DiscoItems                  master      X    X                       
-
-=head1 http://jabber.org/protocol/disco#items - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Action                      scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 http://jabber.org/protocol/feature-neg
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  FeatureNeg                  master      X    X                       
-
-=head1 http://jabber.org/protocol/muc
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Password                    scalar      X    X     X        X        
-  MUC                         master      X    X                       
-
-=head1 http://jabber.org/protocol/muc#admin
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  Admin                       master      X    X                       
-
-=head1 http://jabber.org/protocol/muc#admin - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  ActorJID                    jid         X    X     X        X        
-  Affiliation                 scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Nick                        scalar      X    X     X        X        
-  Reason                      scalar      X    X     X        X        
-  Role                        scalar      X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 http://jabber.org/protocol/muc#user
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Alt                         scalar      X    X     X        X        
-  Password                    scalar      X    X     X        X        
-  StatusCode                  scalar      X    X     X        X        
-  Invite                      child       X          X        X      X 
-  Item                        child       X          X        X      X 
-  User                        master      X    X                       
-
-=head1 http://jabber.org/protocol/muc#user - invite objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  From                        jid         X    X     X        X        
-  Reason                      scalar      X    X     X        X        
-  To                          jid         X    X     X        X        
-  Invite                      master      X    X                       
-
-=head1 http://jabber.org/protocol/muc#user - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  ActorJID                    jid         X    X     X        X        
-  Affiliation                 scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Nick                        scalar      X    X     X        X        
-  Reason                      scalar      X    X     X        X        
-  Role                        scalar      X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Affiliations                child       X          X        X      X 
-  Configure                   child       X          X        X      X 
-  Create                      child       X          X        X      X 
-  Delete                      child       X          X        X      X 
-  Entities                    child       X          X        X      X 
-  Entity                      child       X          X        X      X 
-  Item                        child       X          X        X      X 
-  Items                       child       X          X        X      X 
-  Options                     child       X          X        X      X 
-  Publish                     child       X          X        X      X 
-  Purge                       child       X          X        X      X 
-  Retract                     child       X          X        X      X 
-  Subscribe                   child       X          X        X      X 
-  Unsubscribe                 child       X          X        X      X 
-  PubSub                      master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - affiliations objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Entity                      child       X          X        X      X 
-  Affiliations                master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - configure objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Configure                   master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - create objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Create                      master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - delete objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Delete                      master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - entities objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Entity                      child       X          X        X      X 
-  Entities                    master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - entity objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Affiliation                 scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  Subscription                scalar      X    X     X        X        
-  SubscribeOptions            child       X          X        X      X 
-  Entity                      master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  ID                          scalar      X    X     X        X        
-  Payload                     raw         X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - items objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  MaxItems                    scalar      X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  Item                        child       X          X        X      X 
-  Items                       master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - options objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  JID                         jid         X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  Options                     master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - publish objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Item                        child       X          X        X      X 
-  Publish                     master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - purge objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Purge                       master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - retract objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Item                        child       X          X        X      X 
-  Retract                     master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - subscribe objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  JID                         jid         X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  Subscribe                   master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - subscribe-options objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Required                    flag        X    X     X        X        
-  SubscribeOptions            master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - unsubscribe objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  JID                         jid         X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  Unsubscribe                 master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub#event
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Delete                      child       X          X        X      X 
-  Items                       child       X          X        X      X 
-  Event                       master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub#event - delete objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Delete                      master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub#event - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  ID                          scalar      X    X     X        X        
-  Payload                     raw         X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub#event - items objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Item                        child       X          X        X      X 
-  Items                       master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub#owner
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Action                      scalar      X    X     X        X        
-  Configure                   child       X          X        X      X 
-  Owner                       master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub#owner - configure objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Configure                   master      X    X                       
-
-=head1 http://jabber.org/protocol/si
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  ID                          scalar      X    X     X        X        
-  MimeType                    scalar      X    X     X        X        
-  Profile                     scalar      X    X     X        X        
-  Stream                      master      X    X                       
-
-=head1 http://jabber.org/protocol/si/profile/file-transfer
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Date                        scalar      X    X     X        X        
-  Desc                        scalar      X    X     X        X        
-  Hash                        scalar      X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Range                       flag        X    X     X        X        
-  RangeLength                 scalar      X    X     X        X        
-  RangeOffset                 scalar      X    X     X        X        
-  Size                        scalar      X    X     X        X        
-  File                        master      X    X                       
-
-=head1 jabber:iq:agent - DEPRECATED
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Agents                      flag        X    X     X        X        
-  Description                 scalar      X    X     X        X        
-  GroupChat                   flag        X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Register                    flag        X    X     X        X        
-  Search                      flag        X    X     X        X        
-  Service                     scalar      X    X     X        X        
-  Transport                   scalar      X    X     X        X        
-  URL                         scalar      X    X     X        X        
-  Agent                       master      X    X                       
-
-=head1 jabber:iq:agents - DEPRECATED
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Agent                       child                                  X 
-  Agents                      child       X          X        X        
-
-=head1 jabber:iq:autoupdate
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Beta                        child                                  X 
-  Dev                         child                                  X 
-  Release                     child                                  X 
-  Releases                    child       X          X        X        
-
-=head1 jabber:iq:autoupdate - release objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Desc                        scalar      X    X     X        X        
-  Priority                    scalar      X    X     X        X        
-  URL                         scalar      X    X     X        X        
-  Version                     scalar      X    X     X        X        
-  Release                     master      X    X                       
-
-=head1 jabber:iq:browse - DEPRECATED
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Category                    scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  NS                          array       X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  Browse                      master      X    X                       
-
-=head1 jabber:iq:browse - item objects - DEPRECATED
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Category                    scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  NS                          array       X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  Browse                      master      X    X                       
-
-=head1 jabber:iq:conference
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  ID                          scalar      X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Nick                        scalar      X    X     X        X        
-  Privacy                     flag        X    X     X        X        
-  Secret                      scalar      X    X     X        X        
-  Conference                  master      X    X                       
-
-=head1 jabber:iq:filter - DEPRECATED
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Rule                        child                                  X 
-  Rules                       child       X          X        X        
-
-=head1 jabber:iq:filter - rule objects - DEPRECATED
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Body                        scalar      X    X     X        X        
-  Continued                   scalar      X    X     X        X        
-  Drop                        scalar      X    X     X        X        
-  Edit                        scalar      X    X     X        X        
-  Error                       scalar      X    X     X        X        
-  From                        scalar      X    X     X        X        
-  Offline                     scalar      X    X     X        X        
-  Reply                       scalar      X    X     X        X        
-  Resource                    scalar      X    X     X        X        
-  Show                        scalar      X    X     X        X        
-  Size                        scalar      X    X     X        X        
-  Subject                     scalar      X    X     X        X        
-  Time                        scalar      X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Unavailable                 scalar      X    X     X        X        
-  Rule                        master      X    X                       
-
-=head1 jabber:iq:gateway
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Desc                        scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Prompt                      scalar      X    X     X        X        
-  Gateway                     master      X    X                       
-
-=head1 jabber:iq:last
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Message                     scalar      X    X     X        X        
-  Seconds                     scalar      X    X     X        X        
-  Last                        master      X    X                       
-
-=head1 jabber:iq:oob
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Desc                        scalar      X    X     X        X        
-  URL                         scalar      X    X     X        X        
-  Oob                         master      X    X                       
-
-=head1 jabber:iq:pass
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Client                      scalar      X    X     X        X        
-  ClientPort                  scalar      X    X     X        X        
-  Close                       flag        X    X     X        X        
-  Expire                      scalar      X    X     X        X        
-  OneShot                     flag        X    X     X        X        
-  Proxy                       scalar      X    X     X        X        
-  ProxyPort                   scalar      X    X     X        X        
-  Server                      scalar      X    X     X        X        
-  ServerPort                  scalar      X    X     X        X        
-  Pass                        master      X    X                       
-
-=head1 jabber:iq:rpc
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  MethodCall                  child       X          X        X      X 
-  MethodResponse              child       X          X        X      X 
-
-=head1 jabber:iq:rpc - array objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Data                        child                                  X 
-  Datas                       child       X          X        X        
-
-=head1 jabber:iq:rpc - data objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Value                       child       X          X        X      X 
-
-=head1 jabber:iq:rpc - fault objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Value                       child       X          X        X      X 
-
-=head1 jabber:iq:rpc - member objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Name                        scalar      X    X     X        X        
-  Value                       child       X          X        X      X 
-  Member                      master      X    X                       
-
-=head1 jabber:iq:rpc - methodCall objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  MethodName                  scalar      X    X     X        X        
-  Params                      child       X          X        X      X 
-  MethodCall                  master      X    X                       
-
-=head1 jabber:iq:rpc - methodResponse objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Fault                       child       X          X        X      X 
-  Params                      child       X          X        X      X 
-
-=head1 jabber:iq:rpc - param objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Value                       child       X          X        X      X 
-
-=head1 jabber:iq:rpc - params objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Param                       child                                  X 
-  Params                      child       X          X        X        
-
-=head1 jabber:iq:rpc - struct objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Member                      child                                  X 
-  Members                     child       X          X        X        
-
-=head1 jabber:iq:rpc - value objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Base64                      scalar      X    X     X        X        
-  Boolean                     scalar      X    X     X        X        
-  DateTime                    scalar      X    X     X        X        
-  Double                      scalar      X    X     X        X        
-  I4                          scalar      X    X     X        X        
-  Int                         scalar      X    X     X        X        
-  String                      scalar      X    X     X        X        
-  Value                       scalar      X    X     X        X        
-  Array                       child       X          X        X      X 
-  Struct                      child       X          X        X      X 
-  RPCValue                    master      X    X                       
-
-=head1 jabber:iq:search
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Email                       scalar      X    X     X        X        
-  Family                      scalar      X    X     X        X        
-  First                       scalar      X    X     X        X        
-  Given                       scalar      X    X     X        X        
-  Instructions                scalar      X    X     X        X        
-  Key                         scalar      X    X     X        X        
-  Last                        scalar      X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Nick                        scalar      X    X     X        X        
-  Truncated                   flag        X    X     X        X        
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  Search                      master      X    X                       
-
-=head1 jabber:iq:search - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Email                       scalar      X    X     X        X        
-  Family                      scalar      X    X     X        X        
-  First                       scalar      X    X     X        X        
-  Given                       scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Key                         scalar      X    X     X        X        
-  Last                        scalar      X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Nick                        scalar      X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 jabber:iq:time
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Display                     special     X    X     X        X        
-  TZ                          special     X    X     X        X        
-  UTC                         special     X    X     X        X        
-  Time                        master      X    X                       
-
-=head1 jabber:iq:version
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Name                        scalar      X    X     X        X        
-  OS                          special     X    X     X        X        
-  Ver                         special     X    X     X        X        
-  Version                     master      X    X                       
-
-=head1 jabber:x:autoupdate
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  JID                         jid         X    X     X        X        
-  Autoupdate                  master      X    X                       
-
-=head1 jabber:x:conference
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  JID                         jid         X    X     X        X        
-  Conference                  master      X    X                       
-
-=head1 jabber:x:data
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Form                        scalar      X    X     X        X        
-  Instructions                scalar      X    X     X        X        
-  Title                       scalar      X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Field                       child                                  X 
-  Fields                      child       X          X        X        
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  Reported                    child       X          X        X      X 
-  Data                        master      X    X                       
-
-=head1 jabber:x:data - field objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Desc                        scalar      X    X     X        X        
-  Label                       scalar      X    X     X        X        
-  Required                    flag        X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Value                       array       X    X     X        X        
-  Var                         scalar      X    X     X        X        
-  Option                      child                                  X 
-  Options                     child       X          X        X        
-  Field                       master      X    X                       
-
-=head1 jabber:x:data - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Field                       child                                  X 
-  Fields                      child       X          X        X        
-  Item                        master      X    X                       
-
-=head1 jabber:x:data - option objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Label                       scalar      X    X     X        X        
-  Value                       scalar      X    X     X        X        
-  Option                      master      X    X                       
-
-=head1 jabber:x:data - reported objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Field                       child                                  X 
-  Fields                      child       X          X        X        
-  Reported                    master      X    X                       
-
-=head1 jabber:x:delay
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  From                        jid         X    X     X        X        
-  Message                     scalar      X    X     X        X        
-  Stamp                       timestamp   X    X     X        X        
-  Delay                       master      X    X                       
-
-=head1 jabber:x:encrypted
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Message                     scalar      X    X     X        X        
-  Encrypted                   master      X    X                       
-
-=head1 jabber:x:event
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Composing                   flag        X    X     X        X        
-  Delivered                   flag        X    X     X        X        
-  Displayed                   flag        X    X     X        X        
-  ID                          scalar      X    X     X        X        
-  Offline                     flag        X    X     X        X        
-  Event                       master      X    X                       
-
-=head1 jabber:x:expire
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Seconds                     scalar      X    X     X        X        
-  Expire                      master      X    X                       
-
-=head1 jabber:x:oob
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Desc                        scalar      X    X     X        X        
-  URL                         scalar      X    X     X        X        
-  Oob                         master      X    X                       
-
-=head1 jabber:x:roster
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  Roster                      master      X    X                       
-
-=head1 jabber:x:roster - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Ask                         scalar      X    X     X        X        
-  Group                       array       X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Subscription                scalar      X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 jabber:x:signed
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Signature                   scalar      X    X     X        X        
-  Signed                      master      X    X                       
-
-# DOC_BEGIN
-=head1 http://jabber.org/protocol/bytestreams
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Activate                    scalar      X    X     X        X        
-  SID                         scalar      X    X     X        X        
-  StreamHostUsedJID           jid         X    X     X        X        
-  StreamHost                  child                                  X 
-  StreamHosts                 child       X          X        X        
-  ByteStreams                 master      X    X                       
-
-=head1 http://jabber.org/protocol/bytestreams - streamhost objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Host                        scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Port                        scalar      X    X     X        X        
-  ZeroConf                    scalar      X    X     X        X        
-  StreamHost                  master      X    X                       
-
-=head1 http://jabber.org/protocol/commands
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Action                      scalar      X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  SessionID                   scalar      X    X     X        X        
-  Status                      scalar      X    X     X        X        
-  Note                        child                                  X 
-  Notes                       child       X          X        X        
-  Command                     master      X    X                       
-
-=head1 http://jabber.org/protocol/commands - note objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Message                     scalar      X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Note                        master      X    X                       
-
-=head1 http://jabber.org/protocol/disco#info
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Feature                     child                                  X 
-  Features                    child       X          X        X        
-  Identities                  child       X          X        X        
-  Identity                    child                                  X 
-  DiscoInfo                   master      X    X                       
-
-=head1 http://jabber.org/protocol/disco#info - feature objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Var                         scalar      X    X     X        X        
-  Feature                     master      X    X                       
-
-=head1 http://jabber.org/protocol/disco#info - identity objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Category                    scalar      X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Identity                    master      X    X                       
-
-=head1 http://jabber.org/protocol/disco#items
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  DiscoItems                  master      X    X                       
-
-=head1 http://jabber.org/protocol/disco#items - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Action                      scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 http://jabber.org/protocol/feature-neg
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  FeatureNeg                  master      X    X                       
-
-=head1 http://jabber.org/protocol/muc
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Password                    scalar      X    X     X        X        
-  MUC                         master      X    X                       
-
-=head1 http://jabber.org/protocol/muc#admin
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  Admin                       master      X    X                       
-
-=head1 http://jabber.org/protocol/muc#admin - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  ActorJID                    jid         X    X     X        X        
-  Affiliation                 scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Nick                        scalar      X    X     X        X        
-  Reason                      scalar      X    X     X        X        
-  Role                        scalar      X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 http://jabber.org/protocol/muc#user
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Alt                         scalar      X    X     X        X        
-  Password                    scalar      X    X     X        X        
-  StatusCode                  scalar      X    X     X        X        
-  Invite                      child       X          X        X      X 
-  Item                        child       X          X        X      X 
-  User                        master      X    X                       
-
-=head1 http://jabber.org/protocol/muc#user - invite objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  From                        jid         X    X     X        X        
-  Reason                      scalar      X    X     X        X        
-  To                          jid         X    X     X        X        
-  Invite                      master      X    X                       
-
-=head1 http://jabber.org/protocol/muc#user - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  ActorJID                    jid         X    X     X        X        
-  Affiliation                 scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Nick                        scalar      X    X     X        X        
-  Reason                      scalar      X    X     X        X        
-  Role                        scalar      X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Affiliations                child       X          X        X      X 
-  Configure                   child       X          X        X      X 
-  Create                      child       X          X        X      X 
-  Delete                      child       X          X        X      X 
-  Entities                    child       X          X        X      X 
-  Entity                      child       X          X        X      X 
-  Item                        child       X          X        X      X 
-  Items                       child       X          X        X      X 
-  Options                     child       X          X        X      X 
-  Publish                     child       X          X        X      X 
-  Purge                       child       X          X        X      X 
-  Retract                     child       X          X        X      X 
-  Subscribe                   child       X          X        X      X 
-  Unsubscribe                 child       X          X        X      X 
-  PubSub                      master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - affiliations objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Entity                      child       X          X        X      X 
-  Affiliations                master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - configure objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Configure                   master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - create objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Create                      master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - delete objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Delete                      master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - entities objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Entity                      child       X          X        X      X 
-  Entities                    master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - entity objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Affiliation                 scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  Subscription                scalar      X    X     X        X        
-  SubscribeOptions            child       X          X        X      X 
-  Entity                      master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  ID                          scalar      X    X     X        X        
-  Payload                     raw         X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - items objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  MaxItems                    scalar      X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  Item                        child       X          X        X      X 
-  Items                       master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - options objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  JID                         jid         X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  Options                     master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - publish objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Item                        child       X          X        X      X 
-  Publish                     master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - purge objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Purge                       master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - retract objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Item                        child       X          X        X      X 
-  Retract                     master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - subscribe objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  JID                         jid         X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  Subscribe                   master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - subscribe-options objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Required                    flag        X    X     X        X        
-  SubscribeOptions            master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub - unsubscribe objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  JID                         jid         X    X     X        X        
-  Node                        scalar      X    X     X        X        
-  Unsubscribe                 master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub#event
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Delete                      child       X          X        X      X 
-  Items                       child       X          X        X      X 
-  Event                       master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub#event - delete objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Delete                      master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub#event - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  ID                          scalar      X    X     X        X        
-  Payload                     raw         X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub#event - items objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Item                        child       X          X        X      X 
-  Items                       master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub#owner
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Action                      scalar      X    X     X        X        
-  Configure                   child       X          X        X      X 
-  Owner                       master      X    X                       
-
-=head1 http://jabber.org/protocol/pubsub#owner - configure objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Node                        scalar      X    X     X        X        
-  Configure                   master      X    X                       
-
-=head1 http://jabber.org/protocol/si
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  ID                          scalar      X    X     X        X        
-  MimeType                    scalar      X    X     X        X        
-  Profile                     scalar      X    X     X        X        
-  Stream                      master      X    X                       
-
-=head1 http://jabber.org/protocol/si/profile/file-transfer
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Date                        scalar      X    X     X        X        
-  Desc                        scalar      X    X     X        X        
-  Hash                        scalar      X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Range                       flag        X    X     X        X        
-  RangeLength                 scalar      X    X     X        X        
-  RangeOffset                 scalar      X    X     X        X        
-  Size                        scalar      X    X     X        X        
-  File                        master      X    X                       
-
-=head1 jabber:iq:agent - DEPRECATED
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Agents                      flag        X    X     X        X        
-  Description                 scalar      X    X     X        X        
-  GroupChat                   flag        X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Register                    flag        X    X     X        X        
-  Search                      flag        X    X     X        X        
-  Service                     scalar      X    X     X        X        
-  Transport                   scalar      X    X     X        X        
-  URL                         scalar      X    X     X        X        
-  Agent                       master      X    X                       
-
-=head1 jabber:iq:agents - DEPRECATED
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Agent                       child                                  X 
-  Agents                      child       X          X        X        
-
-=head1 jabber:iq:autoupdate
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Beta                        child                                  X 
-  Dev                         child                                  X 
-  Release                     child                                  X 
-  Releases                    child       X          X        X        
-
-=head1 jabber:iq:autoupdate - release objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Desc                        scalar      X    X     X        X        
-  Priority                    scalar      X    X     X        X        
-  URL                         scalar      X    X     X        X        
-  Version                     scalar      X    X     X        X        
-  Release                     master      X    X                       
-
-=head1 jabber:iq:browse - DEPRECATED
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Category                    scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  NS                          array       X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  Browse                      master      X    X                       
-
-=head1 jabber:iq:browse - item objects - DEPRECATED
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Category                    scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  NS                          array       X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  Browse                      master      X    X                       
-
-=head1 jabber:iq:conference
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  ID                          scalar      X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Nick                        scalar      X    X     X        X        
-  Privacy                     flag        X    X     X        X        
-  Secret                      scalar      X    X     X        X        
-  Conference                  master      X    X                       
-
-=head1 jabber:iq:filter - DEPRECATED
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Rule                        child                                  X 
-  Rules                       child       X          X        X        
-
-=head1 jabber:iq:filter - rule objects - DEPRECATED
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Body                        scalar      X    X     X        X        
-  Continued                   scalar      X    X     X        X        
-  Drop                        scalar      X    X     X        X        
-  Edit                        scalar      X    X     X        X        
-  Error                       scalar      X    X     X        X        
-  From                        scalar      X    X     X        X        
-  Offline                     scalar      X    X     X        X        
-  Reply                       scalar      X    X     X        X        
-  Resource                    scalar      X    X     X        X        
-  Show                        scalar      X    X     X        X        
-  Size                        scalar      X    X     X        X        
-  Subject                     scalar      X    X     X        X        
-  Time                        scalar      X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Unavailable                 scalar      X    X     X        X        
-  Rule                        master      X    X                       
-
-=head1 jabber:iq:gateway
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Desc                        scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Prompt                      scalar      X    X     X        X        
-  Gateway                     master      X    X                       
-
-=head1 jabber:iq:last
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Message                     scalar      X    X     X        X        
-  Seconds                     scalar      X    X     X        X        
-  Last                        master      X    X                       
-
-=head1 jabber:iq:oob
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Desc                        scalar      X    X     X        X        
-  URL                         scalar      X    X     X        X        
-  Oob                         master      X    X                       
-
-=head1 jabber:iq:pass
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Client                      scalar      X    X     X        X        
-  ClientPort                  scalar      X    X     X        X        
-  Close                       flag        X    X     X        X        
-  Expire                      scalar      X    X     X        X        
-  OneShot                     flag        X    X     X        X        
-  Proxy                       scalar      X    X     X        X        
-  ProxyPort                   scalar      X    X     X        X        
-  Server                      scalar      X    X     X        X        
-  ServerPort                  scalar      X    X     X        X        
-  Pass                        master      X    X                       
-
-=head1 jabber:iq:rpc
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  MethodCall                  child       X          X        X      X 
-  MethodResponse              child       X          X        X      X 
-
-=head1 jabber:iq:rpc - array objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Data                        child                                  X 
-  Datas                       child       X          X        X        
-
-=head1 jabber:iq:rpc - data objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Value                       child       X          X        X      X 
-
-=head1 jabber:iq:rpc - fault objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Value                       child       X          X        X      X 
-
-=head1 jabber:iq:rpc - member objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Name                        scalar      X    X     X        X        
-  Value                       child       X          X        X      X 
-  Member                      master      X    X                       
-
-=head1 jabber:iq:rpc - methodCall objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  MethodName                  scalar      X    X     X        X        
-  Params                      child       X          X        X      X 
-  MethodCall                  master      X    X                       
-
-=head1 jabber:iq:rpc - methodResponse objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Fault                       child       X          X        X      X 
-  Params                      child       X          X        X      X 
-
-=head1 jabber:iq:rpc - param objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Value                       child       X          X        X      X 
-
-=head1 jabber:iq:rpc - params objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Param                       child                                  X 
-  Params                      child       X          X        X        
-
-=head1 jabber:iq:rpc - struct objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Member                      child                                  X 
-  Members                     child       X          X        X        
-
-=head1 jabber:iq:rpc - value objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Base64                      scalar      X    X     X        X        
-  Boolean                     scalar      X    X     X        X        
-  DateTime                    scalar      X    X     X        X        
-  Double                      scalar      X    X     X        X        
-  I4                          scalar      X    X     X        X        
-  Int                         scalar      X    X     X        X        
-  String                      scalar      X    X     X        X        
-  Value                       scalar      X    X     X        X        
-  Array                       child       X          X        X      X 
-  Struct                      child       X          X        X      X 
-  RPCValue                    master      X    X                       
-
-=head1 jabber:iq:search
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Email                       scalar      X    X     X        X        
-  Family                      scalar      X    X     X        X        
-  First                       scalar      X    X     X        X        
-  Given                       scalar      X    X     X        X        
-  Instructions                scalar      X    X     X        X        
-  Key                         scalar      X    X     X        X        
-  Last                        scalar      X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Nick                        scalar      X    X     X        X        
-  Truncated                   flag        X    X     X        X        
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  Search                      master      X    X                       
-
-=head1 jabber:iq:search - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Email                       scalar      X    X     X        X        
-  Family                      scalar      X    X     X        X        
-  First                       scalar      X    X     X        X        
-  Given                       scalar      X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Key                         scalar      X    X     X        X        
-  Last                        scalar      X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Nick                        scalar      X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 jabber:iq:time
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Display                     special     X    X     X        X        
-  TZ                          special     X    X     X        X        
-  UTC                         special     X    X     X        X        
-  Time                        master      X    X                       
-
-=head1 jabber:iq:version
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Name                        scalar      X    X     X        X        
-  OS                          special     X    X     X        X        
-  Ver                         special     X    X     X        X        
-  Version                     master      X    X                       
-
-=head1 jabber:x:autoupdate
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  JID                         jid         X    X     X        X        
-  Autoupdate                  master      X    X                       
-
-=head1 jabber:x:conference
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  JID                         jid         X    X     X        X        
-  Conference                  master      X    X                       
-
-=head1 jabber:x:data
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Form                        scalar      X    X     X        X        
-  Instructions                scalar      X    X     X        X        
-  Title                       scalar      X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Field                       child                                  X 
-  Fields                      child       X          X        X        
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  Reported                    child       X          X        X      X 
-  Data                        master      X    X                       
-
-=head1 jabber:x:data - field objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Desc                        scalar      X    X     X        X        
-  Label                       scalar      X    X     X        X        
-  Required                    flag        X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Value                       array       X    X     X        X        
-  Var                         scalar      X    X     X        X        
-  Option                      child                                  X 
-  Options                     child       X          X        X        
-  Field                       master      X    X                       
-
-=head1 jabber:x:data - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Field                       child                                  X 
-  Fields                      child       X          X        X        
-  Item                        master      X    X                       
-
-=head1 jabber:x:data - option objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Label                       scalar      X    X     X        X        
-  Value                       scalar      X    X     X        X        
-  Option                      master      X    X                       
-
-=head1 jabber:x:data - reported objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Field                       child                                  X 
-  Fields                      child       X          X        X        
-  Reported                    master      X    X                       
-
-=head1 jabber:x:delay
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  From                        jid         X    X     X        X        
-  Message                     scalar      X    X     X        X        
-  Stamp                       timestamp   X    X     X        X        
-  Delay                       master      X    X                       
-
-=head1 jabber:x:encrypted
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Message                     scalar      X    X     X        X        
-  Encrypted                   master      X    X                       
-
-=head1 jabber:x:event
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Composing                   flag        X    X     X        X        
-  Delivered                   flag        X    X     X        X        
-  Displayed                   flag        X    X     X        X        
-  ID                          scalar      X    X     X        X        
-  Offline                     flag        X    X     X        X        
-  Event                       master      X    X                       
-
-=head1 jabber:x:expire
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Seconds                     scalar      X    X     X        X        
-  Expire                      master      X    X                       
-
-=head1 jabber:x:oob
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Desc                        scalar      X    X     X        X        
-  URL                         scalar      X    X     X        X        
-  Oob                         master      X    X                       
-
-=head1 jabber:x:roster
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  Roster                      master      X    X                       
-
-=head1 jabber:x:roster - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Ask                         scalar      X    X     X        X        
-  Group                       array       X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Subscription                scalar      X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 jabber:x:signed
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Signature                   scalar      X    X     X        X        
-  Signed                      master      X    X                       
-
-
-=cut
-
-# DOC_END
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use Carp;
-use Net::XMPP::Stanza;
-use Net::Jabber::Namespaces;
-
-use base qw( Net::XMPP::Stanza );
-
-use vars qw( $TIMEZONE );
-
-if (eval "require Time::Timezone")
-{
-    $TIMEZONE = 1;
-    Time::Timezone->import(qw(tz_local_offset tz_name));
-}
-else
-{
-    $TIMEZONE = 0;
-}
-
-
-sub _init
-{
-    my $self = shift;
-
-    my $result = $self->SUPER::_init(@_);
-
-    if (defined($result))
-    {
-        $result->_CustomSet_init();
-        return $result;
-    }
-
-    $self->_CustomSet_init();
-    return;
-}
-
-sub GetX     { my $self = shift; $self->GetChild(@_);    } 
-sub DefinedX { my $self = shift; $self->DefinedChild(@_); }
-sub NewX     { my $self = shift; $self->NewChild(@_);    }
-sub AddX     { my $self = shift; $self->AddChild(@_);    } 
-sub RemoveX  { my $self = shift; $self->RemoveChild(@_); }
-
-sub GetQuery     { my $self = shift; $self->GetChild(@_);     }
-sub DefinedQuery { my $self = shift; $self->DefinedChild(@_); }
-sub NewQuery     { my $self = shift; $self->NewChild(@_);     }
-sub AddQuery     { my $self = shift; $self->AddChild(@_);     } 
-sub RemoveQuery  { my $self = shift; $self->RemoveChild(@_);  }
-
-sub _new_jid    { my $self = shift; return Net::Jabber::JID->new(@_);    }
-sub _new_packet { my $self = shift; return Net::Jabber::Stanza->new(@_); }
-
-
-sub _CustomSet_init
-{
-    my $self = shift;
-
-    $self->{CUSTOMSET}->{"time-display"} = \&_CustomSet_timedisplay;
-    $self->{CUSTOMSET}->{"time-tz"} = \&_CustomSet_timetz;
-    $self->{CUSTOMSET}->{"time-utc"} = \&_CustomSet_timeutc;
-    $self->{CUSTOMSET}->{"version-os"} = \&_CustomSet_versionos;
-    $self->{CUSTOMSET}->{"version-version"} = \&_CustomSet_versionversion;
-}
-
-
-sub _CustomSet_timedisplay
-{
-    my $self = shift;
-    my $value = shift;
-
-    return $value if defined($value);
-    $self->{DATA}->{__netjabbertime__} = time
-        unless exists($self->{DATA}->{__netjabbertime__});
-    return &Net::XMPP::GetTimeStamp("local",$self->{DATA}->{__netjabbertime__});
-}
-
-
-sub _CustomSet_timetz
-{
-    my $self = shift;
-    my $value = shift;
-    
-    if (!defined($value) && ($TIMEZONE == 1))
-    {
-        return uc(&tz_name(&tz_local_offset()))
-    }
-    return $value;
-}
-
-
-sub _CustomSet_timeutc
-{
-    my $self = shift;
-    my $value = shift;
-
-    return $value if defined($value);
-    $self->{DATA}->{__netjabbertime__} = time
-        unless exists($self->{DATA}->{__netjabbertime__});
-    return &Net::XMPP::GetTimeStamp("utc",$self->{DATA}->{__netjabbertime__},"stamp");
-}
-
-
-sub _CustomSet_versionos
-{
-    my $self = shift;
-    my $value = shift;
-
-    return (&POSIX::uname())[0];
-}
-
-
-sub _CustomSet_versionversion
-{
-    my $self = shift;
-    my $value = shift;
-    
-    if (defined($value))
-    {
-        $value .= " - [ Net::Jabber v$Net::Jabber::VERSION ]";
-    }
-    else
-    {
-        $value = "Net::Jabber v$Net::Jabber::VERSION";
-    }
-
-    return $value;
-}
-
-
-sub GetResults
-{
-    my $self = shift;
-    my %results;
-    foreach my $item ($self->GetItems())
-    {
-        my %result;
-        my @xData = $item->GetX("jabber:x:data");
-        if ($#xData == -1) 
-        {
-            %result = $item->GetItem();
-        }
-        else
-        {
-            foreach my $field ($xData[0]->GetFields())
-            {
-                $result{$field->GetVar()} = $field->GetValue();
-            }
-        }
-        $results{$item->GetJID()} = \%result;
-    }
-    return %results;
-}
-
-1;
Index: rl/modules/Jabber/lib/Net/Jabber/XDB.pm
===================================================================
--- perl/modules/Jabber/lib/Net/Jabber/XDB.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,441 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
-#
-##############################################################################
-
-package Net::Jabber::XDB;
-
-=head1 NAME
-
-Net::Jabber::XDB - Jabber XDB Library
-
-=head1 SYNOPSIS
-
-  Net::Jabber::XDB is a companion to the Net::Jabber module. It
-  provides the user a simple interface to set and retrieve all
-  parts of a Jabber XDB.
-
-=head1 DESCRIPTION
-
-  Net::Jabber::XDB differs from the other Net::Jabber::* modules in that
-  the XMLNS of the data is split out into more submodules under
-  XDB.  For specifics on each module please view the documentation
-  for each Net::Jabber::Data::* module.  To see the list of avilable
-  namspaces and modules see Net::Jabber::Data.
-
-  To initialize the XDB with a Jabber <xdb/> you must pass it the 
-  XML::Parser Tree array.  For example:
-
-    my $xdb = Net::Jabber::XDB->new(@tree);
-
-  There has been a change from the old way of handling the callbacks.
-  You no longer have to do the above, a Net::Jabber::XDB object is passed
-  to the callback function for the xdb:
-
-    use Net::Jabber qw(Component);
-
-    sub xdb {
-      my ($XDB) = @_;
-      .
-      .
-      .
-    }
-
-  You now have access to all of the retrieval functions available.
-
-  To create a new xdb to send to the server:
-
-    use Net::Jabber;
-
-    $XDB = Net::Jabber::XDB->new();
-    $XDBType = $XDB->NewData( type );
-    $XDBType->SetXXXXX("yyyyy");
-
-  Now you can call the creation functions for the XDB, and for the <data/>
-  on the new Data object itself.  See below for the <xdb/> functions, and
-  in each data module for those functions.
-
-  For more information about the array format being passed to the CallBack
-  please read the Net::Jabber::Client documentation.
-
-=head1 METHODS
-
-=head2 Retrieval functions
-
-  GetTo()      - returns either a string with the Jabber Identifier,
-  GetTo("jid")   or a Net::Jabber::JID object for the person who is
-                 going to receive the <xdb/>.  To get the JID
-                 object set the string to "jid", otherwise leave
-                 blank for the text string.
-
-                 $to    = $XDB->GetTo();
-                 $toJID = $XDB->GetTo("jid");
-
-  GetFrom()      -  returns either a string with the Jabber Identifier,
-  GetFrom("jid")    or a Net::Jabber::JID object for the person who
-                    sent the <xdb/>.  To get the JID object set
-                    the string to "jid", otherwise leave blank for the
-                    text string.
-
-                    $from    = $XDB->GetFrom();
-                    $fromJID = $XDB->GetFrom("jid");
-
-  GetType() - returns a string with the type <xdb/> this is.
-
-              $type = $XDB->GetType();
-
-  GetID() - returns an integer with the id of the <xdb/>.
-
-            $id = $XDB->GetID();
-
-  GetAction() - returns a string with the action <xdb/> this is.
-
-              $action = $XDB->GetAction();
-
-  GetMatch() - returns a string with the match <xdb/> this is.
-
-              $match = $XDB->GetMatch();
-
-  GetError() - returns a string with the text description of the error.
-
-               $error = $XDB->GetError();
-
-  GetErrorCode() - returns a string with the code of error.
-
-                   $errorCode = $XDB->GetErrorCode();
-
-  GetData() - returns a Net::Jabber::Data object that contains the data
-              in the <data/> of the <xdb/>.
-
-              $dataTag = $XDB->GetData();
-
-  GetDataXMLNS() - returns a string with the namespace of the data
-                   for this <xdb/>, if one exists.
-
-                   $xmlns = $XDB->GetDataXMLNS();
-
-=head2 Creation functions
-
-  SetXDB(to=>string|JID,    - set multiple fields in the <xdb/> at one
-        from=>string|JID,     time.  This is a cumulative and over
-        id=>string,           writing action.  If you set the "to"
-        type=>string,         attribute twice, the second setting is
-        action=>string,       what is used.  If you set the status, and
-        match=>string)        then set the priority then both will be in
-        errorcode=>string,    the <xdb/> tag.  For valid settings read the
-        error=>string)        specific Set functions below.
-
-                              $XDB->SetXDB(type=>"get",
- 		   			   to=>"bob\@jabber.org",
-	  				   data=>"info");
-
-                              $XDB->SetXDB(to=>"bob\@jabber.org",
-			 		   errorcode=>403,
-					   error=>"Permission Denied");
-
-  SetTo(string) - sets the to attribute.  You can either pass a string
-  SetTo(JID)      or a JID object.  They must be a valid Jabber
-                  Identifiers or the server will return an error message.
-                  (ie.  jabber:bob@jabber.org, etc...)
-
-                 $XDB->SetTo("bob\@jabber.org");
-
-  SetFrom(string) - sets the from attribute.  You can either pass a string
-  SetFrom(JID)      or a JID object.  They must be a valid Jabber
-                    Identifiers or the server will return an error message.
-                    (ie.  jabber:bob@jabber.org, etc...)
-
-                    $XDB->SetFrom("me\@jabber.org");
-
-  SetType(string) - sets the type attribute.  Valid settings are:
-
-                    get      request information
-                    set      set information
-                    result   results of a get
-                    error    there was an error
-
-                    $XDB->SetType("set");
-
-  SetAction(string) - sets the error code of the <xdb/>.
-
-                      $XDB->SetAction("foo");
-
-  SetMatch(string) - sets the error code of the <xdb/>.
-
-                     $XDB->SetMatch("foo");
-
-  SetErrorCode(string) - sets the error code of the <xdb/>.
-
-                         $XDB->SetErrorCode(403);
-
-  SetError(string) - sets the error string of the <xdb/>.
-
-                     $XDB->SetError("Permission Denied");
-
-  NewData(string) - creates a new Net::Jabber::Data object with the
-                     namespace in the string.  In order for this function
-                     to work with a custom namespace, you must define and
-                     register that namespace with the XDB module.  For more
-                     information please read the documentation for
-                     Net::Jabber::Data.
-
-                     $dataObj = $XDB->NewData("jabber:xdb:auth");
-                     $dataObj = $XDB->NewData("jabber:xdb:roster");
-
-  Reply(hash) - creates a new XDB object and populates the to/from
-                fields.  If you specify a hash the same as with SetXDB
-                then those values will override the Reply values.
-
-                $xdbReply = $XDB->Reply();
-                $xdbReply = $XDB->Reply(type=>"result");
-
-=head2 Test functions
-
-  DefinedTo() - returns 1 if the to attribute is defined in the <xdb/>,
-                0 otherwise.
-
-                $test = $XDB->DefinedTo();
-
-  DefinedFrom() - returns 1 if the from attribute is defined in the <xdb/>,
-                  0 otherwise.
-
-                  $test = $XDB->DefinedFrom();
-
-  DefinedID() - returns 1 if the id attribute is defined in the <xdb/>,
-                0 otherwise.
-
-                $test = $XDB->DefinedID();
-
-  DefinedType() - returns 1 if the type attribute is defined in the <xdb/>,
-                  0 otherwise.
-
-                  $test = $XDB->DefinedType();
-
-  DefinedAction() - returns 1 if the action attribute is defined in the <xdb/>,
-                   0 otherwise.
-
-                   $test = $XDB->DefinedAction();
-
-  DefinedMatch() - returns 1 if the match attribute is defined in the <xdb/>,
-                   0 otherwise.
-
-                   $test = $XDB->DefinedMatch();
-
-  DefinedError() - returns 1 if <error/> is defined in the <xdb/>,
-                   0 otherwise.
-
-                   $test = $XDB->DefinedError();
-
-  DefinedErrorCode() - returns 1 if the code attribute is defined in
-                       <error/>, 0 otherwise.
-
-                       $test = $XDB->DefinedErrorCode();
-
-=head1 AUTHOR
-
-By Ryan Eatmon in May of 2001 for http://jabber.org..
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-use vars qw($VERSION $AUTOLOAD %FUNCTIONS);
-
-$VERSION = "2.0";
-
-sub new
-{
-    my $proto = shift;
-    my $class = ref($proto) || $proto;
-    my $self = { };
-
-    $self->{VERSION} = $VERSION;
-
-    bless($self, $proto);
-
-    $self->{DEBUGHEADER} = "XDB";
-
-    $self->{DATA} = {};
-    $self->{CHILDREN} = {};
-
-    $self->{TAG} = "xdb";
-
-    if ("@_" ne (""))
-    {
-        if (ref($_[0]) eq "Net::Jabber::XDB")
-        {
-            return $_[0];
-        }
-        else
-        {
-            $self->{TREE} = shift;
-            $self->ParseTree();
-        }
-    }
-    else
-    {
-        $self->{TREE} = new XML::Stream::Node($self->{TAG});
-    }
-
-    return $self;
-}
-
-
-##############################################################################
-#
-# AUTOLOAD - This function calls the main AutoLoad function in Jabber.pm
-#
-##############################################################################
-sub AUTOLOAD
-{
-    my $self = shift;
-    &Net::Jabber::AutoLoad($self,$AUTOLOAD,@_);
-}
-
-$FUNCTIONS{Action}->{Get}           = "action";
-$FUNCTIONS{Action}->{Set}           = ["scalar","action"];
-$FUNCTIONS{Action}->{Defined}       = "action";
-$FUNCTIONS{Action}->{Hash}          = "att";
-$FUNCTIONS{Action}->{XPath}->{Type} = 'scalar';
-$FUNCTIONS{Action}->{XPath}->{Path} = '@action';
-
-$FUNCTIONS{Error}->{Get}           = "error";
-$FUNCTIONS{Error}->{Set}           = ["scalar","error"];
-$FUNCTIONS{Error}->{Defined}       = "error";
-$FUNCTIONS{Error}->{Hash}          = "child-data";
-$FUNCTIONS{Error}->{XPath}->{Type} = 'scalar';
-$FUNCTIONS{Error}->{XPath}->{Path} = 'error/text()';
-
-$FUNCTIONS{ErrorCode}->{Get}           = "errorcode";
-$FUNCTIONS{ErrorCode}->{Set}           = ["scalar","errorcode"];
-$FUNCTIONS{ErrorCode}->{Defined}       = "errorcode";
-$FUNCTIONS{ErrorCode}->{Hash}          = "att-error-code";
-$FUNCTIONS{ErrorCode}->{XPath}->{Type} = 'scalar';
-$FUNCTIONS{ErrorCode}->{XPath}->{Path} = 'error/@code';
-
-$FUNCTIONS{From}->{Get}           = "from";
-$FUNCTIONS{From}->{Set}           = ["jid","from"];
-$FUNCTIONS{From}->{Defined}       = "from";
-$FUNCTIONS{From}->{Hash}          = "att";
-$FUNCTIONS{From}->{XPath}->{Type} = 'jid';
-$FUNCTIONS{From}->{XPath}->{Path} = '@from';
-
-$FUNCTIONS{Match}->{Get}           = "match";
-$FUNCTIONS{Match}->{Set}           = ["scalar","match"];
-$FUNCTIONS{Match}->{Defined}       = "match";
-$FUNCTIONS{Match}->{Hash}          = "att";
-$FUNCTIONS{Match}->{XPath}->{Type} = 'scalar';
-$FUNCTIONS{Match}->{XPath}->{Path} = '@match';
-
-$FUNCTIONS{NS}->{Get}           = "ns";
-$FUNCTIONS{NS}->{Set}           = ["scalar","ns"];
-$FUNCTIONS{NS}->{Defined}       = "ns";
-$FUNCTIONS{NS}->{Hash}          = "att";
-$FUNCTIONS{NS}->{XPath}->{Type} = 'scalar';
-$FUNCTIONS{NS}->{XPath}->{Path} = '@ns';
-
-$FUNCTIONS{ID}->{Get}           = "id";
-$FUNCTIONS{ID}->{Set}           = ["scalar","id"];
-$FUNCTIONS{ID}->{Defined}       = "id";
-$FUNCTIONS{ID}->{Hash}          = "att";
-$FUNCTIONS{ID}->{XPath}->{Type} = 'scalar';
-$FUNCTIONS{ID}->{XPath}->{Path} = '@id';
-
-$FUNCTIONS{To}->{Get}           = "to";
-$FUNCTIONS{To}->{Set}           = ["jid","to"];
-$FUNCTIONS{To}->{Defined}       = "to";
-$FUNCTIONS{To}->{Hash}          = "att";
-$FUNCTIONS{To}->{XPath}->{Type} = 'jid';
-$FUNCTIONS{To}->{XPath}->{Path} = '@to';
-
-$FUNCTIONS{Type}->{Get}           = "type";
-$FUNCTIONS{Type}->{Set}           = ["scalar","type"];
-$FUNCTIONS{Type}->{Defined}       = "type";
-$FUNCTIONS{Type}->{Hash}          = "att";
-$FUNCTIONS{Type}->{XPath}->{Type} = 'scalar';
-$FUNCTIONS{Type}->{XPath}->{Path} = '@type';
-
-$FUNCTIONS{Data}->{Get}           = "__netjabber__:children:data";
-$FUNCTIONS{Data}->{Defined}       = "__netjabber__:children:data";
-$FUNCTIONS{Data}->{XPath}->{Type} = 'node';
-$FUNCTIONS{Data}->{XPath}->{Path} = '*[@xmlns]';
-
-$FUNCTIONS{X}->{Get}           = "__netjabber__:children:x";
-$FUNCTIONS{X}->{Defined}       = "__netjabber__:children:x";
-$FUNCTIONS{X}->{XPath}->{Type} = 'node';
-$FUNCTIONS{X}->{XPath}->{Path} = '*[@xmlns]';
-
-$FUNCTIONS{XDB}->{Get} = "__netjabber__:master";
-$FUNCTIONS{XDB}->{Set} = ["master"];
-
-
-##############################################################################
-#
-# GetDataXMLNS - returns the xmlns of the <data/> tag
-#
-##############################################################################
-sub GetDataXMLNS
-{
-    my $self = shift;
-    #XXX fix this
-    return $self->{CHILDREN}->{data}->[0]->GetXMLNS() if exists($self->{CHILDREN}->{data});
-}
-
-
-##############################################################################
-#
-# Reply - returns a Net::Jabber::XDB object with the proper fields
-#         already populated for you.
-#
-##############################################################################
-sub Reply
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $reply = Net::Jabber::XDB->new();
-
-    $reply->SetID($self->GetID()) if ($self->GetID() ne "");
-    $reply->SetType("result");
-
-    if ($self->DefinedData())
-    {
-        my $selfData = $self->GetData();
-        $reply->NewData($selfData->GetXMLNS());
-    }
-
-    $reply->SetXDB(to=>$self->GetFrom(),
-                   from=>$self->GetTo()
-                  );
-
-    $reply->SetXDB(%args);
-
-    return $reply;
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/XMPP.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,360 +1,0 @@
-###############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-###############################################################################
-
-package Net::XMPP;
-
-=head1 NAME
-
-Net::XMPP - XMPP Perl Library
-
-=head1 SYNOPSIS
-
-  Net::XMPP provides a Perl user with access to the Extensible
-  Messaging and Presence Protocol (XMPP).
-
-  For more information about XMPP visit:
-
-    http://www.xmpp.org
-
-=head1 DESCRIPTION
-
-  Net::XMPP is a convenient tool to use for any perl script that would
-  like to utilize the XMPP Instant Messaging protocol.  While not a
-  client in and of itself, it provides all of the necessary back-end
-  functions to make a CGI client or command-line perl client feasible 
-  and easy to use.  Net::XMPP is a wrapper around the rest of the
-  official Net::XMPP::xxxxxx packages.
-
-  There is are example scripts in the example directory that provide you
-  with examples of very simple XMPP programs.
-
-
-  NOTE: The parser that XML::Stream::Parser provides, as are most Perl
-  parsers, is synchronous.  If you are in the middle of parsing a packet
-  and call a user defined callback, the Parser is blocked until your
-  callback finishes.  This means you cannot be operating on a packet,
-  send out another packet and wait for a response to that packet.  It
-  will never get to you.  Threading might solve this, but as of this
-  writing threading in Perl is not quite up to par yet.  This issue will
-  be revisted in the future.
-
-
-=head1 EXAMPLES
-
-      use Net::XMPP;
-      my $client = Net::XMPP::Client->new();
-
-=head1 METHODS
-
-  The Net::XMPP module does not define any methods that you will call
-  directly in your code.  Instead you will instantiate objects that call
-  functions from this module to do work.  The three main objects that
-  you will work with are the Message, Presence, and IQ modules. Each one
-  corresponds to the Jabber equivilant and allows you get and set all
-  parts of those packets.
-
-  There are a few functions that are the same across all of the objects:
-
-=head2 Retrieval functions
-
-  GetXML() - returns the XML string that represents the data contained
-             in the object.
-
-             $xml  = $obj->GetXML();
-
-  GetChild()          - returns an array of Net::XMPP::Stanza objects
-  GetChild(namespace)   that represent all of the stanzas in the object
-                        that are namespaced.  If you specify a namespace
-                        then only stanza objects with that XMLNS are
-                        returned.
-
-                        @xObj = $obj->GetChild();
-                        @xObj = $obj->GetChild("my:namespace");
-
-  GetTag() - return the root tag name of the packet.
-
-  GetTree() - return the XML::Stream::Node object that contains the data.
-              See XML::Stream::Node for methods you can call on this
-              object.
-
-=head2 Creation functions
-
-  NewChild(namespace)     - creates a new Net::XMPP::Stanza object with
-  NewChild(namespace,tag)   the specified namespace and root tag of
-                            whatever the namespace says its root tag
-                            should be.  Optionally you may specify
-                            another root tag if the default is not
-                            desired, or the namespace requres you to set
-                            one.
-
-                            $xObj = $obj->NewChild("my:namespace");
-                            $xObj = $obj->NewChild("my:namespace","foo");
-                              ie. <foo xmlns='my:namespace'...></foo>
-
-  InsertRawXML(string) - puts the specified string raw into the XML
-                         packet that you call this on.
-
-                         $message->InsertRawXML("<foo></foo>")
-                           <message...>...<foo></foo></message>
-
-                         $x = $message->NewChild(..);
-                         $x->InsertRawXML("test");
-
-                         $query = $iq->GetChild(..);
-                         $query->InsertRawXML("test");
-
-  ClearRawXML() - removes the raw XML from the packet.
-
-=head2 Removal functions
-
-  RemoveChild()          - removes all of the namespaces child elements
-  RemoveChild(namespace)   from the object.  If a namespace is provided,
-                           then only the children with that namespace are
-                           removed.
-
-=head2 Test functions
-
-  DefinedChild()          - returns 1 if there are any known namespaced
-  DefinedChild(namespace)   stanzas in the packet, 0 otherwise.
-                            Optionally you can specify a namespace and
-                            determine if there are any stanzas with that
-                            namespace.
-
-                            $test = $obj->DefinedChild();
-                            $test = $obj->DefinedChild("my:namespace");
-
-=head1 PACKAGES
-
-  For more information on each of these packages, please see the man page
-  for each one.
-
-=head2 Net::XMPP::Client
-
-  This package contains the code needed to communicate with an XMPP
-  server: login, wait for messages, send messages, and logout.  It uses
-  XML::Stream to read the stream from the server and based on what kind
-  of tag it encounters it calls a function to handle the tag.
-
-=head2 Net::XMPP::Protocol
-
-  A collection of high-level functions that Client uses to make their
-  lives easier.  These methods are inherited by the Client.
-
-=head2 Net::XMPP::JID
-
-  The XMPP IDs consist of three parts: user id, server, and resource.
-  This module gives you access to those components without having to
-  parse the string yourself.
-
-=head2 Net::XMPP::Message
-
-  Everything needed to create and read a <message/> received from the
-  server.
-
-=head2 Net::XMPP::Presence
-
-  Everything needed to create and read a <presence/> received from the
-  server.
-
-=head2 Net::XMPP::IQ
-
-  IQ is a wrapper around a number of modules that provide support for
-  the various Info/Query namespaces that XMPP recognizes.
-
-=head2 Net::XMPP::Stanza
-
-  This module represents a namespaced stanza that is used to extend a
-  <message/>, <presence/>, and <iq/>.
-
-  The man page for Net::XMPP::Stanza contains a listing of all supported
-  namespaces, and the methods that are supported by the objects that
-  represent those namespaces.
-
-=head2 Net::XMPP::Namespaces
-
-  XMPP allows for any stanza to be extended by any bit of XML.  This
-  module contains all of the internals for defining the XMPP based
-  extensions defined by the IETF.  The documentation for this module
-  explains more about how to add your own custom namespace and have it
-  be supported.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software, you can redistribute it and/or modify it
-under the same terms as Perl itself.
-
-=cut
-
-require 5.005;
-use strict;
-use XML::Stream 1.22 qw( Node );
-use Time::Local;
-use Carp;
-use Digest::SHA1;
-use Authen::SASL;
-use MIME::Base64;
-use POSIX;
-use vars qw( $AUTOLOAD $VERSION $PARSING );
-
-$VERSION = "1.0";
-
-use Net::XMPP::Debug;
-use Net::XMPP::JID;
-use Net::XMPP::Namespaces;
-use Net::XMPP::Stanza;
-use Net::XMPP::Message;
-use Net::XMPP::IQ;
-use Net::XMPP::Presence;
-use Net::XMPP::Protocol;
-use Net::XMPP::Client;
-
-
-##############################################################################
-#
-# printData - debugging function to print out any data structure in an
-#             organized manner.  Very useful for debugging XML::Parser::Tree
-#             objects.  This is a private function that will only exist in
-#             in the development version.
-#
-##############################################################################
-sub printData
-{
-    print &sprintData(@_);
-}
-
-
-##############################################################################
-#
-# sprintData - debugging function to build a string out of any data structure
-#              in an organized manner.  Very useful for debugging
-#              XML::Parser::Tree objects and perl hashes of hashes.
-#
-#              This is a private function.
-#
-##############################################################################
-sub sprintData
-{
-    return &XML::Stream::sprintData(@_);
-}
-
-
-##############################################################################
-#
-# GetTimeStamp - generic funcion for getting a timestamp.
-#
-##############################################################################
-sub GetTimeStamp
-{
-    my($type,$time,$length) = @_;
-
-    return "" if (($type ne "local") && ($type ne "utc") && !($type =~ /^(local|utc)delay(local|utc|time)$/));
-
-    $length = "long" unless defined($length);
-
-    my ($sec,$min,$hour,$mday,$mon,$year,$wday);
-    if ($type =~ /utcdelay/)
-    {
-        ($year,$mon,$mday,$hour,$min,$sec) = ($time =~ /^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)\:(\d\d)\:(\d\d)$/);
-        $mon--;
-        ($type) = ($type =~ /^utcdelay(.*)$/);
-        $time = timegm($sec,$min,$hour,$mday,$mon,$year);
-    }
-    if ($type =~ /localdelay/)
-    {
-        ($year,$mon,$mday,$hour,$min,$sec) = ($time =~ /^(\d\d\d\d)(\d\d)(\d\d)T(\d\d)\:(\d\d)\:(\d\d)$/);
-        $mon--;
-        ($type) = ($type =~ /^localdelay(.*)$/);
-        $time = timelocal($sec,$min,$hour,$mday,$mon,$year);
-    }
-
-    return $time if ($type eq "time");
-    ($sec,$min,$hour,$mday,$mon,$year,$wday) =
-        localtime(((defined($time) && ($time ne "")) ? $time : time)) if ($type eq "local");
-    ($sec,$min,$hour,$mday,$mon,$year,$wday) =
-        gmtime(((defined($time) && ($time ne "")) ? $time : time)) if ($type eq "utc");
-
-    return sprintf("%d%02d%02dT%02d:%02d:%02d",($year + 1900),($mon+1),$mday,$hour,$min,$sec) if ($length eq "stamp");
-
-    $wday = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat')[$wday];
-
-    my $month = ('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')[$mon];
-    $mon++;
-
-    return sprintf("%3s %3s %02d, %d %02d:%02d:%02d",$wday,$month,$mday,($year + 1900),$hour,$min,$sec) if ($length eq "long");
-    return sprintf("%3s %d/%02d/%02d %02d:%02d",$wday,($year + 1900),$mon,$mday,$hour,$min) if ($length eq "normal");
-    return sprintf("%02d:%02d:%02d",$hour,$min,$sec) if ($length eq "short");
-    return sprintf("%02d:%02d",$hour,$min) if ($length eq "shortest");
-}
-
-
-##############################################################################
-#
-# GetHumanTime - convert seconds, into a human readable time string.
-#
-##############################################################################
-sub GetHumanTime
-{
-    my $seconds = shift;
-
-    my $minutes = 0;
-    my $hours = 0;
-    my $days = 0;
-    my $weeks = 0;
-
-    while ($seconds >= 60) {
-        $minutes++;
-        if ($minutes == 60) {
-            $hours++;
-            if ($hours == 24) {
-                $days++;
-                if ($days == 7) {
-                    $weeks++;
-                    $days -= 7;
-                }
-                $hours -= 24;
-            }
-            $minutes -= 60;
-        }
-        $seconds -= 60;
-    }
-
-    my $humanTime;
-    $humanTime .= "$weeks week " if ($weeks == 1);
-    $humanTime .= "$weeks weeks " if ($weeks > 1);
-    $humanTime .= "$days day " if ($days == 1);
-    $humanTime .= "$days days " if ($days > 1);
-    $humanTime .= "$hours hour " if ($hours == 1);
-    $humanTime .= "$hours hours " if ($hours > 1);
-    $humanTime .= "$minutes minute " if ($minutes == 1);
-    $humanTime .= "$minutes minutes " if ($minutes > 1);
-    $humanTime .= "$seconds second " if ($seconds == 1);
-    $humanTime .= "$seconds seconds " if ($seconds > 1);
-
-    $humanTime = "none" if ($humanTime eq "");
-
-    return $humanTime;
-}
-
-1;
Index: rl/modules/Jabber/lib/Net/XMPP/Client.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/Client.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,250 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::XMPP::Client;
-
-=head1 NAME
-
-Net::XMPP::Client - XMPP Client Module
-
-=head1 SYNOPSIS
-
-  Net::XMPP::Client is a module that provides a developer easy access
-  to the Extensible Messaging and Presence Protocol (XMPP).
-
-=head1 DESCRIPTION
-
-  Client.pm uses Protocol.pm to provide enough high level APIs and
-  automation of the low level APIs that writing an XMPP Client in
-  Perl is trivial.  For those that wish to work with the low level
-  you can do that too, but those functions are covered in the
-  documentation for each module.
-
-  Net::XMPP::Client provides functions to connect to an XMPP server,
-  login, send and receive messages, set personal information, create
-  a new user account, manage the roster, and disconnect.  You can use
-  all or none of the functions, there is no requirement.
-
-  For more information on how the details for how Net::XMPP is written
-  please see the help for Net::XMPP itself.
-
-  For a full list of high level functions available please see
-  Net::XMPP::Protocol.
-
-=head2 Basic Functions
-
-    use Net::XMPP;
-
-    $Con = Net::XMPP::Client->new();
-
-    $Con->SetCallbacks(...);
-
-    $Con->Execute(hostname=>"jabber.org",
-                  username=>"bob",
-                  password=>"XXXX",
-                  resource=>"Work'
-                 );
-
-    #
-    # For the list of available functions see Net::XMPP::Protocol.
-    #
-
-    $Con->Disconnect();
-
-=head1 METHODS
-
-=head2 Basic Functions
-
-    new(debuglevel=>0|1|2, - creates the Client object.  debugfile
-        debugfile=>string,   should be set to the path for the debug
-        debugtime=>0|1)      log to be written.  If set to "stdout"
-                             then the debug will go there.  debuglevel
-                             controls the amount of debug.  For more
-                             information about the valid setting for
-                             debuglevel, debugfile, and debugtime see
-                             Net::XMPP::Debug.
-
-    Connect(hostname=>string,      - opens a connection to the server
-            port=>integer,           listed in the hostname (default
-            timeout=>int             localhost), on the port (default
-            connectiontype=>string,  5222) listed, using the
-            tls=>0|1)                connectiontype listed (default
-                                     tcpip).  The two connection types
-                                     available are:
-                                       tcpip  standard TCP socket
-                                       http   TCP socket, but with the
-                                              headers needed to talk
-                                              through a web proxy
-                                     If you specify tls, then it TLS
-                                     will be used if it is available
-                                     as a feature.
-
-    Execute(hostname=>string,       - Generic inner loop to handle
-            port=>int,                connecting to the server, calling
-            tls=>0|1,                 Process, and reconnecting if the
-            username=>string,         connection is lost.  There are
-            password=>string,         five callbacks available that are
-            resource=>string,         called at various places:
-            register=>0|1,              onconnect - when the client has
-            connectiontype=>string,                 made a connection.
-            connecttimeout=>string,     onauth - when the connection is
-            connectattempts=>int,                made and user has been
-            connectsleep=>int,                   authed.  Essentially,
-            processtimeout=>int)                 this is when you can
-                                                 start doing things
-                                                 as a Client.  Like
-                                                 send presence, get your
-                                                 roster, etc...
-                                        onprocess - this is the most
-                                                    inner loop and so
-                                                    gets called the most.
-                                                    Be very very careful
-                                                    what you put here
-                                                    since it can
-                                                    *DRASTICALLY* affect
-                                                    performance.
-                                        ondisconnect - when the client
-                                                       disconnects from
-                                                       the server.
-                                        onexit - when the function gives
-                                                 up trying to connect and
-                                                 exits.
-                                      The arguments are passed straight
-                                      on to the Connect function, except
-                                      for connectattempts and connectsleep.
-                                      connectattempts is the number of
-                                      times that the Component should try
-                                      to connect before giving up.  -1
-                                      means try forever.  The default is
-                                      -1. connectsleep is the number of
-                                      seconds to sleep between each
-                                      connection attempt.
-
-                                      If you specify register=>1, then the
-                                      Client will attempt to register the
-                                      sepecified account for you, if it
-                                      does not exist.
-            
-    Process(integer) - takes the timeout period as an argument.  If no
-                       timeout is listed then the function blocks until
-                       a packet is received.  Otherwise it waits that
-                       number of seconds and then exits so your program
-                       can continue doing useful things.  NOTE: This is
-                       important for GUIs.  You need to leave time to
-                       process GUI commands even if you are waiting for
-                       packets.  The following are the possible return
-                       values, and what they mean:
-
-                           1   - Status ok, data received.
-                           0   - Status ok, no data received.
-                         undef - Status not ok, stop processing.
-                       
-                       IMPORTANT: You need to check the output of every
-                       Process.  If you get an undef then the connection
-                       died and you should behave accordingly.
-
-    Disconnect() - closes the connection to the server.
-
-    Connected() - returns 1 if the Transport is connected to the server,
-                  and 0 if not.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use Carp;
-use Net::XMPP::Connection;
-use base qw( Net::XMPP::Connection );
-
-sub new
-{
-    my $proto = shift;
-    my $self = { };
-
-    bless($self, $proto);
-    $self->init(@_);
-    
-    $self->{SERVER}->{port} = 5222;
-    $self->{SERVER}->{namespace} = "jabber:client";
-    $self->{SERVER}->{allow_register} = 1;
-
-    return $self;
-}
-
-
-sub _auth
-{
-    my $self = shift;
-
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my %auth;
-    $auth{username} = $args{username};
-    $auth{password} = $args{password};
-    $auth{resource} = $args{resource} if exists($args{resource});
-    
-    return $self->AuthSend(%auth);
-}
-
-
-sub _connection_args
-{
-    my $self = shift;
-    my (%args) = @_;
-    
-    my %connect;
-    $connect{hostname}       = $args{hostname};
-    $connect{port}           = $args{port}           if exists($args{port});
-    $connect{connectiontype} = $args{connectiontype} if exists($args{connectiontype});
-    $connect{timeout}        = $args{connecttimeout} if exists($args{connecttimeout});
-    $connect{tls}            = $args{tls}            if exists($args{tls});
-
-    return %connect;
-}
-
-
-sub _register
-{
-    my $self = shift;
-
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my %fields = $self->RegisterRequest();
-
-    $fields{username} = $args{username};
-    $fields{password} = $args{password};
-
-    $self->RegisterSend(%fields);
-
-    return $self->_auth(%args);
-}
-
-1;
Index: rl/modules/Jabber/lib/Net/XMPP/Connection.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/Connection.pm	(revision 3bf5516302d86ca04ac47f1e963eadbacefeeacb)
+++ 	(revision )
@@ -1,469 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::XMPP::Connection;
-
-=head1 NAME
-
-Net::XMPP::Connection - XMPP Connection Module
-
-=head1 SYNOPSIS
-
-  Net::XMPP::Connection is a private package that serves as a basis
-  for anything wanting to open a socket connection to a server.
-
-=head1 DESCRIPTION
-
-  This module is not meant to be used directly.  You should be using
-  either Net::XMPP::Client, or another package that inherits from
-  Net::XMPP::Connection.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use Carp;
-use base qw( Net::XMPP::Protocol );
-
-
-sub new
-{
-    my $proto = shift;
-    my $self = { };
-
-    bless($self, $proto);
-    
-    $self->init(@_);
-    
-    $self->{SERVER}->{namespace} = "unknown";
-
-    return $self;
-}
-
-
-##############################################################################
-#
-# init - do all of the heavy lifting for a generic connection.
-#
-##############################################################################
-sub init
-{
-    my $self = shift;
-    
-    $self->{ARGS} = {};
-    while($#_ >= 0) { $self->{ARGS}->{ lc(pop(@_)) } = pop(@_); }
-
-    $self->{DEBUG} =
-        Net::XMPP::Debug->new(level      => $self->_arg("debuglevel",-1),
-                              file       => $self->_arg("debugfile","stdout"),
-                              time       => $self->_arg("debugtime",0),
-                              setdefault => 1,
-                              header     => "XMPP::Conn"
-                             );
-
-    $self->{SERVER} = {};
-    $self->{SERVER}->{hostname} = "localhost";
-    $self->{SERVER}->{tls} = $self->_arg("tls",0);
-    $self->{SERVER}->{ssl} = $self->_arg("ssl",0);
-    $self->{SERVER}->{connectiontype} = $self->_arg("connectiontype","tcpip");
-
-    $self->{CONNECTED} = 0;
-    $self->{DISCONNECTED} = 0;
-
-    $self->{STREAM} =
-        XML::Stream->new(style      => "node",
-                         debugfh    => $self->{DEBUG}->GetHandle(),
-                         debuglevel => $self->{DEBUG}->GetLevel(),
-                         debugtime  => $self->{DEBUG}->GetTime(),
-                        );
-    
-    $self->{RCVDB}->{currentID} = 0;
-
-    $self->callbackInit();
-
-    return $self;
-}
-
-
-##############################################################################
-#
-# Connect - Takes a has and opens the connection to the specified server.
-#           Registers CallBack as the main callback for all packets from
-#           the server.
-#
-#           NOTE:  Need to add some error handling if the connection is
-#           not made because the server hostname is wrong or whatnot.
-#
-##############################################################################
-sub Connect
-{
-    my $self = shift;
-
-    while($#_ >= 0) { $self->{SERVER}{ lc pop(@_) } = pop(@_); }
-
-    $self->{SERVER}->{timeout} = 10 unless exists($self->{SERVER}->{timeout});
-
-    $self->{DEBUG}->Log1("Connect: host($self->{SERVER}->{hostname}:$self->{SERVER}->{port}) namespace($self->{SERVER}->{namespace})");
-    $self->{DEBUG}->Log1("Connect: timeout($self->{SERVER}->{timeout})");
-    
-    delete($self->{SESSION});
-    $self->{SESSION} =
-        $self->{STREAM}->
-            Connect(hostname       => $self->{SERVER}->{hostname},
-                    port           => $self->{SERVER}->{port},
-                    namespace      => $self->{SERVER}->{namespace},
-                    connectiontype => $self->{SERVER}->{connectiontype},
-                    timeout        => $self->{SERVER}->{timeout},
-                    ssl            => $self->{SERVER}->{ssl}, #LEGACY
-                    (defined($self->{SERVER}->{componentname}) ?
-                     (to => $self->{SERVER}->{componentname}) :
-                     ()
-                    ),
-                   );
-
-    if ($self->{SESSION})
-    {
-        $self->{DEBUG}->Log1("Connect: connection made");
-
-        $self->{STREAM}->SetCallBacks(node=>sub{ $self->CallBack(@_) });
-        $self->{CONNECTED} = 1;
-
-        if (exists($self->{SESSION}->{version}) &&
-            ($self->{SESSION}->{version} ne ""))
-        {
-            my $tls = $self->GetStreamFeature("xmpp-tls");
-            if (defined($tls) && $self->{SERVER}->{tls})
-            {
-                $self->{SESSION} =
-                    $self->{STREAM}->StartTLS(
-                        $self->{SESSION}->{id},
-                        $self->{SERVER}->{timeout},
-                    );
-            }
-            elsif (defined($tls) && ($tls eq "required"))
-            {
-                $self->SetErrorCode("The server requires us to use TLS, but you did not specify that\nTLS was an option.");
-                return;
-            }
-        }
-
-        return 1;
-    }
-    else
-    {
-        $self->SetErrorCode($self->{STREAM}->GetErrorCode());
-        return;
-    }
-}
-
-
-##############################################################################
-#
-# Connected - returns 1 if the Transport is connected to the server, 0
-#             otherwise.
-#
-##############################################################################
-sub Connected
-{
-    my $self = shift;
-
-    $self->{DEBUG}->Log1("Connected: ($self->{CONNECTED})");
-    return $self->{CONNECTED};
-}
-
-
-##############################################################################
-#
-# Disconnect - Sends the string to close the connection cleanly.
-#
-##############################################################################
-sub Disconnect
-{
-    my $self = shift;
-
-    $self->{STREAM}->Disconnect($self->{SESSION}->{id})
-        if ($self->{CONNECTED} == 1);
-    $self->{STREAM}->SetCallBacks(node=>undef);    
-    $self->{CONNECTED} = 0;
-    $self->{DISCONNECTED} = 1;
-    $self->{DEBUG}->Log1("Disconnect: bye bye");
-    $self->{DEBUG}->GetHandle()->close();
-}
-
-
-##############################################################################
-#
-# Execute - generic inner loop to listen for incoming messages, stay
-#           connected to the server, and do all the right things.  It
-#           calls a couple of callbacks for the user to put hooks into
-#           place if they choose to.
-#
-##############################################################################
-sub Execute
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $args{connectiontype} = "tcpip" unless exists($args{connectiontype});
-    $args{connectattempts} = -1 unless exists($args{connectattempts});
-    $args{connectsleep} = 5 unless exists($args{connectsleep});
-    $args{register} = 0 unless exists($args{register});
-
-    my %connect = $self->_connect_args(%args);
-
-    $self->{DEBUG}->Log1("Execute: begin");
-
-    my $connectAttempt = $args{connectattempts};
-
-    while(($connectAttempt == -1) || ($connectAttempt > 0))
-    {
-
-        $self->{DEBUG}->Log1("Execute: Attempt to connect ($connectAttempt)");
-
-        my $status = $self->Connect(%connect);
-
-        if (!(defined($status)))
-        {
-            $self->{DEBUG}->Log1("Execute: Server is not answering.  (".$self->GetErrorCode().")");
-            $self->{CONNECTED} = 0;
-
-            $connectAttempt-- unless ($connectAttempt == -1);
-            sleep($args{connectsleep});
-            next;
-        }
-
-        $self->{DEBUG}->Log1("Execute: Connected...");
-        &{$self->{CB}->{onconnect}}() if exists($self->{CB}->{onconnect});
-
-        my @result = $self->_auth(%args);
-
-        if (@result && $result[0] ne "ok")
-        {
-            $self->{DEBUG}->Log1("Execute: Could not auth with server: ($result[0]: $result[1])");
-            &{$self->{CB}->{onauthfail}}()
-                if exists($self->{CB}->{onauthfail});
-            
-            if (!$self->{SERVER}->{allow_register} || $args{register} == 0)
-            {
-                $self->{DEBUG}->Log1("Execute: Register turned off.  Exiting.");
-                $self->Disconnect();
-                &{$self->{CB}->{ondisconnect}}()
-                    if exists($self->{CB}->{ondisconnect});
-                $connectAttempt = 0;
-            }
-            else
-            {
-                @result = $self->_register(%args);
-
-                if ($result[0] ne "ok")
-                {
-                    $self->{DEBUG}->Log1("Execute: Register failed.  Exiting.");
-                    &{$self->{CB}->{onregisterfail}}()
-                        if exists($self->{CB}->{onregisterfail});
-            
-                    $self->Disconnect();
-                    &{$self->{CB}->{ondisconnect}}()
-                        if exists($self->{CB}->{ondisconnect});
-                    $connectAttempt = 0;
-                }
-                else
-                {
-                    &{$self->{CB}->{onauth}}()
-                        if exists($self->{CB}->{onauth});
-                }
-            }
-        }
-        else
-        {
-            &{$self->{CB}->{onauth}}()
-                if exists($self->{CB}->{onauth});
-        }
- 
-        while($self->Connected())
-        {
-
-            while(defined($status = $self->Process($args{processtimeout})))
-            {
-                &{$self->{CB}->{onprocess}}()
-                    if exists($self->{CB}->{onprocess});
-            }
-
-            if (!defined($status))
-            {
-                $self->Disconnect();
-                $self->{DEBUG}->Log1("Execute: Connection to server lost...");
-                &{$self->{CB}->{ondisconnect}}()
-                    if exists($self->{CB}->{ondisconnect});
-
-                $connectAttempt = $args{connectattempts};
-                next;
-            }
-        }
-
-        last if $self->{DISCONNECTED};
-    }
-
-    $self->{DEBUG}->Log1("Execute: end");
-    &{$self->{CB}->{onexit}}() if exists($self->{CB}->{onexit});
-}
-
-
-###############################################################################
-#
-#  Process - If a timeout value is specified then the function will wait
-#            that long before returning.  This is useful for apps that
-#            need to handle other processing while still waiting for
-#            packets.  If no timeout is listed then the function waits
-#            until a packet is returned.  Either way the function exits
-#            as soon as a packet is returned.
-#
-###############################################################################
-sub Process
-{
-    my $self = shift;
-    my ($timeout) = @_;
-    my %status;
-
-    if (exists($self->{PROCESSERROR}) && ($self->{PROCESSERROR} == 1))
-    {
-        croak("There was an error in the last call to Process that you did not check for and\nhandle.  You should always check the output of the Process call.  If it was\nundef then there was a fatal error that you need to check.  There is an error\nin your program");
-    }
-
-    $self->{DEBUG}->Log5("Process: timeout($timeout)") if defined($timeout);
-
-    if (!defined($timeout) || ($timeout eq ""))
-    {
-        while(1)
-        {
-            %status = $self->{STREAM}->Process();
-            $self->{DEBUG}->Log1("Process: status($status{$self->{SESSION}->{id}})");
-            last if ($status{$self->{SESSION}->{id}} != 0);
-            select(undef,undef,undef,.25);
-        }
-        $self->{DEBUG}->Log1("Process: return($status{$self->{SESSION}->{id}})");
-        if ($status{$self->{SESSION}->{id}} == -1)
-        {
-            $self->{PROCESSERROR} = 1;
-            return;
-        }
-        else
-        {
-            return $status{$self->{SESSION}->{id}};
-        }
-    }
-    else
-    {
-        %status = $self->{STREAM}->Process($timeout);
-        if ($status{$self->{SESSION}->{id}} == -1)
-        {
-            $self->{PROCESSERROR} = 1;
-            return;
-        }
-        else
-        {
-            return $status{$self->{SESSION}->{id}};
-        }
-    }
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Overloadable Methods
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# _auth - Overload this method to provide the authentication method for your
-#         type of connection.
-#
-##############################################################################
-sub _auth
-{
-    my $self = shift;
-    croak("You must override the _auth method.");
-}
-
-
-##############################################################################
-#
-# _connect_args - The Connect function that the Execute loop uses needs
-#                 certain args.  This method lets you map the Execute args
-#                 into the Connect args for your Connection type.
-#
-##############################################################################
-sub _connect_args
-{
-    my $self = shift;
-    my (%args) = @_;
-
-    return %args;
-}
-
-
-##############################################################################
-#
-# _register - overload this method if you need your connection to register
-#             with the server.
-#
-##############################################################################
-sub _register
-{
-    my $self = shift;
-    return ( "ok" ,"" );
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Private Helpers
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-sub _arg
-{
-    my $self = shift;
-    my $arg = shift;
-    my $default = shift;
-
-    return exists($self->{ARGS}->{$arg}) ? $self->{ARGS}->{$arg} : $default;
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/XMPP/Debug.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/Debug.pm	(revision b7b2a76676535044fc771b1bb087e020102d7af2)
+++ 	(revision )
@@ -1,346 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::XMPP::Debug;
-
-=head1 NAME
-
-Net::XMPP::Debug - XMPP Debug Module
-
-=head1 SYNOPSIS
-
-  Net::XMPP::Debug is a module that provides a developer easy access
-  to logging debug information.
-
-=head1 DESCRIPTION
-
-  Debug is a helper module for the Net::XMPP modules.  It provides
-  the Net::XMPP modules with an object to control where, how, and
-  what is logged.
-
-=head2 Basic Functions
-
-    $Debug = Net::XMPP::Debug->new();
-
-    $Debug->Init(level=>2,
-	             file=>"stdout",
-  	             header=>"MyScript");
-
-    $Debug->Log0("Connection established");
-
-=head1 METHODS
-
-=head2 Basic Functions
-
-    new(hash) - creates the Debug object.  The hash argument is passed
-                to the Init function.  See that function description
-                below for the valid settings.
-
-    Init(level=>integer,  - initializes the debug object.  The level
-         file=>string,      determines the maximum level of debug
-         header=>string,    messages to log:
-         setdefault=>0|1,     0 - Base level Output (default)
-         usedefault=>0|1,     1 - High level API calls
-         time=>0|1)           2 - Low level API calls
-                              ...
-                              N - Whatever you want....
-                            The file determines where the debug log
-                            goes.  You can either specify a path to
-                            a file, or "stdout" (the default).  "stdout"
-                            tells Debug to send all of the debug info
-                            sent to this object to go to stdout.
-                            header is a string that will preappended
-                            to the beginning of all log entries.  This
-                            makes it easier to see what generated the
-                            log entry (default is "Debug").
-                            setdefault saves the current filehandle
-                            and makes it available for other Debug
-                            objects to use.  To use the default set
-                            usedefault to 1.  The time parameter
-                            specifies whether or not to add a timestamp
-                            to the beginning of each logged line.
-
-    LogN(array) - Logs the elements of the array at the corresponding
-                  debug level N.  If you pass in a reference to an
-                  array or hash then they are printed in a readable
-                  way.  (ie... Log0, Log2, Log100, etc...)
-
-=head1 EXAMPLE
-
-  $Debug = Net::XMPP:Debug->new(level=>2,
-                               header=>"Example");
-
-    $Debug->Log0("test");
-
-    $Debug->Log2("level 2 test");
-
-    $hash{a} = "atest";
-    $hash{b} = "btest";
-
-    $Debug->Log1("hashtest",\%hash);
-
-  You would get the following log:
-
-    Example: test
-    Example: level 2 test
-    Example: hashtest { a=>"atest" b=>"btest" }
-
-  If you had set the level to 1 instead of 2 you would get:
-
-    Example: test
-    Example: hashtest { a=>"atest" b=>"btest" }
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use FileHandle;
-use Carp;
-use vars qw( %HANDLES $DEFAULT $DEFAULTLEVEL $DEFAULTTIME $AUTOLOAD );
-
-$DEFAULTLEVEL = -1;
-
-sub new
-{
-    my $proto = shift;
-    my $self = { };
-    bless($self, $proto);
-
-    $self->Init(@_);
-
-    return $self;
-}
-
-
-##############################################################################
-#
-# Init - opens the fielhandle and initializes the Debug object.
-#
-##############################################################################
-sub Init
-{
-    my $self = shift;
-
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-    
-    delete($args{file}) if (lc($args{file}) eq "stdout");
-
-    $args{time} = 0 if !exists($args{time});
-    $args{setdefault} = 0 if !exists($args{setdefault});
-    $args{usedefault} = 0 if !exists($args{usedefault});
-
-    $self->{TIME} = $args{time};
-
-    if ($args{usedefault} == 1)
-    {
-        $args{setdefault} = 0;
-        $self->{USEDEFAULT} = 1;
-    }
-    else
-    {
-        $self->{LEVEL} = 0;
-        $self->{LEVEL} = $args{level} if exists($args{level});
-
-        $self->{HANDLE} = new FileHandle(">&STDERR");
-        $self->{HANDLE}->autoflush(1);
-        if (exists($args{file}))
-        {
-            if (exists($Net::XMPP::Debug::HANDLES{$args{file}}))
-            {
-                $self->{HANDLE} = $Net::XMPP::Debug::HANDLES{$args{file}};
-                $self->{HANDLE}->autoflush(1);
-            }
-            else
-            {
-                if (-e $args{file})
-                {
-                    if (-w $args{file})
-                    {
-                        $self->{HANDLE} = new FileHandle(">$args{file}");
-                        if (defined($self->{HANDLE}))
-                        {
-                            $self->{HANDLE}->autoflush(1);
-                            binmode $self->{HANDLE}, ":utf8";
-                            $Net::XMPP::Debug::HANDLES{$args{file}} = $self->{HANDLE};
-                        }
-                        else
-                        {
-                            print STDERR "ERROR: Debug filehandle could not be opened.\n";
-                            print STDERR"        Debugging disabled.\n";
-                            print STDERR "       ($!)\n";
-                            $self->{LEVEL} = -1;
-                        }
-                    }
-                    else
-                    {
-                        print STDERR "ERROR: You do not have permission to write to $args{file}.\n";
-                        print STDERR"        Debugging disabled.\n";
-                        $self->{LEVEL} = -1;
-                    }
-                }
-                else
-                {
-                    $self->{HANDLE} = new FileHandle(">$args{file}");
-                    if (defined($self->{HANDLE}))
-                    {
-                        $self->{HANDLE}->autoflush(1);
-                        $Net::XMPP::Debug::HANDLES{$args{file}} = $self->{HANDLE};
-                    }
-                    else
-                    {
-                        print STDERR "ERROR: Debug filehandle could not be opened.\n";
-                        print STDERR"        Debugging disabled.\n";
-                        print STDERR "       ($!)\n";
-                        $self->{LEVEL} = -1;
-                    }
-                }
-            }
-        }
-    }
-    if ($args{setdefault} == 1)
-    {
-        $Net::XMPP::Debug::DEFAULT = $self->{HANDLE};
-        $Net::XMPP::Debug::DEFAULTLEVEL = $self->{LEVEL};
-        $Net::XMPP::Debug::DEFAULTTIME = $self->{TIME};
-    }
-
-    $self->{HEADER} = "Debug";
-    $self->{HEADER} = $args{header} if exists($args{header});
-}
-
-
-##############################################################################
-#
-# Log - takes the limit and the array to log and logs them
-#
-##############################################################################
-sub Log
-{
-    my $self = shift;
-    my (@args) = @_;
-
-    my $fh = $self->{HANDLE};
-    $fh = $Net::XMPP::Debug::DEFAULT if exists($self->{USEDEFAULT});
-
-    my $string = "";
-
-    my $testTime = $self->{TIME};
-    $testTime = $Net::XMPP::Debug::DEFAULTTIME if exists($self->{USEDEFAULT});
-
-    $string .= "[".&Net::XMPP::GetTimeStamp("local",time,"short")."] "
-        if ($testTime == 1);
-    $string .= $self->{HEADER}.": ";
-
-    my $arg;
-
-    foreach $arg (@args)
-    {
-        if (ref($arg) eq "HASH")
-        {
-            $string .= " {";
-            my $key;
-            foreach $key (sort {$a cmp $b} keys(%{$arg}))
-            {
-                $string .= " ".$key."=>'".$arg->{$key}."'";
-            }
-            $string .= " }";
-        }
-        else
-        {
-            if (ref($arg) eq "ARRAY")
-            {
-                $string .= " [ ".join(" ",@{$arg})." ]";
-            }  else {
-                $string .= $arg;
-            }
-        }
-    }
-    print $fh "$string\n";
-    return 1;
-}
-
-
-##############################################################################
-#
-# AUTOLOAD - if a function is called that is not defined then this function
-#            will examine the function name and either give an error or call
-#            the appropriate function.
-#
-##############################################################################
-sub AUTOLOAD
-{
-    my $self = shift;
-    return if ($AUTOLOAD =~ /::DESTROY$/);
-    my ($function) = ($AUTOLOAD =~ /\:\:(.*)$/);
-    croak("$function not defined") if !($function =~ /Log\d+/);
-    my ($level) = ($function =~ /Log(\d+)/);
-    return 0 if ($level > (exists($self->{USEDEFAULT}) ? $Net::XMPP::Debug::DEFAULTLEVEL : $self->{LEVEL}));
-    $self->Log(@_);
-}
-
-
-##############################################################################
-#
-# GetHandle - returns the filehandle being used by this object.
-#
-##############################################################################
-sub GetHandle
-{
-    my $self = shift;
-    return $self->{HANDLE};
-}
-
-
-##############################################################################
-#
-# GetLevel - returns the debug level used by this object.
-#
-##############################################################################
-sub GetLevel
-{
-    my $self = shift;
-    return $self->{LEVEL};
-}
-
-
-##############################################################################
-#
-# GetTime - returns the debug time used by this object.
-#
-##############################################################################
-sub GetTime
-{
-    my $self = shift;
-    return $self->{TIME};
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/XMPP/IQ.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/IQ.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,367 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::XMPP::IQ;
-
-=head1 NAME
-
-Net::XMPP::IQ - XMPP Info/Query Module
-
-=head1 SYNOPSIS
-
-  Net::XMPP::IQ is a companion to the Net::XMPP module. It
-  provides the user a simple interface to set and retrieve all
-  parts of an XMPP IQ.
-
-=head1 DESCRIPTION
-
-  Net::XMPP::IQ differs from the other Net::XMPP::* modules in that
-  the XMLNS of the query is split out into a submodule under
-  IQ.  For specifics on each module please view the documentation
-  for the Net::XMPP::Namespaces module.
-
-  A Net::XMPP::IQ object is passed to the callback function for the
-  message.  Also, the first argument to the callback functions is the
-  session ID from XML::Stream.  There are some cases where you might
-  want this information, like if you created a Client that connects to
-  two servers at once, or for writing a mini server.
-
-    use Net::XMPP;
-
-    sub iq {
-      my ($sid,$IQ) = @_;
-      .
-      .
-      my $reply = $IQ->Reply();
-      my $replyQuery->GetQuery();
-      .
-    }
-
-  You now have access to all of the retrieval functions available.
-
-  To create a new iq to send to the server:
-
-    use Net::XMPP;
-
-    $IQ = Net::XMPP::IQ->new();
-    $IQType = $IQ->NewChild( type );
-    $IQType->SetXXXXX("yyyyy");
-
-  Now you can call the creation functions for the IQ, and for the
-  <query/> on the new query object itself.  See below for the <iq/>
-  functions, and in each query module for those functions.
-
-=head1 METHODS
-
-=head2 General functions
-
-  Reply(%args) - Creates a return <iq/> with the to and from
-                 filled in correctly, and a query object already
-                 added in.  The %args that you pass are passed
-                 to SetIQ() and will overwrite the IQ settings
-                 that Reply sets.
-
-=head2 Retrieval functions
-
-  GetTo()      - returns either a string with the JID, or a
-  GetTo("jid")   Net::XMPP::JID object for the person who is
-                 going to receive the <iq/>.  To get the JID
-                 object set the string to "jid", otherwise leave
-                 blank for the text string.
-
-                 $to    = $IQ->GetTo();
-                 $toJID = $IQ->GetTo("jid");
-
-  GetFrom()      -  returns either a string with the JID, or a
-  GetFrom("jid")    Net::XMPP::JID object for the person who
-                    sent the <iq/>.  To get the JID object set
-                    the string to "jid", otherwise leave blank for the
-                    text string.
-
-                    $from    = $IQ->GetFrom();
-                    $fromJID = $IQ->GetFrom("jid");
-
-  GetType() - returns a string with the type <iq/> this is.
-
-              $type = $IQ->GetType();
-
-  GetID() - returns an integer with the id of the <iq/>.
-
-            $id = $IQ->GetID();
-
-  GetError() - returns a string with the text description of the error.
-
-               $error = $IQ->GetError();
-
-  GetErrorCode() - returns a string with the code of error.
-
-                   $errorCode = $IQ->GetErrorCode();
-
-  GetQuery() - returns a Net::XMPP::Stanza object that contains the data
-               in the query of the <iq/>.  Basically, it returns the
-               first child in the <iq/>.
-
-               $query = $IQ->GetQuery();
-
-  GetQueryXMLNS() - returns a string with the namespace of the query
-                    for this <iq/>, if one exists.
-
-                    $xmlns = $IQ->GetQueryXMLNS();
-
-=head2 Creation functions
-
-  SetIQ(to=>string|JID,    - set multiple fields in the <iq/> at one
-        from=>string|JID,    time.  This is a cumulative and over
-        id=>string,          writing action.  If you set the "to"
-        type=>string,        attribute twice, the second setting is
-        errorcode=>string,   what is used.  If you set the status, and
-        error=>string)       then set the priority then both will be in
-                             the <iq/> tag.  For valid settings read the
-                             specific Set functions below.
-
-                             $IQ->SetIQ(type=>"get",
-                                        to=>"bob\@jabber.org");
-
-                             $IQ->SetIQ(to=>"bob\@jabber.org",
-                                        errorcode=>403,
-                                        error=>"Permission Denied");
-
-  SetTo(string) - sets the to attribute.  You can either pass a string
-  SetTo(JID)      or a JID object.  They must be a valid Jabber
-                  Identifiers or the server will return an error message.
-                  (ie.  bob@jabber.org, etc...)
-
-                  $IQ->SetTo("bob\@jabber.org");
-
-  SetFrom(string) - sets the from attribute.  You can either pass a
-  SetFrom(JID)      string or a JID object.  They must be a valid JIDs
-                    or the server will return an error message.
-                    (ie.  bob@jabber.org, etc...)
-
-                    $IQ->SetFrom("me\@jabber.org");
-
-  SetType(string) - sets the type attribute.  Valid settings are:
-
-                    get      request information
-                    set      set information
-                    result   results of a get
-                    error    there was an error
-
-                    $IQ->SetType("set");
-
-  SetErrorCode(string) - sets the error code of the <iq/>.
-
-                         $IQ->SetErrorCode(403);
-
-  SetError(string) - sets the error string of the <iq/>.
-
-                     $IQ->SetError("Permission Denied");
-
-  NewChild(string) - creates a new Net::XMPP::Stanza object with the
-                     namespace in the string.  In order for this
-                     function to work with a custom namespace, you
-                     must define and register that namespace with the
-                     IQ module.  For more information please read the
-                     documentation for Net::XMPP::Stanza.
-
-                     $queryObj = $IQ->NewChild("jabber:iq:auth");
-                     $queryObj = $IQ->NewChild("jabber:iq:roster");
-
-  Reply(hash) - creates a new IQ object and populates the to/from
-                fields.  If you specify a hash the same as with SetIQ
-                then those values will override the Reply values.
-
-                $iqReply = $IQ->Reply();
-                $iqReply = $IQ->Reply(type=>"result");
-
-=head2 Removal functions
-
-  RemoveTo() - removes the to attribute from the <iq/>.
-
-               $IQ->RemoveTo();
-  
-  RemoveFrom() - removes the from attribute from the <iq/>.
-
-                 $IQ->RemoveFrom();
-  
-  RemoveID() - removes the id attribute from the <iq/>.
-
-               $IQ->RemoveID();
-  
-  RemoveType() - removes the type attribute from the <iq/>.
-
-                 $IQ->RemoveType();
-  
-  RemoveError() - removes the <error/> element from the <iq/>.
-
-                  $IQ->RemoveError();
-  
-  RemoveErrorCode() - removes the code attribute from the <error/>
-                      element in the <iq/>.
-
-                      $IQ->RemoveErrorCode();
-
-=head2 Test functions
-
-  DefinedTo() - returns 1 if the to attribute is defined in the <iq/>, 
-                0 otherwise.
-
-                $test = $IQ->DefinedTo();
-
-  DefinedFrom() - returns 1 if the from attribute is defined in the
-                  <iq/>, 0 otherwise.
-
-                  $test = $IQ->DefinedFrom();
-
-  DefinedID() - returns 1 if the id attribute is defined in the <iq/>, 
-                0 otherwise.
-
-                $test = $IQ->DefinedID();
-
-  DefinedType() - returns 1 if the type attribute is defined in the
-                  <iq/>, 0 otherwise.
-
-                  $test = $IQ->DefinedType();
-
-  DefinedError() - returns 1 if <error/> is defined in the <iq/>, 
-                   0 otherwise.
-
-                   $test = $IQ->DefinedError();
-
-  DefinedErrorCode() - returns 1 if the code attribute is defined in
-                       <error/>, 0 otherwise.
-
-                       $test = $IQ->DefinedErrorCode();
-
-  DefinedQuery() - returns 1 if there is at least one namespaced
-                   child in the object.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-use vars qw( %FUNCTIONS );
-use Net::XMPP::Stanza;
-use base qw( Net::XMPP::Stanza );
-
-sub new
-{
-    my $proto = shift;
-    my $class = ref($proto) || $proto;
-    my $self = { };
-
-    bless($self, $proto);
-
-    $self->{DEBUGHEADER} = "IQ";
-    $self->{TAG} = "iq";
-
-    $self->{FUNCS} = \%FUNCTIONS;
-    
-    $self->_init(@_);
-
-    return $self;
-}
-
-sub _iq { my $self = shift; return Net::XMPP::IQ->new(); }
-
-$FUNCTIONS{Error}->{path} = 'error/text()';
-
-$FUNCTIONS{ErrorCode}->{path} = 'error/@code';
-
-$FUNCTIONS{From}->{type} = 'jid';
-$FUNCTIONS{From}->{path} = '@from';
-
-$FUNCTIONS{ID}->{path} = '@id';
-
-$FUNCTIONS{To}->{type} = 'jid';
-$FUNCTIONS{To}->{path} = '@to';
-
-$FUNCTIONS{Type}->{path} = '@type';
-
-$FUNCTIONS{XMLNS}->{path} = '@xmlns';
-
-$FUNCTIONS{IQ}->{type}  = 'master';
-
-$FUNCTIONS{Child}->{type}  = 'child';
-$FUNCTIONS{Child}->{path}  = '*[@xmlns]';
-$FUNCTIONS{Child}->{child} = { };
-
-$FUNCTIONS{Query}->{type}  = 'child';
-$FUNCTIONS{Query}->{path}  = '*[@xmlns][0]';
-$FUNCTIONS{Query}->{child} = { child_index=>0 };
-
-##############################################################################
-#
-# GetQueryXMLNS - returns the xmlns of the first child
-#
-##############################################################################
-sub GetQueryXMLNS
-{
-    my $self = shift;
-    return $self->{CHILDREN}->[0]->GetXMLNS() if ($#{$self->{CHILDREN}} > -1);
-}
-
-
-##############################################################################
-#
-# Reply - returns a Net::XMPP::IQ object with the proper fields
-#         already populated for you.
-#
-##############################################################################
-sub Reply
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $reply = $self->_iq();
-
-    $reply->SetID($self->GetID()) if ($self->GetID() ne "");
-    $reply->SetType("result");
-
-    $reply->NewChild($self->GetQueryXMLNS());
-
-    $reply->SetIQ((($self->GetFrom() ne "") ?
-                   (to=>$self->GetFrom()) :
-                   ()
-                  ),
-                  (($self->GetTo() ne "") ?
-                   (from=>$self->GetTo()) :
-                   ()
-                  ),
-                 );
-    $reply->SetIQ(%args);
-
-    return $reply;
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/XMPP/JID.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/JID.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,358 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::XMPP::JID;
-
-=head1 NAME
-
-Net::XMPP::JID - XMPP JID Module
-
-=head1 SYNOPSIS
-
-  Net::XMPP::JID is a companion to the Net::XMPP module.
-  It provides the user a simple interface to set and retrieve all 
-  parts of a Jabber ID (userid on a server).
-
-=head1 DESCRIPTION
-
-  To initialize the JID you must pass it the string that represents the
-  jid from the XML packet.  Inside the XMPP modules this is done
-  automatically and the JID object is returned instead of a string.
-  For example, in the callback function for the XMPP object foo:
-
-    use Net::XMPP;
-
-    sub foo {
-      my $foo = Net::XMPP::Foo->new(@_);
-      my $from = $foo->GetFrom();
-      my $JID = Net::XMPP::JID->new($from);
-      .
-      .
-      .
-    }
-
-  You now have access to all of the retrieval functions available.
-
-  To create a new JID to send to the server:
-
-    use Net::XMPP;
-
-    $JID = Net::XMPP::JID->new();
-
-  Now you can call the creation functions below to populate the tag
-  before sending it.
-
-=head2 Retrieval functions
-
-    $userid   = $JID->GetUserID();
-    $server   = $JID->GetServer();
-    $resource = $JID->GetResource();
-
-    $JID      = $JID->GetJID();
-    $fullJID  = $JID->GetJID("full");
-    $baseJID  = $JID->GetJID("base");
-
-=head2 Creation functions
-
-    $JID->SetJID(userid=>"bob",
-                 server=>"jabber.org",
-                 resource=>"Work");
-
-    $JID->SetJID('blue@moon.org/Home');
-
-    $JID->SetUserID("foo");
-    $JID->SetServer("bar.net");
-    $JID->SetResource("Foo Bar");
-
-=head1 METHODS
-
-=head2 Retrieval functions
-
-  GetUserID() - returns a string with the userid of the JID.
-                If the string is an address (bob%jabber.org) then
-                the function will return it as an address 
-                (bob@jabber.org).
-
-  GetServer() - returns a string with the server of the JID.
-
-  GetResource() - returns a string with the resource of the JID. 
-
-  GetJID()       - returns a string that represents the JID stored
-  GetJID("full")   within.  If the "full" string is specified, then
-  GetJID("base")   you get the full JID, including Resource, which
-                   should be used to send to the server.  If the "base",
-                   string is specified, then you will just get
-                   user@server, or the base JID.
-
-=head2 Creation functions
-
-  SetJID(userid=>string,   - set multiple fields in the jid at
-         server=>string,     one time.  This is a cumulative
-         resource=>string)   and over writing action.  If you set
-  SetJID(string)             the "userid" attribute twice, the second
-                             setting is what is used.  If you set
-                             the server, and then set the resource
-                             then both will be in the jid.  If all
-                             you pass is a string, then that string
-                             is used as the JID.  For valid settings 
-                             read the specific Set functions below.
-
-  SetUserID(string) - sets the userid.  Must be a valid userid or the
-                      server will complain if you try to use this JID
-                      to talk to the server.  If the string is an 
-                      address then it will be converted to the %
-                      form suitable for using as a User ID.
-
-  SetServer(string) - sets the server.  Must be a valid host on the 
-                      network or the server will not be able to talk
-                      to it.
-
-  SetResource(string) - sets the resource of the userid to talk to.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-
-sub new
-{
-    my $proto = shift;
-    my $class = ref($proto) || $proto;
-    my $self = { };
-
-    bless($self, $proto);
-
-    if ("@_" ne (""))
-    {
-        my ($jid) = @_;
-        return $jid if ((ref($jid) ne "") && ($jid->isa("Net::XMPP::JID")));
-        $self->{JID} = $jid;
-    }
-    else
-    {
-        $self->{JID} = "";
-    }
-    $self->ParseJID();
-
-    return $self;
-}
-
-
-##############################################################################
-#
-# ParseJID - private helper function that takes the JID and sets the
-#            the three parts of it.
-#
-##############################################################################
-sub ParseJID
-{
-    my $self = shift;
-
-    my $userid;
-    my $server;
-    my $resource;
-
-    ($userid,$server,$resource) =
-        ($self->{JID} =~ /^([^\@\/'"&:<>]*)\@([A-Za-z0-9\.\-\_]+)\/?(.*?)$/);
-    if (!defined($server))
-    {
-        ($server,$resource) =
-            ($self->{JID} =~ /^([A-Za-z0-9\.\-\_]+)\/?(.*?)$/);
-    }
-
-    $userid = "" unless defined($userid);
-    $server = "" unless defined($server);
-    $resource = "" unless defined($resource);
-
-    $self->{USERID} = $userid;
-    $self->{SERVER} = $server;
-    $self->{RESOURCE} = $resource;
-}
-
-
-##############################################################################
-#
-# BuildJID - private helper function that takes the three parts and sets the
-#            JID from them.
-#
-##############################################################################
-sub BuildJID
-{
-    my $self = shift;
-    $self->{JID} = $self->{USERID};
-    $self->{JID} .= "\@" if ($self->{USERID} ne "");
-    $self->{JID} .= $self->{SERVER} if (exists($self->{SERVER}) &&
-                        defined($self->{SERVER}));
-    $self->{JID} .= "/".$self->{RESOURCE} if (exists($self->{RESOURCE}) &&
-                        defined($self->{RESOURCE}) &&
-                        ($self->{RESOURCE} ne ""));
-}
-
-
-##############################################################################
-#
-# GetUserID - returns the userid of the JID.
-#
-##############################################################################
-sub GetUserID
-{
-    my $self = shift;
-    my $userid = $self->{USERID};
-    $userid =~ s/\%/\@/;
-    return $userid;
-}
-
-
-##############################################################################
-#
-# GetServer - returns the server of the JID.
-#
-##############################################################################
-sub GetServer
-{
-    my $self = shift;
-    return $self->{SERVER};
-}
-
-
-##############################################################################
-#
-# GetResource - returns the resource of the JID.
-#
-##############################################################################
-sub GetResource
-{
-    my $self = shift;
-    return $self->{RESOURCE};
-}
-
-
-##############################################################################
-#
-# GetJID - returns the full jid of the JID.
-#
-##############################################################################
-sub GetJID
-{
-    my $self = shift;
-    my $type = shift;
-    $type = "" unless defined($type);
-    return $self->{JID} if ($type eq "full");
-    return $self->{USERID}."\@".$self->{SERVER} if ($self->{USERID} ne "");
-    return $self->{SERVER};
-}
-
-
-##############################################################################
-#
-# SetJID - takes a hash of all of the things you can set on a JID and sets
-#          each one.
-#
-##############################################################################
-sub SetJID
-{
-    my $self = shift;
-    my %jid;
-
-    if ($#_ > 0 ) { 
-        while($#_ >= 0) { $jid{ lc pop(@_) } = pop(@_); }
-
-        $self->SetUserID($jid{userid}) if exists($jid{userid});
-        $self->SetServer($jid{server}) if exists($jid{server});
-        $self->SetResource($jid{resource}) if exists($jid{resource});
-    } else {
-        ($self->{JID}) = @_;
-        $self->ParseJID();
-    }
-}
-
-
-##############################################################################
-#
-# SetUserID - sets the userid of the JID.
-#
-##############################################################################
-sub SetUserID
-{
-    my $self = shift;
-    my ($userid) = @_;
-    $userid =~ s/\@/\%/;
-    $self->{USERID} = $userid;
-    $self->BuildJID();
-}
-
-
-##############################################################################
-#
-# SetServer - sets the server of the JID.
-#
-##############################################################################
-sub SetServer
-{
-    my $self = shift;
-    my ($server) = @_;
-    $self->{SERVER} = $server;
-    $self->BuildJID();
-}
-
-
-##############################################################################
-#
-# SetResource - sets the resource of the JID.
-#
-##############################################################################
-sub SetResource
-{
-    my $self = shift;
-    my ($resource) = @_;
-    $self->{RESOURCE} = $resource;
-    $self->BuildJID();
-}
-
-
-##############################################################################
-#
-# debug - prints out the contents of the JID
-#
-##############################################################################
-sub debug
-{
-    my $self = shift;
-
-    print "debug JID: $self\n";
-    print "UserID:   (",$self->{USERID},")\n";
-    print "Server:   (",$self->{SERVER},")\n";
-    print "Resource: (",$self->{RESOURCE},")\n";
-    print "JID:      (",$self->{JID},")\n";
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/XMPP/Message.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/Message.pm	(revision 8574801f6dba0d88fd1fb74c123861816eb077f8)
+++ 	(revision )
@@ -1,407 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::XMPP::Message;
-
-=head1 NAME
-
-Net::XMPP::Message - XMPP Message Module
-
-=head1 SYNOPSIS
-
-  Net::XMPP::Message is a companion to the Net::XMPP module.
-  It provides the user a simple interface to set and retrieve all
-  parts of an XMPP Message.
-
-=head1 DESCRIPTION
-
-  A Net::XMPP::Message object is passed to the callback function for
-  the message.  Also, the first argument to the callback functions is
-  the session ID from XML::Stream.  There are some cases where you
-  might want thisinformation, like if you created a Client that
-  connects to two servers at once, or for writing a mini server.
-
-    use Net::XMPP;
-
-    sub message {
-      my ($sid,$Mess) = @_;
-      .
-      .
-      .
-    }
-
-  You now have access to all of the retrieval functions available.
-
-  To create a new message to send to the server:
-
-    use Net::XMPP;
-
-    $Mess = Net::XMPP::Message->new();
-
-  Now you can call the creation functions below to populate the tag
-  before sending it.
-
-=head1 METHODS
-
-=head2 Retrieval functions
-
-  GetTo()      - returns the value in the to='' attribute for the
-  GetTo("jid")   <message/>.  If you specify "jid" as an argument
-                 then a Net::XMPP::JID object is returned and
-                 you can easily parse the parts of the JID.
-
-                 $to    = $Mess->GetTo();
-                 $toJID = $Mess->GetTo("jid");
-
-  GetFrom()      - returns the value in the from='' attribute for the
-  GetFrom("jid")   <message/>.  If you specify "jid" as an argument
-                   then a Net::XMPP::JID object is returned and
-                   you can easily parse the parts of the JID.
-
-                   $from    = $Mess->GetFrom();
-                   $fromJID = $Mess->GetFrom("jid");
-
-  GetType() - returns the type='' attribute of the <message/>.  Each
-              message is one of four types:
-
-                normal        regular message (default if type is blank)
-                chat          one on one chat
-                groupchat     multi-person chat
-                headline      headline
-                error         error message
-
-              $type = $Mess->GetType();
-
-  GetSubject() - returns the data in the <subject/> tag.
-
-                 $subject = $Mess->GetSubject();
-
-  GetBody() - returns the data in the <body/> tag.
-
-              $body = $Mess->GetBody();
-
-  GetThread() - returns the data in the <thread/> tag.
-
-                $thread = $Mess->GetThread();
-
-  GetError() - returns a string with the data of the <error/> tag.
-
-               $error = $Mess->GetError();
-
-  GetErrorCode() - returns a string with the code='' attribute of the
-                   <error/> tag.
-
-                   $errCode = $Mess->GetErrorCode();
-
-  GetTimeStamp() - returns a string that represents the time this
-                   message object was created (and probably received)
-                   for sending to the client.  If there is a
-                   jabber:x:delay tag then that time is used to show
-                   when the message was sent.
-
-                   $date = $Mess->GetTimeStamp();
-
-
-=head2 Creation functions
-
-  SetMessage(to=>string|JID,    - set multiple fields in the <message/>
-             from=>string|JID,    at one time.  This is a cumulative
-             type=>string,        and over writing action.  If you set
-             subject=>string,     the "to" attribute twice, the second
-             body=>string,        setting is what is used.  If you set
-             thread=>string,      the subject, and then set the body
-             errorcode=>string,   then both will be in the <message/>
-             error=>string)       tag.  For valid settings read the
-                                  specific Set functions below.
-
-                            $Mess->SetMessage(TO=>"bob\@jabber.org",
-                                              Subject=>"Lunch",
-                                              Body=>"Let's do lunch!");
-                            $Mess->SetMessage(to=>"bob\@jabber.org",
-                                              from=>"jabber.org",
-                                              errorcode=>404,
-                                              error=>"Not found");
-
-  SetTo(string) - sets the to='' attribute.  You can either pass
-  SetTo(JID)      a string or a JID object.  They must be valid JIDs
-                  or the server will return an error message.
-                  (ie.  bob@jabber.org/Work)
-
-                  $Mess->SetTo("test\@jabber.org");
-
-  SetFrom(string) - sets the from='' attribute.  You can either pass
-  SetFrom(JID)      a string or a JID object.  They must be valid JIDs
-                    or the server will return an error message. (ie.
-                    jabber:bob@jabber.org/Work) This field is not
-                    required if you are writing a Client since the
-                    server will put the JID of your connection in
-                    there to prevent spamming.
-
-                    $Mess->SetFrom("me\@jabber.org");
-
-  SetType(string) - sets the type attribute.  Valid settings are:
-
-                      normal         regular message (default if blank)
-                      chat           one one one chat style message
-                      groupchat      multi-person chatroom message
-                      headline       news headline, stock ticker, etc...
-                      error          error message
-
-                    $Mess->SetType("groupchat");
-
-  SetSubject(string) - sets the subject of the <message/>.
-
-                       $Mess->SetSubject("This is a test");
-
-  SetBody(string) - sets the body of the <message/>.
-
-                    $Mess->SetBody("To be or not to be...");
-
-  SetThread(string) - sets the thread of the <message/>.  You should
-                      copy this out of the message being replied to so
-                      that the thread is maintained.
-
-                      $Mess->SetThread("AE912B3");
-
-  SetErrorCode(string) - sets the error code of the <message/>.
-
-                         $Mess->SetErrorCode(403);
-
-  SetError(string) - sets the error string of the <message/>.
-
-                     $Mess->SetError("Permission Denied");
-
-  Reply(hash) - creates a new Message object and populates the
-                to/from, and the subject by putting "re: " in
-                front.  If you specify a hash the same as with
-                SetMessage then those values will override the
-                Reply values.
-
-                $Reply = $Mess->Reply();
-                $Reply = $Mess->Reply(type=>"chat");
-
-=head2 Removal functions
-
-  RemoveTo() - removes the to attribute from the <message/>.
-
-               $Mess->RemoveTo();
-  
-  RemoveFrom() - removes the from attribute from the <message/>.
-
-                 $Mess->RemoveFrom();
-  
-  RemoveType() - removes the type attribute from the <message/>.
-
-                 $Mess->RemoveType();
-  
-  RemoveSubject() - removes the <subject/> element from the
-                    <message/>.
-
-                    $Mess->RemoveSubject();
-
-  RemoveBody() - removes the <body/> element from the
-                 <message/>.
-                  
-                 $Mess->RemoveBody();
-
-  RemoveThread() - removes the <thread/> element from the <message/>.
-
-                   $Mess->RemoveThread();
-  
-  RemoveError() - removes the <error/> element from the <message/>.
-
-                  $Mess->RemoveError();
-  
-  RemoveErrorCode() - removes the code attribute from the <error/>
-                      element in the <message/>.
-
-                      $Mess->RemoveErrorCode();
-
-=head2 Test functions
-
-  DefinedTo() - returns 1 if the to attribute is defined in the
-                <message/>, 0 otherwise.
-
-                $test = $Mess->DefinedTo();
-
-  DefinedFrom() - returns 1 if the from attribute is defined in the
-                  <message/>, 0 otherwise.
-
-                  $test = $Mess->DefinedFrom();
-
-  DefinedType() - returns 1 if the type attribute is defined in the
-                  <message/>, 0 otherwise.
-
-                  $test = $Mess->DefinedType();
-
-  DefinedSubject() - returns 1 if <subject/> is defined in the
-                     <message/>, 0 otherwise.
-
-                     $test = $Mess->DefinedSubject();
-
-  DefinedBody() - returns 1 if <body/> is defined in the <message/>,
-                  0 otherwise.
-
-                  $test = $Mess->DefinedBody();
-
-  DefinedThread() - returns 1 if <thread/> is defined in the <message/>,
-                    0 otherwise.
-
-                    $test = $Mess->DefinedThread();
-
-  DefinedErrorCode() - returns 1 if <error/> is defined in the
-                       <message/>, 0 otherwise.
-
-                       $test = $Mess->DefinedErrorCode();
-
-  DefinedError() - returns 1 if the code attribute is defined in the
-                   <error/>, 0 otherwise.
-
-                   $test = $Mess->DefinedError();
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software, you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-use vars qw( %FUNCTIONS );
-use Net::XMPP::Stanza;
-use base qw( Net::XMPP::Stanza );
-
-sub new
-{
-    my $proto = shift;
-    my $class = ref($proto) || $proto;
-    my $self = {};
-
-    bless($self, $proto);
-
-    $self->{DEBUGHEADER} = "Message";
-    $self->{TAG} = "message";
-    $self->{TIMESTAMP} = &Net::XMPP::GetTimeStamp("local");
-
-    $self->{FUNCS} = \%FUNCTIONS;
-
-    $self->_init(@_);
-
-    return $self;
-}
-
-sub _message { my $self = shift; return Net::XMPP::Message->new(); }
-
-
-$FUNCTIONS{Body}->{path}  = 'body/text()';
-
-$FUNCTIONS{Error}->{path} = 'error/text()';
-
-$FUNCTIONS{ErrorCode}->{path} = 'error/@code';
-
-$FUNCTIONS{From}->{type} = 'jid';
-$FUNCTIONS{From}->{path} = '@from';
-
-$FUNCTIONS{ID}->{path} = '@id';
-
-$FUNCTIONS{Subject}->{path} = 'subject/text()';
-
-$FUNCTIONS{Thread}->{path} = 'thread/text()';
-
-$FUNCTIONS{To}->{type} = 'jid';
-$FUNCTIONS{To}->{path} = '@to';
-
-$FUNCTIONS{Type}->{path} = '@type';
-
-$FUNCTIONS{XMLNS}->{path} = '@xmlns';
-
-$FUNCTIONS{Message}->{type}  = 'master';
-
-$FUNCTIONS{Child}->{type} = 'child';
-$FUNCTIONS{Child}->{path} = '*[@xmlns]';
-$FUNCTIONS{Child}->{child} = {};
-
-##############################################################################
-#
-# GetTimeStamp - returns a string with the time stamp of when this object
-#                was created.
-#
-##############################################################################
-sub GetTimeStamp
-{
-    my $self = shift;
-
-    if ($self->DefinedX("jabber:x:delay"))
-    {
-        my @xTags = $self->GetX("jabber:x:delay");
-        my $xTag = $xTags[0];
-        $self->{TIMESTAMP} = &Net::XMPP::GetTimeStamp("utcdelaylocal",$xTag->GetStamp());
-    }
-
-    return $self->{TIMESTAMP};
-}
-
-
-##############################################################################
-#
-# Reply - returns a Net::XMPP::Message object with the proper fields
-#         already populated for you.
-#
-##############################################################################
-sub Reply
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $reply = $self->_message();
-
-    if (($self->GetType() eq "") || ($self->GetType() eq "normal"))
-    {
-        my $subject = $self->GetSubject();
-        $subject =~ s/re\:\s+//i;
-        $reply->SetSubject("re: $subject");
-    }
-    $reply->SetThread($self->GetThread()) if ($self->GetThread() ne "");
-    $reply->SetID($self->GetID()) if ($self->GetID() ne "");
-    $reply->SetType($self->GetType()) if ($self->GetType() ne "");
-    $reply->SetMessage((($self->GetFrom() ne "") ?
-                         (to=>$self->GetFrom()) :
-                         ()
-                        ),
-                        (($self->GetTo() ne "") ?
-                         (from=>$self->GetTo()) :
-                         ()
-                        ),
-                       );
-    $reply->SetMessage(%args);
-
-    return $reply;
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/XMPP/Namespaces.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/Namespaces.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,602 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::XMPP::Namespaces;
-
-=head1 NAME
-
-Net::XMPP::Namespaces - In depth discussion on how namespaces are handled
-
-=head1 SYNOPSIS
-
-  Net::XMPP::Namespaces provides an depth look at how Net::XMPP handles
-  namespacs, and how to add your own custom ones.  It also serves as the
-  storage bin for all of the Namespace information Net::XMPP requires.
-
-=head1 DESCRIPTION
-
-  XMPP as a protocol is very well defined.  There are three main top
-  level packets (message, iq, and presence).  There is also a way to
-  extend the protocol in a very clear and strucutred way, via namespaces.
-
-  Two major ways that namespaces are used in Jabber is for making the
-  <iq/> a generic wrapper, and as a way for adding data to any packet via
-  a child tag <x/>.  We will use <x/> to represent the packet, but in
-  reality it could be any child tag: <foo/>, <data/>, <error/>, etc.
-
-  The Info/Query <iq/> packet uses namespaces to determine the type of
-  information to access.  Usually there is a <query/> tag in the <iq/>
-  that represents the namespace, but in fact it can be any tag.  The
-  definition of the Query portion, is the first tag that has a namespace.
-
-    <iq type="get"><query xmlns="..."/></iq>
-
-      or
-
-    <iq type="get"><foo xmlns="..."/></iq>
-
-  After that Query stanza can be any number of other stanzas (<x/> tags)
-  you want to include.  The Query packet is represented and available by
-  calling GetQuery() or GetChild(), and the other namespaces are
-  available by calling GetChild().
-
-  The X tag is just a way to piggy back data on other packets.  Like
-  embedding the timestamp for a message using jabber:x:delay, or signing
-  you presence for encryption using jabber:x:signed.
-
-  To this end, Net::XMPP has sought to find a way to easily, and clearly
-  define the functions needed to access the XML for a namespace.  We will
-  go over the full docs, and then show two examples of real namespaces so
-  that you can see what we are talking about.
-
-=head2 Overview
-
-  To avoid a lot of nasty modules populating memory that are not used,
-  and to avoid having to change 15 modules when a minor change is
-  introduced, the Net::XMPP modules have taken AUTOLOADing to the
-  extreme.  Namespaces.pm is nothing but a set of function calls that
-  generates a big hash of hashes.  The hash is accessed by the Stanza.pm
-  AUTOLOAD function to do something.  (This will make sense, I promise.)
-
-  Before going on, I highly suggest you read a Perl book on AUTOLOAD and
-  how it works.  From this point on I will assume that you understand it.
-
-  When you create a Net::XMPP::IQ object and add a Query to it (NewChild)
-  several things are happening in the background.  The argument to
-  NewChild is the namespace you want to add. (custom-namespace)
-
-  Now that you have a Query object to work with you will call the GetXXX
-  functions, and SetXXX functions to set the data.  There are no defined
-  GetXXX and SetXXXX functions.  You cannot look in the Namespaces.pm
-  file and find them.  Instead you will find something like this:
-
-  &add_ns(ns    => "mynamespace",
-          tag   => "mytag",
-          xpath => {
-                    JID       => { type=>'jid', path => '@jid' },
-                    Username  => { path => 'username/text()' },
-                    Test      => { type => 'master' }
-                   }
-         );
-
-  When the GetUsername() function is called, the AUTOLOAD function looks
-  in the Namespaces.pm hash for a "Username" key.  Based on the "type" of
-  the field (scalar being the default) it will use the "path" as an XPath
-  to retrieve the data and call the XPathGet() method in Stanza.pm.
-
-  Confused yet?
-
-=head2 Net::XMPP private namespaces
-
-  Now this is where this starts to get a little sticky.  When you see a
-  namespace with __netxmpp__, or __netjabber__ from Net::Jabber, at the
-  beginning it is usually something custom to Net::XMPP and NOT part of
-  the actual XMPP protocol.
-
-  There are some places where the structure of the XML allows for
-  multiple children with the same name.  The main places you will see
-  this behavior is where you have multiple tags with the same name and
-  those have children under them (jabber:iq:roster).
-
-  In jabber:iq:roster, the <item/> tag can be repeated multiple times,
-  and is sort of like a mini-namespace in itself.  To that end, we treat
-  it like a seperate namespace and defined a __netxmpp__:iq:roster:item
-  namespace to hold it.  What happens is this, in my code I define that
-  the <item/>s tag is "item" and anything with that tag name is to create
-  a new Net::XMPP::Stanza object with the namespace
-  __netxmpp__:iq:roster:item which then becomes a child of the
-  jabber:iq:roster Stanza object.  Also, when you want to add a new item
-  to a jabber:iq:roster project you call NewQuery with the private
-  namespace.
-
-  I know this sounds complicated.  And if after reading this entire
-  document it is still complicated, email me, ask questions, and I will
-  monitor it and adjust these docs to answer the questions that people
-  ask.
-
-=head2 add_ns()
-
-  To repeat, here is an example call to add_ns():
-  
-    &add_ns(ns    => "mynamespace",
-            tag   => "mytag",
-            xpath => {
-                      JID       => { type=>'jid', path => '@jid' },
-                      Username  => { path => 'username/text()' },
-                      Test      => { type => 'master' }
-                     }
-           );
-
-  ns - This is the new namespace that you are trying to add.
-
-  tag - This is the root tag to use for objects based on this namespace.
-
-  xpath - The hash reference passed in the add_ns call to each name of
-  entry tells Net::XMPP how to handle subsequent GetXXXX(), SetXXXX(),
-  DefinedXXXX(), RemoveXXXX(), AddXXXX() calls.  The basic options you
-  can pass in are:
-  
-     type - This tells Stanza how to handle the call.  The possible
-            values are:
-                       
-           array - The value to set and returned is an an array
-                   reference.  For example, <group/> in jabber:iq:roster.
-
-           child - This tells Stanza that it needs to look for the
-                   __netxmpp__ style namesapced children.  AddXXX() adds
-                   a new child, and GetXXX() will return a new Stanza
-                   object representing the packet.
-
-           flag - This is for child elements that are tags by themselves:
-                  <foo/>.  Since the presence of the tag is what is
-                  important, and there is no cdata to store, we just call
-                  it a flag.
-
-           jid - The value is a Jabber ID.  GetXXX() will return a
-                 Net::XMPP::JID object unless you pass it "jid", then it
-                 returns a string.
-
-           master - The GetXXX() and SetXXX() calls return and take a
-                    hash representing all of the GetXXX() and SetXXX()
-                    calls.  For example:
-
-                      SetTest(foo=>"bar",
-                              bar=>"baz");
-
-                    Translates into:
-
-                      SetFoo("bar");
-                      SetBar("baz");
-
-                    GetTest() would return a hash containing what the
-                    packet contains:
-
-                      { foo=>"bar",  bar=>"baz" }
-
-           raw - This will stick whatever raw XML you specify directly
-                 into the Stanza at the point where the path specifies.
-
-           scalar - This will set and get a scalar value.  This is the
-                    main workhorse as attributes and CDATA is represented
-                    by a scalar.  This is the default setting if you do
-                    not provide one.
-
-           special - The special type is unique in that instead of a
-                     string "special", you actually give it an array:
-
-                       [ "special" , <subtype> ]
-
-                     This allows Net::XMPP to be able to handle the
-                     SetXXXX() call in a special manner according to your
-                     choosing.  Right now this is mainly used by
-                     jabber:iq:time to automatically set the time info in
-                     the correct format, and jabber:iq:version to set the
-                     machine OS and add the Net::Jabber version to the
-                     return packet.  You will likely NOT need to use
-                     this, but I wanted to mention it.
-
-           timestamp - If you call SetXXX() but do not pass it anything,
-                       or pass it "", then Net::XMPP will place a
-                       timestamp in the xpath location.
-
-     path - This is the XPath path to where the bit data lives.  The
-            difference.  Now, this is not full XPath due to the nature
-            of how it gets used.  Instead of providing a rooted path
-            all the way to the top, it's a relative path ignoring what
-            the parent is.  For example, if the "tag" you specified was
-            "foo", and the path is "bar/text()", then the XPath will be
-            rooted in the XML of the <foo/> packet.  It will set and get
-            the CDATA from:
-
-               <foo><bar>xxxxx</bar></foo>
-
-            For a flag and a child type, just specify the child element.
-            Take a look at the code in this file for more help on what
-            this means.  Also, read up on XPath if you don't already know
-            what it is.
-
-     child - This is a hash reference that tells Net::XMPP how to handle
-             adding and getting child objects.  The keys for the hash are
-             as follows:
-
-             ns - the real or custom (__netxmpp__) namesapce to use for
-                  this child packet.
-
-             skip_xmlns => 1 - this tells Net::XMPP not to add an
-                               xmlns='' into the XML for the child
-                               object.
-
-             specify_name => 1 - allows you to call NewChild("ns","tag")
-                                 and specify the tag to use for the child
-                                 object.  This, IMHO, is BAD XML
-                                 practice.  You should always know what
-                                 the tag of the child is and use an
-                                 attribute or CDATA to change the type
-                                 of the stanza.  You do not want to use
-                                 this.
-
-             tag - If you use specify_name, then this is the default tag
-                   to use.  You do not want to use this.
-
-     calls - Array reference telling Net::XMPP what functions to create
-             for this name.  For most of the types above you will get
-             Get, Set, Defined, and Remove.  For child types you need to
-             decide how you API will look and specify them yourself:
-
-               ["Get","Defined"]
-               ["Add"]
-               ["Get","Add","Defined"]
-             
-            It all depends on how you want your API to look.
-     
-  Once more... The following:
-  
-    &add_ns(ns    => "mynamespace",
-            tag   => "mytag",
-            xpath => {
-                      JID       => { type=>'jid', path => '@jid' },
-                      Username  => { path => 'username/text()' },
-                      Test      => { type => 'master' }
-                     }
-           );
-
-  generates the following API calls:
-
-    GetJID()
-    SetJID()
-    DefinedJID()
-    RemoveJID()
-    GetUsername()
-    SetUsername()
-    DefinedUsername()
-    RemoveUsername()
-    GetTest()
-    SetTest()
-
-=head2 Wrap Up
-
-  Well.  I hope that I have not scared you off from writing a custom
-  namespace for you application and use Net::XMPP.  Look in the
-  Net::XMPP::Protocol manpage for an example on using the add_ns()
-  function to register your custom namespace so that Net::XMPP can
-  properly handle it.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use vars qw ( %NS %SKIPNS );
-
-$SKIPNS{'__netxmpp__'} = 1;
-
-#------------------------------------------------------------------------------
-# __netxmpp__:child:test
-#------------------------------------------------------------------------------
-{
-    &add_ns(ns    => "__netxmpptest__:child:test",
-            tag   => "test",
-            xpath => {
-                      Bar  => { path => 'bar/text()' },
-                      Foo  => { path => '@foo' },
-                      Test => { type => 'master' }
-                     }
-           );
-}
-
-#------------------------------------------------------------------------------
-# __netxmpp__:child:test:two
-#------------------------------------------------------------------------------
-{
-    &add_ns(ns    => "__netxmpptest__:child:test:two",
-            tag   => "test",
-            xpath => {
-                      Bob  => { path => 'owner/@bob' },
-                      Joe  => { path => 'joe/text()' },
-                      Test => { type => 'master' }
-                     }
-           );
-}
-
-#-----------------------------------------------------------------------------
-# urn:ietf:params:xml:ns:xmpp-bind
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => "urn:ietf:params:xml:ns:xmpp-bind",
-            tag   => "bind",
-            xpath => {
-                      JID      => { type => 'jid',
-                                    path => 'jid/text()',
-                                  },
-                      Resource => { path => 'resource/text()' },
-                      Bind     => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::XMPP',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# urn:ietf:params:xml:ns:xmpp-session
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => "urn:ietf:params:xml:ns:xmpp-session",
-            tag   => "session",
-            xpath => { Session => { type => 'master' } },
-            docs  => {
-                      module => 'Net::XMPP',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:auth
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => "jabber:iq:auth",
-            tag   => "query",
-            xpath => {
-                      Digest   => { path => 'digest/text()' },
-                      Hash     => { path => 'hash/text()' },
-                      Password => { path => 'password/text()' },
-                      Resource => { path => 'resource/text()' },
-                      Sequence => { path => 'sequence/text()' },
-                      Token    => { path => 'token/text()' },
-                      Username => { path => 'username/text()' },
-                      Auth     => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::XMPP',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:privacy
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => "jabber:iq:privacy",
-            tag   => "query",
-            xpath => {
-                      Active  => { path => 'active/@name' },
-                      Default => { path => 'default/@name' },
-                      List    => {
-                                  type  => 'child',
-                                  path  => 'list',
-                                  child => { ns => '__netxmpp__:iq:privacy:list', },
-                                  calls => [ 'Add' ],
-                                 },
-                      Lists   => {
-                                  type  => 'child',
-                                  path  => 'list',
-                                  child => { ns => '__netxmpp__:iq:privacy:list', },
-                                 },
-                      Privacy => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::XMPP',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netxmpp__:iq:privacy:list
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netxmpp__:iq:privacy:list',
-            xpath => {
-                      Name  => { path => '@name' },
-                      Item  => {
-                                type  => 'child',
-                                path  => 'item',
-                                child => { ns => '__netxmpp__:iq:privacy:list:item', },
-                                calls => [ 'Add' ],
-                               },
-                      Items => {
-                                type  => 'child',
-                                path  => 'item',
-                                child => { ns => '__netxmpp__:iq:privacy:item', },
-                               },
-                      List  => { type => 'master' },
-                    },
-            docs  => {
-                      module => 'Net::XMPP',
-                      name   => 'jabber:iq:privacy - list objects',
-                     },
-           );
-}
-        
-#-----------------------------------------------------------------------------
-# __netxmpp__:iq:privacy:list:item
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => '__netxmpp__:iq:privacy:list:item',
-            xpath => {
-                      Action      => { path => '@action' },
-                      IQ          => {
-                                      type => 'flag',
-                                      path => 'iq',
-                                     },
-                      Message     => {
-                                      type => 'flag',
-                                      path => 'message',
-                                     },
-                      Order       => { path => '@order' },
-                      PresenceIn  => {
-                                      type => 'flag',
-                                      path => 'presence-in',
-                                     },
-                      PresenceOut => {
-                                      type => 'flag',
-                                      path => 'presence-out',
-                                     },
-                      Type        => { path => '@type' },
-                      Value       => { path => '@value' },
-                      Item        => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::XMPP',
-                      name   => 'jabber:iq:privacy - item objects',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:register
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => "jabber:iq:register",
-            tag   => "query",
-            xpath => {
-                      Address      => { path => 'address/text()' },
-                      City         => { path => 'city/text()' },
-                      Date         => { path => 'date/text()' },
-                      Email        => { path => 'email/text()' },
-                      First        => { path => 'first/text()' },
-                      Instructions => { path => 'instructions/text()' },
-                      Key          => { path => 'key/text()' },
-                      Last         => { path => 'last/text()' },
-                      Misc         => { path => 'misc/text()' },
-                      Name         => { path => 'name/text()' },
-                      Nick         => { path => 'nick/text()' },
-                      Password     => { path => 'password/text()' },
-                      Phone        => { path => 'phone/text()' },
-                      Registered   => {
-                                       type => 'flag',
-                                       path => 'registered',
-                                      },
-                      Remove       => {
-                                       type => 'flag',
-                                       path => 'password/text()',
-                                      },
-                      State        => { path => 'state/text()' },
-                      Text         => { path => 'text/text()' },
-                      URL          => { path => 'url/text()' },
-                      Username     => { path => 'username/text()' },
-                      Zip          => { path => 'zip/text()' },
-                      Register     => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::XMPP',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# jabber:iq:roster
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => 'jabber:iq:roster',
-            tag   => "query",
-            xpath => {
-                      Item  => {
-                                type  => 'child',
-                                path  => 'item',
-                                child => { ns => '__netxmpp__:iq:roster:item', },
-                                calls => [ 'Add' ],
-                               },
-                      Items => {
-                                type  => 'child',
-                                path  => 'item',
-                                child => { ns => '__netxmpp__:iq:roster:item', },
-                                calls => [ 'Get' ],
-                               },
-                      Roster => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::XMPP',
-                     },
-           );
-}
-
-#-----------------------------------------------------------------------------
-# __netxmpp__:iq:roster:item
-#-----------------------------------------------------------------------------
-{
-    &add_ns(ns    => "__netxmpp__:iq:roster:item",
-            xpath => {
-                      Ask          => { path => '@ask' },
-                      Group        => {
-                                       type => 'array',
-                                       path => 'group/text()',
-                                      },
-                      JID          => {
-                                       type => 'jid',
-                                       path => '@jid',
-                                      },
-                      Name         => { path => '@name' },
-                      Subscription => { path => '@subscription' },
-                      Item         => { type => 'master' },
-                     },
-            docs  => {
-                      module => 'Net::XMPP',
-                      name   => 'jabber:iq:roster - item objects',
-                     },
-           );
-}
-
-
-
-sub add_ns
-{
-    my (%args) = @_;
-
-    # XXX error check...
-    
-    $NS{$args{ns}}->{tag} = $args{tag} if exists($args{tag});
-    $NS{$args{ns}}->{xpath} = $args{xpath};
-    if (exists($args{docs}))
-    {
-        $NS{$args{ns}}->{docs} = $args{docs};
-        $NS{$args{ns}}->{docs}->{name} = $args{ns}
-            unless exists($args{docs}->{name});
-    }
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/XMPP/Presence.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/Presence.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,335 +1,0 @@
-#############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::XMPP::Presence;
-
-=head1 NAME
-
-Net::XMPP::Presence - XMPP Presence Module
-
-=head1 SYNOPSIS
-
-  Net::XMPP::Presence is a companion to the Net::XMPP module.
-  It provides the user a simple interface to set and retrieve all
-  parts of an XMPP Presence.
-
-=head1 DESCRIPTION
-
-  A Net::XMPP::Presence object is passed to the callback function for
-  the message.  Also, the first argument to the callback functions is
-  the session ID from XML::Streams.  There are some cases where you
-  might want this information, like if you created a Client that
-  connects to two servers at once, or for writing a mini server.
-
-    use Net::XMPP;
-
-    sub presence {
-      my ($sid,$Pres) = @_;
-      .
-      .
-      .
-    }
-
-  You now have access to all of the retrieval functions available.
-
-  To create a new presence to send to the server:
-
-    use Net::XMPP;
-
-    $Pres = Net::XMPP::Presence->new();
-
-  Now you can call the creation functions below to populate the tag
-  before sending it.
-
-=head1 METHODS
-
-=head2 Retrieval functions
-
-  GetTo()      - returns the value in the to='' attribute for the
-  GetTo("jid")   <presence/>.  If you specify "jid" as an argument
-                 then a Net::XMPP::JID object is returned and
-                 you can easily parse the parts of the JID.
-
-                 $to    = $Pres->GetTo();
-                 $toJID = $Pres->GetTo("jid");
-
-  GetFrom()      - returns the value in the from='' attribute for the
-  GetFrom("jid")   <presence/>.  If you specify "jid" as an argument
-                   then a Net::XMPP::JID object is returned and
-                   you can easily parse the parts of the JID.
-
-                   $from    = $Pres->GetFrom();
-                   $fromJID = $Pres->GetFrom("jid");
-
-  GetType() - returns the type='' attribute of the <presence/>.  Each
-              presence is one of seven types:
-
-                available       available to receive messages; default
-                unavailable     unavailable to receive anything
-                subscribe       ask the recipient to subscribe you
-                subscribed      tell the sender they are subscribed
-                unsubscribe     ask the recipient to unsubscribe you
-                unsubscribed    tell the sender they are unsubscribed
-                probe           probe
-
-              $type = $Pres->GetType();
-
-  GetStatus() - returns a string with the current status of the resource.
-
-                $status = $Pres->GetStatus();
-
-  GetPriority() - returns an integer with the priority of the resource
-                  The default is 0 if there is no priority in this
-                  presence.
-
-                  $priority = $Pres->GetPriority();
-
-  GetShow() - returns a string with the state the client should show.
-
-              $show = $Pres->GetShow();
-
-=head2 Creation functions
-
-  SetPresence(to=>string|JID     - set multiple fields in the <presence/>
-              from=>string|JID,    at one time.  This is a cumulative
-              type=>string,        and over writing action.  If you set
-              status=>string,      the "to" attribute twice, the second
-              priority=>integer,   setting is what is used.  If you set
-              meta=>string,        the status, and then set the priority
-              icon=>string,        then both will be in the <presence/>
-              show=>string,        tag.  For valid settings read the
-              loc=>string)         specific Set functions below.
-
-                        $Pres->SetPresence(TYPE=>"away",
-					   StatuS=>"Out for lunch");
-
-  SetTo(string) - sets the to attribute.  You can either pass a string
-  SetTo(JID)      or a JID object.  They must be valid JIDs or the 
-                  server will return an error message.
-                  (ie.  bob@jabber.org/Silent Bob, etc...)
-
-                  $Pres->SetTo("bob\@jabber.org");
-
-  SetFrom(string) - sets the from='' attribute.  You can either pass
-  SetFrom(JID)      a string or a JID object.  They must be valid JIDs
-                    or the server will return an error message. (ie.
-                    jabber:bob@jabber.org/Work)  This field is not
-                    required if you are writing a Client since the
-                    server will put the JID of your connection in there
-                    to prevent spamming.
-
-                    $Pres->SetFrom("jojo\@jabber.org");
-
-  SetType(string) - sets the type attribute.  Valid settings are:
-
-                    available      available to receive messages; default
-                    unavailable    unavailable to receive anything
-                    subscribe      ask the recipient to subscribe you
-                    subscribed     tell the sender they are subscribed
-                    unsubscribe    ask the recipient to unsubscribe you
-                    unsubscribed   tell the sender they are unsubscribed
-                    probe          probe
-
-                    $Pres->SetType("unavailable");
-
-  SetStatus(string) - sets the status tag to be whatever string the user
-                      wants associated with that resource.
-
-                      $Pres->SetStatus("Taking a nap");
-
-  SetPriority(integer) - sets the priority of this resource.  The highest
-                         resource attached to the xmpp account is the
-                         one that receives the messages.
-
-                         $Pres->SetPriority(10);
-
-  SetShow(string) - sets the name of the icon or string to display for
-                    this resource.
-
-                    $Pres->SetShow("away");
-
-  Reply(hash) - creates a new Presence object and populates the to/from
-                fields.  If you specify a hash the same as with
-                SetPresence then those values will override the Reply
-                values.
-
-                $Reply = $Pres->Reply();
-                $Reply = $Pres->Reply(type=>"subscribed");
-
-=head2 Removal functions
-
-  RemoveTo() -  removes the to attribute from the <presence/>.
-
-                $Pres->RemoveTo();
-  
-  RemoveFrom() -  removes the from attribute from the <presence/>.
-
-                  $Pres->RemoveFrom();
-  
-  RemoveType() -  removes the type attribute from the <presence/>.
-
-                  $Pres->RemoveType();
-  
-  RemoveStatus() -  removes the <status/> element from the <presence/>.
-
-                    $Pres->RemoveStatus();
-  
-  RemovePriority() -  removes the <priority/> element from the
-                      <presence/>.
-
-                      $Pres->RemovePriority();
-  
-  RemoveShow() -  removes the <show/> element from the <presence/>.
-
-                  $Pres->RemoveShow();
-  
-=head2 Test functions
-
-  DefinedTo() - returns 1 if the to attribute is defined in the
-                <presence/>, 0 otherwise.
-
-                $test = $Pres->DefinedTo();
-
-  DefinedFrom() - returns 1 if the from attribute is defined in the
-                  <presence/>, 0 otherwise.
-
-                  $test = $Pres->DefinedFrom();
-
-  DefinedType() - returns 1 if the type attribute is defined in the
-                  <presence/>, 0 otherwise.
-
-                   $test = $Pres->DefinedType();
-
-  DefinedStatus() - returns 1 if <status/> is defined in the
-                    <presence/>, 0 otherwise.
-
-                    $test = $Pres->DefinedStatus();
-
-  DefinedPriority() - returns 1 if <priority/> is defined in the
-                      <presence/>, 0 otherwise.
-
-                      $test = $Pres->DefinedPriority();
-
-  DefinedShow() - returns 1 if <show/> is defined in the <presence/>,
-                  0 otherwise.
-
-                  $test = $Pres->DefinedShow();
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-require 5.003;
-use strict;
-use Carp;
-use vars qw( %FUNCTIONS );
-use Net::XMPP::Stanza;
-use base qw( Net::XMPP::Stanza );
-
-sub new
-{
-    my $proto = shift;
-    my $class = ref($proto) || $proto;
-    my $self = { };
-
-    bless($self, $proto);
-
-    $self->{DEBUGHEADER} = "Presence";
-    $self->{TAG} = "presence";
-
-    $self->{FUNCS} = \%FUNCTIONS;
-    
-    $self->_init(@_);
-
-    return $self;
-}
-
-sub _presence { my $self = shift; return Net::XMPP::Presence->new(); }
-
-
-$FUNCTIONS{Error}->{path} = 'error/text()';
-
-$FUNCTIONS{ErrorCode}->{path} = 'error/@code';
-
-$FUNCTIONS{From}->{type} = 'jid';
-$FUNCTIONS{From}->{path} = '@from';
-
-$FUNCTIONS{ID}->{path} = '@id';
-
-$FUNCTIONS{Priority}->{path} = 'priority/text()';
-
-$FUNCTIONS{Show}->{path} = 'show/text()';
-
-$FUNCTIONS{Status}->{path} = 'status/text()';
-
-$FUNCTIONS{To}->{type} = 'jid';
-$FUNCTIONS{To}->{path} = '@to';
-
-$FUNCTIONS{Type}->{path} = '@type';
-
-$FUNCTIONS{XMLNS}->{path} = '@xmlns';
-
-$FUNCTIONS{Presence}->{type}  = 'master';
-
-$FUNCTIONS{Child}->{type}  = 'child';
-$FUNCTIONS{Child}->{path}  = '*[@xmlns]';
-$FUNCTIONS{Child}->{child} = {};
-
-##############################################################################
-#
-# Reply - returns a Net::XMPP::Presence object with the proper fields
-#         already populated for you.
-#
-##############################################################################
-sub Reply
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $reply = $self->_presence();
-
-    $reply->SetID($self->GetID()) if ($self->GetID() ne "");
-
-    $reply->SetPresence((($self->GetFrom() ne "") ?
-                         (to=>$self->GetFrom()) :
-                         ()
-                        ),
-                        (($self->GetTo() ne "") ?
-                         (from=>$self->GetTo()) :
-                         ()
-                        ),
-                       );
-
-    $reply->SetPresence(%args);
-
-    return $reply;
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/XMPP/PrivacyLists.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/PrivacyLists.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,358 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::XMPP::PrivacyLists;
-
-=head1 NAME
-
-Net::XMPP::PrivacyLists - XMPP Privacy Lists Object
-
-=head1 SYNOPSIS
-
-  This module is not yet complete.  Do not use.
-
-=head1 DESCRIPTION
-
-=head2 Basic Functions
-
-=head2 Advanced Functions
-
-=head1 METHODS
-
-=head2 Basic Functions
-
-=head2 Advanced Functions
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use Carp;
-
-sub new
-{
-    my $proto = shift;
-    my $self = { };
-
-    my %args;
-    while($#_ >= 0) { $args{ lc(pop(@_)) } = pop(@_); }
-
-    $self->{CONNECTION} = $args{connection};
-    
-    bless($self, $proto);
-
-    $self->init();
-    
-    return $self;
-}
-
-
-##############################################################################
-#
-# init - initialize the module to use the privacy lists.
-#
-##############################################################################
-sub init
-{
-    my $self = shift;
-
-    $self->{CONNECTION}-> SetXPathCallBacks('/iq[@type="result" or @type="set"]/query[@xmlns="jabber:iq:privacy"]'=>sub{ $self->handler(@_) });
-}
-
-
-##############################################################################
-#
-# debug - print out a representation of the privacy lists.
-#
-##############################################################################
-sub debug
-{
-    my $self = shift;
-
-    &XML::Stream::printData("\$self->{LISTS}",$self->{LISTS});
-}
-
-
-##############################################################################
-#
-# addItem - add list item to a list.
-#
-##############################################################################
-sub addItem
-{
-    my $self = shift;
-    my ($list,%item) = @_;
-
-    my $order = delete($item{order});
-    $self->{LISTS}->{$list}->{$order} = \%item;
-}
-
-
-###############################################################################
-#
-# clear - delete all of the JIDs from the DB completely.
-#
-###############################################################################
-sub clear
-{
-    my $self = shift;
-
-    $self->{CONNECTION}->{DEBUG}->Log3("PrivacyLists::clear: clearing the database");
-    foreach my $list ($self->lists())
-    {
-        $self->remove($list);
-    }
-    $self->{CONNECTION}->{DEBUG}->Log3("PrivacyLists::clear: database is empty");
-}
-
-
-##############################################################################
-#
-# exists - allows you to query if the JID exists in the Roster DB.
-#
-##############################################################################
-sub exists
-{
-    my $self = shift;
-    my $list = shift;
-
-    return unless exists($self->{LISTS});
-    return unless exists($self->{LISTS}->{$list});
-    return 1;
-}
-
-
-##############################################################################
-#
-# fetch - fetch the privacy lists from the server and populate the database.
-#
-##############################################################################
-sub fetch
-{
-    my $self = shift;
-
-    my $iq = $self->{CONNECTION}->PrivacyListsGet();
-    $self->handleIQ($iq);
-}
-
-
-##############################################################################
-#
-# fetchList - fetch the privacy list from the server and populate the database.
-#
-##############################################################################
-sub fetchList
-{
-    my $self = shift;
-    my $list = shift;
-    
-    my $iq = $self->{CONNECTION}->PrivacyListsGet(list=>$list);
-    $self->handleIQ($iq);
-}
-
-
-##############################################################################
-#
-# lists - returns a list of the current privacy lists.
-#
-##############################################################################
-sub lists
-{
-    my $self = shift;
-
-    return () unless exists($self->{LISTS});
-    return () if (scalar(keys(%{$self->{LISTS}})) == 0);
-    return keys(%{$self->{LISTS}});
-}
-
-
-##############################################################################
-#
-# items - returns a list of all of the items in the specified privacy list.
-#
-##############################################################################
-sub items
-{
-    my $self = shift;
-    my $list = shift;
-
-    my @items;
-
-    return () unless $self->exists($list);
-    foreach my $order (sort{ $a <=> $b } keys(%{$self->{LISTS}->{$list}}))
-    {
-        my %item = %{$self->{LISTS}->{$list}->{$order}};
-        $item{order} = $order;
-        push(@items,\%item);
-    }
-
-    return @items;
-}
-
-
-##############################################################################
-#
-# handler - takes a packet and calls the correct handler.
-#
-##############################################################################
-sub handler
-{
-    my $self = shift;
-    my $sid = shift;
-    my $packet = shift;
-
-    $self->handleIQ($packet) if ($packet->GetTag() eq "iq");
-}
-
-
-##############################################################################
-#
-# handleIQ - takes an iq packet that contains roster, parses it, and puts
-#            the roster into the Roster DB.
-#
-##############################################################################
-sub handleIQ
-{
-    my $self = shift;
-    my $iq = shift;
-
-    print "handleIQ: iq(",$iq->GetXML(),")\n";
-
-    my $type = $iq->GetType();
-    return unless (($type eq "set") || ($type eq "result"));
-
-    if ($type eq "result")
-    {
-        my $query = $iq->GetChild("jabber:iq:privacy");
-        
-        my @lists = $query->GetLists();
-
-        return unless ($#lists > -1);
-        
-        my @items = $lists[0]->GetItems();
-        
-        if (($#lists == 0) && ($#items > -1))
-        {
-            $self->parseList($lists[0]);
-        }
-        elsif ($#lists >= -1)
-        {
-            $self->parseLists(\@lists);
-        }
-    }
-}
-
-
-sub parseList
-{
-    my $self = shift;
-    my $list = shift;
-    
-    my $name = $list->GetName();
-
-    foreach my $item ($list->GetItems())
-    {
-        my %item = $item->GetItem();
-        
-        $self->addItem($name,%item);
-    }
-}
-
-
-sub parseLists
-{
-    my $self = shift;
-    my $lists = shift;
-    
-    foreach my $list (@{$lists})
-    {
-        my $name = $list->GetName();
-        $self->fetchList($name);
-    }
-}
-
-
-##############################################################################
-#
-# reload - clear and refetch the privacy lists.
-#
-##############################################################################
-sub reload
-{
-    my $self = shift;
-
-    $self->clear();
-    $self->fetch();
-}
-
-
-##############################################################################
-#
-# remove - removes the list from the database.
-#
-##############################################################################
-sub remove
-{
-    my $self = shift;
-    my $list = shift;
-
-    if ($self->exists($list))
-    {
-        $self->{CONNECTION}->{DEBUG}->Log3("PrivacyLists::remove: deleting $list from the DB");
-        
-        delete($self->{LISTS}->{$list});
-        delete($self->{LISTS}) if (scalar(keys(%{$self->{LISTS}})) == 0);
-    }
-}
-
-
-sub save
-{
-    my $self = shift;
-
-    foreach my $list ($self->lists())
-    {
-        $self->saveList($list);
-    }
-}
-
-
-sub saveList
-{
-    my $self = shift;
-    my $list = shift;
-
-    my @items = $self->items($list);
-    $self->{CONNECTION}->PrivacyListsSet(list=>$list,
-                                         items=>\@items);
-}
-
-
-1;
-
Index: rl/modules/Jabber/lib/Net/XMPP/Protocol.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/Protocol.pm	(revision 7f33c18e0188d1359c7b0981d9e26757a4f01bb4)
+++ 	(revision )
@@ -1,3316 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::XMPP::Protocol;
-
-=head1 NAME
-
-Net::XMPP::Protocol - XMPP Protocol Module
-
-=head1 SYNOPSIS
-
-  Net::XMPP::Protocol is a module that provides a developer easy
-  access to the XMPP Instant Messaging protocol.  It provides high
-  level functions to the Net::XMPP Client object.  These functions are
-  inherited by that modules.
-
-=head1 DESCRIPTION
-
-  Protocol.pm seeks to provide enough high level APIs and automation of
-  the low level APIs that writing a XMPP Client in Perl is trivial.  For
-  those that wish to work with the low level you can do that too, but
-  those functions are covered in the documentation for each module.
-
-  Net::XMPP::Protocol provides functions to login, send and receive
-  messages, set personal information, create a new user account, manage
-  the roster, and disconnect.  You can use all or none of the functions,
-  there is no requirement.
-
-  For more information on how the details for how Net::XMPP is written
-  please see the help for Net::XMPP itself.
-
-  For more information on writing a Client see Net::XMPP::Client.
-
-=head2 Modes
-
-  Several of the functions take a mode argument that let you specify how
-  the function should behave:
-
-    block - send the packet with an ID, and then block until an answer
-            comes back.  You can optionally specify a timeout so that
-            you do not block forever.
-           
-    nonblock - send the packet with an ID, but then return that id and
-               control to the master program.  Net::XMPP is still
-               tracking this packet, so you must use the CheckID function
-               to tell when it comes in.  (This might not be very
-               useful...)
-
-    passthru - send the packet with an ID, but do NOT register it with
-               Net::XMPP, then return the ID.  This is useful when
-               combined with the XPath function because you can register
-               a one shot function tied to the id you get back.
-               
-
-=head2 Basic Functions
-
-    use Net::XMPP qw( Client );
-    $Con = Net::XMPP::Client->new();                  # From
-    $status = $Con->Connect(hostname=>"jabber.org"); # Net::XMPP::Client
-
-    $Con->SetCallBacks(send=>\&sendCallBack,
-                       receive=>\&receiveCallBack,
-                       message=>\&messageCallBack,
-                       iq=>\&handleTheIQTag);
-
-    $Con->SetMessageCallBacks(normal=>\&messageNormalCB,
-                              chat=>\&messageChatCB);
-
-    $Con->SetPresenceCallBacks(available=>\&presenceAvailableCB,
-                               unavailable=>\&presenceUnavailableCB);
-
-    $Con->SetIQCallBacks("custom-namespace"=>
-                                             {
-                                                 get=>\&iqCustomGetCB,
-                                                 set=>\&iqCustomSetCB,
-                                                 result=>\&iqCustomResultCB,
-                                             },
-                                             etc...
-                                            );
-
-    $Con->SetXPathCallBacks("/message[@type='chat']"=>&messageChatCB,
-                            "/message[@type='chat']"=>&otherMessageChatCB,
-                            ...
-                           );
-
-    $Con->RemoveXPathCallBacks("/message[@type='chat']"=>&otherMessageChatCB);
-
-    $error = $Con->GetErrorCode();
-    $Con->SetErrorCode("Timeout limit reached");
-
-    $status = $Con->Process();
-    $status = $Con->Process(5);
-
-    $Con->Send($object);
-    $Con->Send("<tag>XML</tag>");
-
-    $Con->Send($object,1);
-    $Con->Send("<tag>XML</tag>",1);
-
-    $Con->Disconnect();
-
-=head2 ID Functions
-
-    $id         = $Con->SendWithID($sendObj);
-    $id         = $Con->SendWithID("<tag>XML</tag>");
-    $receiveObj = $Con->SendAndReceiveWithID($sendObj);
-    $receiveObj = $Con->SendAndReceiveWithID($sendObj,
-                                             10);
-    $receiveObj = $Con->SendAndReceiveWithID("<tag>XML</tag>");
-    $receiveObj = $Con->SendAndReceiveWithID("<tag>XML</tag>",
-                                             5);
-    $yesno      = $Con->ReceivedID($id);
-    $receiveObj = $Con->GetID($id);
-    $receiveObj = $Con->WaitForID($id);
-    $receiveObj = $Con->WaitForID($id,
-                                  20);
-
-=head2 Namespace Functions
-
-    $Con->AddNamespace(ns=>"foo:bar",
-                       tag=>"myfoo",
-                       xpath=>{Foo=>{ path=> "foo/text()" },
-                               Bar=>{ path=> "bar/text()" },
-                               FooBar=>{ type=> "master" },
-                              }
-                      );
-
-=head2 Message Functions
-
-    $Con->MessageSend(to=>"bob@jabber.org",
-                      subject=>"Lunch",
-                      body=>"Let's go grab some...\n",
-                      thread=>"ABC123",
-                      priority=>10);
-
-=head2 Presence Functions
-
-    $Con->PresenceSend();
-    $Con->PresenceSend(type=>"unavailable");
-    $Con->PresenceSend(show=>"away");
-    $Con->PresenceSend(signature=>...signature...);
-
-=head2 Subscription Functions
-
-    $Con->Subscription(type=>"subscribe",
-                       to=>"bob@jabber.org");
-
-    $Con->Subscription(type=>"unsubscribe",
-                       to=>"bob@jabber.org");
-
-    $Con->Subscription(type=>"subscribed",
-                       to=>"bob@jabber.org");
-
-    $Con->Subscription(type=>"unsubscribed",
-                       to=>"bob@jabber.org");
-
-=head2 Presence DB Functions
-
-    $Con->PresenceDB();
-
-    $Con->PresenceDBParse(Net::XMPP::Presence);
-
-    $Con->PresenceDBDelete("bob\@jabber.org");
-    $Con->PresenceDBDelete(Net::XMPP::JID);
-
-    $Con->PresenceDBClear();
-
-    $presence  = $Con->PresenceDBQuery("bob\@jabber.org");
-    $presence  = $Con->PresenceDBQuery(Net::XMPP::JID);
-
-    @resources = $Con->PresenceDBResources("bob\@jabber.org");
-    @resources = $Con->PresenceDBResources(Net::XMPP::JID);
-
-=head2 IQ  Functions
-
-=head2 Auth Functions
-
-    @result = $Con->AuthSend();
-    @result = $Con->AuthSend(username=>"bob",
-                             password=>"bobrulez",
-                             resource=>"Bob");
-
-=head2 Register Functions
-
-    %hash   = $Con->RegisterRequest();
-    %hash   = $Con->RegisterRequest(to=>"transport.jabber.org");
-    %hash   = $Con->RegisterRequest(to=>"transport.jabber.org",
-                                    timeout=>10);
-
-    @result = $Con->RegisterSend(to=>"somewhere",
-                                 username=>"newuser",
-                                 resource=>"New User",
-                                 password=>"imanewbie",
-                                 email=>"newguy@new.com",
-                                 key=>"some key");
-
-=head2 Roster Functions
-
-    $Roster = $Con->Roster();
-
-    %roster = $Con->RosterParse($iq);
-    %roster = $Con->RosterGet();
-    $Con->RosterRequest();
-    $Con->RosterAdd(jid=>"bob\@jabber.org",
-                    name=>"Bob");
-    $Con->RosterRemove(jid=>"bob@jabber.org");
-
-=head2 Roster DB Functions
-
-    $Con->RosterDB();
-
-    $Con->RosterDBParse(Net::XMPP::IQ);
-
-    $Con->RosterDBAdd("bob\@jabber.org",
-                      name=>"Bob",
-                      groups=>["foo"]
-                     );
-    
-    $Con->RosterDBRemove("bob\@jabber.org");
-    $Con->RosterDBRemove(Net::XMPP::JID);
-
-    $Con->RosterDBClear();
-
-    if ($Con->RosterDBExists("bob\@jabber.org")) { ...
-    if ($Con->RosterDBExists(Net::XMPP::JID)) { ...
-
-    @jids = $Con->RosterDBJIDs();
-    
-    if ($Con->RosterDBGroupExists("foo")) { ...
-
-    @groups = $Con->RosterDBGroups();
-    
-    @jids = $Con->RosterDBGroupJIDs("foo");
-    
-    @jids = $Con->RosterDBNonGroupJIDs();
-    
-    %hash = $Con->RosterDBQuery("bob\@jabber.org");
-    %hash = $Con->RosterDBQuery(Net::XMPP::JID);
-
-    $value = $Con->RosterDBQuery("bob\@jabber.org","name");
-    $value = $Con->RosterDBQuery(Net::XMPP::JID,"groups");
-
-
-=head1 METHODS
-
-=head2 Basic Functions
-
-    GetErrorCode() - returns a string that will hopefully contain some
-                     useful information about why a function returned
-                     an undef to you.
-
-    SetErrorCode(string) - set a useful error message before you return
-                           an undef to the caller.
-
-    SetCallBacks(message=>function,  - sets the callback functions for
-                 presence=>function,   the top level tags listed.  The
-                 iq=>function,         available tags to look for are
-                 send=>function,       <message/>, <presence/>, and
-                 receive=>function,    <iq/>.  If a packet is received
-                 update=>function)     with an ID which is found in the
-                                       registerd ID list (see RegisterID
-                                       below) then it is not sent to
-                                       these functions, instead it
-                                       is inserted into a LIST and can
-                                       be retrieved by some functions
-                                       we will mention later.
-
-                                       send and receive are used to
-                                       log what XML is sent and received.
-                                       update is used as way to update
-                                       your program while waiting for
-                                       a packet with an ID to be
-                                       returned (useful for GUI apps).
-
-                                       A major change that came with
-                                       the last release is that the
-                                       session id is passed to the
-                                       callback as the first argument.
-                                       This was done to facilitate
-                                       the Server module.
-
-                                       The next argument depends on
-                                       which callback you are talking
-                                       about.  message, presence, and iq
-                                       all get passed in Net::XMPP
-                                       objects that match those types.
-                                       send and receive get passed in
-                                       strings.  update gets passed
-                                       nothing, not even the session id.
-
-                                       If you set the function to undef,
-                                       then the callback is removed from
-                                       the list.
-
-    SetPresenceCallBacks(type=>function - sets the callback functions for
-                         etc...)          the specified presence type.
-                                          The function takes types as the
-                                          main key, and lets you specify
-                                          a function for each type of
-                                          packet you can get.
-                                            "available"
-                                            "unavailable"
-                                            "subscribe"
-                                            "unsubscribe"
-                                            "subscribed"
-                                            "unsubscribed"
-                                            "probe"
-                                            "error"
-                                          When it gets a <presence/>
-                                          packet it checks the type=''
-                                          for a defined callback.  If
-                                          there is one then it calls the
-                                          function with two arguments:
-                                            the session ID, and the
-                                            Net::XMPP::Presence object.
-
-                                          If you set the function to
-                                          undef, then the callback is
-                                          removed from the list.
-
-                        NOTE: If you use this, which is a cleaner method,
-                              then you must *NOT* specify a callback for
-                              presence in the SetCallBacks function.
- 
-                                          Net::XMPP defines a few default
-                                          callbacks for various types:
- 
-                                          "subscribe" -
-                                            replies with subscribed
-                                          
-                                          "unsubscribe" -
-                                            replies with unsubscribed
-                                          
-                                          "subscribed" -
-                                            replies with subscribed
-                                          
-                                          "unsubscribed" -
-                                            replies with unsubscribed
-                                         
-
-    SetMessageCallBacks(type=>function, - sets the callback functions for
-                        etc...)           the specified message type. The
-                                          function takes types as the
-                                          main key, and lets you specify
-                                          a function for each type of
-                                          packet you can get.
-                                           "normal"
-                                           "chat"
-                                           "groupchat"
-                                           "headline"
-                                           "error"
-                                         When it gets a <message/> packet
-                                         it checks the type='' for a
-                                         defined callback. If there is
-                                         one then it calls the function
-                                         with two arguments:
-                                           the session ID, and the
-                                           Net::XMPP::Message object.
-
-                                         If you set the function to
-                                         undef, then the callback is
-                                         removed from the list.
-
-                       NOTE: If you use this, which is a cleaner method,
-                             then you must *NOT* specify a callback for
-                             message in the SetCallBacks function.
-
-
-    SetIQCallBacks(namespace=>{      - sets the callback functions for
-                     get=>function,    the specified namespace. The
-                     set=>function,    function takes namespaces as the
-                     result=>function  main key, and lets you specify a
-                   },                  function for each type of packet
-                   etc...)             you can get.
-                                         "get"
-                                         "set"
-                                         "result"
-                                       When it gets an <iq/> packet it
-                                       checks the type='' and the
-                                       xmlns='' for a defined callback.
-                                       If there is one then it calls
-                                       the function with two arguments:
-                                       the session ID, and the
-                                       Net::XMPP::xxxx object.
-
-                                       If you set the function to undef,
-                                       then the callback is removed from
-                                       the list.
-
-                       NOTE: If you use this, which is a cleaner method,
-                             then you must *NOT* specify a callback for
-                             iq in the SetCallBacks function.
-
-    SetXPathCallBacks(xpath=>function, - registers a callback function
-                        etc...)          for each xpath specified.  If
-                                         Net::XMPP matches the xpath,
-                                         then it calls the function with
-                                         two arguments:
-                                           the session ID, and the
-                                           Net::XMPP::Message object.
-
-                                         Xpaths are rooted at each
-                                         packet:
-                                           /message[@type="chat"]
-                                           /iq/*[xmlns="jabber:iq:roster"][1]
-                                           ...
-
-    RemoveXPathCallBacks(xpath=>function, - unregisters a callback
-                        etc...)             function for each xpath
-                                            specified.
-
-    Process(integer) - takes the timeout period as an argument.  If no
-                       timeout is listed then the function blocks until
-                       a packet is received.  Otherwise it waits that
-                       number of seconds and then exits so your program
-                       can continue doing useful things.  NOTE: This is
-                       important for GUIs.  You need to leave time to
-                       process GUI commands even if you are waiting for
-                       packets.  The following are the possible return
-                       values, and what they mean:
-
-                           1   - Status ok, data received.
-                           0   - Status ok, no data received.
-                         undef - Status not ok, stop processing.
-                       
-                       IMPORTANT: You need to check the output of every
-                       Process.  If you get an undef then the connection
-                       died and you should behave accordingly.
-
-    Send(object,         - takes either a Net::XMPP::xxxxx object or
-         ignoreActivity)   an XML string as an argument and sends it to
-    Send(string,           the server.  If you set ignoreActivty to 1,
-         ignoreActivity)   then the XML::Stream module will not record
-                           this packet as couting towards user activity.
-=head2 ID Functions
-
-    SendWithID(object) - takes either a Net::XMPP::xxxxx object or an
-    SendWithID(string)   XML string as an argument, adds the next
-                         available ID number and sends that packet to
-                         the server.  Returns the ID number assigned.
-
-    SendAndReceiveWithID(object,  - uses SendWithID and WaitForID to
-                         timeout)   provide a complete way to send and
-    SendAndReceiveWithID(string,    receive packets with IDs.  Can take
-                         timeout)   either a Net::XMPP::xxxxx object
-                                    or an XML string.  Returns the
-                                    proper Net::XMPP::xxxxx object
-                                    based on the type of packet
-                                    received.  The timeout is passed
-                                    on to WaitForID, see that function
-                                    for how the timeout works.
-
-    ReceivedID(integer) - returns 1 if a packet has been received with
-                          specified ID, 0 otherwise.
-
-    GetID(integer) - returns the proper Net::XMPP::xxxxx object based
-                     on the type of packet received with the specified
-                     ID.  If the ID has been received the GetID returns
-                     0.
-
-    WaitForID(integer, - blocks until a packet with the ID is received.
-              timeout)   Returns the proper Net::XMPP::xxxxx object
-                         based on the type of packet received.  If the
-                         timeout limit is reached then if the packet
-                         does come in, it will be discarded.
-
-
-    NOTE:  Only <iq/> officially support ids, so sending a <message/>, or
-           <presence/> with an id is a risk.  The server will ignore the
-           id tag and pass it through, so both clients must support the
-           id tag for these functions to be useful.
-
-=head2 Namespace Functions
-
-    AddNamespace(ns=>string,  - This function is very complex.
-                 tag=>string,   It is a little too complex to
-                 xpath=>hash)   discuss within the confines of
-                                this small paragraph.  Please
-                                refer to the man page for
-                                Net::XMPP::Namespaces for the
-                                full documentation on this
-                                subject.
-
-=head2 Message Functions
-
-    MessageSend(hash) - takes the hash and passes it to SetMessage in
-                        Net::XMPP::Message (refer there for valid
-                        settings).  Then it sends the message to the
-                        server.
-
-=head2 Presence Functions
-
-    PresenceSend()                  - no arguments will send an empty
-    PresenceSend(hash,                Presence to the server to tell it
-                 signature=>string)   that you are available.  If you
-                                      provide a hash, then it will pass
-                                      that hash to the SetPresence()
-                                      function as defined in the
-                                      Net::XMPP::Presence module.
-                                      Optionally, you can specify a
-                                      signature and a jabber:x:signed
-                                      will be placed in the <presence/>.
-
-=head2 Subscription Functions
-
-    Subscription(hash) - taks the hash and passes it to SetPresence in
-                         Net::XMPP::Presence (refer there for valid
-                         settings).  Then it sends the subscription to
-                         server.
-
-                         The valid types of subscription are:
-
-                           subscribe    - subscribe to JID's presence
-                           unsubscribe  - unsubscribe from JID's presence
-                           subscribed   - response to a subscribe
-                           unsubscribed - response to an unsubscribe
-
-=head2 Presence DB Functions
-
-    PresenceDB() - Tell the object to initialize the callbacks to
-                   automatically populate the Presence DB.
-
-    PresenceDBParse(Net::XMPP::Presence) - for every presence that you
-                                             receive pass the Presence
-                                             object to the DB so that
-                                             it can track the resources
-                                             and priorities for you.
-                                             Returns either the presence
-                                             passed in, if it not able
-                                             to parsed for the DB, or the
-                                             current presence as found by
-                                             the PresenceDBQuery
-                                             function.
-
-    PresenceDBDelete(string|Net::XMPP::JID) - delete thes JID entry
-                                                from the DB.
-
-    PresenceDBClear() - delete all entries in the database.
-
-    PresenceDBQuery(string|Net::XMPP::JID) - returns the NJ::Presence
-                                               that was last received for
-                                               the highest priority of
-                                               this JID.  You can pass
-                                               it a string or a NJ::JID
-                                               object.
-
-    PresenceDBResources(string|Net::XMPP::JID) - returns an array of
-                                                   resources in order
-                                                   from highest priority
-                                                   to lowest.
-
-=head2 IQ Functions
-
-=head2 Auth Functions
-
-    AuthSend(username=>string, - takes all of the information and
-             password=>string,   builds a Net::XMPP::IQ::Auth packet.
-             resource=>string)   It then sends that packet to the
-                                 server with an ID and waits for that
-                                 ID to return.  Then it looks in
-                                 resulting packet and determines if
-                                 authentication was successful for not.
-                                 The array returned from AuthSend looks
-                                 like this:
-                                   [ type , message ]
-                                 If type is "ok" then authentication
-                                 was successful, otherwise message
-                                 contains a little more detail about the
-                                 error.
-
-=head2 IQ::Register Functions
-
-    RegisterRequest(to=>string,  - send an <iq/> request to the specified
-                    timeout=>int)  server/transport, if not specified it
-    RegisterRequest()              sends to the current active server.
-                                   The function returns a hash that
-                                   contains the required fields.   Here
-                                   is an example of the hash:
-
-                                   $hash{fields}    - The raw fields from
-                                                      the iq:register.
-                                                      To be used if there
-                                                      is no x:data in the
-                                                      packet.
-                                   $hash{instructions} - How to fill out
-                                                         the form.
-                                   $hash{form}   - The new dynamic forms.
-
-                                   In $hash{form}, the fields that are
-                                   present are the required fields the
-                                   server needs.
-
-    RegisterSend(hash) - takes the contents of the hash and passes it
-                         to the SetRegister function in the module
-                         Net::XMPP::Query jabber:iq:register namespace.
-                         This function returns an array that looks like
-                         this:
-
-                            [ type , message ]
-
-                         If type is "ok" then registration was
-                         successful, otherwise message contains a
-                         little more detail about the error.
-
-=head2 Roster Functions
-
-    Roster() - returns a Net::XMPP::Roster object.  This will automatically
-               intercept all of the roster and presence packets sent from
-               the server and give you an accurate Roster.  For more
-               information please read the man page for Net::XMPP::Roster.
-
-    RosterParse(IQ object) - returns a hash that contains the roster
-                             parsed into the following data structure:
-
-                  $roster{'bob@jabber.org'}->{name}
-                                      - Name you stored in the roster
-
-                  $roster{'bob@jabber.org'}->{subscription}
-                                      - Subscription status
-                                        (to, from, both, none)
-
-                  $roster{'bob@jabber.org'}->{ask}
-                                      - The ask status from this user
-                                        (subscribe, unsubscribe)
-
-                  $roster{'bob@jabber.org'}->{groups}
-                                      - Array of groups that
-                                        bob@jabber.org is in
-
-    RosterGet() - sends an empty Net::XMPP::IQ::Roster tag to the
-                  server so the server will send the Roster to the
-                  client.  Returns the above hash from RosterParse.
-
-    RosterRequest() - sends an empty Net::XMPP::IQ::Roster tag to the
-                      server so the server will send the Roster to the
-                      client.
-
-    RosterAdd(hash) - sends a packet asking that the jid be
-                      added to the roster.  The hash format
-                      is defined in the SetItem function
-                      in the Net::XMPP::Query jabber:iq:roster
-                      namespace.
-
-    RosterRemove(hash) - sends a packet asking that the jid be
-                         removed from the roster.  The hash
-                         format is defined in the SetItem function
-                         in the Net::XMPP::Query jabber:iq:roster
-                         namespace.
-
-=head2 Roster DB Functions
-
-    RosterDB() - Tell the object to initialize the callbacks to
-                 automatically populate the Roster DB.  If you do this,
-                 then make sure that you call RosterRequest() instead of
-                 RosterGet() so that the callbacks can catch it and
-                 parse it.
-
-    RosterDBParse(IQ object) - If you want to manually control the
-                               database, then you can pass in all iq
-                               packets with jabber:iq:roster queries to
-                               this function.
-
-    RosterDBAdd(jid,hash) - Add a new JID into the roster DB.  The JID
-                            is either a string, or a Net::XMPP::JID
-                            object.  The hash must be the same format as
-                            the has returned by RosterParse above, and
-                            is the actual hash, not a reference.
-    
-    RosterDBRemove(jid) - Remove a JID from the roster DB. The JID is
-                          either a string, or a Net::XMPP::JID object.
-
-    RosterDBClear() - Remove all JIDs from the roster DB.
-
-    RosterDBExists(jid) - return 1 if the JID exists in the roster DB,
-                          undef otherwise.  The JID is either a string,
-                          or a Net::XMPP::JID object.
-
-    RosterDBJIDs() - returns a list of Net::XMPP::JID objects that
-                     represents all of the JIDs in the DB.
-    
-    RosterDBGroups() - returns the complete list of roster groups in the
-                       roster.
-    
-    RosterDBGroupExists(group) - return 1 if the group is a group in the
-                                 roster DB, undef otherwise.
-
-    RosterDBGroupJIDs(group) - returns a list of Net::XMPP::JID objects
-                               that represents all of the JIDs in the
-                               specified roster group.
-    
-    RosterDBNonGroupJIDs() - returns a list of Net::XMPP::JID objects
-                             that represents all of the JIDs not in a
-                             roster group.
-
-    RosterDBQuery(jid) - returns a hash containing the data from the
-                         roster DB for the specified JID.  The JID is
-                         either a string, or a Net::XMPP::JID object.
-                         The hash format the same as in RosterParse
-                         above.
-
-    RosterDBQuery(jid,key) - returns the entry from the above hash for
-                             the given key.  The available keys are:
-                               name, ask, subsrcription and groups
-                             The JID is either a string, or a 
-                             Net::XMPP::JID object.
-
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use Net::XMPP::Roster;
-use Net::XMPP::PrivacyLists;
-use strict;
-use Carp;
-use vars qw( %XMLNS %NEWOBJECT $SASL_CALLBACK $TLS_CALLBACK );
-
-##############################################################################
-# Define the namespaces in an easy/constant manner.
-#-----------------------------------------------------------------------------
-# 1.0
-#-----------------------------------------------------------------------------
-$XMLNS{'xmppstreams'}   = "urn:ietf:params:xml:ns:xmpp-streams";
-$XMLNS{'xmpp-bind'}     = "urn:ietf:params:xml:ns:xmpp-bind";
-$XMLNS{'xmpp-sasl'}     = "urn:ietf:params:xml:ns:xmpp-sasl";
-$XMLNS{'xmpp-session'}  = "urn:ietf:params:xml:ns:xmpp-session";
-$XMLNS{'xmpp-tls'}      = "urn:ietf:params:xml:ns:xmpp-tls";
-##############################################################################
-
-##############################################################################
-# BuildObject takes a root tag and builds the correct object.  NEWOBJECT is
-# the table that maps tag to package.  Override these, or provide new ones.
-#-----------------------------------------------------------------------------
-$NEWOBJECT{'iq'}       = "Net::XMPP::IQ";
-$NEWOBJECT{'message'}  = "Net::XMPP::Message";
-$NEWOBJECT{'presence'} = "Net::XMPP::Presence";
-$NEWOBJECT{'jid'}      = "Net::XMPP::JID";
-##############################################################################
-
-sub _message  { shift; my $o; eval "\$o = new $NEWOBJECT{'message'}(\@_);"; return $o;  }
-sub _presence { shift; my $o; eval "\$o = new $NEWOBJECT{'presence'}(\@_);"; return $o; }
-sub _iq       { shift; my $o; eval "\$o = new $NEWOBJECT{'iq'}(\@_);"; return $o;       }
-sub _jid      { shift; my $o; eval "\$o = new $NEWOBJECT{'jid'}(\@_);"; return $o;      }
-
-###############################################################################
-#+-----------------------------------------------------------------------------
-#|
-#| Base API
-#|
-#+-----------------------------------------------------------------------------
-###############################################################################
-
-###############################################################################
-#
-# GetErrorCode - if you are returned an undef, you can call this function
-#                and hopefully learn more information about the problem.
-#
-###############################################################################
-sub GetErrorCode
-{
-    my $self = shift;
-    return ((exists($self->{ERRORCODE}) && ($self->{ERRORCODE} ne "")) ?
-            $self->{ERRORCODE} :
-            $!
-           );
-}
-
-
-###############################################################################
-#
-# SetErrorCode - sets the error code so that the caller can find out more
-#                information about the problem
-#
-###############################################################################
-sub SetErrorCode
-{
-    my $self = shift;
-    my ($errorcode) = @_;
-    $self->{ERRORCODE} = $errorcode;
-}
-
-
-###############################################################################
-#
-# CallBack - Central callback function.  If a packet comes back with an ID
-#            and the tag and ID have been registered then the packet is not
-#            returned as normal, instead it is inserted in the LIST and
-#            stored until the user wants to fetch it.  If the tag and ID
-#            are not registered the function checks if a callback exists
-#            for this tag, if it does then that callback is called,
-#            otherwise the function drops the packet since it does not know
-#            how to handle it.
-#
-###############################################################################
-sub CallBack
-{
-    my $self = shift;
-    my $sid = shift;
-    my ($object) = @_;
-
-    my $tag;
-    my $id;
-    my $tree;
-    
-    if (ref($object) !~ /^Net::XMPP/)
-    {
-        if ($self->{DEBUG}->GetLevel() >= 1 || exists($self->{CB}->{receive}))
-        {
-            my $xml = $object->GetXML();
-            $self->{DEBUG}->Log1("CallBack: sid($sid) received($xml)");
-            &{$self->{CB}->{receive}}($sid,$xml) if exists($self->{CB}->{receive});
-        }
-
-        $tag = $object->get_tag();
-        $id = "";
-        $id = $object->get_attrib("id")
-            if defined($object->get_attrib("id"));
-        $tree = $object;
-    }
-    else
-    {
-        $tag = $object->GetTag();
-        $id = $object->GetID();
-        $tree = $object->GetTree();
-    }
-
-    $self->{DEBUG}->Log1("CallBack: tag($tag)");
-    $self->{DEBUG}->Log1("CallBack: id($id)") if ($id ne "");
-
-    my $pass = 1;
-    $pass = 0
-        if (!exists($self->{CB}->{$tag}) &&
-            !exists($self->{CB}->{XPath}) &&
-            !exists($self->{CB}->{DirectXPath}) &&
-            !$self->CheckID($tag,$id)
-           );
-
-    if ($pass)
-    {
-        $self->{DEBUG}->Log1("CallBack: we either want it or were waiting for it.");
-
-        if (exists($self->{CB}->{DirectXPath}))
-        {
-            $self->{DEBUG}->Log1("CallBack: check directxpath");
-
-            my $direct_pass = 0;
-
-            foreach my $xpath (keys(%{$self->{CB}->{DirectXPath}}))
-            {
-                $self->{DEBUG}->Log1("CallBack: check directxpath($xpath)");
-                if ($object->XPathCheck($xpath))
-                {
-                    foreach my $func (keys(%{$self->{CB}->{DirectXPath}->{$xpath}}))
-                    {
-                        $self->{DEBUG}->Log1("CallBack: goto directxpath($xpath) function($func)");
-                        &{$self->{CB}->{DirectXPath}->{$xpath}->{$func}}($sid,$object);
-                        $direct_pass = 1;
-                    }
-                }
-            }
-            
-            return if $direct_pass;
-        }
-
-        my $NJObject;
-        if (ref($object) !~ /^Net::XMPP/)
-        {
-            $NJObject = $self->BuildObject($tag,$object);
-        }
-        else
-        {
-            $NJObject = $object;
-        }
-
-        if ($NJObject == -1)
-        {
-            $self->{DEBUG}->Log1("CallBack: DANGER!! DANGER!! We didn't build a packet!  We're all gonna die!!");
-        }
-        else
-        {
-            if ($self->CheckID($tag,$id))
-            {
-                $self->{DEBUG}->Log1("CallBack: found registry entry: tag($tag) id($id)");
-                $self->DeregisterID($tag,$id);
-                if ($self->TimedOutID($id))
-                {
-                    $self->{DEBUG}->Log1("CallBack: dropping packet due to timeout");
-                    $self->CleanID($id);
-                }
-                else
-                {
-                    $self->{DEBUG}->Log1("CallBack: they still want it... we still got it...");
-                    $self->GotID($id,$NJObject);
-                }
-            }
-            else
-            {
-                $self->{DEBUG}->Log1("CallBack: no registry entry");
-
-                if (exists($self->{CB}->{XPath}))
-                {
-                    $self->{DEBUG}->Log1("CallBack: check xpath");
-
-                    foreach my $xpath (keys(%{$self->{CB}->{XPath}}))
-                    {
-                        if ($NJObject->GetTree()->XPathCheck($xpath))
-                        {
-                            foreach my $func (keys(%{$self->{CB}->{XPath}->{$xpath}}))
-                            {
-                                $self->{DEBUG}->Log1("CallBack: goto xpath($xpath) function($func)");
-                                &{$self->{CB}->{XPath}->{$xpath}->{$func}}($sid,$NJObject);
-                            }
-                        }
-                    }
-                }
-
-                if (exists($self->{CB}->{$tag}))
-                {
-                    $self->{DEBUG}->Log1("CallBack: goto user function($self->{CB}->{$tag})");
-                    &{$self->{CB}->{$tag}}($sid,$NJObject);
-                }
-                else
-                {
-                    $self->{DEBUG}->Log1("CallBack: no defined function.  Dropping packet.");
-                }
-            }
-        }
-    }
-    else
-    {
-        $self->{DEBUG}->Log1("CallBack: a packet that no one wants... how sad. =(");
-    }
-}
-
-
-###############################################################################
-#
-# BuildObject - turn the packet into an object.
-#
-###############################################################################
-sub BuildObject
-{
-    my $self = shift;
-    my ($tag,$tree) = @_;
-
-    my $obj = -1;
-
-    if (exists($NEWOBJECT{$tag}))
-    {
-        $self->{DEBUG}->Log1("BuildObject: tag($tag) package($NEWOBJECT{$tag})");
-        eval "\$obj = new $NEWOBJECT{$tag}(\$tree);";
-    }
-
-    return $obj;
-}
-
-
-###############################################################################
-#
-# SetCallBacks - Takes a hash with top level tags to look for as the keys
-#                and pointers to functions as the values.  The functions
-#                are called and passed the XML::Parser::Tree objects
-#                generated by XML::Stream.
-#
-###############################################################################
-sub SetCallBacks
-{
-    my $self = shift;
-    while($#_ >= 0)
-    {
-        my $func = pop(@_);
-        my $tag = pop(@_);
-        $self->{DEBUG}->Log1("SetCallBacks: tag($tag) func($func)");
-        if (defined($func))
-        {
-            $self->{CB}->{$tag} = $func;
-        }
-        else
-        {
-            delete($self->{CB}->{$tag});
-        }
-        $self->{STREAM}->SetCallBacks(update=>$func) if ($tag eq "update");
-    }
-}
-
-
-###############################################################################
-#
-# SetIQCallBacks - define callbacks for the namespaces inside an iq.
-#
-###############################################################################
-sub SetIQCallBacks
-{
-    my $self = shift;
-
-    while($#_ >= 0)
-    {
-        my $hash = pop(@_);
-        my $namespace = pop(@_);
-
-        foreach my $type (keys(%{$hash}))
-        {
-            if (defined($hash->{$type}))
-            {
-                $self->{CB}->{IQns}->{$namespace}->{$type} = $hash->{$type};
-            }
-            else
-            {
-                delete($self->{CB}->{IQns}->{$namespace}->{$type});
-            }
-        }
-    }
-}
-
-
-###############################################################################
-#
-# SetPresenceCallBacks - define callbacks for the different presence packets.
-#
-###############################################################################
-sub SetPresenceCallBacks
-{
-    my $self = shift;
-    my (%types) = @_;
-
-    foreach my $type (keys(%types))
-    {
-        if (defined($types{$type}))
-        {
-            $self->{CB}->{Pres}->{$type} = $types{$type};
-        }
-        else
-        {
-            delete($self->{CB}->{Pres}->{$type});
-        }
-    }
-}
-
-
-###############################################################################
-#
-# SetMessageCallBacks - define callbacks for the different message packets.
-#
-###############################################################################
-sub SetMessageCallBacks
-{
-    my $self = shift;
-    my (%types) = @_;
-
-    foreach my $type (keys(%types))
-    {
-        if (defined($types{$type}))
-        {
-            $self->{CB}->{Mess}->{$type} = $types{$type};
-        }
-        else
-        {
-            delete($self->{CB}->{Mess}->{$type});
-        }
-    }
-}
-
-
-###############################################################################
-#
-# SetXPathCallBacks - define callbacks for packets based on XPath.
-#
-###############################################################################
-sub SetXPathCallBacks
-{ 
-    my $self = shift;
-    my (%xpaths) = @_;
-
-    foreach my $xpath (keys(%xpaths))
-    {
-        $self->{DEBUG}->Log1("SetXPathCallBacks: xpath($xpath) func($xpaths{$xpath})");
-        $self->{CB}->{XPath}->{$xpath}->{$xpaths{$xpath}} = $xpaths{$xpath};
-    }
-}
-
-
-###############################################################################
-#
-# RemoveXPathCallBacks - remove callbacks for packets based on XPath.
-#
-###############################################################################
-sub RemoveXPathCallBacks
-{
-    my $self = shift;
-    my (%xpaths) = @_;
-
-    foreach my $xpath (keys(%xpaths))
-    {
-        $self->{DEBUG}->Log1("RemoveXPathCallBacks: xpath($xpath) func($xpaths{$xpath})");
-        delete($self->{CB}->{XPath}->{$xpath}->{$xpaths{$xpath}});
-        delete($self->{CB}->{XPath}->{$xpath})
-            if (scalar(keys(%{$self->{CB}->{XPath}->{$xpath}})) == 0);
-        delete($self->{CB}->{XPath})
-            if (scalar(keys(%{$self->{CB}->{XPath}})) == 0);
-    }
-}
-
-
-###############################################################################
-#
-# SetDirectXPathCallBacks - define callbacks for packets based on XPath.
-#
-###############################################################################
-sub SetDirectXPathCallBacks
-{ 
-    my $self = shift;
-    my (%xpaths) = @_;
-
-    foreach my $xpath (keys(%xpaths))
-    {
-        $self->{DEBUG}->Log1("SetDirectXPathCallBacks: xpath($xpath) func($xpaths{$xpath})");
-        $self->{CB}->{DirectXPath}->{$xpath}->{$xpaths{$xpath}} = $xpaths{$xpath};
-    }
-}
-
-
-###############################################################################
-#
-# RemoveDirectXPathCallBacks - remove callbacks for packets based on XPath.
-#
-###############################################################################
-sub RemoveDirectXPathCallBacks
-{
-    my $self = shift;
-    my (%xpaths) = @_;
-
-    foreach my $xpath (keys(%xpaths))
-    {
-        $self->{DEBUG}->Log1("RemoveDirectXPathCallBacks: xpath($xpath) func($xpaths{$xpath})");
-        delete($self->{CB}->{DirectXPath}->{$xpath}->{$xpaths{$xpath}});
-        delete($self->{CB}->{DirectXPath}->{$xpath})
-            if (scalar(keys(%{$self->{CB}->{DirectXPath}->{$xpath}})) == 0);
-        delete($self->{CB}->{DirectXPath})
-            if (scalar(keys(%{$self->{CB}->{DirectXPath}})) == 0);
-    }
-}
-
-
-###############################################################################
-#
-# Send - Takes either XML or a Net::XMPP::xxxx object and sends that
-#        packet to the server.
-#
-###############################################################################
-sub Send
-{
-    my $self = shift;
-    my $object = shift;
-    my $ignoreActivity = shift;
-    $ignoreActivity = 0 unless defined($ignoreActivity);
-
-    if (ref($object) eq "")
-    {
-        $self->SendXML($object,$ignoreActivity);
-    }
-    else
-    {
-        $self->SendXML($object->GetXML(),$ignoreActivity);
-    }
-}
-
-
-###############################################################################
-#
-# SendXML - Sends the XML packet to the server
-#
-###############################################################################
-sub SendXML
-{
-    my $self = shift;
-    my $xml = shift;
-    my $ignoreActivity = shift;
-    $ignoreActivity = 0 unless defined($ignoreActivity);
-
-    $self->{DEBUG}->Log1("SendXML: sent($xml)");
-    &{$self->{CB}->{send}}($self->GetStreamID(),$xml) if exists($self->{CB}->{send});
-    $self->{STREAM}->IgnoreActivity($self->GetStreamID(),$ignoreActivity);
-    $self->{STREAM}->Send($self->GetStreamID(),$xml);
-    $self->{STREAM}->IgnoreActivity($self->GetStreamID(),0);
-}
-
-
-###############################################################################
-#
-# SendWithID - Take either XML or a Net::XMPP::xxxx object and send it
-#              with the next available ID number.  Then return that ID so
-#              the client can track it.
-#
-###############################################################################
-sub SendWithID
-{
-    my $self = shift;
-    my ($object) = @_;
-
-    #--------------------------------------------------------------------------
-    # Take the current XML stream and insert an id attrib at the top level.
-    #--------------------------------------------------------------------------
-    my $id = $self->UniqueID();
-
-    $self->{DEBUG}->Log1("SendWithID: id($id)");
-
-    my $xml;
-    if (ref($object) eq "")
-    {
-        $self->{DEBUG}->Log1("SendWithID: in($object)");
-        $xml = $object;
-        $xml =~ s/^(\<[^\>]+)(\>)/$1 id\=\'$id\'$2/;
-        my ($tag) = ($xml =~ /^\<(\S+)\s/);
-        $self->RegisterID($tag,$id);
-    }
-    else
-    {
-        $self->{DEBUG}->Log1("SendWithID: in(",$object->GetXML(),")");
-        $object->SetID($id);
-        $xml = $object->GetXML();
-        $self->RegisterID($object->GetTag(),$id);
-    }
-    $self->{DEBUG}->Log1("SendWithID: out($xml)");
-
-    #--------------------------------------------------------------------------
-    # Send the new XML string.
-    #--------------------------------------------------------------------------
-    $self->SendXML($xml);
-
-    #--------------------------------------------------------------------------
-    # Return the ID number we just assigned.
-    #--------------------------------------------------------------------------
-    return $id;
-}
-
-
-###############################################################################
-#
-# UniqueID - Increment and return a new unique ID.
-#
-###############################################################################
-sub UniqueID
-{
-    my $self = shift;
-
-    my $id_num = $self->{RCVDB}->{currentID};
-
-    $self->{RCVDB}->{currentID}++;
-
-    return "netjabber-$id_num";
-}
-
-
-###############################################################################
-#
-# SendAndReceiveWithID - Take either XML or a Net::XMPP::xxxxx object and
-#                        send it with the next ID.  Then wait for that ID
-#                        to come back and return the response in a
-#                        Net::XMPP::xxxx object.
-#
-###############################################################################
-sub SendAndReceiveWithID
-{
-    my $self = shift;
-    my ($object,$timeout) = @_;
-    &{$self->{CB}->{startwait}}() if exists($self->{CB}->{startwait});
-    $self->{DEBUG}->Log1("SendAndReceiveWithID: object($object)");
-    my $id = $self->SendWithID($object);
-    $self->{DEBUG}->Log1("SendAndReceiveWithID: sent with id($id)");
-    my $packet = $self->WaitForID($id,$timeout);
-    &{$self->{CB}->{endwait}}() if exists($self->{CB}->{endwait});
-    return $packet;
-}
-
-
-###############################################################################
-#
-# ReceivedID - returns 1 if a packet with the ID has been received, or 0
-#              if it has not.
-#
-###############################################################################
-sub ReceivedID
-{
-    my $self = shift;
-    my ($id) = @_;
-
-    $self->{DEBUG}->Log1("ReceivedID: id($id)");
-    return 1 if exists($self->{RCVDB}->{$id});
-    $self->{DEBUG}->Log1("ReceivedID: nope...");
-    return 0;
-}
-
-
-###############################################################################
-#
-# GetID - Return the Net::XMPP::xxxxx object that is stored in the LIST
-#         that matches the ID if that ID exists.  Otherwise return 0.
-#
-###############################################################################
-sub GetID
-{
-    my $self = shift;
-    my ($id) = @_;
-
-    $self->{DEBUG}->Log1("GetID: id($id)");
-    return $self->{RCVDB}->{$id} if $self->ReceivedID($id);
-    $self->{DEBUG}->Log1("GetID: haven't gotten that id yet...");
-    return 0;
-}
-
-
-###############################################################################
-#
-# CleanID - Delete the list entry for this id since we don't want a leak.
-#
-###############################################################################
-sub CleanID
-{
-    my $self = shift;
-    my ($id) = @_;
-
-    $self->{DEBUG}->Log1("CleanID: id($id)");
-    delete($self->{RCVDB}->{$id});
-}
-
-
-###############################################################################
-#
-# WaitForID - Keep looping and calling Process(1) to poll every second
-#             until the response from the server occurs.
-#
-###############################################################################
-sub WaitForID
-{
-    my $self = shift;
-    my ($id,$timeout) = @_;
-    $timeout = "300" unless defined($timeout);
-
-    $self->{DEBUG}->Log1("WaitForID: id($id)");
-    my $endTime = time + $timeout;
-    while(!$self->ReceivedID($id) && ($endTime >= time))
-    {
-        $self->{DEBUG}->Log1("WaitForID: haven't gotten it yet... let's wait for more packets");
-        return unless (defined($self->Process(1)));
-        &{$self->{CB}->{update}}() if exists($self->{CB}->{update});
-    }
-    if (!$self->ReceivedID($id))
-    {
-        $self->TimeoutID($id);
-        $self->{DEBUG}->Log1("WaitForID: timed out...");
-        return;
-    }
-    else
-    {
-        $self->{DEBUG}->Log1("WaitForID: we got it!");
-        my $packet = $self->GetID($id);
-        $self->CleanID($id);
-        return $packet;
-    }
-}
-
-
-###############################################################################
-#
-# GotID - Callback to store the Net::XMPP::xxxxx object in the LIST at
-#         the ID index.  This is a private helper function.
-#
-###############################################################################
-sub GotID
-{
-    my $self = shift;
-    my ($id,$object) = @_;
-
-    $self->{DEBUG}->Log1("GotID: id($id) xml(",$object->GetXML(),")");
-    $self->{RCVDB}->{$id} = $object;
-}
-
-
-###############################################################################
-#
-# CheckID - Checks the ID registry if this tag and ID have been registered.
-#           0 = no, 1 = yes
-#
-###############################################################################
-sub CheckID
-{
-    my $self = shift;
-    my ($tag,$id) = @_;
-    $id = "" unless defined($id);
-
-    $self->{DEBUG}->Log1("CheckID: tag($tag) id($id)");
-    return 0 if ($id eq "");
-    $self->{DEBUG}->Log1("CheckID: we have that here somewhere...");
-    return exists($self->{IDRegistry}->{$tag}->{$id});
-}
-
-
-###############################################################################
-#
-# TimeoutID - Timeout the tag and ID in the registry so that the CallBack
-#             can know what to put in the ID list and what to pass on.
-#
-###############################################################################
-sub TimeoutID
-{
-    my $self = shift;
-    my ($id) = @_;
-
-    $self->{DEBUG}->Log1("TimeoutID: id($id)");
-    $self->{RCVDB}->{$id} = 0;
-}
-
-
-###############################################################################
-#
-# TimedOutID - Timeout the tag and ID in the registry so that the CallBack
-#             can know what to put in the ID list and what to pass on.
-#
-###############################################################################
-sub TimedOutID
-{
-    my $self = shift;
-    my ($id) = @_;
-
-    return (exists($self->{RCVDB}->{$id}) && ($self->{RCVDB}->{$id} == 0));
-}
-
-
-###############################################################################
-#
-# RegisterID - Register the tag and ID in the registry so that the CallBack
-#              can know what to put in the ID list and what to pass on.
-#
-###############################################################################
-sub RegisterID
-{
-    my $self = shift;
-    my ($tag,$id) = @_;
-
-    $self->{DEBUG}->Log1("RegisterID: tag($tag) id($id)");
-    $self->{IDRegistry}->{$tag}->{$id} = 1;
-}
-
-
-###############################################################################
-#
-# DeregisterID - Delete the tag and ID in the registry so that the CallBack
-#                can knows that it has been received.
-#
-###############################################################################
-sub DeregisterID
-{
-    my $self = shift;
-    my ($tag,$id) = @_;
-
-    $self->{DEBUG}->Log1("DeregisterID: tag($tag) id($id)");
-    delete($self->{IDRegistry}->{$tag}->{$id});
-}
-
-
-###############################################################################
-#
-# AddNamespace - Add a custom namespace into the mix.
-#
-###############################################################################
-sub AddNamespace
-{
-    my $self = shift;
-    &Net::XMPP::Namespaces::add_ns(@_);
-}
-
-
-###############################################################################
-#
-# MessageSend - Takes the same hash that Net::XMPP::Message->SetMessage
-#               takes and sends the message to the server.
-#
-###############################################################################
-sub MessageSend
-{
-    my $self = shift;
-
-    my $mess = $self->_message();
-    $mess->SetMessage(@_);
-    $self->Send($mess);
-}
-
-
-##############################################################################
-#
-# PresenceDB - initialize the module to use the presence database
-#
-##############################################################################
-sub PresenceDB
-{
-    my $self = shift;
-
-    $self->SetXPathCallBacks('/presence'=>sub{ shift; $self->PresenceDBParse(@_) });
-}
-
-
-###############################################################################
-#
-# PresenceDBParse - adds the presence information to the Presence DB so
-#                   you can keep track of the current state of the JID and
-#                   all of it's resources.
-#
-###############################################################################
-sub PresenceDBParse
-{
-    my $self = shift;
-    my ($presence) = @_;
-
-    $self->{DEBUG}->Log4("PresenceDBParse: pres(",$presence->GetXML(),")");
-    
-    my $type = $presence->GetType();
-    $type = "" unless defined($type);
-    return $presence unless (($type eq "") ||
-                 ($type eq "available") ||
-                 ($type eq "unavailable"));
-
-    my $fromJID = $presence->GetFrom("jid");
-    my $fromID = $fromJID->GetJID();
-    $fromID = "" unless defined($fromID);
-    my $resource = $fromJID->GetResource();
-    $resource = " " unless ($resource ne "");
-    my $priority = $presence->GetPriority();
-    $priority = 0 unless defined($priority);
-
-    $self->{DEBUG}->Log1("PresenceDBParse: fromJID(",$fromJID->GetJID("full"),") resource($resource) priority($priority) type($type)");
-    $self->{DEBUG}->Log2("PresenceDBParse: xml(",$presence->GetXML(),")");
-
-    if (exists($self->{PRESENCEDB}->{$fromID}))
-    {
-        my $oldPriority = $self->{PRESENCEDB}->{$fromID}->{resources}->{$resource};
-        $oldPriority = "" unless defined($oldPriority);
-
-        my $loc = 0;
-        foreach my $index (0..$#{$self->{PRESENCEDB}->{$fromID}->{priorities}->{$oldPriority}})
-        {
-            $loc = $index
-               if ($self->{PRESENCEDB}->{$fromID}->{priorities}->{$oldPriority}->[$index]->{resource} eq $resource);
-        }
-        splice(@{$self->{PRESENCEDB}->{$fromID}->{priorities}->{$oldPriority}},$loc,1);
-        delete($self->{PRESENCEDB}->{$fromID}->{resources}->{$resource});
-        delete($self->{PRESENCEDB}->{$fromID}->{priorities}->{$oldPriority})
-            if (exists($self->{PRESENCEDB}->{$fromID}->{priorities}->{$oldPriority}) &&
-        ($#{$self->{PRESENCEDB}->{$fromID}->{priorities}->{$oldPriority}} == -1));
-        delete($self->{PRESENCEDB}->{$fromID})
-            if (scalar(keys(%{$self->{PRESENCEDB}->{$fromID}})) == 0);
-
-        $self->{DEBUG}->Log1("PresenceDBParse: remove ",$fromJID->GetJID("full")," from the DB");
-    }
-
-    if (($type eq "") || ($type eq "available"))
-    {
-        my $loc = -1;
-        foreach my $index (0..$#{$self->{PRESENCEDB}->{$fromID}->{priorities}->{$priority}}) {
-            $loc = $index
-                if ($self->{PRESENCEDB}->{$fromID}->{priorities}->{$priority}->[$index]->{resource} eq $resource);
-        }
-        $loc = $#{$self->{PRESENCEDB}->{$fromID}->{priorities}->{$priority}}+1
-            if ($loc == -1);
-        $self->{PRESENCEDB}->{$fromID}->{resources}->{$resource} = $priority;
-        $self->{PRESENCEDB}->{$fromID}->{priorities}->{$priority}->[$loc]->{presence} =
-            $presence;
-        $self->{PRESENCEDB}->{$fromID}->{priorities}->{$priority}->[$loc]->{resource} =
-            $resource;
-
-        $self->{DEBUG}->Log1("PresenceDBParse: add ",$fromJID->GetJID("full")," to the DB");
-    }
-
-    my $currentPresence = $self->PresenceDBQuery($fromJID);
-    return (defined($currentPresence) ? $currentPresence : $presence);
-}
-
-
-###############################################################################
-#
-# PresenceDBDelete - delete the JID from the DB completely.
-#
-###############################################################################
-sub PresenceDBDelete
-{
-    my $self = shift;
-    my ($jid) = @_;
-
-    my $indexJID = $jid;
-    $indexJID = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
-
-    return if !exists($self->{PRESENCEDB}->{$indexJID});
-    delete($self->{PRESENCEDB}->{$indexJID});
-    $self->{DEBUG}->Log1("PresenceDBDelete: delete ",$indexJID," from the DB");
-}
-
-
-###############################################################################
-#
-# PresenceDBClear - delete all of the JIDs from the DB completely.
-#
-###############################################################################
-sub PresenceDBClear
-{
-    my $self = shift;
-
-    $self->{DEBUG}->Log1("PresenceDBClear: clearing the database");
-    foreach my $indexJID (keys(%{$self->{PRESENCEDB}}))
-    {
-        $self->{DEBUG}->Log3("PresenceDBClear: deleting ",$indexJID," from the DB");
-        delete($self->{PRESENCEDB}->{$indexJID});
-    }
-    $self->{DEBUG}->Log3("PresenceDBClear: database is empty");
-}
-
-
-###############################################################################
-#
-# PresenceDBQuery - retrieve the last Net::XMPP::Presence received with
-#                  the highest priority.
-#
-###############################################################################
-sub PresenceDBQuery
-{
-    my $self = shift;
-    my ($jid) = @_;
-
-    my $indexJID = $jid;
-    $indexJID = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
-
-    return if !exists($self->{PRESENCEDB}->{$indexJID});
-    return if (scalar(keys(%{$self->{PRESENCEDB}->{$indexJID}->{priorities}})) == 0);
-
-    my $highPriority =
-        (sort {$b cmp $a} keys(%{$self->{PRESENCEDB}->{$indexJID}->{priorities}}))[0];
-
-    return $self->{PRESENCEDB}->{$indexJID}->{priorities}->{$highPriority}->[0]->{presence};
-}
-
-
-###############################################################################
-#
-# PresenceDBResources - returns a list of the resources from highest
-#                       priority to lowest.
-#
-###############################################################################
-sub PresenceDBResources
-{
-    my $self = shift;
-    my ($jid) = @_;
-
-    my $indexJID = $jid;
-    $indexJID = $jid->GetJID() if $jid->isa("Net::XMPP::JID");
-
-    my @resources;
-
-    return if !exists($self->{PRESENCEDB}->{$indexJID});
-
-    foreach my $priority (sort {$b cmp $a} keys(%{$self->{PRESENCEDB}->{$indexJID}->{priorities}}))
-    {
-        foreach my $index (0..$#{$self->{PRESENCEDB}->{$indexJID}->{priorities}->{$priority}})
-        {
-            next if ($self->{PRESENCEDB}->{$indexJID}->{priorities}->{$priority}->[$index]->{resource} eq " ");
-            push(@resources,$self->{PRESENCEDB}->{$indexJID}->{priorities}->{$priority}->[$index]->{resource});
-        }
-    }
-    return @resources;
-}
-
-
-###############################################################################
-#
-# PresenceSend - Sends a presence tag to announce your availability
-#
-###############################################################################
-sub PresenceSend
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $args{ignoreactivity} = 0 unless exists($args{ignoreactivity});
-    my $ignoreActivity = delete($args{ignoreactivity});
-
-    my $presence = $self->_presence();
-
-    $presence->SetPresence(%args);
-    $self->Send($presence,$ignoreActivity);
-    return $presence;
-}
-
-
-###############################################################################
-#
-# PresenceProbe - Sends a presence probe to the server
-#
-###############################################################################
-sub PresenceProbe
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-    delete($args{type});
-
-    my $presence = $self->_presence();
-    $presence->SetPresence(type=>"probe",
-                           %args);
-    $self->Send($presence);
-}
-
-
-###############################################################################
-#
-# Subscription - Sends a presence tag to perform the subscription on the
-#                specified JID.
-#
-###############################################################################
-sub Subscription
-{
-    my $self = shift;
-
-    my $presence = $self->_presence();
-    $presence->SetPresence(@_);
-    $self->Send($presence);
-}
-
-
-###############################################################################
-#
-# AuthSend - This is a self contained function to send a login iq tag with
-#            an id.  Then wait for a reply what the same id to come back
-#            and tell the caller what the result was.
-#
-###############################################################################
-sub AuthSend
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    carp("AuthSend requires a username arguement")
-        unless exists($args{username});
-    carp("AuthSend requires a password arguement")
-        unless exists($args{password});
-
-    if($self->{STREAM}->GetStreamFeature($self->GetStreamID(),"xmpp-sasl"))
-    {
-        return $self->AuthSASL(%args);
-    }
-
-    return $self->AuthIQAuth(%args);
-}
-
-
-###############################################################################
-#
-# AuthIQAuth - Try and auth using jabber:iq:auth, the old Jabber way of
-#              authenticating.
-#
-###############################################################################
-sub AuthIQAuth
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $self->{DEBUG}->Log1("AuthIQAuth: old school auth");
-
-    carp("AuthIQAuth requires a resource arguement")
-        unless exists($args{resource});
-
-    my $authType = "digest";
-    my $token;
-    my $sequence;
-
-    #--------------------------------------------------------------------------
-    # First let's ask the sever what all is available in terms of auth types.
-    # If we get an error, then all we can do is digest or plain.
-    #--------------------------------------------------------------------------
-    my $iqAuth = $self->_iq();
-    $iqAuth->SetIQ(type=>"get");
-    my $iqAuthQuery = $iqAuth->NewChild("jabber:iq:auth");
-    $iqAuthQuery->SetUsername($args{username});
-    $iqAuth = $self->SendAndReceiveWithID($iqAuth);
-
-    return unless defined($iqAuth);
-    return ( $iqAuth->GetErrorCode() , $iqAuth->GetError() )
-        if ($iqAuth->GetType() eq "error");
-
-    if ($iqAuth->GetType() eq "error")
-    {
-        $authType = "digest";
-    }
-    else
-    {
-        $iqAuthQuery = $iqAuth->GetChild();
-        $authType = "plain" if $iqAuthQuery->DefinedPassword();
-        $authType = "digest" if $iqAuthQuery->DefinedDigest();
-        $authType = "zerok" if ($iqAuthQuery->DefinedSequence() &&
-                    $iqAuthQuery->DefinedToken());
-        $token = $iqAuthQuery->GetToken() if ($authType eq "zerok");
-        $sequence = $iqAuthQuery->GetSequence() if ($authType eq "zerok");
-    }
-
-    $self->{DEBUG}->Log1("AuthIQAuth: authType($authType)");
-
-    delete($args{digest});
-    delete($args{type});
-    my $password = delete $args{password};
-    if (ref($password) eq 'CODE')
-    {
-        $password = $password->();
-    }
-
-    #--------------------------------------------------------------------------
-    # 0k authenticaion (http://core.jabber.org/0k.html)
-    #
-    # Tell the server that we want to connect this way, the server sends back
-    # a token and a sequence number.  We take that token + the password and
-    # SHA1 it.  Then we SHA1 it sequence number more times and send that hash.
-    # The server SHA1s that hash one more time and compares it to the hash it
-    # stored last time.  IF they match, we are in and it stores the hash we sent
-    # for the next time and decreases the sequence number, else, no go.
-    #--------------------------------------------------------------------------
-    if ($authType eq "zerok")
-    {
-        my $hashA = Digest::SHA1::sha1_hex($password);
-        $args{hash} = Digest::SHA1::sha1_hex($hashA.$token);
-
-        for (1..$sequence)
-        {
-            $args{hash} = Digest::SHA1::sha1_hex($args{hash});
-        }
-    }
-
-    #--------------------------------------------------------------------------
-    # If we have access to the SHA-1 digest algorithm then let's use it.
-    # Remove the password from the hash, create the digest, and put the
-    # digest in the hash instead.
-    #
-    # Note: Concat the Session ID and the password and then digest that
-    # string to get the server to accept the digest.
-    #--------------------------------------------------------------------------
-    if ($authType eq "digest")
-    {
-        $args{digest} = Digest::SHA1::sha1_hex($self->GetStreamID().$password);
-    }
-
-    #--------------------------------------------------------------------------
-    # Create a Net::XMPP::IQ object to send to the server
-    #--------------------------------------------------------------------------
-    my $iqLogin = $self->_iq();
-    $iqLogin->SetIQ(type=>"set");
-    my $iqLoginQuery = $iqLogin->NewChild("jabber:iq:auth");
-    $iqLoginQuery->SetAuth(%args);
-
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    $iqLogin = $self->SendAndReceiveWithID($iqLogin);
-
-    #--------------------------------------------------------------------------
-    # From the reply IQ determine if we were successful or not.  If yes then
-    # return "".  If no then return error string from the reply.
-    #--------------------------------------------------------------------------
-    $password =~ tr/\0-\377/x/;
-    return unless defined($iqLogin);
-    return ( $iqLogin->GetErrorCode() , $iqLogin->GetError() )
-        if ($iqLogin->GetType() eq "error");
-
-    $self->{DEBUG}->Log1("AuthIQAuth: we authed!");
-
-    return ("ok","");
-}
-
-
-###############################################################################
-#
-# AuthSASL - Try and auth using SASL, the XMPP preferred way of authenticating.
-#
-###############################################################################
-sub AuthSASL
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $self->{DEBUG}->Log1("AuthSASL: shiney new auth");
-
-    carp("AuthSASL requires a username arguement")
-        unless exists($args{username});
-    carp("AuthSASL requires a password arguement")
-        unless exists($args{password});
-
-    $args{resource} = "" unless exists($args{resource});
-
-    #-------------------------------------------------------------------------
-    # Create the SASLClient on our end
-    #-------------------------------------------------------------------------
-    my $sid = $self->{SESSION}->{id};
-    my $status =
-        $self->{STREAM}->SASLClient($sid,
-                                    $args{username},
-                                    $args{password}
-                                   );
-
-    $args{timeout} = "120" unless exists($args{timeout});
-
-    #-------------------------------------------------------------------------
-    # While we haven't timed out, keep waiting for the SASLClient to finish
-    #-------------------------------------------------------------------------
-    my $endTime = time + $args{timeout};
-    while(!$self->{STREAM}->SASLClientDone($sid) && ($endTime >= time))
-    {
-        $self->{DEBUG}->Log1("AuthSASL: haven't authed yet... let's wait.");
-        return unless (defined($self->Process(1)));
-        &{$self->{CB}->{update}}() if exists($self->{CB}->{update});
-    }
-    
-    #-------------------------------------------------------------------------
-    # The loop finished... but was it done?
-    #-------------------------------------------------------------------------
-    if (!$self->{STREAM}->SASLClientDone($sid))
-    {
-        $self->{DEBUG}->Log1("AuthSASL: timed out...");
-        return( "system","SASL timed out authenticating");
-    }
-    
-    #-------------------------------------------------------------------------
-    # Ok, it was done... but did we auth?
-    #-------------------------------------------------------------------------
-    if (!$self->{STREAM}->SASLClientAuthed($sid))
-    {
-        $self->{DEBUG}->Log1("AuthSASL: Authentication failed.");
-        return ( "error", $self->{STREAM}->SASLClientError($sid));
-    }
-    
-    #-------------------------------------------------------------------------
-    # Phew... Restart the <stream:stream> per XMPP
-    #-------------------------------------------------------------------------
-    $self->{DEBUG}->Log1("AuthSASL: We authed!");
-    $self->{SESSION} = $self->{STREAM}->OpenStream($sid);
-    $sid = $self->{SESSION}->{id};
-    
-    $self->{DEBUG}->Log1("AuthSASL: We got a new session. sid($sid)");
-
-    #-------------------------------------------------------------------------
-    # Look in the new set of <stream:feature/>s and see if xmpp-bind was
-    # offered.
-    #-------------------------------------------------------------------------
-    my $bind = $self->{STREAM}->GetStreamFeature($sid,"xmpp-bind");
-    if ($bind)
-    {
-        $self->{DEBUG}->Log1("AuthSASL: Binding to resource");
-        my $jid = $self->BindResource($args{resource});
-	$self->{SESSION}->{FULLJID} = $jid;
-    }
-
-    #-------------------------------------------------------------------------
-    # Look in the new set of <stream:feature/>s and see if xmpp-session was
-    # offered.
-    #-------------------------------------------------------------------------
-    my $session = $self->{STREAM}->GetStreamFeature($sid,"xmpp-session");
-    if ($session)
-    {
-        $self->{DEBUG}->Log1("AuthSASL: Starting session");
-        $self->StartSession();
-    }
-
-    return ("ok","");
-}
-
-
-##############################################################################
-#
-# BindResource - bind to a resource
-#
-##############################################################################
-sub BindResource
-{
-    my $self = shift;
-    my $resource = shift;
-
-    $self->{DEBUG}->Log2("BindResource: Binding to resource");
-    my $iq = $self->_iq();
-
-    $iq->SetIQ(type=>"set");
-    my $bind = $iq->NewChild(&ConstXMLNS("xmpp-bind"));
-    
-    if (defined($resource) && ($resource ne ""))
-    {
-        $self->{DEBUG}->Log2("BindResource: resource($resource)");
-        $bind->SetBind(resource=>$resource);
-    }
-
-    my $result = $self->SendAndReceiveWithID($iq);
-    return $result->GetChild(&ConstXMLNS("xmpp-bind"))->GetJID();;
-}
-
-
-##############################################################################
-#
-# StartSession - Initialize a session
-#
-##############################################################################
-sub StartSession
-{
-    my $self = shift;
-
-    my $iq = $self->_iq();
-
-    $iq->SetIQ(type=>"set");
-    my $session = $iq->NewChild(&ConstXMLNS("xmpp-session"));
-    
-    my $result = $self->SendAndReceiveWithID($iq);
-}
-
-
-##############################################################################
-#
-# PrivacyLists - Initialize a Net::XMPP::PrivacyLists object and return it.
-#
-##############################################################################
-sub PrivacyLists
-{
-    my $self = shift;
-
-    return Net::XMPP::PrivacyLists->new(connection=>$self);
-}
-
-
-##############################################################################
-#
-# PrivacyListsGet - Sends an empty IQ to the server to request that the user's
-#                   Privacy Lists be sent to them.  Returns the iq packet
-#                   of the result.
-#
-##############################################################################
-sub PrivacyListsGet
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(type=>"get");
-    my $query = $iq->NewChild("jabber:iq:privacy");
-
-    if (exists($args{list}))
-    {
-        $query->AddList(name=>$args{list});
-    }
-
-    $iq = $self->SendAndReceiveWithID($iq);
-    return unless defined($iq);
-
-    return $iq;
-}
-
-
-##############################################################################
-#
-# PrivacyListsRequest - Sends an empty IQ to the server to request that the
-#                       user's privacy lists be sent to them, and return to
-#                       let the user's program handle parsing the return packet.
-#
-##############################################################################
-sub PrivacyListsRequest
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-    
-    my $iq = $self->_iq();
-    $iq->SetIQ(type=>"get");
-    my $query = $iq->NewChild("jabber:iq:privacy");
-
-    if (exists($args{list}))
-    {
-        $query->AddList(name=>$args{list});
-    }
-
-    $self->Send($iq);
-}
-
-
-##############################################################################
-#
-# PrivacyListsSet - Sends an empty IQ to the server to request that the
-#                       user's privacy lists be sent to them, and return to
-#                       let the user's program handle parsing the return packet.
-#
-##############################################################################
-sub PrivacyListsSet
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-    
-    my $iq = $self->_iq();
-    $iq->SetIQ(type=>"set");
-    my $query = $iq->NewChild("jabber:iq:privacy");
-
-    #XXX error check that there is a list
-    my $list = $query->AddList(name=>$args{list});
-
-    foreach my $item (@{$args{items}})
-    {
-        $list->AddItem(%{$item});
-    }
-
-    $iq = $self->SendAndReceiveWithID($iq);
-    return unless defined($iq);
-
-    return if $iq->DefinedError();
-
-    return 1;
-}
-
-
-###############################################################################
-#
-# RegisterRequest - This is a self contained function to send an iq tag
-#                   an id that requests the target address to send back
-#                   the required fields.  It waits for a reply what the
-#                   same id to come back and tell the caller what the
-#                   fields are.
-#
-###############################################################################
-sub RegisterRequest
-{
-    my $self = shift;
-    my %args;
-    $args{mode} = "block";
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $timeout = exists($args{timeout}) ? delete($args{timeout}) : undef;
-
-    #--------------------------------------------------------------------------
-    # Create a Net::XMPP::IQ object to send to the server
-    #--------------------------------------------------------------------------
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>delete($args{to})) if exists($args{to});
-    $iq->SetIQ(type=>"get");
-    my $query = $iq->NewChild("jabber:iq:register");
-
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    if ($args{mode} eq "passthru")
-    {
-        my $id = $self->UniqueID();
-        $iq->SetIQ(id=>$id);
-        $self->Send($iq);
-        return $id;
-    }
-    
-    return $self->SendWithID($iq) if ($args{mode} eq "nonblock");
-
-    $iq = $self->SendAndReceiveWithID($iq,$timeout);
-
-    #--------------------------------------------------------------------------
-    # Check if there was an error.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    if ($iq->GetType() eq "error")
-    {
-        $self->SetErrorCode($iq->GetErrorCode().": ".$iq->GetError());
-        return;
-    }
-
-    my %register;
-    #--------------------------------------------------------------------------
-    # From the reply IQ determine what fields are required and send a hash
-    # back with the fields and any values that are already defined (like key)
-    #--------------------------------------------------------------------------
-    $query = $iq->GetChild();
-    $register{fields} = { $query->GetRegister() };
-
-    return %register;
-}
-
-
-###############################################################################
-#
-# RegisterSend - This is a self contained function to send a registration
-#                iq tag with an id.  Then wait for a reply what the same
-#                id to come back and tell the caller what the result was.
-#
-###############################################################################
-sub RegisterSend
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    #--------------------------------------------------------------------------
-    # Create a Net::XMPP::IQ object to send to the server
-    #--------------------------------------------------------------------------
-    my $iq = $self->_iq();
-    $iq->SetIQ(to=>delete($args{to})) if exists($args{to});
-    $iq->SetIQ(type=>"set");
-    my $iqRegister = $iq->NewChild("jabber:iq:register");
-    $iqRegister->SetRegister(%args);
-
-    #--------------------------------------------------------------------------
-    # Send the IQ with the next available ID and wait for a reply with that
-    # id to be received.  Then grab the IQ reply.
-    #--------------------------------------------------------------------------
-    $iq = $self->SendAndReceiveWithID($iq);
-
-    #--------------------------------------------------------------------------
-    # From the reply IQ determine if we were successful or not.  If yes then
-    # return "".  If no then return error string from the reply.
-    #--------------------------------------------------------------------------
-    return unless defined($iq);
-    return ( $iq->GetErrorCode() , $iq->GetError() )
-        if ($iq->GetType() eq "error");
-    return ("ok","");
-}
-
-
-##############################################################################
-#
-# RosterAdd - Takes the Jabber ID of the user to add to their Roster and
-#             sends the IQ packet to the server.
-#
-##############################################################################
-sub RosterAdd
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(type=>"set");
-    my $roster = $iq->NewChild("jabber:iq:roster");
-    my $item = $roster->AddItem();
-    $item->SetItem(%args);
-
-    $self->{DEBUG}->Log1("RosterAdd: xml(",$iq->GetXML(),")");
-    $self->Send($iq);
-}
-
-
-##############################################################################
-#
-# RosterAdd - Takes the Jabber ID of the user to remove from their Roster
-#             and sends the IQ packet to the server.
-#
-##############################################################################
-sub RosterRemove
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-    delete($args{subscription});
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(type=>"set");
-    my $roster = $iq->NewChild("jabber:iq:roster");
-    my $item = $roster->AddItem();
-    $item->SetItem(%args,
-                   subscription=>"remove");
-    $self->Send($iq);
-}
-
-
-##############################################################################
-#
-# RosterParse - Returns a hash of roster items.
-#
-##############################################################################
-sub RosterParse
-{
-    my $self = shift;
-    my($iq) = @_;
-
-    my %roster;
-    my $query = $iq->GetChild("jabber:iq:roster");
-
-    if (defined($query)) #$query->GetXMLNS() eq "jabber:iq:roster")
-    {
-        my @items = $query->GetItems();
-
-        foreach my $item (@items)
-        {
-            my $jid = $item->GetJID();
-            $roster{$jid}->{name} = $item->GetName();
-            $roster{$jid}->{subscription} = $item->GetSubscription();
-            $roster{$jid}->{ask} = $item->GetAsk();
-            $roster{$jid}->{groups} = [ $item->GetGroup() ];
-        }
-    }
-
-    return %roster;
-}
-
-
-##############################################################################
-#
-# RosterGet - Sends an empty IQ to the server to request that the user's
-#             Roster be sent to them.  Returns a hash of roster items.
-#
-##############################################################################
-sub RosterGet
-{
-    my $self = shift;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(type=>"get");
-    my $query = $iq->NewChild("jabber:iq:roster");
-
-    $iq = $self->SendAndReceiveWithID($iq);
-
-    return unless defined($iq);
-
-    return $self->RosterParse($iq);
-}
-
-
-##############################################################################
-#
-# RosterRequest - Sends an empty IQ to the server to request that the user's
-#                 Roster be sent to them, and return to let the user's program
-#                 handle parsing the return packet.
-#
-##############################################################################
-sub RosterRequest
-{
-    my $self = shift;
-
-    my $iq = $self->_iq();
-    $iq->SetIQ(type=>"get");
-    my $query = $iq->NewChild("jabber:iq:roster");
-
-    $self->Send($iq);
-}
-
-
-##############################################################################
-#
-# Roster - Initialize a Net::XMPP::Roster object and return it.
-#
-##############################################################################
-sub Roster
-{
-    my $self = shift;
-
-    return Net::XMPP::Roster->new(connection=>$self);
-}
-
-
-##############################################################################
-#
-# RosterDB - initialize the module to use the roster database
-#
-##############################################################################
-sub RosterDB
-{
-    my $self = shift;
-
-    $self->SetXPathCallBacks('/iq[@type="result" or @type="set"]/query[@xmlns="jabber:iq:roster"]'=>sub{ shift; $self->RosterDBParse(@_) });
-}
-
-
-##############################################################################
-#
-# RosterDBAdd - adds the entry to the Roster DB.
-#
-##############################################################################
-sub RosterDBAdd
-{
-    my $self = shift;
-    my ($jid,%item) = @_;
-
-    $self->{ROSTERDB}->{JIDS}->{$jid} = \%item;
-
-    foreach my $group (@{$item{groups}})
-    {
-        $self->{ROSTERDB}->{GROUPS}->{$group}->{$jid} = 1;
-    }
-}
-
-
-###############################################################################
-#
-# RosterDBClear - delete all of the JIDs from the DB completely.
-#
-###############################################################################
-sub RosterDBClear
-{
-    my $self = shift;
-
-    $self->{DEBUG}->Log1("RosterDBClear: clearing the database");
-    foreach my $jid ($self->RosterDBJIDs())
-    {
-        $self->{DEBUG}->Log3("RosterDBClear: deleting ",$jid->GetJID()," from the DB");
-        $self->RosterDBRemove($jid);
-    }
-    $self->{DEBUG}->Log3("RosterDBClear: database is empty");
-}
-
-
-##############################################################################
-#
-# RosterDBExists - allows you to query if the JID exists in the Roster DB.
-#
-##############################################################################
-sub RosterDBExists
-{
-    my $self = shift;
-    my ($jid) = @_;
-
-    if ($jid->isa("Net::XMPP::JID"))
-    {
-        $jid = $jid->GetJID();
-    }
-    
-    return unless exists($self->{ROSTERDB});
-    return unless exists($self->{ROSTERDB}->{JIDS});
-    return unless exists($self->{ROSTERDB}->{JIDS}->{$jid});
-    return 1;
-}
-
-
-##############################################################################
-#
-# RosterDBGroupExists - allows you to query if the group exists in the Roster
-#                       DB.
-#
-##############################################################################
-sub RosterDBGroupExists
-{
-    my $self = shift;
-    my ($group) = @_;
-
-    return unless exists($self->{ROSTERDB});
-    return unless exists($self->{ROSTERDB}->{GROUPS});
-    return unless exists($self->{ROSTERDB}->{GROUPS}->{$group});
-    return 1;
-}
-
-
-##############################################################################
-#
-# RosterDBGroupJIDs - returns a list of the current groups in your roster.
-#
-##############################################################################
-sub RosterDBGroupJIDs
-{
-    my $self = shift;
-    my $group = shift;
-
-    return unless $self->RosterDBGroupExists($group);
-    my @jids;
-    foreach my $jid (keys(%{$self->{ROSTERDB}->{GROUPS}->{$group}}))
-    {
-        push(@jids,$self->_jid($jid));
-    }
-    return @jids;
-}
-
-
-##############################################################################
-#
-# RosterDBGroups - returns a list of the current groups in your roster.
-#
-##############################################################################
-sub RosterDBGroups
-{
-    my $self = shift;
-
-    return () unless exists($self->{ROSTERDB}->{GROUPS});
-    return () if (scalar(keys(%{$self->{ROSTERDB}->{GROUPS}})) == 0);
-    return keys(%{$self->{ROSTERDB}->{GROUPS}});
-}
-
-
-##############################################################################
-#
-# RosterDBJIDs - returns a list of all of the JIDs in your roster.
-#
-##############################################################################
-sub RosterDBJIDs
-{
-    my $self = shift;
-    my $group = shift;
-
-    my @jids;
-
-    return () unless exists($self->{ROSTERDB});
-    return () unless exists($self->{ROSTERDB}->{JIDS});
-    foreach my $jid (keys(%{$self->{ROSTERDB}->{JIDS}}))
-    {
-        push(@jids,$self->_jid($jid));
-    }
-    return @jids;
-}
-
-
-##############################################################################
-#
-# RosterDBNonGroupJIDs - returns a list of the JIDs not in a group.
-#
-##############################################################################
-sub RosterDBNonGroupJIDs
-{
-    my $self = shift;
-    my $group = shift;
-
-    my @jids;
-
-    return () unless exists($self->{ROSTERDB});
-    return () unless exists($self->{ROSTERDB}->{JIDS});
-    foreach my $jid (keys(%{$self->{ROSTERDB}->{JIDS}}))
-    {
-        next if (exists($self->{ROSTERDB}->{JIDS}->{$jid}->{groups}) &&
-                 ($#{$self->{ROSTERDB}->{JIDS}->{$jid}->{groups}} > -1));
-
-        push(@jids,$self->_jid($jid));
-    }
-    return @jids;
-}
-
-
-##############################################################################
-#
-# RosterDBParse - takes an iq packet that containsa roster, parses it, and puts
-#                 the roster into the Roster DB.
-#
-##############################################################################
-sub RosterDBParse
-{
-    my $self = shift;
-    my ($iq) = @_;
-
-    #print "RosterDBParse: iq(",$iq->GetXML(),")\n";
-
-    my $type = $iq->GetType();
-    return unless (($type eq "set") || ($type eq "result"));
-
-    my %newroster = $self->RosterParse($iq);
-
-    $self->RosterDBProcessParsed(%newroster);
-}
-
-
-##############################################################################
-#
-# RosterDBProcessParsed - takes a parsed roster and puts it into the Roster DB.
-#
-##############################################################################
-sub RosterDBProcessParsed
-{
-    my $self = shift;
-    my (%roster) = @_;
-
-    foreach my $jid (keys(%roster))
-    {
-        $self->RosterDBRemove($jid);
-
-        if ($roster{$jid}->{subscription} ne "remove")
-        {
-            $self->RosterDBAdd($jid, %{$roster{$jid}} );
-        }
-    }
-}
-
-
-##############################################################################
-#
-# RosterDBQuery - allows you to get one of the pieces of info from the
-#                 Roster DB.
-#
-##############################################################################
-sub RosterDBQuery
-{
-    my $self = shift;
-    my $jid = shift;
-    my $key = shift;
-
-    if ($jid->isa("Net::XMPP::JID"))
-    {
-        $jid = $jid->GetJID();
-    }
-    
-    return unless $self->RosterDBExists($jid);
-    if (defined($key))
-    {
-        return unless exists($self->{ROSTERDB}->{JIDS}->{$jid}->{$key});
-        return $self->{ROSTERDB}->{JIDS}->{$jid}->{$key};
-    }
-    return %{$self->{ROSTERDB}->{JIDS}->{$jid}};
-}                        
-
-
-##############################################################################
-#
-# RosterDBRemove - removes the JID from the Roster DB.
-#
-##############################################################################
-sub RosterDBRemove
-{
-    my $self = shift;
-    my ($jid) = @_;
-
-    if ($self->RosterDBExists($jid))
-    {
-        if (defined($self->RosterDBQuery($jid,"groups")))
-        {
-            foreach my $group (@{$self->RosterDBQuery($jid,"groups")})
-            {
-                delete($self->{ROSTERDB}->{GROUPS}->{$group}->{$jid});
-                delete($self->{ROSTERDB}->{GROUPS}->{$group})
-                    if (scalar(keys(%{$self->{ROSTERDB}->{GROUPS}->{$group}})) == 0);
-                delete($self->{ROSTERDB}->{GROUPS})
-                    if (scalar(keys(%{$self->{ROSTERDB}->{GROUPS}})) == 0);
-            }
-        }
-    
-        delete($self->{ROSTERDB}->{JIDS}->{$jid});
-    }
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| TLS Functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# TLSInit - Initialize the connection for TLS.
-#
-##############################################################################
-sub TLSInit
-{
-    my $self = shift;
-
-    $TLS_CALLBACK = sub{ $self->ProcessTLSStanza( @_ ) };
-    $self->SetDirectXPathCallBacks('/[@xmlns="'.&ConstXMLNS("xmpp-tls").'"]'=>$TLS_CALLBACK);
-}
-
-
-##############################################################################
-#
-# ProcessTLSStanza - process a TLS based packet.
-#
-##############################################################################
-sub ProcessTLSStanza
-{
-    my $self = shift;
-    my $sid = shift;
-    my $node = shift;
-
-    my $tag = &XML::Stream::XPath($node,"name()");
-
-    if ($tag eq "failure")
-    {
-        $self->TLSClientFailure($node);
-    }
-    
-    if ($tag eq "proceed")
-    {
-        $self->TLSClientProceed($node);
-    }
-}
-
-
-##############################################################################
-#
-# TLSStart - client function to have the socket start TLS.
-#
-##############################################################################
-sub TLSStart
-{
-    my $self = shift;
-    my $timeout = shift;
-    $timeout = 120 unless defined($timeout);
-    $timeout = 120 if ($timeout eq "");
-    
-    $self->TLSSendStartTLS();
-
-    my $endTime = time + $timeout;
-    while(!$self->TLSClientDone() && ($endTime >= time))
-    {
-        $self->Process();
-    }
-
-    if (!$self->TLSClientSecure())
-    {
-        return;
-    }
-
-    $self->RestartStream($timeout);
-}
-
-
-##############################################################################
-#
-# TLSClientProceed - handle a <proceed/> packet.
-#
-##############################################################################
-sub TLSClientProceed
-{
-    my $self = shift;
-    my $node = shift;
-
-    my ($status,$message) = $self->{STREAM}->StartTLS($self->GetStreamID());
-
-    if ($status)
-    {
-        $self->{TLS}->{done} = 1;
-        $self->{TLS}->{secure} = 1;
-    }
-    else
-    {
-        $self->{TLS}->{done} = 1;
-        $self->{TLS}->{error} = $message;
-    }
-    
-    $self->RemoveDirectXPathCallBacks('/[@xmlns="'.&ConstXMLNS("xmpp-tls").'"]'=>$TLS_CALLBACK);
-}
-
-
-##############################################################################
-#
-# TLSClientSecure - return 1 if the socket is secure, 0 otherwise.
-#
-##############################################################################
-sub TLSClientSecure
-{
-    my $self = shift;
-    
-    return $self->{TLS}->{secure};
-}
-
-
-##############################################################################
-#
-# TLSClientDone - return 1 if the TLS process is done
-#
-##############################################################################
-sub TLSClientDone
-{
-    my $self = shift;
-    
-    return $self->{TLS}->{done};
-}
-
-
-##############################################################################
-#
-# TLSClientError - return the TLS error if any
-#
-##############################################################################
-sub TLSClientError
-{
-    my $self = shift;
-    
-    return $self->{TLS}->{error};
-}
-
-
-##############################################################################
-#
-# TLSClientFailure - handle a <failure/>
-#
-##############################################################################
-sub TLSClientFailure
-{
-    my $self = shift;
-    my $node = shift;
-    
-    my $type = &XML::Stream::XPath($node,"*/name()");
-
-    $self->{TLS}->{error} = $type;
-    $self->{TLS}->{done} = 1;
-}
-
-
-##############################################################################
-#
-# TLSSendFailure - Send a <failure/> in the TLS namespace
-#
-##############################################################################
-sub TLSSendFailure
-{
-    my $self = shift;
-    my $type = shift;
-    
-    $self->Send("<failure xmlns='".&ConstXMLNS('xmpp-tls')."'><${type}/></failure>");
-}
-
-
-##############################################################################
-#
-# TLSSendStartTLS - send a <starttls/> in the TLS namespace.
-#
-##############################################################################
-sub TLSSendStartTLS
-{
-    my $self = shift;
-
-    $self->Send("<starttls xmlns='".&ConstXMLNS('xmpp-tls')."'/>");
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| SASL Functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# SASLInit - Initialize the connection for SASL.
-#
-##############################################################################
-sub SASLInit
-{
-    my $self = shift;
-
-    $SASL_CALLBACK = sub{ $self->ProcessSASLStanza( @_ ) };
-    $self->SetDirectXPathCallBacks('/[@xmlns="'.&ConstXMLNS("xmpp-sasl").'"]'=> $SASL_CALLBACK);
-}
-
-
-##############################################################################
-#
-# ProcessSASLStanza - process a SASL based packet.
-#
-##############################################################################
-sub ProcessSASLStanza
-{
-    my $self = shift;
-    my $sid = shift;
-    my $node = shift;
-
-    my $tag = &XML::Stream::XPath($node,"name()");
-
-    if ($tag eq "challenge")
-    {
-        $self->SASLAnswerChallenge($node);
-    }
-    
-    if ($tag eq "failure")
-    {
-        $self->SASLClientFailure($node);
-    }
-    
-    if ($tag eq "success")
-    {
-        $self->SASLClientSuccess($node);
-    }
-}
-
-
-##############################################################################
-#
-# SASLAnswerChallenge - when we get a <challenge/> we need to do the grunt
-#                       work to return a <response/>.
-#
-##############################################################################
-sub SASLAnswerChallenge
-{
-    my $self = shift;
-    my $node = shift;
-
-    my $challenge64 = &XML::Stream::XPath($node,"text()");
-    my $challenge = MIME::Base64::decode_base64($challenge64);
-    
-    my $response = $self->SASLGetClient()->client_step($challenge);
-
-    my $response64 = MIME::Base64::encode_base64($response,"");
-    $self->SASLSendResponse($response64);
-}
-
-
-###############################################################################
-#
-# SASLClient - This is a helper function to perform all of the required steps
-#              for doing SASL with the server.
-#
-###############################################################################
-sub SASLClient
-{
-    my $self = shift;
-    my $username = shift;
-    my $password = shift;
-
-    my $mechanisms = $self->GetStreamFeature("xmpp-sasl");
-
-    return unless defined($mechanisms);
-    
-    my $sasl = new Authen::SASL(mechanism=>join(" ",@{$mechanisms}),
-                                callback=>{ user => $username,
-                                            pass => $password
-                                          }
-                               );
-
-    $self->{SASL}->{client} = $sasl->client_new();
-    $self->{SASL}->{username} = $username;
-    $self->{SASL}->{password} = $password;
-    $self->{SASL}->{authed} = 0;
-    $self->{SASL}->{done} = 0;
-
-    $self->SASLSendAuth();
-}
-
-
-##############################################################################
-#
-# SASLClientAuthed - return 1 if we authed via SASL, 0 otherwise
-#
-##############################################################################
-sub SASLClientAuthed
-{
-    my $self = shift;
-    
-    return $self->{SASL}->{authed};
-}
-
-
-##############################################################################
-#
-# SASLClientDone - return 1 if the SASL process is finished
-#
-##############################################################################
-sub SASLClientDone
-{
-    my $self = shift;
-    
-    return $self->{SASL}->{done};
-}
-
-
-##############################################################################
-#
-# SASLClientError - return the error if any
-#
-##############################################################################
-sub SASLClientError
-{
-    my $self = shift;
-    
-    return $self->{SASL}->{error};
-}
-
-
-##############################################################################
-#
-# SASLClientFailure - handle a received <failure/>
-#
-##############################################################################
-sub SASLClientFailure
-{
-    my $self = shift;
-    my $node = shift;
-    
-    my $type = &XML::Stream::XPath($node,"*/name()");
-
-    $self->{SASL}->{error} = $type;
-    $self->{SASL}->{done} = 1;
-}
-
-
-##############################################################################
-#
-# SASLClientSuccess - handle a received <success/>
-#
-##############################################################################
-sub SASLClientSuccess
-{
-    my $self = shift;
-    my $node = shift;
-    
-    $self->{SASL}->{authed} = 1;
-    $self->{SASL}->{done} = 1;
-
-    $self->RemoveDirectXPathCallBacks('/[@xmlns="'.&ConstXMLNS("xmpp-sasl").'"]'=>$SASL_CALLBACK);
-}
-
-
-###############################################################################
-#
-# SASLGetClient - This is a helper function to return the SASL client object.
-#
-###############################################################################
-sub SASLGetClient
-{
-    my $self = shift;
-    
-    return $self->{SASL}->{client};
-}
-
-
-##############################################################################
-#
-# SASLSendAuth - send an <auth/> in the SASL namespace
-#
-##############################################################################
-sub SASLSendAuth
-{
-    my $self = shift;
-
-    $self->Send("<auth xmlns='".&ConstXMLNS('xmpp-sasl')."' mechanism='".$self->SASLGetClient()->mechanism()."'/>");
-}
-
-
-##############################################################################
-#
-# SASLSendChallenge - Send a <challenge/> in the SASL namespace
-#
-##############################################################################
-sub SASLSendChallenge
-{
-    my $self = shift;
-    my $challenge = shift;
-
-    $self->Send("<challenge xmlns='".&ConstXMLNS('xmpp-sasl')."'>${challenge}</challenge>");
-}
-
-
-##############################################################################
-#
-# SASLSendFailure - Send a <failure/> tag in the SASL namespace
-#
-##############################################################################
-sub SASLSendFailure
-{
-    my $self = shift;
-    my $type = shift;
-    
-    $self->Send("<failure xmlns='".&ConstXMLNS('xmpp-sasl')."'><${type}/></failure>");
-}
-
-
-##############################################################################
-#
-# SASLSendResponse - Send a <response/> tag in the SASL namespace
-#
-##############################################################################
-sub SASLSendResponse
-{
-    my $self = shift;
-    my $response = shift;
-
-    $self->Send("<response xmlns='".&ConstXMLNS('xmpp-sasl')."'>${response}</response>");
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Default CallBacks
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-
-##############################################################################
-#
-# callbackInit - initialize the default callbacks
-#
-##############################################################################
-sub callbackInit
-{
-    my $self = shift;
-
-    $self->SetCallBacks(iq=>sub{ $self->callbackIQ(@_) },
-                        presence=>sub{ $self->callbackPresence(@_) },
-                        message=>sub{ $self->callbackMessage(@_) },
-                        );
-
-    $self->SetPresenceCallBacks(subscribe=>sub{ $self->callbackPresenceSubscribe(@_) },
-                                unsubscribe=>sub{ $self->callbackPresenceUnsubscribe(@_) },
-                                subscribed=>sub{ $self->callbackPresenceSubscribed(@_) },
-                                unsubscribed=>sub{ $self->callbackPresenceUnsubscribed(@_) },
-                               );
-
-    $self->TLSInit();
-    $self->SASLInit();
-}
-
-
-##############################################################################
-#
-# callbackMessage - default callback for <message/> packets.
-#
-##############################################################################
-sub callbackMessage
-{
-    my $self = shift;
-    my $sid = shift;
-    my $message = shift;
-
-    my $type = "normal";
-    $type = $message->GetType() if $message->DefinedType();
-
-    if (exists($self->{CB}->{Mess}->{$type}) &&
-        (ref($self->{CB}->{Mess}->{$type}) eq "CODE"))
-    {
-        &{$self->{CB}->{Mess}->{$type}}($sid,$message);
-    }
-}
-
-
-##############################################################################
-#
-# callbackPresence - default callback for <presence/> packets.
-#
-##############################################################################
-sub callbackPresence
-{
-    my $self = shift;
-    my $sid = shift;
-    my $presence = shift;
-
-    my $type = "available";
-    $type = $presence->GetType() if $presence->DefinedType();
-
-    if (exists($self->{CB}->{Pres}->{$type}) &&
-        (ref($self->{CB}->{Pres}->{$type}) eq "CODE"))
-    {
-        &{$self->{CB}->{Pres}->{$type}}($sid,$presence);
-    }
-}
-
-
-##############################################################################
-#
-# callbackIQ - default callback for <iq/> packets.
-#
-##############################################################################
-sub callbackIQ
-{
-    my $self = shift;
-    my $sid = shift;
-    my $iq = shift;
-
-    return unless $iq->DefinedChild();
-    my $query = $iq->GetChild();
-    return unless defined($query);
-
-    my $type = $iq->GetType();
-    my $ns = $query->GetXMLNS();
-
-    if (exists($self->{CB}->{IQns}->{$ns}) &&
-        (ref($self->{CB}->{IQns}->{$ns}) eq "CODE"))
-    {
-        &{$self->{CB}->{IQns}->{$ns}}($sid,$iq);
-
-    }
-    elsif (exists($self->{CB}->{IQns}->{$ns}->{$type}) &&
-           (ref($self->{CB}->{IQns}->{$ns}->{$type}) eq "CODE"))
-    {
-        &{$self->{CB}->{IQns}->{$ns}->{$type}}($sid,$iq);
-    }
-}
-
-
-##############################################################################
-#
-# callbackPresenceSubscribe - default callback for subscribe packets.
-#
-##############################################################################
-sub callbackPresenceSubscribe
-{
-    my $self = shift;
-    my $sid = shift;
-    my $presence = shift;
-
-    my $reply = $presence->Reply(type=>"subscribed");
-    $self->Send($reply,1);
-    $reply->SetType("subscribe");
-    $self->Send($reply,1);
-}
-
-
-##############################################################################
-#
-# callbackPresenceUnsubscribe - default callback for unsubscribe packets.
-#
-##############################################################################
-sub callbackPresenceUnsubscribe
-{
-    my $self = shift;
-    my $sid = shift;
-    my $presence = shift;
-
-    my $reply = $presence->Reply(type=>"unsubscribed");
-    $self->Send($reply,1);
-}
-
-   
-##############################################################################
-#
-# callbackPresenceSubscribed - default callback for subscribed packets.
-#
-##############################################################################
-sub callbackPresenceSubscribed
-{
-    my $self = shift;
-    my $sid = shift;
-    my $presence = shift;
-
-    my $reply = $presence->Reply(type=>"subscribed");
-    $self->Send($reply,1);
-}
-
-
-##############################################################################
-#
-# callbackPresenceUnsubscribed - default callback for unsubscribed packets.
-#
-##############################################################################
-sub callbackPresenceUnsubscribed
-{
-    my $self = shift;
-    my $sid = shift;
-    my $presence = shift;
-
-    my $reply = $presence->Reply(type=>"unsubscribed");
-    $self->Send($reply,1);
-}
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Stream functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-sub GetStreamID
-{
-    my $self = shift;
-
-    return $self->{SESSION}->{id};
-}
-
-
-sub GetStreamFeature
-{
-    my $self = shift;
-    my $feature = shift;
-
-    return $self->{STREAM}->GetStreamFeature($self->GetStreamID(),$feature);
-}
-
-
-sub RestartStream
-{
-    my $self = shift;
-    my $timeout = shift;
-
-    $self->{SESSION} =
-        $self->{STREAM}->OpenStream($self->GetStreamID(),$timeout);
-    return $self->GetStreamID();
-}
-
-
-##############################################################################
-#
-# ConstXMLNS - Return the namespace from the constant string.
-#
-##############################################################################
-sub ConstXMLNS
-{
-    my $const = shift;
-    
-    return $XMLNS{$const};
-}
-
-
-1;
Index: rl/modules/Jabber/lib/Net/XMPP/Roster.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/Roster.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,856 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::XMPP::Roster;
-
-=head1 NAME
-
-Net::XMPP::Roster - XMPP Roster Object
-
-=head1 SYNOPSIS
-
-  Net::XMPP::Roster is a module that provides a developer an easy
-  interface to an XMPP roster.  It provides high level functions to
-  query, update, and manage a user's roster.  
-
-=head1 DESCRIPTION
-
-  The Roster object seeks to provide an easy to use API for interfacing
-  with a user's roster.  When you instantiate it, it automatically
-  registers with the connection to receivce the correct packets so
-  that it can track all roster updates, and presence packets.
-  
-=head2 Basic Functions
-
-  my $Client = Net::XMPP::Client->new(...);
-
-  my $Roster = Net::XMPP::Roster->new(connection=>$Client);
-    or
-  my $Roster = $Client->Roster();
-
-  $Roster->clear();
-
-  if ($Roster->exists('bob@jabber.org')) { ... }
-  if ($Roster->exists(Net::XMPP::JID)) { ... }
-
-  if ($Roster->groupExists("Friends")) { ... }
-
-  my @groups = $Roster->groups();
-
-  my @jids    = $Roster->jids();
-  my @friends = $Roster->jids("group","Friends");
-  my @unfiled = $Roster->jids("nogroup");
-
-  if ($Roster->online('bob@jabber.org')) { ... }
-  if ($Roster->online(Net::XMPP::JID)) { ... }
-
-  my %hash = $Roster->query('bob@jabber.org');
-  my %hash = $Roster->query(Net::XMPP::JID);
-
-  my $name = $Roster->query('bob@jabber.org',"name");
-  my $ask  = $Roster->query(Net::XMPP::JID,"ask");
-
-  my $resource = $Roster->resource('bob@jabber.org');
-  my $resource = $Roster->resource(Net::XMPP::JID);
-
-  my %hash = $Roster->resourceQuery('bob@jabber.org',"Home");
-  my %hash = $Roster->resourceQuery(Net::XMPP::JID,"Club");
-
-  my $show   = $Roster->resourceQuery('bob@jabber.org',"Home","show");
-  my $status = $Roster->resourceQuery(Net::XMPP::JID,"Work","status");
-
-  my @resource = $Roster->resources('bob@jabber.org');
-  my @resource = $Roster->resources(Net::XMPP::JID);
-
-  $Roster->resourceStore('bob@jabber.org',"Home","gpgkey",key);
-  $Roster->resourceStore(Net::XMPP::JID,"logged on","2004/04/07 ...");
-
-  $Roster->store('bob@jabber.org',"avatar",avatar);
-  $Roster->store(Net::XMPP::JID,"display_name","Bob");
-
-=head2 Advanced Functions
-
-  These functions are only needed if you want to manually control
-  the Roster.
-  
-  $Roster->add('bob@jabber.org',
-               name=>"Bob",
-               groups=>["Friends"]
-              );
-  $Roster->add(Net::XMPP::JID);
-
-  $Roster->addResource('bob@jabber.org',
-                       "Home",
-                       show=>"dnd",
-                       status=>"Working"
-                      );
-  $Roster->addResource(Net::XMPP::JID,"Work");
-
-  $Roster->remove('bob@jabber.org');
-  $Roster->remove(Net::XMPP::JID);
-
-  $Roster->removeResource('bob@jabber.org',"Home");
-  $Roster->removeResource(Net::XMPP::JID,"Work");
-
-  $Roster->handler(Net::XMPP::IQ);
-  $Roster->handler(Net::XMPP::Presence);
-
-=head1 METHODS
-
-=head2 Basic Functions
-
-
-  new(connection=>object) - This creates and initializes the Roster
-                            object.  The connection object is required
-                            so that the Roster can interact with the
-                            main connection object.  It needs to be an
-                            object that inherits from
-                            Net::XMPP::Connection.
-
-  clear() - removes everything from the database.
-
-  exists(jid) - return 1 if the JID exists in the database, undef
-                otherwise.  The jid can either be a string, or a
-                Net::XMPP::JID object.
-                
-  groupExists(group) - return 1 if the group exists in the database,
-                       undef otherwise.
-
-  groups() - returns a list of all of the roster groups.
-
-  jids([type,    - returns a list of all of the matching JIDs.  The valid
-       [group]])   types are:
-
-                    all     - return all JIDs in the roster. (default)
-                    nogroup - return all JIDs not in a roster group.
-                    group   - return all of the JIDs in the specified
-                              roster group.
-
-  online(jid) - return 1 if the JID is online, undef otherwise.  The
-                jid can either be a string, or a Net::XMPP::JID object.
-
-  query(jid,   - return a hash representing all of the data in the
-        [key])   DB for this JID.  The jid can either be a string,
-                 or a Net::XMPP::JID object.  If you specify a key,
-                 then only the value for that key is returned.
-
-  resource(jid) - return the string representing the resource with the
-                  highest priority for the JID.  The jid can either be
-                  a string, or a Net::XMPP::JID object.
-
-  resourceQuery(jid,      - return a hash representing all of the data
-                resource,   the DB for the resource for this JID.  The
-                [key])      jid can either be a string, or a
-                            Net::XMPP::JID object.  If you specify a
-                            key, then only the value for that key is
-                            returned.
-
-  resources(jid) - returns the list of resources for the JID in order
-                   of highest priority to lowest priority.  The jid can
-                   either be a string, or a Net::XMPP::JID object.
-
-  resourceStore(jid,      - store the specified value in the DB under
-                resource,   the specified key for the resource for this
-                key,        JID.  The jid can either be a string, or a
-                value)      Net::XMPP::JID object.
-
-  store(jid,      - store the specified value in the DB under the
-        key,        specified key for this JID.  The jid can either
-        value)      be a string, or a Net::XMPP::JID object.
-
-
-
-=head2 Advanced Functions
-
-add(jid,                 - Manually adds the JID to the Roster with the
-    ask=>string,           specified roster item settings.  This does not
-    groups=>arrayref       handle subscribing to other users, only
-    name=>string,          manipulating the Roster object.  The jid
-    subscription=>string)  can either be a string or a Net::XMPP::JID.
-
-addResource(jid,            - Manually add the resource to the JID in the
-            resource,         Roster with the specified presence settings.
-            priority=>int,    This does not handle subscribing to other
-            show=>string,     users, only manipulating the Roster object.
-            status=>string)   The jid can either be a string or a
-                              Net::XMPP::JID.
-
-remove(jid) - Removes all reference to the JID from the Roster object.
-              The jid can either be a string or a Net::XMPP::JID.
-
-removeResource(jid,      - Removes the resource from the jid in the
-               resource)   Roster object.  The jid can either be a string
-                           or a Net::XMPP::JID.
-
-handler(packet) - Take either a Net::XMPP::IQ or Net::XMPP::Presence
-                  packet and parse them according to the rules of the
-                  Roster object.  Note, that it will only waste CPU time
-                  if you pass in IQs or Presences that are not roster
-                  related.
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use Carp;
-
-sub new
-{
-    my $proto = shift;
-    my $self = { };
-
-    my %args;
-    while($#_ >= 0) { $args{ lc(pop(@_)) } = pop(@_); }
-
-    if (!exists($args{connection}) ||
-        !$args{connection}->isa("Net::XMPP::Connection"))
-    {
-        croak("You must pass Net::XMPP::Roster a valid connection object.");
-    }
-
-    $self->{CONNECTION} = $args{connection};
-    
-    bless($self, $proto);
-
-    $self->init();
-    
-    return $self;
-}
-
-
-##############################################################################
-#
-# init - initialize the module to use the roster database
-#
-##############################################################################
-sub init
-{
-    my $self = shift;
-
-    $self->{CONNECTION}-> SetXPathCallBacks('/iq[@type="result" or @type="set"]/query[@xmlns="jabber:iq:roster"]'=>sub{ $self->handler(@_) });
-    $self->{CONNECTION}-> SetXPathCallBacks('/presence'=>sub{ $self->handler(@_) });
-}
-
-
-##############################################################################
-#
-# add - adds the entry to the Roster DB.
-#
-##############################################################################
-sub add
-{
-    my $self = shift;
-    my ($jid,%item) = @_;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-    if (exists $self->{JIDS}->{$jid})
-    {
-        foreach my $key (keys %item)
-        {
-            $self->{JIDS}->{$jid}->{$key} = $item{$key};
-        }
-    }
-    else
-    {
-        $self->{JIDS}->{$jid} = \%item;
-    }
-
-    foreach my $group (keys %{ $self->{GROUPS} })
-    {
-        # Clear user from old groups.
-        delete $self->{GROUPS}->{$group}->{$jid};
-        # Clean up empty groups.
-        delete $self->{GROUPS}->{$group} unless scalar keys %{ $self->{GROUPS}->{$group} };
-    }
-
-    foreach my $group (@{$item{groups}})
-    {
-        $self->{GROUPS}->{$group}->{$jid} = 1;
-    }
-}
-
-
-
-##############################################################################
-#
-# addResource - adds the resource to the JID in the Roster DB.
-#
-##############################################################################
-sub addResource
-{
-    my $self = shift;
-    my $jid = shift;
-    my $resource = shift;
-    my (%item) = @_;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-
-    my $priority = $item{priority};
-    $priority = 0 unless defined($priority);
-
-    $self->{CONNECTION}->{DEBUG}->Log3("Roster::addResource: add $jid/$resource with priority $priority to the DB");
-
-    my $loc = -1;
-    $self->{JIDS}->{$jid}->{priorities}->{$priority} = []
-        unless exists($self->{JIDS}->{$jid}->{priorities}->{$priority});
-    foreach my $index (0..$#{$self->{JIDS}->{$jid}->{priorities}->{$priority}})
-    {
-        $loc = $index
-            if ($self->{JIDS}->{$jid}->{priorities}->{$priority}->[$index]->{resource} eq $resource);
-    }
-    $loc = $#{$self->{JIDS}->{$jid}->{priorities}->{$priority}} + 1 if ($loc == -1);
-
-    $self->{JIDS}->{$jid}->{resources}->{$resource}->{priority} = $priority;
-    $self->{JIDS}->{$jid}->{resources}->{$resource}->{status} = $item{status}
-        if exists($item{status});
-    $self->{JIDS}->{$jid}->{resources}->{$resource}->{show} = $item{show}
-        if exists($item{show});
-    $self->{JIDS}->{$jid}->{priorities}->{$priority}->[$loc]->{resource} = $resource;
-}
-
-
-###############################################################################
-#
-# clear - delete all of the JIDs from the DB completely.
-#
-###############################################################################
-sub clear
-{
-    my $self = shift;
-
-    $self->{CONNECTION}->{DEBUG}->Log3("Roster::clear: clearing the database");
-    foreach my $jid ($self->jids())
-    {
-        $self->remove($jid);
-    }
-    $self->{CONNECTION}->{DEBUG}->Log3("Roster::clear: database is empty");
-}
-
-
-##############################################################################
-#
-# exists - allows you to query if the JID exists in the Roster DB.
-#
-##############################################################################
-sub exists
-{
-    my $self = shift;
-    my ($jid) = @_;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-    
-    return unless exists($self->{JIDS});
-    return unless exists($self->{JIDS}->{$jid});
-    return 1;
-}
-
-
-sub fetch
-{
-    my $self = shift;
-
-    my %newroster = $self->{CONNECTION}->RosterGet();
-
-    $self->handleRoster(\%newroster);
-}
-
-
-##############################################################################
-#
-# groupExists - allows you to query if the group exists in the Roster
-#                       DB.
-#
-##############################################################################
-sub groupExists
-{
-    my $self = shift;
-    my ($group) = @_;
-
-    return unless exists($self->{GROUPS});
-    return unless exists($self->{GROUPS}->{$group});
-    return 1;
-}
-
-
-##############################################################################
-#
-# groups - returns a list of the current groups in your roster.
-#
-##############################################################################
-sub groups
-{
-    my $self = shift;
-
-    return () unless exists($self->{GROUPS});
-    return () if (scalar(keys(%{$self->{GROUPS}})) == 0);
-    return keys(%{$self->{GROUPS}});
-}
-
-
-##############################################################################
-#
-# handler - takes a packet and calls the correct handler.
-#
-##############################################################################
-sub handler
-{
-    my $self = shift;
-    my $sid = shift;
-    my $packet = shift;
-
-    $self->handleIQ($packet) if ($packet->GetTag() eq "iq");
-    $self->handlePresence($packet) if ($packet->GetTag() eq "presence");
-}
-
-
-##############################################################################
-#
-# handleIQ - takes an iq packet that contains roster, parses it, and puts
-#            the roster into the Roster DB.
-#
-##############################################################################
-sub handleIQ
-{
-    my $self = shift;
-    my $iq = shift;
-
-    my $type = $iq->GetType();
-    return unless (($type eq "set") || ($type eq "result"));
-
-    my %newroster = $self->{CONNECTION}->RosterParse($iq);
-
-    $self->handleRoster(\%newroster);
-}
-
-
-sub handleRoster
-{
-    my $self = shift;
-    my $roster = shift;
-
-    foreach my $jid (keys(%{$roster}))
-    {
-        if ($roster->{$jid}->{subscription} ne "remove")
-        {
-            $self->add($jid, %{$roster->{$jid}});
-        }
-        else
-        {
-            $self->remove($jid);
-        }
-    }
-}
-
-
-##############################################################################
-#
-# handlePresence - takes a presence packet and groks the presence.
-#
-##############################################################################
-sub handlePresence
-{
-    my $self = shift;
-    my $presence = shift;
-
-    my $type = $presence->GetType();
-    $type = "" unless defined($type);
-    return unless (($type eq "") ||
-                   ($type eq "available") ||
-                   ($type eq "unavailable"));
-
-    my $jid = $presence->GetFrom("jid");
-
-    my $resource = $jid->GetResource();
-    $resource = " " unless ($resource ne "");
-    
-    $jid = $jid->GetJID();
-    $jid = "" unless defined($jid);
-
-    return unless $self->exists($jid);
-    #XXX if it doesn't exist... is it us?
-    #XXX is this a presence based roster?
-
-    $self->{CONNECTION}->{DEBUG}->Log3("Roster::PresenceDBParse: fromJID(",$presence->GetFrom(),") resource($resource) type($type)");
-    $self->{CONNECTION}->{DEBUG}->Log4("Roster::PresenceDBParse: xml(",$presence->GetXML(),")");
-
-    $self->removeResource($jid,$resource);
-
-    if (($type eq "") || ($type eq "available"))
-    {
-        my %item;
-        
-        $item{priority} = $presence->GetPriority();
-        $item{priority} = 0 unless defined($item{priority});
-
-        $item{show} = $presence->GetShow();
-        $item{show} = "" unless defined($item{show});
-
-        $item{status} = $presence->GetStatus();
-        $item{status} = "" unless defined($item{status});
-
-        $self->addResource($jid,$resource,%item);
-    }
-}
-
-
-##############################################################################
-#
-# jids - returns a list of all of the JIDs in your roster.
-#
-##############################################################################
-sub jids
-{
-    my $self = shift;
-    my $type = shift;
-    my $group = shift;
-
-    $type = "all" unless defined($type);
-
-    my @jids;
-
-    if (($type eq "all") || ($type eq "nogroup"))
-    {
-        return () unless exists($self->{JIDS});
-        foreach my $jid (keys(%{$self->{JIDS}}))
-        {
-            next if (($type eq "nogroup") &&
-                     exists($self->{JIDS}->{$jid}->{groups}) &&
-                     ($#{$self->{JIDS}->{$jid}->{groups}} > -1));
-
-            push(@jids, Net::XMPP::JID->new($jid));
-        }
-    }
-    
-    if ($type eq "group")
-    {
-        return () unless exists($self->{GROUPS});
-        if (defined($group) && $self->groupExists($group))
-        {
-            foreach my $jid (keys(%{$self->{GROUPS}->{$group}}))
-            {
-                push(@jids, Net::XMPP::JID->new($jid));
-            }
-        }
-    }
-
-    return @jids;
-}
-
-
-###############################################################################
-#
-# online - returns if the jid is online or not.
-#
-###############################################################################
-sub online
-{
-    my $self = shift;
-    my $jid = shift;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-
-    return unless $self->exists($jid);
-
-    my @resources = $self->resources($jid);
-
-    return ($#resources > -1);
-}
-
-
-##############################################################################
-#
-# priority - return the highest priority for the jid, or for the specified
-#            resource.
-#
-##############################################################################
-sub priority
-{
-    my $self = shift;
-    my $jid = shift;
-    my $resource = shift;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-    
-    if (defined($resource))
-    {
-        return unless $self->resourceExists($jid,$resource);
-        return unless exists($self->{JIDS}->{$jid}->{resources}->{$resource}->{priority});
-        return $self->{JIDS}->{$jid}->{resources}->{$resource}->{priority};
-    }
-    
-    return unless exists($self->{JIDS}->{$jid}->{priorities});
-    my @priorities = sort{ $b <=> $a } keys(%{$self->{JIDS}->{$jid}->{priorities}});
-    return $priorities[0];
-}
-
-
-##############################################################################
-#
-# query - allows you to get one of the pieces of info from the Roster DB.
-#
-##############################################################################
-sub query
-{
-    my $self = shift;
-    my $jid = shift;
-    my $key = shift;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-    
-    return unless $self->exists($jid);
-    if (defined($key))
-    {
-        return unless exists($self->{JIDS}->{$jid}->{$key});
-        return $self->{JIDS}->{$jid}->{$key};
-    }
-    return %{$self->{JIDS}->{$jid}};
-}
-
-
-##############################################################################
-#
-# remove - removes the JID from the Roster DB.
-#
-##############################################################################
-sub remove
-{
-    my $self = shift;
-    my $jid = shift;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-
-    if ($self->exists($jid))
-    {
-        $self->{CONNECTION}->{DEBUG}->Log3("Roster::remove: deleting $jid from the DB");
-        
-        if (defined($self->query($jid,"groups")))
-        {
-            foreach my $group (@{$self->query($jid,"groups")})
-            {
-                delete($self->{GROUPS}->{$group}->{$jid});
-                delete($self->{GROUPS}->{$group})
-                    if (scalar(keys(%{$self->{GROUPS}->{$group}})) == 0);
-                delete($self->{GROUPS})
-                    if (scalar(keys(%{$self->{GROUPS}})) == 0);
-            }
-        }
-    
-        delete($self->{JIDS}->{$jid});
-        delete($self->{JIDS}) if (scalar(keys(%{$self->{JIDS}})) == 0);
-    }
-}
-
-
-##############################################################################
-#
-# removeResource - removes the resource from the JID from the Roster DB.
-#
-##############################################################################
-sub removeResource
-{
-    my $self = shift;
-    my $jid = shift;
-    my $resource = shift;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-
-    if ($self->resourceExists($jid,$resource))
-    {
-        $self->{CONNECTION}->{DEBUG}->Log3("Roster::removeResource: remove $jid/$resource from the DB");
-
-        my $oldPriority = $self->priority($jid,$resource);
-        $oldPriority = "" unless defined($oldPriority);
-
-        if (exists($self->{JIDS}->{$jid}->{priorities}->{$oldPriority}))
-        {
-            my $loc = 0;
-            foreach my $index (0..$#{$self->{JIDS}->{$jid}->{priorities}->{$oldPriority}})
-            {
-                $loc = $index
-                    if ($self->{JIDS}->{$jid}->{priorities}->{$oldPriority}->[$index]->{resource} eq $resource);
-            }
-            
-            splice(@{$self->{JIDS}->{$jid}->{priorities}->{$oldPriority}},$loc,1);
-
-            delete($self->{JIDS}->{$jid}->{priorities}->{$oldPriority})
-                if (exists($self->{JIDS}->{$jid}->{priorities}->{$oldPriority}) &&
-                    ($#{$self->{JIDS}->{$jid}->{priorities}->{$oldPriority}} == -1));
-        }
-
-        delete($self->{JIDS}->{$jid}->{resources}->{$resource});
-
-    }
-}
-
-
-###############################################################################
-#
-# resource - retrieve the resource with the highest priority.
-#
-###############################################################################
-sub resource
-{
-    my $self = shift;
-    my $jid = shift;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-
-    return unless $self->exists($jid);
-
-    my $priority = $self->priority($jid);
-
-    return unless defined($priority);
-
-    return $self->{JIDS}->{$jid}->{priorities}->{$priority}->[0]->{resource};
-}
-
-
-##############################################################################
-#
-# resourceExists - check that the specified resource exists.
-#
-##############################################################################
-sub resourceExists
-{
-    my $self = shift;
-    my $jid = shift;
-    my $resource = shift;
-    
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-
-    return unless $self->exists($jid);
-    return unless exists($self->{JIDS}->{$jid}->{resources});
-    return unless exists($self->{JIDS}->{$jid}->{resources}->{$resource});
-}
-
-
-##############################################################################
-#
-# resourceQuery - allows you to get one of the pieces of info from the Roster
-#                 DB.
-#
-##############################################################################
-sub resourceQuery
-{
-    my $self = shift;
-    my $jid = shift;
-    my $resource = shift;
-    my $key = shift;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-    
-    return unless $self->resourceExists($jid,$resource);
-    if (defined($key))
-    {
-        return unless exists($self->{JIDS}->{$jid}->{resources}->{$resource}->{$key});
-        return $self->{JIDS}->{$jid}->{resources}->{$resource}->{$key};
-    }
-    return %{$self->{JIDS}->{$jid}->{resources}->{$resource};}
-}
-
-
-###############################################################################
-#
-# resources - returns a list of the resources from highest priority to lowest.
-#
-###############################################################################
-sub resources
-{
-    my $self = shift;
-    my $jid = shift;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-
-    return () unless $self->exists($jid);
-
-    my @resources;
-
-    foreach my $priority (sort {$b cmp $a} keys(%{$self->{JIDS}->{$jid}->{priorities}}))
-    {
-        foreach my $index (0..$#{$self->{JIDS}->{$jid}->{priorities}->{$priority}})
-        {
-            next if ($self->{JIDS}->{$jid}->{priorities}->{$priority}->[$index]->{resource} eq " ");
-            push(@resources,$self->{JIDS}->{$jid}->{priorities}->{$priority}->[$index]->{resource});
-        }
-    }
-    return @resources;
-}
-
-
-##############################################################################
-#
-# resourceStore - allows you to store anything on the item that you want to.
-#                 The only drawback is that when the item is removed, the data
-#                 is not kept.  You must restore it in the DB.
-#
-##############################################################################
-sub resourceStore
-{
-    my $self = shift;
-    my $jid = shift;
-    my $resource = shift;
-    my $key = shift;
-    my $value = shift;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-
-    return unless defined($key);
-    return unless defined($value);
-    return unless $self->resourceExists($jid,$resource);
-
-    $self->{JIDS}->{$jid}->{resources}->{$resource}->{$key} = $value;
-}
-
-
-##############################################################################
-#
-# store - allows you to store anything on the item that you want to.  The
-#         only drawback is that when the item is removed, the data is not
-#         kept.  You must restore it in the DB.
-#
-##############################################################################
-sub store
-{
-    my $self = shift;
-    my $jid = shift;
-    my $key = shift;
-    my $value = shift;
-
-    $jid = $jid->GetJID() if UNIVERSAL::isa($jid,"Net::XMPP::JID");
-
-    return unless defined($key);
-    return unless defined($value);
-    return unless $self->exists($jid);
-
-    $self->{JIDS}->{$jid}->{$key} = $value;
-}
-
-
-1;
-
Index: rl/modules/Jabber/lib/Net/XMPP/Stanza.pm
===================================================================
--- perl/modules/Jabber/lib/Net/XMPP/Stanza.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,1444 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package Net::XMPP::Stanza;
-
-=head1 NAME
-
-Net::XMPP::Stanza - XMPP Stanza Module
-
-=head1 SYNOPSIS
-
-  Net::XMPP::Stanza is a private package that serves as a basis for all
-  XMPP stanzas generated by Net::XMPP.
-
-=head1 DESCRIPTION
-
-  This module is not meant to be used directly.  You should be using
-  either Net::XMPP::IQ, Net::XMPP::Message, Net::XMPP::Presence, or
-  another package that inherits from Net::XMPP::Stanza.
-
-  That said, this is where all of the namespaced methods are documented.
-
-  The current supported namespaces are:
-
-=cut
-
-# NS_BEGIN
-
-=pod
-
-    jabber:iq:auth
-    jabber:iq:privacy
-    jabber:iq:register
-    jabber:iq:roster
-    urn:ietf:params:xml:ns:xmpp-bind
-    urn:ietf:params:xml:ns:xmpp-session
-
-=cut
-
-# NS_END
-
-=pod
-    
-  For more information on what these namespaces are for, visit 
-  http://www.jabber.org and browse the Jabber Programmers Guide.
-
-  The following tables can be read as follows:
-
-  ny:private:ns
-  
-  Name                        Type     Get  Set  Remove  Defined  Add
-  ==========================  =======  ===  ===  ======  =======  ===
-  Foo                         scalar    X    X     X        X
-  Bar                         child                                X 
-  Bars                        child     X
-  Test                        master    X    X
-
-  Withing the my:private:ns namespace, there exists the functions:
-
-    GetFoo(), SetFoo(), RemoveFoo(), DefinedFoo()
-    
-    AddBar()
-    
-    GetBars(), DefinedBars()
-    
-    GetTest(), SetMaster()
-
-  Hopefully it should be obvious how this all works.  If not feel free to
-  contact me and I'll work on adding more documentation.
-
-=cut
-
-# DOC_BEGIN
-=head1 jabber:iq:auth
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Digest                      scalar      X    X     X        X        
-  Hash                        scalar      X    X     X        X        
-  Password                    scalar      X    X     X        X        
-  Resource                    scalar      X    X     X        X        
-  Sequence                    scalar      X    X     X        X        
-  Token                       scalar      X    X     X        X        
-  Username                    scalar      X    X     X        X        
-  Auth                        master      X    X                       
-
-=head1 jabber:iq:privacy
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Active                      scalar      X    X     X        X        
-  Default                     scalar      X    X     X        X        
-  List                        child                                  X 
-  Lists                       child       X          X        X        
-  Privacy                     master      X    X                       
-
-=head1 jabber:iq:privacy - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Action                      scalar      X    X     X        X        
-  IQ                          flag        X    X     X        X        
-  Message                     flag        X    X     X        X        
-  Order                       scalar      X    X     X        X        
-  PresenceIn                  flag        X    X     X        X        
-  PresenceOut                 flag        X    X     X        X        
-  Type                        scalar      X    X     X        X        
-  Value                       scalar      X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 jabber:iq:privacy - list objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Name                        scalar      X    X     X        X        
-  Item                        child                                  X 
-  Items                       child       X          X        X        
-  List                        master      X    X                       
-
-=head1 jabber:iq:register
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Address                     scalar      X    X     X        X        
-  City                        scalar      X    X     X        X        
-  Date                        scalar      X    X     X        X        
-  Email                       scalar      X    X     X        X        
-  First                       scalar      X    X     X        X        
-  Instructions                scalar      X    X     X        X        
-  Key                         scalar      X    X     X        X        
-  Last                        scalar      X    X     X        X        
-  Misc                        scalar      X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Nick                        scalar      X    X     X        X        
-  Password                    scalar      X    X     X        X        
-  Phone                       scalar      X    X     X        X        
-  Registered                  flag        X    X     X        X        
-  Remove                      flag        X    X     X        X        
-  State                       scalar      X    X     X        X        
-  Text                        scalar      X    X     X        X        
-  URL                         scalar      X    X     X        X        
-  Username                    scalar      X    X     X        X        
-  Zip                         scalar      X    X     X        X        
-  Register                    master      X    X                       
-
-=head1 jabber:iq:roster
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Item                        child                                  X 
-  Items                       child       X                            
-  Roster                      master      X    X                       
-
-=head1 jabber:iq:roster - item objects
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Ask                         scalar      X    X     X        X        
-  Group                       array       X    X     X        X        
-  JID                         jid         X    X     X        X        
-  Name                        scalar      X    X     X        X        
-  Subscription                scalar      X    X     X        X        
-  Item                        master      X    X                       
-
-=head1 urn:ietf:params:xml:ns:xmpp-bind
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  JID                         jid         X    X     X        X        
-  Resource                    scalar      X    X     X        X        
-  Bind                        master      X    X                       
-
-=head1 urn:ietf:params:xml:ns:xmpp-session
-
-  Name                        Type       Get  Set  Remove  Defined  Add
-  ==========================  =========  ===  ===  ======  =======  ===
-  Session                     master      X    X                       
-
-
-=cut
-
-# DOC_END
-
-=head1 AUTHOR
-
-Ryan Eatmon
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use Carp;
-use Net::XMPP::Namespaces;
-use vars qw( $AUTOLOAD %FUNCTIONS $DEBUG );
-
-$DEBUG = Net::XMPP::Debug->new(usedefault=>1,
-                               header=>"XMPP");
-
-# XXX need to look at evals and $@
-
-sub new
-{
-    my $proto = shift;
-    my $class = ref($proto) || $proto;
-    my $self = { };
-
-    bless($self, $proto);
-
-    $self->{DEBUGHEADER} = "Stanza";
-    $self->{TAG} = "__netxmpp__:unknown:tag";
-
-    $self->{FUNCS} = \%FUNCTIONS;
-    
-    my $result = $self->_init(@_);
-
-    return $result if defined($result);
-    
-    return $self;
-}
-
-
-sub _init
-{
-    my $self = shift;
-
-    $self->{CHILDREN} = [];
-
-    if ("@_" ne (""))
-    {
-        if ($_[0]->isa("Net::XMPP::Stanza"))
-        {
-            return $_[0];
-        }
-        elsif (ref($_[0]) eq "")
-        {
-            $self->{TAG} = shift;
-            $self->{TREE} = new XML::Stream::Node($self->{TAG});
-        }
-        else
-        {
-            $self->{TREE} = shift;
-            $self->{TAG} = $self->{TREE}->get_tag();
-            $self->_parse_xmlns();
-            $self->_parse_tree();
-        }
-    }
-    else
-    {
-        $self->{TREE} = new XML::Stream::Node($self->{TAG});
-    }
-
-    return;
-}
-
-
-$FUNCTIONS{XMLNS}->{path} = '@xmlns';
-
-$FUNCTIONS{Child}->{type} = 'child';
-$FUNCTIONS{Child}->{path} = '*[@xmlns]';
-$FUNCTIONS{Child}->{child} = {};
-
-##############################################################################
-#
-# debug - prints out the XML::Parser Tree in a readable format for debugging
-#
-##############################################################################
-sub debug
-{
-    my $self = shift;
-
-    print "debug ",$self,":\n";
-    &Net::XMPP::printData("debug: \$self->{CHILDREN}->",$self->{CHILDREN});
-}
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Public Methods
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# GetXML - Returns a string that represents the packet.
-#
-##############################################################################
-sub GetXML 
-{
-    my $self = shift;
-    return $self->GetTree()->GetXML();
-}
-
-
-##############################################################################
-#
-# GetTag - Returns the root tag of the object.
-#
-##############################################################################
-sub GetTag
-{
-    my $self = shift;
-    
-    return $self->{TAG};
-}
-
-
-##############################################################################
-#
-# GetTree - Returns an XML::Stream::Node that contains the full tree including
-#           Query, and X children.
-#
-##############################################################################
-sub GetTree
-{
-    my $self = shift;
-    my $keepXMLNS = shift;
-    $keepXMLNS = 0 unless defined($keepXMLNS);
-
-    my $node = $self->{TREE}->copy();
-
-    $node->remove_attrib("xmlns")
-        if (exists($self->{SKIPXMLNS}) && ($keepXMLNS == 0));
-    
-    foreach my $child (@{$self->{CHILDREN}})
-    {
-        my $child_tree = $child->GetTree($keepXMLNS);
-        $node->add_child($child_tree);
-    }
-
-    my $remove_ns = 0;
-    if (defined($node->get_attrib("xmlns")) && ($keepXMLNS == 0))
-    {
-        $remove_ns = 1
-            if ($self->_check_skip_xmlns($node->get_attrib("xmlns")));
-    }
-
-    $node->remove_attrib("xmlns") if ($remove_ns == 1);
-
-    $node->add_raw_xml(@{$self->{RAWXML}})
-        if (exists($self->{RAWXML}) && ($#{$self->{RAWXML}} > -1));
-
-    return $node;
-} 
-
-
-##############################################################################
-#
-# NewChild - calls AddChild to create a new Net::XMPP::Stanza object, sets the
-#            xmlns and returns a pointer to the new object.
-#
-##############################################################################
-sub NewChild
-{
-    my $self = shift;
-    my $xmlns = shift;
-    my $tag = shift;
-    
-    return unless exists($Net::XMPP::Namespaces::NS{$xmlns});
-
-    if (!defined($tag))
-    {
-        $tag = "x";
-        $tag = $Net::XMPP::Namespaces::NS{$xmlns}->{tag}
-            if exists($Net::XMPP::Namespaces::NS{$xmlns});
-    }
-    
-    my $node = new XML::Stream::Node($tag);
-    $node->put_attrib(xmlns=>$xmlns);
-
-    return $self->AddChild($node);
-}
-
-
-##############################################################################
-#
-# AddChild - creates a new Net::XMPP::packet object, pushes it on the child
-#            list, and returns a pointer to the new object.  This is a
-#            private helper function.
-#
-##############################################################################
-sub AddChild
-{
-    my $self = shift;
-    my $node = shift;
-    my $packet = $self->_new_packet($node);
-    push(@{$self->{CHILDREN}},$packet);
-    return $packet;
-}
-
-
-##############################################################################
-#
-# RemoveChild - removes all xtags that have the specified namespace.
-#
-##############################################################################
-sub RemoveChild
-{
-    my $self = shift;
-    my $xmlns = shift;
-
-    foreach my $index (reverse(0..$#{$self->{CHILDREN}}))
-    {
-        splice(@{$self->{CHILDREN}},$index,1)
-            if (!defined($xmlns) ||
-                ($xmlns eq "") ||
-                ($self->{CHILDREN}->[$index]->GetXMLNS() eq $xmlns));
-    }
-}
-
-
-##############################################################################
-#
-# NewFirstChild - calls AddFirstChild to create a new Net::XMPP::Stanza
-#                 object, sets the xmlns and returns a pointer to the new
-#                 object.
-#
-##############################################################################
-sub NewFirstChild
-{
-    my $self = shift;
-    my $xmlns = shift;
-    my $tag = shift;
-    
-    return unless exists($Net::XMPP::Namespaces::NS{$xmlns});
-
-    if (!defined($tag))
-    {
-        $tag = "x";
-        $tag = $Net::XMPP::Namespaces::NS{$xmlns}->{tag}
-            if exists($Net::XMPP::Namespaces::NS{$xmlns});
-    }
-    
-    my $node = new XML::Stream::Node($tag);
-    $node->put_attrib(xmlns=>$xmlns);
-
-    return $self->AddFirstChild($node);
-}
-
-
-##############################################################################
-#
-# AddFirstChild - creates a new Net::XMPP::packet object, puts it on the child
-#                 list in the front, and returns a pointer to the new object.
-#                 This is a private helper function.
-#
-##############################################################################
-sub AddFirstChild
-{
-    my $self = shift;
-    my $node = shift;
-    my $packet = $self->_new_packet($node);
-    unshift(@{$self->{CHILDREN}},$packet);
-    return $packet;
-}
-
-
-##############################################################################
-#
-# RemoveFirstChild - removes all xtags that have the specified namespace.
-#
-##############################################################################
-sub RemoveFirstChild
-{
-    my $self = shift;
-
-    shift(@{$self->{CHILDREN}});
-}
-
-
-##############################################################################
-#
-# InsertRawXML - puts the specified string onto the list for raw XML to be
-#                included in the packet.
-#
-##############################################################################
-sub InsertRawXML
-{
-    my $self = shift;
-    my(@rawxml) = @_;
-    if (!exists($self->{RAWXML}))
-    {
-        $self->{RAWXML} = [];
-    }
-    push(@{$self->{RAWXML}},@rawxml);
-}
-
-
-##############################################################################
-#
-# ClearRawXML - removes all raw XML from the packet.
-#
-##############################################################################
-sub ClearRawXML
-{
-    my $self = shift;
-    $self->{RAWXML} = [];
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| AutoLoad methods
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# AutoLoad - This function is a central location for handling all of the
-#            AUTOLOADS for all of the sub modules.
-#
-##############################################################################
-sub AUTOLOAD
-{
-    my $self = shift;
-    return if ($AUTOLOAD =~ /::DESTROY$/);
-    my ($package) = ($AUTOLOAD =~ /^(.*)::/);
-    $AUTOLOAD =~ s/^.*:://;
-    my ($call,$var) = ($AUTOLOAD =~ /^(Add|Get|Set|Remove|Defined)(.*)$/);
-    $call = "" unless defined($call);
-    $var = "" unless defined($var);
-
-    #$self->_debug("AUTOLOAD: self($self) AUTOLOAD($AUTOLOAD) package($package)");
-    #$self->_debug("AUTOLOAD: tag($self->{TAG}) call($call) var($var) args(",join(",",@_),")");
-
-    #-------------------------------------------------------------------------
-    # Pick off calls for top level tags <message/>, <presence/>, and <iq/>
-    #-------------------------------------------------------------------------
-    my @xmlns = $self->{TREE}->XPath('@xmlns');
-    my $XPathArgs = $self->_xpath_AUTOLOAD($package,$call,$var,$xmlns[0]);
-    return $self->_xpath($call,@{$XPathArgs},@_) if defined($XPathArgs);
-
-    #-------------------------------------------------------------------------
-    # We don't know what this function is... Hand it off to Missing Persons...
-    #-------------------------------------------------------------------------
-    $self->_missing_function($AUTOLOAD);
-}
-
-
-##############################################################################
-#
-# _xpath_AUTOLOAD - This function is a helper function for the main AutoLoad
-#                   function to help cut down on repeating code.
-#
-##############################################################################
-sub _xpath_AUTOLOAD
-{
-    my $self = shift;
-    my $package = shift;
-    my $call = shift;
-    my $var = shift;
-    my $xmlns = shift;
-
-    #$self->_debug("_xpath_AUTOLOAD: self($self) package($package) call($call) var($var)");
-    #$self->_debug("_xpath_AUTOLOAD: xmlns($xmlns)") if defined($xmlns);
-
-    #-------------------------------------------------------------------------
-    # First thing, figure out which group of functions we are going to be
-    # working with.  FUNCTIONS, or NS{$xmlns}->{xpath}...
-    #-------------------------------------------------------------------------
-    my $funcs = $self->_xpath_funcs($package,$call,$var,$xmlns);
-    return unless defined($funcs);
-
-    my @setFuncs = grep { $_ ne $var } keys(%{$funcs});
-
-    #$self->_debug("_xpath_AUTOLOAD: setFuncs(",join(",",@setFuncs),")");
-                
-    
-    my $type = (exists($funcs->{$var}->{type}) ?
-                $funcs->{$var}->{type} :
-                "scalar"
-               );
-
-    my $path = (exists($funcs->{$var}->{path}) ?
-                $funcs->{$var}->{path} :
-                ""
-               );
-
-    $path = "*" if ($type eq "raw");
-
-    my $child = "";
-    
-    #-------------------------------------------------------------------------
-    # When this is a master function... change the above variables...
-    #-------------------------------------------------------------------------
-    if(($type eq "master") ||
-       ((ref($type) eq "ARRAY") && ($type->[0] eq "master")))
-    {
-        if ($call eq "Get")
-        {
-            my @newSetFuncs;
-            foreach my $func (@setFuncs)
-            {
-                my $funcType = ( exists($funcs->{$func}->{type}) ?
-                                 $funcs->{$func}->{type} :
-                                 undef
-                               );
-
-                push(@newSetFuncs,$func)
-                    if (!defined($funcType) || ($funcType eq "scalar") ||
-                        ($funcType eq "jid") || ($funcType eq "array") ||
-                        ($funcType eq "flag") || ($funcType eq "timestamp") ||
-                        (ref($funcType) eq "ARRAY"));
-            }
-                
-            $child = \@newSetFuncs;
-        }
-        else
-        {
-            $child = \@setFuncs;
-        }
-    }
-    #-------------------------------------------------------------------------
-    # When this is a child based function... change the above variables...
-    #-------------------------------------------------------------------------
-    elsif (exists($funcs->{$var}->{child}))
-    {
-        $child = $funcs->{$var}->{child};
-                
-        #$self->_debug("_xpath_AUTOLOAD: child($child)");
-                
-        if (exists($child->{ns}))
-        {
-            my $addXMLNS = $child->{ns};
-                
-            my $addFuncs = $Net::XMPP::Namespaces::NS{$addXMLNS}->{xpath};
-            my @calls =
-                grep
-                {
-                    exists($addFuncs->{$_}->{type}) &&
-                    ($addFuncs->{$_}->{type} eq "master")
-                }
-                keys(%{$addFuncs});
-
-            if ($#calls > 0)
-            {
-                print STDERR "Warning: I cannot serve two masters.\n";
-            }
-            $child->{master} = $calls[0];
-        }
-    }
-
-    #-------------------------------------------------------------------------
-    # Return the arguments for the xpath function
-    #-------------------------------------------------------------------------
-    #$self->_debug("_xpath_AUTOLOAD: return($type,$path,$child);");
-    return [$type,$path,$child];
-}
-
-
-##############################################################################
-#
-# _xpath_funcs - Return the list of functions either from the FUNCTIONS hash
-#                or from Net::XMPP::Namespaces::NS.
-#
-##############################################################################
-sub _xpath_funcs
-{
-    my $self = shift;
-    my $package = shift;
-    my $call = shift;
-    my $var = shift;
-    my $xmlns = shift;
-
-    my $funcs;
-    
-    my $coreFuncs = $self->{FUNCS};
-    #eval "\$coreFuncs = \\%".$package."::FUNCTIONS";
-    $coreFuncs = {} unless defined($coreFuncs);
-
-    my $nsFuncs = {};
-    $nsFuncs = $Net::XMPP::Namespaces::NS{$xmlns}->{xpath}
-        if (defined($xmlns) && exists($Net::XMPP::Namespaces::NS{$xmlns}));
-
-    foreach my $set ($coreFuncs,$nsFuncs)
-    {
-        if (exists($set->{$var}))
-        {
-            my $type = (exists($set->{$var}->{type}) ?
-                        $set->{$var}->{type} :
-                        "scalar"
-                       );
-
-            my @calls = ('Get','Set','Defined','Remove');
-            @calls = ('Get','Set') if ($type eq "master");
-            @calls = ('Get','Defined','Remove') if ($type eq "child");
-            @calls = @{$set->{$var}->{calls}}
-                if exists($set->{$var}->{calls});
-
-            foreach my $callName (@calls)
-            {
-                if ($callName eq $call)
-                {
-                    $funcs = $set;
-                    last;
-                }
-            }
-        }
-    }
-
-    #-------------------------------------------------------------------------
-    # If we didn't find any functions to return,  Return failure.
-    #-------------------------------------------------------------------------
-    if (!defined($funcs))
-    {
-        #$self->_debug("_xpath_AUTOLOAD: no funcs found");
-        return;
-    }
-
-    return $funcs;
-}
-
-
-##############################################################################
-#
-# _xpath - given a type it calls the appropriate _xpath_* function below
-#
-##############################################################################
-sub _xpath
-{
-    my $self = shift;
-    my $call = shift;
-
-    #$self->_debug("_xpath: call($call) args(",join(",",@_),")");
-    
-    if ($call eq "Get")        { return $self->_xpath_get(@_)    ; }
-    elsif ($call eq "Set")     { return $self->_xpath_set(@_);     }
-    elsif ($call eq "Defined") { return $self->_xpath_defined(@_); }
-    elsif ($call eq "Add")     { return $self->_xpath_add(@_);     }
-    elsif ($call eq "Remove")  { return $self->_xpath_remove(@_);  }
-}
-
-
-##############################################################################
-#
-# _xpath_get - returns the value stored in the node 
-#
-##############################################################################
-sub _xpath_get
-{
-    my $self = shift;
-    my $type = shift;
-    my $xpath = shift;
-    my $childtype = shift;
-    my ($arg0) = shift;
-    
-    #$self->_debug("_xpath_get: self($self) type($type) xpath($xpath) childtype($childtype)");
-    #$self->{TREE}->debug();
-
-    my $subType;
-    ($type,$subType) = $self->_xpath_resolve_types($type);
-    
-
-    #-------------------------------------------------------------------------
-    # type == master
-    #-------------------------------------------------------------------------
-    if ($type eq "master")
-    {
-        my %fields;
-        
-        foreach my $func (sort {$a cmp $b} @{$childtype})
-        {
-            my $defined;
-            eval "\$defined = \$self->Defined$func();";
-            if ($defined)
-            {
-                my @values;
-                eval "\@values = \$self->Get$func();";
-
-                if ($#values > 0)
-                {
-                    $fields{lc($func)} = \@values;
-                }
-                else
-                {
-                    $fields{lc($func)} = $values[0];
-                }
-            }
-        }
-
-        return %fields;
-    }
-    
-    #-------------------------------------------------------------------------
-    # type == node
-    #-------------------------------------------------------------------------
-    # XXX Remove this if there are no problems
-    #if ($type eq "node")
-    #{ 
-        #$self->_debug("_xpath_get: node: xmlns($arg0)") if defined($arg0);
-
-        #my @results;
-        #foreach my $child (@{$self->{CHILDREN}})
-        #{
-            #$self->_debug("_xpath_get: node: child($child)");
-            #$self->_debug("_xpath_get: node: childXML(",$child->GetXML(),")");
-
-            #push(@results,$child)
-            #     if (!defined($arg0) ||
-            #         ($arg0 eq "") || 
-            #         ($child->GetTree(1)->get_attrib("xmlns") eq $arg0));
-            #}
-
-            #return $results[$childtype->{child_index}] if exists($childtype->{child_index});
-            #return @results if (wantarray);
-            #return $results[0];
-            #}
-
-    #-------------------------------------------------------------------------
-    # The rest actually call the XPath, so call it.
-    #-------------------------------------------------------------------------
-    my @nodes = $self->{TREE}->XPath($xpath);
-
-    #-------------------------------------------------------------------------
-    # type == scalar or timestamp
-    #-------------------------------------------------------------------------
-    if (($type eq "scalar") || ($type eq "timestamp"))
-    {
-        return "" if ($#nodes == -1);
-        return $nodes[0];
-    }
-
-    #-------------------------------------------------------------------------
-    # type == jid
-    #-------------------------------------------------------------------------
-    if ($type eq "jid")
-    {
-        return if ($#nodes == -1);
-        return $self->_new_jid($nodes[0])
-            if (defined($arg0) && ($arg0 eq "jid"));
-        return $nodes[0];
-    }
-
-    #-------------------------------------------------------------------------
-    # type == flag
-    #-------------------------------------------------------------------------
-    if ($type eq "flag")
-    {
-        return $#nodes > -1;
-    }
-    
-    #-------------------------------------------------------------------------
-    # type == array
-    #-------------------------------------------------------------------------
-    if ($type eq "array")
-    {
-        return @nodes if (wantarray);
-        return $nodes[0];
-    }
-    
-    #-------------------------------------------------------------------------
-    # type == raw
-    #-------------------------------------------------------------------------
-    if ($type eq "raw")
-    {
-        my $rawXML = "";
-
-        return join("",@{$self->{RAWXML}}) if ($#{$self->{RAWXML}} > -1);
-        
-        foreach my $node (@nodes)
-        {
-            $rawXML .= $node->GetXML();
-        }
-
-        return $rawXML;
-    }
-
-    #-------------------------------------------------------------------------
-    # type == child
-    #-------------------------------------------------------------------------
-    if (($type eq "child") || ($type eq "children") || ($type eq "node"))
-    {
-        my $xmlns = $arg0;
-        $xmlns = $childtype->{ns} if exists($childtype->{ns});
-
-        #$self->_debug("_xpath_get: children: xmlns($xmlns)");
-
-        my @results;
-        foreach my $child (@{$self->{CHILDREN}})
-        {
-            push(@results, $child)
-                if (!defined($xmlns) ||
-                    ($xmlns eq "") ||
-                    ($child->GetTree(1)->get_attrib("xmlns") eq $xmlns));
-        }
-
-        foreach my $node (@nodes)
-        {
-            $node->put_attrib(xmlns=>$xmlns)
-                unless defined($node->get_attrib("xmlns"));
-            my $result = $self->AddChild($node);
-            $self->{TREE}->remove_child($node);
-            push(@results,$result)
-                if (!defined($xmlns) ||
-                    ($xmlns eq "") ||
-                    ($node->get_attrib("xmlns") eq $xmlns));
-        }
-
-        #$self->_debug("_xpath_get: children: ",join(",",@results));
-        return $results[$childtype->{child_index}] if exists($childtype->{child_index});
-        return @results if (wantarray);
-        return $results[0];
-    }
-}
-
-
-##############################################################################
-#
-# _xpath_set - makes the XML tree such that the value was set.
-#
-##############################################################################
-sub _xpath_set
-{
-    my $self = shift;
-    my $type = shift;
-    my $xpath = shift;
-    my $childtype = shift;
-
-    #$self->_debug("_xpath_set: self($self) type($type) xpath($xpath) childtype($childtype)");
-
-    my $subType;
-    ($type,$subType) = $self->_xpath_resolve_types($type);
-
-    my $node = $self->{TREE};
-
-    #$self->_debug("_xpath_set: node($node)");
-
-    #-------------------------------------------------------------------------
-    # When the type is master, the rest of the args are in hash form
-    #-------------------------------------------------------------------------
-    if ($type eq "master")
-    {
-        #$self->_debug("_xpath_set: master: funcs(",join(",",@{$childtype}),")");
-        my %args;
-        while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-        #$self->_debug("_xpath_set: args(",%args,")");
-        foreach my $func (sort {$a cmp $b} @{$childtype})
-        {
-            #$self->_debug("_xpath_set: func($func)");
-            if (exists($args{lc($func)}))
-            {
-                #$self->_debug("_xpath_set: \$self->Set$func(\$args{lc(\$func)});");
-                eval "\$self->Set$func(\$args{lc(\$func)});";
-            }
-            elsif ($subType eq "all")
-            {
-                #$self->_debug("_xpath_set: \$self->Set$func();");
-                eval "\$self->Set$func();";
-            }
-        }
-        return;
-    }
-
-    #-------------------------------------------------------------------------
-    # When the type is not master, there can be only one argument.
-    #-------------------------------------------------------------------------
-    my $value = shift;
-
-    if ($type eq "raw")
-    {
-        $self->ClearRawXML();
-        $self->InsertRawXML($value);
-        return;
-    }
-
-    #-------------------------------------------------------------------------
-    # Hook to support special cases.  You can register the specials with
-    # the module and they will ba called based on match.
-    #-------------------------------------------------------------------------
-    if (($subType ne "") && exists($self->{CUSTOMSET}->{$subType}))
-    {
-        #$self->_debug("_xpath_set: custom: subType($subType)");
-        #$self->_debug("_xpath_set: custom: value($value)") if defined($value);
-        $value = &{$self->{CUSTOMSET}->{$subType}}($self,$value);
-    }
-
-    if ($type eq "timestamp")
-    {
-        $value = "" unless defined($value);
-        if ($value eq "") {
-            $value = &Net::XMPP::GetTimeStamp("utc","","stamp");
-        }
-    }
-
-    #$self->_debug("_xpath_set: value($value)") unless !defined($value);
-
-    #-------------------------------------------------------------------------
-    # Now that we have resolved the value, we put it into an array so that we
-    # can support array refs by referring to the values as an array.
-    #-------------------------------------------------------------------------
-    my @values;
-    push(@values,$value);
-    if ($type eq "array")
-    {
-        if (ref($value) eq "ARRAY")
-        {
-            @values = @{$value};
-        }
-    }
-
-    #$self->_debug("_xpath_set: values(",join(",",@values),")") unless !defined($value);
-
-    #-------------------------------------------------------------------------
-    # And now, for each value...
-    #-------------------------------------------------------------------------
-    foreach my $val (@values)
-    {
-        #$self->_debug("_xpath_set: val($val)") unless !defined($val);
-        #$self->_debug("_xpath_set: type($type)");
-
-        next unless (defined($val) || ($type eq "flag"));
-
-        if ((ref($val) ne "") && ($val->isa("Net::XMPP::JID")))
-        {
-            $val = $val->GetJID("full");
-        }
-
-        my $path = $xpath;
-
-        #$self->_debug("_xpath_set: val($val)") unless !defined($val);
-        #$self->_debug("_xpath_set: path($path)");
-    
-        my $childPath = "";
-        while(($path !~ /^\/?\@/) && ($path !~ /^\/?text\(\)/))
-        {
-            #$self->_debug("_xpath_set: Multi-level!!!!");
-            my ($child) = ($path =~ /^\/?([^\/]+)/);
-            $path =~ s/^\/?[^\/]+//;
-            #$self->_debug("_xpath_set: path($path)");
-            #$self->_debug("_xpath_set: childPath($childPath)");
-            
-            if (($type eq "scalar") || ($type eq "jid") || ($type eq "timestamp"))
-            {
-                my $tmpPath = $child;
-                $tmpPath = "$childPath/$child" if ($childPath ne "");
-                
-                my @nodes = $self->{TREE}->XPath("$tmpPath");
-                #$self->_debug("_xpath_set: \$#nodes($#nodes)");
-                if ($#nodes == -1)
-                {
-                    if ($childPath eq "")
-                    {
-                        $node = $self->{TREE}->add_child($child);
-                    }
-                    else
-                    {
-                        my $tree = $self->{TREE}->XPath("$childPath");
-                        $node = $tree->add_child($child);
-                    }
-                }
-                else
-                {
-                    $node = $nodes[0];
-                }
-            }
-
-            if ($type eq "array")
-            {
-                $node = $self->{TREE}->add_child($child);
-            }
-
-            if ($type eq "flag")
-            {
-                $node = $self->{TREE}->add_child($child);
-                return;
-            }
-            
-            $childPath .= "/" unless ($childPath eq "");
-            $childPath .= $child;
-        }
-
-        my ($piece) = ($path =~ /^\/?([^\/]+)/);
-    
-        #$self->_debug("_xpath_set: piece($piece)");
-
-        if ($piece =~ /^\@(.+)$/)
-        {
-            $node->put_attrib($1=>$val);
-        }
-        elsif ($piece eq "text()")
-        {
-            $node->remove_cdata();
-            $node->add_cdata($val);
-        }
-    }
-}
-
-
-##############################################################################
-#
-# _xpath_defined - returns true if there is data for the requested item, false
-#                otherwise.
-#
-##############################################################################
-sub _xpath_defined
-{
-    my $self = shift;
-    my $type = shift;
-    my $xpath = shift;
-    my $childtype = shift;
-    my $ns = shift;
-
-    #$self->_debug("_xpath_defined: self($self) type($type) xpath($xpath) childtype($childtype)");
-    #$self->_debug("_xpath_defined: ns($ns)") if defined($ns);
-    #$self->_debug("_xpath_defined: xml(",$self->{TREE}->GetXML(),")");
-
-    my $subType;
-    ($type,$subType) = $self->_xpath_resolve_types($type);
-
-    if ($type eq "raw")
-    {
-        if ($#{$self->{RAWXML}} > -1)
-        {
-            return 1;
-        }
-    }
-
-    my @nodes = $self->{TREE}->XPath($xpath);
-    my $defined = ($#nodes > -1);
-    
-    #$self->_debug("_xpath_defined: nodes(",join(",",@nodes),")");
-    #$self->_debug("_xpath_defined: ",$#nodes);
-    
-    if (!$defined && (($type eq "child") || ($type eq "children") || ($type eq "node")))
-    {
-        if ((ref($childtype) eq "HASH") && exists($childtype->{ns}))
-        {
-            $ns = $childtype->{ns};
-        }
-    
-        foreach my $packet (@{$self->{CHILDREN}})
-        {
-            if (!defined($ns) || ($packet->GetXMLNS() eq $ns))
-            {
-                $defined = 1;
-                last;
-            }
-        }
-    }
-
-    #$self->_debug("_xpath_defined: defined($defined)");
-
-    return $defined;
-}
-
-
-##############################################################################
-#
-# _xpath_add - returns the value stored in the node 
-#
-##############################################################################
-sub _xpath_add
-{
-    my $self = shift;
-    my $type = shift;
-    my $xpath = shift;
-    my $childtype = shift;
-
-    my $xmlns = $childtype->{ns};
-    my $master = $childtype->{master};
-
-    #$self->_debug("_xpath_add: self($self) type($type) xpath($xpath) childtype($childtype)");
-    #$self->_debug("_xpath_add: xmlns($xmlns) master($master)");
-
-    my $tag = $xpath;
-    if (exists($childtype->{specify_name}))
-    {
-        if (($#_ > -1) && (($#_/2) =~ /^\d+$/))
-        {
-            $tag = shift;
-        }
-        else
-        {
-            $tag = $childtype->{tag};
-        }
-    }
-
-    my $node = new XML::Stream::Node($tag);
-    $node->put_attrib(xmlns=>$xmlns);
-
-    my $obj = $self->AddChild($node);
-    eval "\$obj->Set${master}(\@_);" if defined($master);
-
-    $obj->_skip_xmlns() if exists($childtype->{skip_xmlns});
-
-    return $obj;
-}
-
-
-##############################################################################
-#
-# _xpath_remove - remove the specified thing from the data (I know it's vague.)
-#
-##############################################################################
-sub _xpath_remove
-{
-    my $self = shift;
-    my $type = shift;
-    my $xpath = shift;
-    my $childtype = shift;
-
-    #$self->_debug("_xpath_remove: self($self) type($type) xpath($xpath) childtype($childtype)");
-
-    my $subType;
-    ($type,$subType) = $self->_xpath_resolve_types($type);
-
-    my $nodePath = $xpath;
-    $nodePath =~ s/\/?\@\S+$//;
-    $nodePath =~ s/\/text\(\)$//;
-
-    #$self->_debug("_xpath_remove: xpath($xpath) nodePath($nodePath)");
-
-    my @nodes;
-    @nodes = $self->{TREE}->XPath($nodePath) if ($nodePath ne "");
-
-    #$self->_debug("_xpath_remove: nodes($#nodes)");
-    
-    if ($xpath =~ /\@(\S+)/)
-    {
-        my $attrib = $1;
-        #$self->_debug("_xpath_remove: attrib($attrib)");
-        
-        if ($nodePath eq "")
-        {
-            $self->{TREE}->remove_attrib($attrib);
-        }
-        else
-        {
-            foreach my $node (@nodes)
-            {
-                $node->remove_attrib($attrib);
-            }
-        }
-        return;
-    }
-    
-    foreach my $node (@nodes)
-    {
-        #$self->_debug("_xpath_remove: node GetXML(".$node->GetXML().")");
-        $self->{TREE}->remove_child($node);
-    }
-
-    if ($type eq "child")
-    {
-        my @keep;
-        foreach my $child (@{$self->{CHILDREN}})
-        {
-            #$self->_debug("_xpath_remove: check(".$child->GetXML().")");
-            next if ($child->GetXMLNS() eq $childtype->{ns});
-            #$self->_debug("_xpath_remove: keep(".$child->GetXML().")");
-            push(@keep,$child);
-        }
-        $self->{CHILDREN} = \@keep;
-    }
-}
-
-
-##############################################################################
-#
-# _xpath_resolve_types - Resolve the type and subType into the correct values.
-#
-##############################################################################
-sub _xpath_resolve_types
-{
-    my $self = shift;
-    my $type = shift;
-    
-    my $subType = "";
-    if (ref($type) eq "ARRAY")
-    {
-        if ($type->[0] eq "special")
-        {
-            $subType = $type->[1];
-            $type = "scalar";
-        }
-        elsif ($type->[0] eq "master")
-        {
-            $subType = $type->[1];
-            $type = "master";
-        }
-    }
-    
-    #$self->_debug("_xpath_resolve_types: type($type) subtype($subType)");
-
-    return ($type,$subType);
-}
-
-
-##############################################################################
-#
-# _parse_xmlns - anything that uses the namespace method must first kow what
-#                the xmlns of this thing is... So here's a function to do
-#                just that.
-#
-##############################################################################
-sub _parse_xmlns
-{
-    my $self = shift;
-
-    $self->SetXMLNS($self->{TREE}->get_attrib("xmlns"))
-        if defined($self->{TREE}->get_attrib("xmlns"));
-}
-
-
-##############################################################################
-#
-# _parse_tree - run through the XML::Stream::Node and pull any child nodes
-#               out that we recognize and create objects for them.
-#
-##############################################################################
-sub _parse_tree
-{
-    my $self = shift;
-
-    my @xTrees = $self->{TREE}->XPath('*[@xmlns]');
-
-    if ($#xTrees > -1)
-    {
-        foreach my $xTree (@xTrees)
-        {
-            if( exists($Net::XMPP::Namespaces::NS{$xTrees[0]->get_attrib("xmlns")}))
-            {
-                $self->AddChild($xTree);
-                $self->{TREE}->remove_child($xTree);
-            }
-        }
-    }
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Private Methods
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-sub _check_skip_xmlns
-{
-    my $self = shift;
-    my $xmlns = shift;
-
-    foreach my $skipns (keys(%Net::XMPP::Namespaces::SKIPNS))
-    {
-        return 1 if ($xmlns =~ /^$skipns/);
-    }
-
-    return 0;
-}
-
-
-##############################################################################
-#
-# _debug - helper function for printing debug messages using Net::XMPP::Debug
-#
-##############################################################################
-sub _debug
-{
-    my $self = shift;
-    return $DEBUG->Log99($self->{DEBUGHEADER},": ",@_);
-}
-
-
-##############################################################################
-#
-# _missing_function - send an error if the function is missing.
-#
-##############################################################################
-sub _missing_function
-{
-    my ($parent,$function) = @_;
-    croak("Undefined function $function in package ".ref($parent));
-}
-
-
-##############################################################################
-#
-# _new_jid - create a new JID object.
-#
-##############################################################################
-sub _new_jid
-{
-    my $self = shift;
-    return Net::XMPP::JID->new(@_);
-}
-
-
-##############################################################################
-#
-# _new_packet - create a new Stanza object.
-#
-##############################################################################
-sub _new_packet
-{
-    my $self = shift;
-    return Net::XMPP::Stanza->new(@_);
-}
-
-
-##############################################################################
-#
-# _skip_xmlns - in the GetTree function, cause the xmlns attribute to be
-#               removed for a node that has this set.
-#
-##############################################################################
-sub _skip_xmlns
-{
-    my $self = shift;
-
-    $self->{SKIPXMLNS} = 1;
-}
-
-
-1;
Index: rl/modules/Jabber/lib/XML/Stream.pm
===================================================================
--- perl/modules/Jabber/lib/XML/Stream.pm	(revision a8d5a39837d6c308c7f46d0f78f528e6b9e6d54f)
+++ 	(revision )
@@ -1,3269 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package XML::Stream;
-
-=head1 NAME
-
-XML::Stream - Creates and XML Stream connection and parses return data
-
-=head1 SYNOPSIS
-
-  XML::Stream is an attempt at solidifying the use of XML via streaming.
-
-=head1 DESCRIPTION
-
-  This module provides the user with methods to connect to a remote
-  server, send a stream of XML to the server, and receive/parse an XML
-  stream from the server.  It is primarily based work for the Etherx XML
-  router developed by the Jabber Development Team.  For more information
-  about this project visit http://etherx.jabber.org/stream/.
-
-  XML::Stream gives the user the ability to define a central callback
-  that will be used to handle the tags received from the server.  These
-  tags are passed in the format defined at instantiation time.
-  the closing tag of an object is seen, the tree is finished and passed
-  to the call back function.  What the user does with it from there is up
-  to them.
-
-  For a detailed description of how this module works, and about the data
-  structure that it returns, please view the source of Stream.pm and
-  look at the detailed description at the end of the file.
-
-
-  NOTE: The parser that XML::Stream::Parser provides, as are most Perl
-  parsers, is synchronous.  If you are in the middle of parsing a
-  packet and call a user defined callback, the Parser is blocked until
-  your callback finishes.  This means you cannot be operating on a
-  packet, send out another packet and wait for a response to that packet.
-  It will never get to you.  Threading might solve this, but as we all
-  know threading in Perl is not quite up to par yet.  This issue will be
-  revisted in the future.
-
-
-
-=head1 METHODS
-
-  new(debug=>string,       - creates the XML::Stream object.  debug
-      debugfh=>FileHandle,   should be set to the path for the debug log
-      debuglevel=>0|1|N,     to be written.  If set to "stdout" then the
-      debugtime=>0|1,        debug will go there.   Also, you can specify
-      style=>string)         a filehandle that already exists byt using
-                             debugfh.  debuglevel determines the amount
-                             of debug to generate.  0 is the least, 1 is
-                             a little more, N is the limit you want.
-                             debugtime determines wether a timestamp
-                             should be preappended to the entry.  style
-                             defines the way the data structure is
-                             returned.  The two available styles are:
-
-                               tree - XML::Parser Tree format
-                               node - XML::Stream::Node format
-
-                             For more information see the respective man
-                             pages.
-
-  Connect(hostname=>string,       - opens a tcp connection to the
-          port=>integer,            specified server and sends the proper
-          to=>string,               opening XML Stream tag.  hostname,
-          from=>string,             port, and namespace are required.
-          myhostname=>string,       namespaces allows you to use
-          namespace=>string,        XML::Stream::Namespace objects.
-          namespaces=>array,        to is needed if you want the stream
-          connectiontype=>string,   to attribute to be something other
-          ssl=>0|1,                 than the hostname you are connecting
-          srv=>string)              to.  from is needed if you want the
-                                    stream from attribute to be something
-                                    other than the hostname you are
-                                    connecting from.  myhostname should
-                                    not be needed but if the module
-                                    cannot determine your hostname
-                                    properly (check the debug log), set
-                                    this to the correct value, or if you
-                                    want the other side of the  stream to
-                                    think that you are someone else.  The
-                                    type determines the kind of
-                                    connection that is made:
-                                      "tcpip"    - TCP/IP (default)
-                                      "stdinout" - STDIN/STDOUT
-                                      "http"     - HTTP
-                                    HTTP recognizes proxies if the ENV
-                                    variables http_proxy or https_proxy
-                                    are set.  ssl specifies if an SLL
-                                    socket should be used for encrypted
-                                    communications.  This function
-                                    returns the same hash from GetRoot()
-                                    below. Make sure you get the SID
-                                    (Session ID) since you have to use it
-                                    to call most other functions in here.
-
-                                    If srv is specified AND Net::DNS is
-                                    installed and can be loaded, then
-                                    an SRV query is sent to srv.hostname
-                                    and the results processed to replace
-                                    the hostname and port.  If the lookup
-                                    fails, or Net::DNS cannot be loaded,
-                                    then hostname and port are left alone
-                                    as the defaults.
-
-
-  OpenFile(string) - opens a filehandle to the argument specified, and
-                     pretends that it is a stream.  It will ignore the
-                     outer tag, and not check if it was a
-                     <stream:stream/>. This is useful for writing a
-                     program that has to parse any XML file that is
-                     basically made up of small packets (like RDF).
-
-  Disconnect(sid) - sends the proper closing XML tag and closes the
-                    specified socket down.
-
-  Process(integer) - waits for data to be available on the socket.  If
-                     a timeout is specified then the Process function
-                     waits that period of time before returning nothing.
-                     If a timeout period is not specified then the
-                     function blocks until data is received.  The
-                     function returns a hash with session ids as the key,
-                     and status values or data as the hash values.
-
-  SetCallBacks(node=>function,   - sets the callback that should be
-               update=>function)   called in various situations.  node
-                                   is used to handle the data structures
-                                   that are built for each top level tag.
-                                   Update is used for when Process is
-                                   blocking waiting for data, but you
-                                   want your original code to be updated.
-
-  GetRoot(sid) - returns the attributes that the stream:stream tag sent
-                 by the other end listed in a hash for the specified
-                 session.
-
-  GetSock(sid) - returns a pointer to the IO::Socket object for the
-                 specified session.
-
-  Send(sid,    - sends the string over the specified connection as is.
-       string)   This does no checking if valid XML was sent or not.
-                 Best behavior when sending information.
-
-  GetErrorCode(sid) - returns a string for the specified session that
-                      will hopefully contain some useful information
-                      about why Process or Connect returned an undef
-                      to you.
-
-  XPath(node,path) - returns an array of results that match the xpath.
-                     node can be any of the three types (Tree, Node).
-
-=head1 VARIABLES
-
-  $NONBLOCKING - tells the Parser to enter into a nonblocking state.  This
-                 might cause some funky behavior since you can get nested
-                 callbacks while things are waiting.  1=on, 0=off(default).
-
-=head1 EXAMPLES
-
-  ##########################
-  # simple example
-
-  use XML::Stream qw( Tree );
-
-  $stream = new XML::Stream;
-
-  my $status = $stream->Connect(hostname => "jabber.org",
-                                port => 5222,
-                                namespace => "jabber:client");
-
-  if (!defined($status)) {
-    print "ERROR: Could not connect to server\n";
-    print "       (",$stream->GetErrorCode(),")\n";
-    exit(0);
-  }
-
-  while($node = $stream->Process()) {
-    # do something with $node
-  }
-
-  $stream->Disconnect();
-
-
-  ###########################
-  # example using a handler
-
-  use XML::Stream qw( Tree );
-
-  $stream = new XML::Stream;
-  $stream->SetCallBacks(node=>\&noder);
-  $stream->Connect(hostname => "jabber.org",
-		   port => 5222,
-		   namespace => "jabber:client",
-		   timeout => undef) || die $!;
-
-  # Blocks here forever, noder is called for incoming
-  # packets when they arrive.
-  while(defined($stream->Process())) { }
-
-  print "ERROR: Stream died (",$stream->GetErrorCode(),")\n";
-
-  sub noder
-  {
-    my $sid = shift;
-    my $node = shift;
-    # do something with $node
-  }
-
-=head1 AUTHOR
-
-Tweaked, tuned, and brightness changes by Ryan Eatmon, reatmon@ti.com
-in May of 2000.
-Colorized, and Dolby Surround sound added by Thomas Charron,
-tcharron@jabber.org
-By Jeremie in October of 1999 for http://etherx.jabber.org/streams/
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use 5.006_001;
-use strict;
-use Sys::Hostname;
-use IO::Socket;
-use IO::Select;
-use FileHandle;
-use Carp;
-use POSIX;
-use Authen::SASL;
-use MIME::Base64;
-use utf8;
-use Encode;
-
-$SIG{PIPE} = "IGNORE";
-
-use vars qw($VERSION $PAC $SSL $NONBLOCKING %HANDLERS $NETDNS %XMLNS );
-
-##############################################################################
-# Define the namespaces in an easy/constant manner.
-#-----------------------------------------------------------------------------
-# 0.9
-#-----------------------------------------------------------------------------
-$XMLNS{'stream'}        = "http://etherx.jabber.org/streams";
-
-#-----------------------------------------------------------------------------
-# 1.0
-#-----------------------------------------------------------------------------
-$XMLNS{'xmppstreams'}   = "urn:ietf:params:xml:ns:xmpp-streams";
-$XMLNS{'xmpp-bind'}     = "urn:ietf:params:xml:ns:xmpp-bind";
-$XMLNS{'xmpp-sasl'}     = "urn:ietf:params:xml:ns:xmpp-sasl";
-$XMLNS{'xmpp-session'}  = "urn:ietf:params:xml:ns:xmpp-session";
-$XMLNS{'xmpp-tls'}      = "urn:ietf:params:xml:ns:xmpp-tls";
-##############################################################################
-
-
-if (eval "require Net::DNS;" )
-{
-    require Net::DNS;
-    import Net::DNS;
-    $NETDNS = 1;
-}
-else
-{
-    $NETDNS = 0;
-}
-
-
-$VERSION = "1.22";
-$NONBLOCKING = 0;
-
-use XML::Stream::Namespace;
-use XML::Stream::Parser;
-use XML::Stream::XPath;
-
-##############################################################################
-#
-# Setup the exportable objects
-#
-##############################################################################
-require Exporter;
-my @ISA = qw(Exporter);
-my @EXPORT_OK = qw(Tree Node);
-
-sub import
-{
-    my $class = shift;
-
-    foreach my $module (@_)
-    {
-        eval "use XML::Stream::$module;";
-        die($@) if ($@);
-
-        my $lc = lc($module);
-        
-        eval("\$HANDLERS{\$lc}->{startElement} = \\&XML::Stream::${module}::_handle_element;");
-        eval("\$HANDLERS{\$lc}->{endElement}   = \\&XML::Stream::${module}::_handle_close;");
-        eval("\$HANDLERS{\$lc}->{characters}   = \\&XML::Stream::${module}::_handle_cdata;");
-    }
-}
-
-
-sub new
-{
-    my $proto = shift;
-    my $self = { };
-
-    bless($self,$proto);
-
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $self->{DATASTYLE} = "tree";
-    $self->{DATASTYLE} = delete($args{style}) if exists($args{style});
-
-    if ((($self->{DATASTYLE} eq "tree") && !defined($XML::Stream::Tree::LOADED)) ||
-        (($self->{DATASTYLE} eq "node") && !defined($XML::Stream::Node::LOADED))
-       )
-    {
-        croak("The style that you have chosen was not defined when you \"use\"d the module.\n");
-    }
-
-    $self->{DEBUGARGS} = \%args;
-
-    $self->{DEBUGTIME} = 0;
-    $self->{DEBUGTIME} = $args{debugtime} if exists($args{debugtime});
-
-    $self->{DEBUGLEVEL} = 0;
-    $self->{DEBUGLEVEL} = $args{debuglevel} if exists($args{debuglevel});
-
-    $self->{DEBUGFILE} = "";
-
-    if (exists($args{debugfh}) && ($args{debugfh} ne ""))
-    {
-        $self->{DEBUGFILE} = $args{debugfh};
-        $self->{DEBUG} = 1;
-    }
-    if ((exists($args{debugfh}) && ($args{debugfh} eq "")) ||
-        (exists($args{debug}) && ($args{debug} ne "")))
-    {
-        $self->{DEBUG} = 1;
-        if (lc($args{debug}) eq "stdout")
-        {
-            $self->{DEBUGFILE} = new FileHandle(">&STDERR");
-            $self->{DEBUGFILE}->autoflush(1);
-        }
-        else
-        {
-            if (-e $args{debug})
-            {
-                if (-w $args{debug})
-                {
-                    $self->{DEBUGFILE} = new FileHandle(">$args{debug}");
-                    $self->{DEBUGFILE}->autoflush(1);
-                }
-                else
-                {
-                    print "WARNING: debug file ($args{debug}) is not writable by you\n";
-                    print "         No debug information being saved.\n";
-                    $self->{DEBUG} = 0;
-                }
-            }
-            else
-            {
-                $self->{DEBUGFILE} = new FileHandle(">$args{debug}");
-                if (defined($self->{DEBUGFILE}))
-                {
-                    $self->{DEBUGFILE}->autoflush(1);
-                }
-                else
-                {
-                    print "WARNING: debug file ($args{debug}) does not exist \n";
-                    print "         and is not writable by you.\n";
-                    print "         No debug information being saved.\n";
-                    $self->{DEBUG} = 0;
-                }
-            }
-        }
-    }
-
-    my $hostname = hostname();
-    my $address = gethostbyname($hostname) ||
-        die("Cannot resolve $hostname: $!");
-    my $fullname = gethostbyaddr($address,AF_INET) || $hostname;
-
-    $self->debug(1,"new: hostname = ($fullname)");
-
-    #---------------------------------------------------------------------------
-    # Setup the defaults that the module will work with.
-    #---------------------------------------------------------------------------
-    $self->{SIDS}->{default}->{hostname} = "";
-    $self->{SIDS}->{default}->{port} = "";
-    $self->{SIDS}->{default}->{sock} = 0;
-    $self->{SIDS}->{default}->{ssl} = (exists($args{ssl}) ? $args{ssl} : 0);
-    $self->{SIDS}->{default}->{namespace} = "";
-    $self->{SIDS}->{default}->{myhostname} = $fullname;
-    $self->{SIDS}->{default}->{derivedhostname} = $fullname;
-    $self->{SIDS}->{default}->{id} = "";
-
-    #---------------------------------------------------------------------------
-    # We are only going to use one callback, let the user call other callbacks
-    # on his own.
-    #---------------------------------------------------------------------------
-    $self->SetCallBacks(node=>sub { $self->_node(@_) });
-
-    $self->{IDCOUNT} = 0;
-
-    return $self;
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Incoming Connection Functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# Listen - starts the stream by listening on a port for someone to connect,
-#          and send the opening stream tag, and then sending a response based
-#          on if the received header was correct for this stream.  Server
-#          name, port, and namespace are required otherwise we don't know
-#          where to listen and what namespace to accept.
-#
-##############################################################################
-sub Listen
-{
-    my $self = shift;
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    my $serverid = "server$args{port}";
-
-    return if exists($self->{SIDS}->{$serverid});
-
-    push(@{$self->{SIDS}->{server}},$serverid);
-
-    foreach my $key (keys(%{$self->{SIDS}->{default}}))
-    {
-        $self->{SIDS}->{$serverid}->{$key} = $self->{SIDS}->{default}->{$key};
-    }
-
-    foreach my $key (keys(%args))
-    {
-        $self->{SIDS}->{$serverid}->{$key} = $args{$key};
-    }
-
-    $self->debug(1,"Listen: start");
-
-    if ($self->{SIDS}->{$serverid}->{namespace} eq "")
-    {
-        $self->SetErrorCode($serverid,"Namespace not specified");
-        return;
-    }
-
-    #---------------------------------------------------------------------------
-    # Check some things that we have to know in order get the connection up
-    # and running.  Server hostname, port number, namespace, etc...
-    #---------------------------------------------------------------------------
-    if ($self->{SIDS}->{$serverid}->{hostname} eq "")
-    {
-        $self->SetErrorCode("$serverid","Server hostname not specified");
-        return;
-    }
-    if ($self->{SIDS}->{$serverid}->{port} eq "")
-    {
-        $self->SetErrorCode("$serverid","Server port not specified");
-        return;
-    }
-    if ($self->{SIDS}->{$serverid}->{myhostname} eq "")
-    {
-        $self->{SIDS}->{$serverid}->{myhostname} = $self->{SIDS}->{$serverid}->{derivedhostname};
-    }
-
-    #-------------------------------------------------------------------------
-    # Open the connection to the listed server and port.  If that fails then
-    # abort ourselves and let the user check $! on his own.
-    #-------------------------------------------------------------------------
-
-    while($self->{SIDS}->{$serverid}->{sock} == 0)
-    {
-        $self->{SIDS}->{$serverid}->{sock} =
-            new IO::Socket::INET(LocalHost=>$self->{SIDS}->{$serverid}->{hostname},
-                                 LocalPort=>$self->{SIDS}->{$serverid}->{port},
-                                 Reuse=>1,
-                                 Listen=>10,
-                                 Proto=>'tcp');
-        select(undef,undef,undef,.1);
-    }
-    $self->{SIDS}->{$serverid}->{status} = 1;
-    $self->nonblock($self->{SIDS}->{$serverid}->{sock});
-    $self->{SIDS}->{$serverid}->{sock}->autoflush(1);
-
-    $self->{SELECT} =
-        new IO::Select($self->{SIDS}->{$serverid}->{sock});
-    $self->{SIDS}->{$serverid}->{select} =
-        new IO::Select($self->{SIDS}->{$serverid}->{sock});
-
-    $self->{SOCKETS}->{$self->{SIDS}->{$serverid}->{sock}} = "$serverid";
-
-    return $serverid;
-}
-
-
-##############################################################################
-#
-# ConnectionAccept - accept an incoming connection.
-#
-##############################################################################
-sub ConnectionAccept
-{
-    my $self = shift;
-    my $serverid = shift;
-
-    my $sid = $self->NewSID();
-
-    $self->debug(1,"ConnectionAccept: sid($sid)");
-
-    $self->{SIDS}->{$sid}->{sock} = $self->{SIDS}->{$serverid}->{sock}->accept();
-
-    $self->nonblock($self->{SIDS}->{$sid}->{sock});
-    $self->{SIDS}->{$sid}->{sock}->autoflush(1);
-
-    $self->debug(3,"ConnectionAccept: sid($sid) client($self->{SIDS}->{$sid}->{sock}) server($self->{SIDS}->{$serverid}->{sock})");
-
-    $self->{SELECT}->add($self->{SIDS}->{$sid}->{sock});
-
-    #-------------------------------------------------------------------------
-    # Create the XML::Stream::Parser and register our callbacks
-    #-------------------------------------------------------------------------
-    $self->{SIDS}->{$sid}->{parser} =
-        new XML::Stream::Parser(%{$self->{DEBUGARGS}},
-                                nonblocking=>$NONBLOCKING,
-                                sid=>$sid,
-                                style=>$self->{DATASTYLE},
-                                Handlers=>{
-                                    startElement=>sub{ $self->_handle_root(@_) },
-                                    endElement=>sub{ &{$HANDLERS{$self->{DATASTYLE}}->{endElement}}($self,@_) },
-                                    characters=>sub{ &{$HANDLERS{$self->{DATASTYLE}}->{characters}}($self,@_) },
-                                }
-                               );
-
-    $self->{SIDS}->{$sid}->{select} =
-        new IO::Select($self->{SIDS}->{$sid}->{sock});
-    $self->{SIDS}->{$sid}->{connectiontype} = "tcpip";
-    $self->{SOCKETS}->{$self->{SIDS}->{$sid}->{sock}} = $sid;
-
-    $self->InitConnection($sid,$serverid);
-
-    #---------------------------------------------------------------------------
-    # Grab the init time so that we can check if we get data in the timeout
-    # period or not.
-    #---------------------------------------------------------------------------
-    $self->{SIDS}->{$sid}->{activitytimeout} = time;
-
-    return $sid;
-}
-
-
-##############################################################################
-#
-# Respond - If this is a listening socket then we need to respond to the
-#           opening <stream:stream/>.
-#
-##############################################################################
-sub Respond
-{
-    my $self = shift;
-    my $sid = shift;
-    my $serverid = $self->{SIDS}->{$sid}->{serverid};
-
-    my $root = $self->GetRoot($sid);
-    
-    if ($root->{xmlns} ne $self->{SIDS}->{$serverid}->{namespace})
-    {
-        my $error = $self->StreamError($sid,"invalid-namespace","Invalid namespace specified");
-        $self->Send($sid,$error);
-
-        $self->{SIDS}->{$sid}->{sock}->flush();
-        select(undef,undef,undef,1);
-        $self->Disconnect($sid);
-    }
-
-    #---------------------------------------------------------------------------
-    # Next, we build the opening handshake.
-    #---------------------------------------------------------------------------
-    my %stream_args;
-
-    $stream_args{from} =
-        (exists($self->{SIDS}->{$serverid}->{from}) ?
-         $self->{SIDS}->{$serverid}->{from} :
-         $self->{SIDS}->{$serverid}->{hostname}
-        );
-
-    $stream_args{to} = $self->GetRoot($sid)->{from};
-    $stream_args{id} = $sid;
-    $stream_args{namespaces} = $self->{SIDS}->{$serverid}->{namespaces};
-
-    my $stream =
-        $self->StreamHeader(
-            xmlns=>$self->{SIDS}->{$serverid}->{namespace},
-            xmllang=>"en",
-            %stream_args
-        );
-
-    #---------------------------------------------------------------------------
-    # Then we send the opening handshake.
-    #---------------------------------------------------------------------------
-    $self->Send($sid,$stream);
-    delete($self->{SIDS}->{$sid}->{activitytimeout});
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Outgoing Connection Functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# Connect - starts the stream by connecting to the server, sending the opening
-#           stream tag, and then waiting for a response and verifying that it
-#           is correct for this stream.  Server name, port, and namespace are
-#           required otherwise we don't know where to send the stream to...
-#
-##############################################################################
-sub Connect
-{
-    my $self = shift;
-
-    foreach my $key (keys(%{$self->{SIDS}->{default}}))
-    {
-        $self->{SIDS}->{newconnection}->{$key} = $self->{SIDS}->{default}->{$key};
-    }
-    while($#_ >= 0) { $self->{SIDS}->{newconnection}->{ lc pop(@_) } = pop(@_); }
-    
-    my $timeout = exists($self->{SIDS}->{newconnection}->{timeout}) ?
-                  delete($self->{SIDS}->{newconnection}->{timeout}) :
-                  "";
-
-    $self->debug(4,"Connect: timeout($timeout)");
-    
-
-    if (exists($self->{SIDS}->{newconnection}->{srv}))
-    {
-        $self->debug(1,"Connect: srv requested");
-        if ($NETDNS)
-        {
-            my $res = Net::DNS::Resolver->new();
-            my $query = $res->query($self->{SIDS}->{newconnection}->{srv}.".".$self->{SIDS}->{newconnection}->{hostname},"SRV");
-            
-            if ($query)
-            { 
-                $self->{SIDS}->{newconnection}->{hostname} = ($query->answer)[0]->target();
-                $self->{SIDS}->{newconnection}->{port} = ($query->answer)[0]->port();
-                $self->debug(1,"Connect: srv host: $self->{SIDS}->{newconnection}->{hostname}");
-                $self->debug(1,"Connect: srv post: $self->{SIDS}->{newconnection}->{port}");
-            }
-            else
-            {
-                $self->debug(1,"Connect: srv query failed");
-            }
-        }
-        else
-        {
-            $self->debug(1,"Connect: srv query failed");
-        }
-        delete($self->{SIDS}->{newconnection}->{srv});
-    }
-
-    $self->{SIDS}->{newconnection}->{connectiontype} = "tcpip"
-        unless exists($self->{SIDS}->{newconnection}->{connectiontype});
-
-    $self->debug(1,"Connect: type($self->{SIDS}->{newconnection}->{connectiontype})");
-
-    if ($self->{SIDS}->{newconnection}->{namespace} eq "")
-    {
-        $self->SetErrorCode("newconnection","Namespace not specified");
-        return;
-    }
-
-    #---------------------------------------------------------------------------
-    # TCP/IP
-    #---------------------------------------------------------------------------
-    if ($self->{SIDS}->{newconnection}->{connectiontype} eq "tcpip")
-    {
-        #-----------------------------------------------------------------------
-        # Check some things that we have to know in order get the connection up
-        # and running.  Server hostname, port number, namespace, etc...
-        #-----------------------------------------------------------------------
-        if ($self->{SIDS}->{newconnection}->{hostname} eq "")
-        {
-            $self->SetErrorCode("newconnection","Server hostname not specified");
-            return;
-        }
-        if ($self->{SIDS}->{newconnection}->{port} eq "")
-        {
-            $self->SetErrorCode("newconnection","Server port not specified");
-            return;
-        }
-        if ($self->{SIDS}->{newconnection}->{myhostname} eq "")
-        {
-            $self->{SIDS}->{newconnection}->{myhostname} = $self->{SIDS}->{newconnection}->{derivedhostname};
-        }
-
-        #-----------------------------------------------------------------------
-        # Open the connection to the listed server and port.  If that fails then
-        # abort ourselves and let the user check $! on his own.
-        #-----------------------------------------------------------------------
-        $self->{SIDS}->{newconnection}->{sock} =
-            new IO::Socket::INET(PeerAddr=>$self->{SIDS}->{newconnection}->{hostname},
-                                 PeerPort=>$self->{SIDS}->{newconnection}->{port},
-                                 Proto=>"tcp",
-                                 (($timeout ne "") ? ( Timeout=>$timeout ) : ()),
-                                );
-        return unless $self->{SIDS}->{newconnection}->{sock};
-
-        if ($self->{SIDS}->{newconnection}->{ssl} == 1)
-        {
-            $self->debug(1,"Connect: Convert normal socket to SSL");
-            $self->debug(1,"Connect: sock($self->{SIDS}->{newconnection}->{sock})");
-            $self->LoadSSL();
-            $self->{SIDS}->{newconnection}->{sock} =
-                IO::Socket::SSL::socketToSSL($self->{SIDS}->{newconnection}->{sock},
-                                             {SSL_verify_mode=>0x00});
-            $self->debug(1,"Connect: ssl_sock($self->{SIDS}->{newconnection}->{sock})");
-            $self->debug(1,"Connect: SSL: We are secure") if ($self->{SIDS}->{newconnection}->{sock});
-        }
-        return unless $self->{SIDS}->{newconnection}->{sock};
-    }
-
-    #---------------------------------------------------------------------------
-    # STDIN/OUT
-    #---------------------------------------------------------------------------
-    if ($self->{SIDS}->{newconnection}->{connectiontype} eq "stdinout")
-    {
-        $self->{SIDS}->{newconnection}->{sock} =
-            new FileHandle(">&STDOUT");
-    }  
-
-    #---------------------------------------------------------------------------
-    # HTTP
-    #---------------------------------------------------------------------------
-    if ($self->{SIDS}->{newconnection}->{connectiontype} eq "http")
-    {
-        #-----------------------------------------------------------------------
-        # Check some things that we have to know in order get the connection up
-        # and running.  Server hostname, port number, namespace, etc...
-        #-----------------------------------------------------------------------
-        if ($self->{SIDS}->{newconnection}->{hostname} eq "")
-        {
-            $self->SetErrorCode("newconnection","Server hostname not specified");
-            return;
-        }
-        if ($self->{SIDS}->{newconnection}->{port} eq "")
-        {
-            $self->SetErrorCode("newconnection","Server port not specified");
-            return;
-        }
-        if ($self->{SIDS}->{newconnection}->{myhostname} eq "")
-        {
-            $self->{SIDS}->{newconnection}->{myhostname} = $self->{SIDS}->{newconnection}->{derivedhostname};
-        }
-
-        if (!defined($PAC))
-        {
-            eval("use HTTP::ProxyAutoConfig;");
-            if ($@)
-            {
-                $PAC = 0;
-            }
-            else
-            {
-                require HTTP::ProxyAutoConfig;
-                $PAC = new HTTP::ProxyAutoConfig();
-            }
-        }
-
-        if ($PAC eq "0") {
-            if (exists($ENV{"http_proxy"}))
-            {
-                my($host,$port) = ($ENV{"http_proxy"} =~ /^(\S+)\:(\d+)$/);
-                $self->{SIDS}->{newconnection}->{httpproxyhostname} = $host;
-                $self->{SIDS}->{newconnection}->{httpproxyport} = $port;
-                $self->{SIDS}->{newconnection}->{httpproxyhostname} =~ s/^http\:\/\///;
-            }
-            if (exists($ENV{"https_proxy"}))
-            {
-                my($host,$port) = ($ENV{"https_proxy"} =~ /^(\S+)\:(\d+)$/);
-                $self->{SIDS}->{newconnection}->{httpsproxyhostname} = $host;
-                $self->{SIDS}->{newconnection}->{httpsproxyport} = $port;
-                $self->{SIDS}->{newconnection}->{httpsproxyhostname} =~ s/^https?\:\/\///;
-            }
-        }
-        else
-        {
-            my $proxy = $PAC->FindProxy("http://".$self->{SIDS}->{newconnection}->{hostname});
-            if ($proxy ne "DIRECT")
-            {
-                ($self->{SIDS}->{newconnection}->{httpproxyhostname},$self->{SIDS}->{newconnection}->{httpproxyport}) = ($proxy =~ /^PROXY ([^:]+):(\d+)$/);
-            }
-
-            $proxy = $PAC->FindProxy("https://".$self->{SIDS}->{newconnection}->{hostname});
-
-            if ($proxy ne "DIRECT")
-            {
-                ($self->{SIDS}->{newconnection}->{httpsproxyhostname},$self->{SIDS}->{newconnection}->{httpsproxyport}) = ($proxy =~ /^PROXY ([^:]+):(\d+)$/);
-            }
-        }
-
-        $self->debug(1,"Connect: http_proxy($self->{SIDS}->{newconnection}->{httpproxyhostname}:$self->{SIDS}->{newconnection}->{httpproxyport})")
-            if (exists($self->{SIDS}->{newconnection}->{httpproxyhostname}) &&
-                defined($self->{SIDS}->{newconnection}->{httpproxyhostname}) &&
-                exists($self->{SIDS}->{newconnection}->{httpproxyport}) &&
-                defined($self->{SIDS}->{newconnection}->{httpproxyport}));
-        $self->debug(1,"Connect: https_proxy($self->{SIDS}->{newconnection}->{httpsproxyhostname}:$self->{SIDS}->{newconnection}->{httpsproxyport})")
-            if (exists($self->{SIDS}->{newconnection}->{httpsproxyhostname}) &&
-                defined($self->{SIDS}->{newconnection}->{httpsproxyhostname}) &&
-                exists($self->{SIDS}->{newconnection}->{httpsproxyport}) &&
-                defined($self->{SIDS}->{newconnection}->{httpsproxyport}));
-
-        #-----------------------------------------------------------------------
-        # Open the connection to the listed server and port.  If that fails then
-        # abort ourselves and let the user check $! on his own.
-        #-----------------------------------------------------------------------
-        my $connect = "CONNECT $self->{SIDS}->{newconnection}->{hostname}:$self->{SIDS}->{newconnection}->{port} HTTP/1.1\r\nHost: $self->{SIDS}->{newconnection}->{hostname}\r\n\r\n";
-        my $put = "PUT http://$self->{SIDS}->{newconnection}->{hostname}:$self->{SIDS}->{newconnection}->{port} HTTP/1.1\r\nHost: $self->{SIDS}->{newconnection}->{hostname}\r\nProxy-Connection: Keep-Alive\r\n\r\n";
-
-        my $connected = 0;
-        #-----------------------------------------------------------------------
-        # Combo #0 - The user didn't specify a proxy
-        #-----------------------------------------------------------------------
-        if (!exists($self->{SIDS}->{newconnection}->{httpproxyhostname}) &&
-            !exists($self->{SIDS}->{newconnection}->{httpsproxyhostname}))
-        {
-
-            $self->debug(1,"Connect: Combo #0: User did not specify a proxy... connecting DIRECT");
-
-            $self->debug(1,"Connect: Combo #0: Create normal socket");
-            $self->{SIDS}->{newconnection}->{sock} =
-            new IO::Socket::INET(PeerAddr=>$self->{SIDS}->{newconnection}->{hostname},
-                                 PeerPort=>$self->{SIDS}->{newconnection}->{port},
-                                 Proto=>"tcp",
-                                 (($timeout ne "") ? ( Timeout=>$timeout ) : ()),
-                                );
-            $connected = defined($self->{SIDS}->{newconnection}->{sock});
-            $self->debug(1,"Connect: Combo #0: connected($connected)");
-            #            if ($connected)
-            #            {
-            #                $self->{SIDS}->{newconnection}->{sock}->syswrite($put,length($put),0);
-            #                my $buff;
-            #                $self->{SIDS}->{newconnection}->{sock}->sysread($buff,4*POSIX::BUFSIZ);
-            #                my ($code) = ($buff =~ /^\S+\s+(\S+)\s+/);
-            #                $self->debug(1,"Connect: Combo #1: buff($buff)");
-            #                $connected = 0 if ($code !~ /2\d\d/);
-            #            }
-            #            $self->debug(1,"Connect: Combo #0: connected($connected)");
-          }
-
-        #-----------------------------------------------------------------------
-        # Combo #1 - PUT through http_proxy
-        #-----------------------------------------------------------------------
-        if (!$connected &&
-            exists($self->{SIDS}->{newconnection}->{httpproxyhostname}) &&
-            ($self->{SIDS}->{newconnection}->{ssl} == 0))
-        {
-
-            $self->debug(1,"Connect: Combo #1: PUT through http_proxy");
-            $self->{SIDS}->{newconnection}->{sock} =
-                new IO::Socket::INET(PeerAddr=>$self->{SIDS}->{newconnection}->{httpproxyhostname},
-                                     PeerPort=>$self->{SIDS}->{newconnection}->{httpproxyport},
-                                     Proto=>"tcp",
-                                     (($timeout ne "") ? ( Timeout=>$timeout ) : ()),
-                                    );
-            $connected = defined($self->{SIDS}->{newconnection}->{sock});
-            $self->debug(1,"Connect: Combo #1: connected($connected)");
-            if ($connected)
-            {
-                $self->debug(1,"Connect: Combo #1: send($put)");
-                $self->{SIDS}->{newconnection}->{sock}->syswrite($put,length($put),0);
-                my $buff;
-                $self->{SIDS}->{newconnection}->{sock}->sysread($buff,4*POSIX::BUFSIZ);
-                my ($code) = ($buff =~ /^\S+\s+(\S+)\s+/);
-                $self->debug(1,"Connect: Combo #1: buff($buff)");
-                $connected = 0 if ($code !~ /2\d\d/);
-            }
-            $self->debug(1,"Connect: Combo #1: connected($connected)");
-        }
-        #-----------------------------------------------------------------------
-        # Combo #2 - CONNECT through http_proxy
-        #-----------------------------------------------------------------------
-        if (!$connected &&
-            exists($self->{SIDS}->{newconnection}->{httpproxyhostname}) &&
-            ($self->{SIDS}->{newconnection}->{ssl} == 0))
-        {
-
-            $self->debug(1,"Connect: Combo #2: CONNECT through http_proxy");
-            $self->{SIDS}->{newconnection}->{sock} =
-                new IO::Socket::INET(PeerAddr=>$self->{SIDS}->{newconnection}->{httpproxyhostname},
-                                     PeerPort=>$self->{SIDS}->{newconnection}->{httpproxyport},
-                                     Proto=>"tcp",
-                                     (($timeout ne "") ? ( Timeout=>$timeout ) : ()),
-                                    );
-            $connected = defined($self->{SIDS}->{newconnection}->{sock});
-            $self->debug(1,"Connect: Combo #2: connected($connected)");
-            if ($connected)
-            {
-                $self->{SIDS}->{newconnection}->{sock}->syswrite($connect,length($connect),0);
-                my $buff;
-                $self->{SIDS}->{newconnection}->{sock}->sysread($buff,4*POSIX::BUFSIZ);
-                my ($code) = ($buff =~ /^\S+\s+(\S+)\s+/);
-                $self->debug(1,"Connect: Combo #2: buff($buff)");
-                $connected = 0 if ($code !~ /2\d\d/);
-            }
-            $self->debug(1,"Connect: Combo #2: connected($connected)");
-        }
-
-        #-----------------------------------------------------------------------
-        # Combo #3 - CONNECT through https_proxy
-        #-----------------------------------------------------------------------
-        if (!$connected &&
-            exists($self->{SIDS}->{newconnection}->{httpsproxyhostname}))
-        {
-            $self->debug(1,"Connect: Combo #3: CONNECT through https_proxy");
-            $self->{SIDS}->{newconnection}->{sock} =
-                new IO::Socket::INET(PeerAddr=>$self->{SIDS}->{newconnection}->{httpsproxyhostname},
-                                     PeerPort=>$self->{SIDS}->{newconnection}->{httpsproxyport},
-                                     Proto=>"tcp");
-            $connected = defined($self->{SIDS}->{newconnection}->{sock});
-            $self->debug(1,"Connect: Combo #3: connected($connected)");
-            if ($connected)
-            {
-                $self->{SIDS}->{newconnection}->{sock}->syswrite($connect,length($connect),0);
-                my $buff;
-                $self->{SIDS}->{newconnection}->{sock}->sysread($buff,4*POSIX::BUFSIZ);
-                my ($code) = ($buff =~ /^\S+\s+(\S+)\s+/);
-                $self->debug(1,"Connect: Combo #3: buff($buff)");
-                $connected = 0 if ($code !~ /2\d\d/);
-            }
-            $self->debug(1,"Connect: Combo #3: connected($connected)");
-        }
-
-        #-----------------------------------------------------------------------
-        # We have failed
-        #-----------------------------------------------------------------------
-        if (!$connected)
-        {
-            $self->debug(1,"Connect: No connection... I have failed... I.. must... end it all...");
-            $self->SetErrorCode("newconnection","Unable to open a connection to destination.  Please check your http_proxy and/or https_proxy environment variables.");
-            return;
-        }
-
-        return unless $self->{SIDS}->{newconnection}->{sock};
-
-        $self->debug(1,"Connect: We are connected");
-
-        if (($self->{SIDS}->{newconnection}->{ssl} == 1) &&
-            (ref($self->{SIDS}->{newconnection}->{sock}) eq "IO::Socket::INET"))
-        {
-            $self->debug(1,"Connect: Convert normal socket to SSL");
-            $self->debug(1,"Connect: sock($self->{SIDS}->{newconnection}->{sock})");
-            $self->LoadSSL();
-            $self->{SIDS}->{newconnection}->{sock} =
-                IO::Socket::SSL::socketToSSL($self->{SIDS}->{newconnection}->{sock},
-                                             {SSL_verify_mode=>0x00});
-            $self->debug(1,"Connect: ssl_sock($self->{SIDS}->{newconnection}->{sock})");
-            $self->debug(1,"Connect: SSL: We are secure") if ($self->{SIDS}->{newconnection}->{sock});
-        }
-        return unless $self->{SIDS}->{newconnection}->{sock};
-    }
-
-    $self->debug(1,"Connect: Got a connection");
-
-    $self->{SIDS}->{newconnection}->{sock}->autoflush(1);
-
-    return $self->OpenStream("newconnection",$timeout);
-}
-
-
-##############################################################################
-#
-# OpenStream - Send the opening stream and save the root element info.
-#
-##############################################################################
-sub OpenStream
-{
-    my $self = shift;
-    my $currsid = shift;
-    my $timeout = shift;
-    $timeout = "" unless defined($timeout);
-
-    $self->InitConnection($currsid,$currsid);
-
-    #---------------------------------------------------------------------------
-    # Next, we build the opening handshake.
-    #---------------------------------------------------------------------------
-    my %stream_args;
-    
-    if (($self->{SIDS}->{$currsid}->{connectiontype} eq "tcpip") ||
-        ($self->{SIDS}->{$currsid}->{connectiontype} eq "http"))
-    {
-        $stream_args{to}= $self->{SIDS}->{$currsid}->{hostname}
-            unless exists($self->{SIDS}->{$currsid}->{to});
-        
-        $stream_args{to} = $self->{SIDS}->{$currsid}->{to}
-            if exists($self->{SIDS}->{$currsid}->{to});
-
-        $stream_args{from} = $self->{SIDS}->{$currsid}->{myhostname}
-            if (!exists($self->{SIDS}->{$currsid}->{from}) &&
-                ($self->{SIDS}->{$currsid}->{myhostname} ne "")
-               );
-        
-        $stream_args{from} = $self->{SIDS}->{$currsid}->{from}
-            if exists($self->{SIDS}->{$currsid}->{from});
-        
-        $stream_args{id} = $self->{SIDS}->{$currsid}->{id}
-            if (exists($self->{SIDS}->{$currsid}->{id}) &&
-                ($self->{SIDS}->{$currsid}->{id} ne "")
-               );
-
-        $stream_args{namespaces} = $self->{SIDS}->{$currsid}->{namespaces};
-    }
-    
-    my $stream =
-        $self->StreamHeader(
-            xmlns=>$self->{SIDS}->{$currsid}->{namespace},
-            xmllang=>"en",
-            %stream_args
-        );
-
-    #---------------------------------------------------------------------------
-    # Create the XML::Stream::Parser and register our callbacks
-    #---------------------------------------------------------------------------
-    $self->{SIDS}->{$currsid}->{parser} =
-        new XML::Stream::Parser(%{$self->{DEBUGARGS}},
-                                nonblocking=>$NONBLOCKING,
-                                sid=>$currsid,
-                                style=>$self->{DATASTYLE},
-                                Handlers=>{
-                                    startElement=>sub{ $self->_handle_root(@_) },
-                                    endElement=>sub{ &{$HANDLERS{$self->{DATASTYLE}}->{endElement}}($self,@_) },
-                                    characters=>sub{ &{$HANDLERS{$self->{DATASTYLE}}->{characters}}($self,@_) },
-                                }
-                               );
-
-    $self->{SIDS}->{$currsid}->{select} =
-        new IO::Select($self->{SIDS}->{$currsid}->{sock});
-
-    if (($self->{SIDS}->{$currsid}->{connectiontype} eq "tcpip") ||
-            ($self->{SIDS}->{$currsid}->{connectiontype} eq "http"))
-    {
-        $self->{SELECT} = new IO::Select($self->{SIDS}->{$currsid}->{sock});
-        $self->{SOCKETS}->{$self->{SIDS}->{$currsid}->{sock}} = "newconnection";
-    }
-
-    if ($self->{SIDS}->{$currsid}->{connectiontype} eq "stdinout")
-    {
-        $self->{SELECT} = new IO::Select(*STDIN);
-        $self->{SOCKETS}->{$self->{SIDS}->{$currsid}->{sock}} = $currsid;
-        $self->{SOCKETS}->{*STDIN} = $currsid;
-        $self->{SIDS}->{$currsid}->{select}->add(*STDIN);
-    }
-
-    $self->{SIDS}->{$currsid}->{status} = 0;
-
-    #---------------------------------------------------------------------------
-    # Then we send the opening handshake.
-    #---------------------------------------------------------------------------
-    $self->Send($currsid,$stream) || return;
-
-    #---------------------------------------------------------------------------
-    # Before going on let's make sure that the server responded with a valid
-    # root tag and that the stream is open.
-    #---------------------------------------------------------------------------
-    my $buff = "";
-    my $timeEnd = ($timeout eq "") ? "" : time + $timeout;
-    while($self->{SIDS}->{$currsid}->{status} == 0)
-    {
-        my $now = time;
-        my $wait = (($timeEnd eq "") || ($timeEnd - $now > 10)) ? 10 :
-                    $timeEnd - $now;
-
-        $self->debug(5,"Connect: can_read(",join(",",$self->{SIDS}->{$currsid}->{select}->can_read(0)),")");
-        if ($self->{SIDS}->{$currsid}->{select}->can_read($wait))
-        {
-            $self->{SIDS}->{$currsid}->{status} = -1
-                unless defined($buff = $self->Read($currsid));
-            return unless($self->{SIDS}->{$currsid}->{status} == 0);
-            return unless($self->ParseStream($currsid,$buff) == 1);
-        }
-        else
-        {
-            if ($timeout ne "")
-            {
-                if (time >= $timeEnd)
-                {
-                    $self->SetErrorCode($currsid,"Timeout limit reached");
-                    return;
-                }
-            }
-        }
-
-        return if($self->{SIDS}->{$currsid}->{select}->has_exception(0));
-    }
-    return if($self->{SIDS}->{$currsid}->{status} != 1);
-
-    $self->debug(3,"Connect: status($self->{SIDS}->{$currsid}->{status})");
-
-    my $sid = $self->GetRoot($currsid)->{id};
-    $| = 1;
-    foreach my $key (keys(%{$self->{SIDS}->{$currsid}}))
-    {
-        $self->{SIDS}->{$sid}->{$key} = $self->{SIDS}->{$currsid}->{$key};
-    }
-    $self->{SIDS}->{$sid}->{parser}->setSID($sid);
-
-    if (($self->{SIDS}->{$sid}->{connectiontype} eq "tcpip") ||
-        ($self->{SIDS}->{$sid}->{connectiontype} eq "http"))
-    {
-        $self->{SOCKETS}->{$self->{SIDS}->{$currsid}->{sock}} = $sid;
-    }
-
-    if ($self->{SIDS}->{$sid}->{connectiontype} eq "stdinout")
-    {
-        $self->{SOCKETS}->{$self->{SIDS}->{$currsid}->{sock}} = $sid;
-        $self->{SOCKETS}->{*STDIN} = $sid;
-    }
-
-    # 08.04.05(Fri) slipstream@yandex.ru for compapility with ejabberd since it reuses stream id
-    delete($self->{SIDS}->{$currsid}) unless ($currsid eq $sid);
-
-    if (exists($self->GetRoot($sid)->{version}) &&
-        ($self->GetRoot($sid)->{version} ne ""))
-    {
-        while(!$self->ReceivedStreamFeatures($sid))
-        {
-            $self->Process(1);
-        }
-    }
-        
-    return $self->GetRoot($sid);
-}
-
-
-##############################################################################
-#
-# OpenFile - starts the stream by opening a file and setting it up so that
-#            Process reads from the filehandle to get the incoming stream.
-#
-##############################################################################
-sub OpenFile
-{
-    my $self = shift;
-    my $file = shift;
-
-    $self->debug(1,"OpenFile: file($file)");
-
-    $self->{SIDS}->{newconnection}->{connectiontype} = "file";
-
-    $self->{SIDS}->{newconnection}->{sock} = new FileHandle($file);
-    $self->{SIDS}->{newconnection}->{sock}->autoflush(1);
-
-    $self->RegisterPrefix("newconnection",&ConstXMLNS("stream"),"stream");
-
-    #---------------------------------------------------------------------------
-    # Create the XML::Stream::Parser and register our callbacks
-    #---------------------------------------------------------------------------
-    $self->{SIDS}->{newconnection}->{parser} =
-        new XML::Stream::Parser(%{$self->{DEBUGARGS}},
-                    nonblocking=>$NONBLOCKING,
-                    sid=>"newconnection",
-                    style=>$self->{DATASTYLE},
-                    Handlers=>{
-                         startElement=>sub{ $self->_handle_root(@_) },
-                         endElement=>sub{ &{$HANDLERS{$self->{DATASTYLE}}->{endElement}}($self,@_) },
-                         characters=>sub{ &{$HANDLERS{$self->{DATASTYLE}}->{characters}}($self,@_) },
-                        }
-                 );
-
-    $self->{SIDS}->{newconnection}->{select} =
-        new IO::Select($self->{SIDS}->{newconnection}->{sock});
-
-    $self->{SELECT} = new IO::Select($self->{SIDS}->{newconnection}->{sock});
-
-    $self->{SIDS}->{newconnection}->{status} = 0;
-
-    my $buff = "";
-    while($self->{SIDS}->{newconnection}->{status} == 0)
-    {
-        $self->debug(5,"OpenFile: can_read(",join(",",$self->{SIDS}->{newconnection}->{select}->can_read(0)),")");
-        if ($self->{SIDS}->{newconnection}->{select}->can_read(0))
-        {
-            $self->{SIDS}->{newconnection}->{status} = -1
-                unless defined($buff = $self->Read("newconnection"));
-            return unless($self->{SIDS}->{newconnection}->{status} == 0);
-            return unless($self->ParseStream("newconnection",$buff) == 1);
-        }
-
-        return if($self->{SIDS}->{newconnection}->{select}->has_exception(0) &&
-                  $self->{SIDS}->{newconnection}->{sock}->error());
-    }
-    return if($self->{SIDS}->{newconnection}->{status} != 1);
-
-
-    my $sid = $self->NewSID();
-    foreach my $key (keys(%{$self->{SIDS}->{newconnection}}))
-    {
-        $self->{SIDS}->{$sid}->{$key} = $self->{SIDS}->{newconnection}->{$key};
-    }
-    $self->{SIDS}->{$sid}->{parser}->setSID($sid);
-
-    $self->{SOCKETS}->{$self->{SIDS}->{newconnection}->{sock}} = $sid;
-
-    delete($self->{SIDS}->{newconnection});
-
-    return $sid;
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Common Functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# Disconnect - sends the closing XML tag and shuts down the socket.
-#
-##############################################################################
-sub Disconnect
-{
-    my $self = shift;
-    my $sid = shift;
-
-    $self->Send($sid,"</stream:stream>");
-    close($self->{SIDS}->{$sid}->{sock})
-        if (($self->{SIDS}->{$sid}->{connectiontype} eq "tcpip") ||
-    ($self->{SIDS}->{$sid}->{connectiontype} eq "http"));
-    delete($self->{SOCKETS}->{$self->{SIDS}->{$sid}->{sock}});
-    foreach my $key (keys(%{$self->{SIDS}->{$sid}}))
-    {
-        delete($self->{SIDS}->{$sid}->{$key});
-    }
-    delete($self->{SIDS}->{$sid});
-}
-
-
-##############################################################################
-#
-# InitConnection - Initialize the connection data structure
-#
-##############################################################################
-sub InitConnection
-{
-    my $self = shift;
-    my $sid = shift;
-    my $serverid = shift;
-
-    #---------------------------------------------------------------------------
-    # Set the default STATUS so that we can keep track of it throughout the
-    # session.
-    #   1 = no errors
-    #   0 = no data has been received yet
-    #  -1 = error from handlers
-    #  -2 = error but keep the connection alive so that we can send some info.
-    #---------------------------------------------------------------------------
-    $self->{SIDS}->{$sid}->{status} = 0;
-
-    #---------------------------------------------------------------------------
-    # A storage place for when we don't have a callback registered and we need
-    # to stockpile the nodes we receive until Process is called and we return
-    # them.
-    #---------------------------------------------------------------------------
-    $self->{SIDS}->{$sid}->{nodes} = ();
-
-    #---------------------------------------------------------------------------
-    # If there is an error on the stream, then we need a place to indicate that.
-    #---------------------------------------------------------------------------
-    $self->{SIDS}->{$sid}->{streamerror} = {};
-
-    #---------------------------------------------------------------------------
-    # Grab the init time so that we can keep the connection alive by sending " "
-    #---------------------------------------------------------------------------
-    $self->{SIDS}->{$sid}->{keepalive} = time;
-
-    #---------------------------------------------------------------------------
-    # Keep track of the "server" we are connected to so we can check stuff
-    # later.
-    #---------------------------------------------------------------------------
-    $self->{SIDS}->{$sid}->{serverid} = $serverid;
-
-    #---------------------------------------------------------------------------
-    # Mark the stream:features as MIA.
-    #---------------------------------------------------------------------------
-    $self->{SIDS}->{$sid}->{streamfeatures}->{received} = 0;
-    
-    #---------------------------------------------------------------------------
-    # First acitivty is the connection... duh. =)
-    #---------------------------------------------------------------------------
-    $self->MarkActivity($sid);
-}
-
-
-##############################################################################
-#
-# ParseStream - takes the incoming stream and makes sure that only full
-#               XML tags gets passed to the parser.  If a full tag has not
-#               read yet, then the Stream saves the incomplete part and
-#               sends the rest to the parser.
-#
-##############################################################################
-sub ParseStream
-{
-    my $self = shift;
-    my $sid = shift;
-    my $stream = shift;
-
-    $stream = "" unless defined($stream);
-
-    $self->debug(3,"ParseStream: sid($sid) stream($stream)");
-
-    $self->{SIDS}->{$sid}->{parser}->parse($stream);
-
-    if (exists($self->{SIDS}->{$sid}->{streamerror}->{type}))
-    {
-        $self->debug(3,"ParseStream: ERROR($self->{SIDS}->{$sid}->{streamerror}->{type})");
-        $self->SetErrorCode($sid,$self->{SIDS}->{$sid}->{streamerror});
-        return 0;
-    }
-
-    return 1;
-}
-
-
-##############################################################################
-#
-# Process - checks for data on the socket and returns a status code depending
-#           on if there was data or not.  If a timeout is not defined in the
-#           call then the timeout defined in Connect() is used.  If a timeout
-#           of 0 is used then the call blocks until it gets some data,
-#           otherwise it returns after the timeout period.
-#
-##############################################################################
-sub Process
-{
-    my $self = shift;
-    my $timeout = shift;
-    $timeout = "" unless defined($timeout);
-
-    $self->debug(4,"Process: timeout($timeout)");
-    #---------------------------------------------------------------------------
-    # We need to keep track of what's going on in the function and tell the
-    # outside world about it so let's return something useful.  We track this
-    # information based on sid:
-    #    -1    connection closed and error
-    #     0    connection open but no data received.
-    #     1    connection open and data received.
-    #   array  connection open and the data that has been collected
-    #          over time (No CallBack specified)
-    #---------------------------------------------------------------------------
-    my %status;
-    foreach my $sid (keys(%{$self->{SIDS}}))
-    {
-        next if ($sid eq "default");
-        $self->debug(5,"Process: initialize sid($sid) status to 0");
-        $status{$sid} = 0;
-    }
-
-    #---------------------------------------------------------------------------
-    # Either block until there is data and we have parsed it all, or wait a
-    # certain period of time and then return control to the user.
-    #---------------------------------------------------------------------------
-    my $block = 1;
-    my $timeEnd = ($timeout eq "") ? "" : time + $timeout;
-    while($block == 1)
-    {
-        $self->debug(4,"Process: let's wait for data");
-
-        my $now = time;
-        my $wait = (($timeEnd eq "") || ($timeEnd - $now > 10)) ? 10 :
-                    $timeEnd - $now;
-
-        foreach my $connection ($self->{SELECT}->can_read($wait))
-        {
-            $self->debug(4,"Process: connection($connection)");
-            $self->debug(4,"Process: sid($self->{SOCKETS}->{$connection})");
-            $self->debug(4,"Process: connection_status($self->{SIDS}->{$self->{SOCKETS}->{$connection}}->{status})");
-
-            next unless (($self->{SIDS}->{$self->{SOCKETS}->{$connection}}->{status} == 1) ||
-                         exists($self->{SIDS}->{$self->{SOCKETS}->{$connection}}->{activitytimeout}));
-
-            my $processit = 1;
-            if (exists($self->{SIDS}->{server}))
-            {
-                foreach my $serverid (@{$self->{SIDS}->{server}})
-                {
-                    if (exists($self->{SIDS}->{$serverid}->{sock}) &&
-                        ($connection == $self->{SIDS}->{$serverid}->{sock}))
-                    {
-                        my $sid = $self->ConnectionAccept($serverid);
-                        $status{$sid} = 0;
-                        $processit = 0;
-                        last;
-                    }
-                }
-            }
-            if ($processit == 1)
-            {
-                my $sid = $self->{SOCKETS}->{$connection};
-                $self->debug(4,"Process: there's something to read");
-                $self->debug(4,"Process: connection($connection) sid($sid)");
-                my $buff;
-                $self->debug(4,"Process: read");
-                $status{$sid} = 1;
-                $self->{SIDS}->{$sid}->{status} = -1
-                    if (!defined($buff = $self->Read($sid)));
-                $buff = "" unless defined($buff);
-                $self->debug(4,"Process: connection_status($self->{SIDS}->{$sid}->{status})");
-                $status{$sid} = -1 unless($self->{SIDS}->{$sid}->{status} == 1);
-                $self->debug(4,"Process: parse($buff)");
-                $status{$sid} = -1 unless($self->ParseStream($sid,$buff) == 1);
-            }
-            $block = 0;
-        }
-
-        if ($timeout ne "")
-        {
-            if (time >= $timeEnd)
-            {
-                $self->debug(4,"Process: Everyone out of the pool! Time to stop blocking.");
-                $block = 0;
-            }
-        }
-
-        $self->debug(4,"Process: timeout($timeout)");
-
-        if (exists($self->{CB}->{update}))
-        {
-            $self->debug(4,"Process: Calling user defined update function");
-            &{$self->{CB}->{update}}();
-        }
-
-        $block = 1 if $self->{SELECT}->can_read(0);
-
-        #---------------------------------------------------------------------
-        # Check for connections that need to be kept alive
-        #---------------------------------------------------------------------
-        $self->debug(4,"Process: check for keepalives");
-        foreach my $sid (keys(%{$self->{SIDS}}))
-        {
-            next if ($sid eq "default");
-            next if ($sid =~ /^server/);
-            next if ($status{$sid} == -1);
-            if ((time - $self->{SIDS}->{$sid}->{keepalive}) > 10)
-            {
-                $self->IgnoreActivity($sid,1);
-                $self->{SIDS}->{$sid}->{status} = -1
-                    if !defined($self->Send($sid," "));
-                $status{$sid} = -1 unless($self->{SIDS}->{$sid}->{status} == 1);
-                if ($status{$sid} == -1)
-                {
-                    $self->debug(2,"Process: Keep-Alive failed.  What the hell happened?!?!");
-                    $self->debug(2,"Process: connection_status($self->{SIDS}->{$sid}->{status})");
-                }
-                $self->IgnoreActivity($sid,0);
-            }
-        }
-        #---------------------------------------------------------------------
-        # Check for connections that have timed out.
-        #---------------------------------------------------------------------
-        $self->debug(4,"Process: check for timeouts");
-        foreach my $sid (keys(%{$self->{SIDS}}))
-        {
-            next if ($sid eq "default");
-            next if ($sid =~ /^server/);
-
-            if (exists($self->{SIDS}->{$sid}->{activitytimeout}))
-            {
-                $self->debug(4,"Process: sid($sid) time(",time,") timeout($self->{SIDS}->{$sid}->{activitytimeout})");
-            }
-            else
-            {
-                $self->debug(4,"Process: sid($sid) time(",time,") timeout(undef)");
-            }
-            
-            $self->Respond($sid)
-                if (exists($self->{SIDS}->{$sid}->{activitytimeout}) &&
-                    defined($self->GetRoot($sid)));
-            $self->Disconnect($sid)
-                if (exists($self->{SIDS}->{$sid}->{activitytimeout}) &&
-                    ((time - $self->{SIDS}->{$sid}->{activitytimeout}) > 10) &&
-                     ($self->{SIDS}->{$sid}->{status} != 1));
-        }
-
-
-        #---------------------------------------------------------------------
-        # If any of the connections have status == -1 then return so that the
-        # user can handle it.
-        #---------------------------------------------------------------------
-        foreach my $sid (keys(%status))
-        {
-            if ($status{$sid} == -1)
-            {
-                $self->debug(4,"Process: sid($sid) is broken... let's tell someone and watch it hit the fan... =)");
-                $block = 0;
-            }
-        }
-
-        $self->debug(2,"Process: block($block)");
-    }
-
-    #---------------------------------------------------------------------------
-    # If the Select has an error then shut this party down.
-    #---------------------------------------------------------------------------
-    foreach my $connection ($self->{SELECT}->has_exception(0))
-    {
-        $self->debug(4,"Process: has_exception sid($self->{SOCKETS}->{$connection})");
-        $status{$self->{SOCKETS}->{$connection}} = -1;
-    }
-
-    #---------------------------------------------------------------------------
-    # If there are data structures that have not been collected return
-    # those, otherwise return the status which indicates if nodes were read or
-    # not.
-    #---------------------------------------------------------------------------
-    foreach my $sid (keys(%status))
-    {
-        $status{$sid} = $self->{SIDS}->{$sid}->{nodes}
-            if (($status{$sid} == 1) &&
-                ($#{$self->{SIDS}->{$sid}->{nodes}} > -1));
-    }
-
-    return %status;
-}
-
-
-##############################################################################
-#
-# Read - Takes the data from the server and returns a string
-#
-##############################################################################
-sub Read
-{
-    my $self = shift;
-    my $sid = shift;
-    my $buff;
-    my $status = 1;
-
-    $self->debug(3,"Read: sid($sid)");
-    $self->debug(3,"Read: connectionType($self->{SIDS}->{$sid}->{connectiontype})");
-    $self->debug(3,"Read: socket($self->{SIDS}->{$sid}->{sock})");
-
-    return if ($self->{SIDS}->{$sid}->{status} == -1);
-
-    if (!defined($self->{SIDS}->{$sid}->{sock}))
-    {
-        $self->{SIDS}->{$sid}->{status} = -1;
-        $self->SetErrorCode($sid,"Socket does not defined.");
-        return;
-    }
-
-    $self->{SIDS}->{$sid}->{sock}->flush();
-
-    $status = $self->{SIDS}->{$sid}->{sock}->sysread($buff,4*POSIX::BUFSIZ)
-        if (($self->{SIDS}->{$sid}->{connectiontype} eq "tcpip") ||
-    ($self->{SIDS}->{$sid}->{connectiontype} eq "http") ||
-    ($self->{SIDS}->{$sid}->{connectiontype} eq "file"));
-    $status = sysread(STDIN,$buff,1024)
-        if ($self->{SIDS}->{$sid}->{connectiontype} eq "stdinout");
-
-    $buff =~ s/^HTTP[\S\s]+\n\n// if ($self->{SIDS}->{$sid}->{connectiontype} eq "http");
-    $self->debug(1,"Read: buff($buff)");
-    $self->debug(3,"Read: status($status)") if defined($status);
-    $self->debug(3,"Read: status(undef)") unless defined($status);
-    $self->{SIDS}->{$sid}->{keepalive} = time
-        unless (($buff eq "") || !defined($status) || ($status == 0));
-    if (defined($status) && ($status != 0))
-    {
-        $buff = Encode::decode_utf8($buff);
-        return $buff;
-    }
-    #return $buff unless (!defined($status) || ($status == 0));
-    $self->debug(1,"Read: ERROR");
-    return;
-}
-
-
-##############################################################################
-#
-# Send - Takes the data string and sends it to the server
-#
-##############################################################################
-sub Send
-{
-    my $self = shift;
-    my $sid = shift;
-    $self->debug(1,"Send: (@_)");
-    $self->debug(3,"Send: sid($sid)");
-    $self->debug(3,"Send: status($self->{SIDS}->{$sid}->{status})");
-    
-    $self->{SIDS}->{$sid}->{keepalive} = time;
-
-    return if ($self->{SIDS}->{$sid}->{status} == -1);
-
-    if (!defined($self->{SIDS}->{$sid}->{sock}))
-    {
-        $self->debug(3,"Send: socket not defined");
-        $self->{SIDS}->{$sid}->{status} = -1;
-        $self->SetErrorCode($sid,"Socket not defined.");
-        return;
-    }
-    else
-    {
-        $self->debug(3,"Send: socket($self->{SIDS}->{$sid}->{sock})");
-    }
-
-    $self->{SIDS}->{$sid}->{sock}->flush();
-
-    if ($self->{SIDS}->{$sid}->{select}->can_write(0))
-    {
-        $self->debug(3,"Send: can_write");
-
-        $self->{SENDSTRING} = Encode::encode_utf8(join("",@_));
-
-        $self->{SENDWRITTEN} = 0;
-        $self->{SENDOFFSET} = 0;
-        $self->{SENDLENGTH} = length($self->{SENDSTRING});
-        while ($self->{SENDLENGTH})
-        {
-            $self->{SENDWRITTEN} = $self->{SIDS}->{$sid}->{sock}->syswrite($self->{SENDSTRING},$self->{SENDLENGTH},$self->{SENDOFFSET});
-
-            if (!defined($self->{SENDWRITTEN}))
-            {
-                $self->debug(4,"Send: SENDWRITTEN(undef)");
-                $self->debug(4,"Send: Ok... what happened?  Did we lose the connection?");
-                $self->{SIDS}->{$sid}->{status} = -1;
-                $self->SetErrorCode($sid,"Socket died for an unknown reason.");
-                return;
-            }
-            
-            $self->debug(4,"Send: SENDWRITTEN($self->{SENDWRITTEN})");
-
-            $self->{SENDLENGTH} -= $self->{SENDWRITTEN};
-            $self->{SENDOFFSET} += $self->{SENDWRITTEN};
-        }
-    }
-    else
-    {
-        $self->debug(3,"Send: can't write...");
-    }
-
-    return if($self->{SIDS}->{$sid}->{select}->has_exception(0));
-
-    $self->debug(3,"Send: no exceptions");
-
-    $self->{SIDS}->{$sid}->{keepalive} = time;
-
-    $self->MarkActivity($sid);
-
-    return 1;
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Feature Functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# ProcessStreamFeatures - process the <stream:featutres/> block.
-#
-##############################################################################
-sub ProcessStreamFeatures
-{
-    my $self = shift;
-    my $sid = shift;
-    my $node = shift;
-
-    $self->{SIDS}->{$sid}->{streamfeatures}->{received} = 1;
-
-    #-------------------------------------------------------------------------
-    # SASL - 1.0
-    #-------------------------------------------------------------------------
-    my @sasl = &XPath($node,'*[@xmlns="'.&ConstXMLNS('xmpp-sasl').'"]');
-    if ($#sasl > -1)
-    {
-        if (&XPath($sasl[0],"name()") eq "mechanisms")
-        {
-            my @mechanisms = &XPath($sasl[0],"mechanism/text()");
-            $self->{SIDS}->{$sid}->{streamfeatures}->{'xmpp-sasl'} = \@mechanisms;
-        }
-    }
-    
-    #-------------------------------------------------------------------------
-    # XMPP-TLS - 1.0
-    #-------------------------------------------------------------------------
-    my @tls = &XPath($node,'*[@xmlns="'.&ConstXMLNS('xmpp-tls').'"]');
-    if ($#tls > -1)
-    {
-        if (&XPath($tls[0],"name()") eq "starttls")
-        {
-            $self->{SIDS}->{$sid}->{streamfeatures}->{'xmpp-tls'} = 1;
-            my @required = &XPath($tls[0],"required");
-            if ($#required > -1)
-            {
-                $self->{SIDS}->{$sid}->{streamfeatures}->{'xmpp-tls'} = "required";
-            }
-        }
-    }
-    
-    #-------------------------------------------------------------------------
-    # XMPP-Bind - 1.0
-    #-------------------------------------------------------------------------
-    my @bind = &XPath($node,'*[@xmlns="'.&ConstXMLNS('xmpp-bind').'"]');
-    if ($#bind > -1)
-    {
-        $self->{SIDS}->{$sid}->{streamfeatures}->{'xmpp-bind'} = 1;
-    }
-    
-    #-------------------------------------------------------------------------
-    # XMPP-Session - 1.0
-    #-------------------------------------------------------------------------
-    my @session = &XPath($node,'*[@xmlns="'.&ConstXMLNS('xmpp-session').'"]');
-    if ($#session > -1)
-    {
-        $self->{SIDS}->{$sid}->{streamfeatures}->{'xmpp-session'} = 1;
-    }
-    
-}
-
-
-##############################################################################
-#
-# GetStreamFeature - Return the value of the stream feature (if any).
-#
-##############################################################################
-sub GetStreamFeature
-{
-    my $self = shift;
-    my $sid = shift;
-    my $feature = shift;
-
-    return unless exists($self->{SIDS}->{$sid}->{streamfeatures}->{$feature});
-    return $self->{SIDS}->{$sid}->{streamfeatures}->{$feature};
-}
-
-
-##############################################################################
-#
-# ReceivedStreamFeatures - Have we received the stream:features yet?
-#
-##############################################################################
-sub ReceivedStreamFeatures
-{
-    my $self = shift;
-    my $sid = shift;
-    my $feature = shift;
-
-    return $self->{SIDS}->{$sid}->{streamfeatures}->{received};
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| TLS Functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# ProcessTLSPacket - process a TLS based packet.
-#
-##############################################################################
-sub ProcessTLSPacket
-{
-    my $self = shift;
-    my $sid = shift;
-    my $node = shift;
-
-    my $tag = &XPath($node,"name()");
-
-    if ($tag eq "failure")
-    {
-        $self->TLSClientFailure($sid,$node);
-    }
-    
-    if ($tag eq "proceed")
-    {
-        $self->TLSClientProceed($sid,$node);
-    }
-}
-
-
-##############################################################################
-#
-# StartTLS - client function to have the socket start TLS.
-#
-##############################################################################
-sub StartTLS
-{
-    my $self = shift;
-    my $sid = shift;
-    my $timeout = shift;
-    $timeout = 120 unless defined($timeout);
-    $timeout = 120 if ($timeout eq "");
-    
-    $self->TLSStartTLS($sid);
-
-    my $endTime = time + $timeout;
-    while(!$self->TLSClientDone($sid) && ($endTime >= time))
-    {
-        $self->Process(1);
-    }
-
-    if (!$self->TLSClientSecure($sid))
-    {
-        return;
-    }
-
-    return $self->OpenStream($sid,$timeout);
-}
-
-
-##############################################################################
-#
-# TLSStartTLS - send a <starttls/> in the TLS namespace.
-#
-##############################################################################
-sub TLSStartTLS
-{
-    my $self = shift;
-    my $sid = shift;
-
-    $self->Send($sid,"<starttls xmlns='".&ConstXMLNS('xmpp-tls')."'/>");
-}
-
-
-##############################################################################
-#
-# TLSClientProceed - handle a <proceed/> packet.
-#
-##############################################################################
-sub TLSClientProceed
-{
-    my $self = shift;
-    my $sid = shift;
-    my $node = shift;
-
-    $self->debug(1,"TLSClientProceed: Convert normal socket to SSL");
-    $self->debug(1,"TLSClientProceed: sock($self->{SIDS}->{$sid}->{sock})");
-    if (!$self->LoadSSL())
-    {
-        $self->{SIDS}->{$sid}->{tls}->{error} = "Could not load IO::Socket::SSL.";
-        $self->{SIDS}->{$sid}->{tls}->{done} = 1;
-        return;
-    }
-    
-    IO::Socket::SSL->start_SSL($self->{SIDS}->{$sid}->{sock},{SSL_verify_mode=>0x00});
-
-    $self->debug(1,"TLSClientProceed: ssl_sock($self->{SIDS}->{$sid}->{sock})");
-    $self->debug(1,"TLSClientProceed: SSL: We are secure")
-        if ($self->{SIDS}->{$sid}->{sock});
-    
-    $self->{SIDS}->{$sid}->{tls}->{done} = 1;
-    $self->{SIDS}->{$sid}->{tls}->{secure} = 1;
-}
-
-
-##############################################################################
-#
-# TLSClientSecure - return 1 if the socket is secure, 0 otherwise.
-#
-##############################################################################
-sub TLSClientSecure
-{
-    my $self = shift;
-    my $sid = shift;
-    
-    return $self->{SIDS}->{$sid}->{tls}->{secure};
-}
-
-
-##############################################################################
-#
-# TLSClientDone - return 1 if the TLS process is done
-#
-##############################################################################
-sub TLSClientDone
-{
-    my $self = shift;
-    my $sid = shift;
-    
-    return $self->{SIDS}->{$sid}->{tls}->{done};
-}
-
-
-##############################################################################
-#
-# TLSClientError - return the TLS error if any
-#
-##############################################################################
-sub TLSClientError
-{
-    my $self = shift;
-    my $sid = shift;
-    
-    return $self->{SIDS}->{$sid}->{tls}->{error};
-}
-
-
-##############################################################################
-#
-# TLSClientFailure - handle a <failure/>
-#
-##############################################################################
-sub TLSClientFailure
-{
-    my $self = shift;
-    my $sid = shift;
-    my $node = shift;
-    
-    my $type = &XPath($node,"*/name()");
-
-    $self->{SIDS}->{$sid}->{tls}->{error} = $type;
-    $self->{SIDS}->{$sid}->{tls}->{done} = 1;
-}
-
-
-##############################################################################
-#
-# TLSFailure - Send a <failure/> in the TLS namespace
-#
-##############################################################################
-sub TLSFailure
-{
-    my $self = shift;
-    my $sid = shift;
-    my $type = shift;
-    
-    $self->Send($sid,"<failure xmlns='".&ConstXMLNS('xmpp-tls')."'><${type}/></failure>");
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| SASL Functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# ProcessSASLPacket - process a SASL based packet.
-#
-##############################################################################
-sub ProcessSASLPacket
-{
-    my $self = shift;
-    my $sid = shift;
-    my $node = shift;
-
-    my $tag = &XPath($node,"name()");
-
-    if ($tag eq "challenge")
-    {
-        $self->SASLAnswerChallenge($sid,$node);
-    }
-    
-    if ($tag eq "failure")
-    {
-        $self->SASLClientFailure($sid,$node);
-    }
-    
-    if ($tag eq "success")
-    {
-        $self->SASLClientSuccess($sid,$node);
-    }
-}
-
-
-##############################################################################
-#
-# SASLAnswerChallenge - when we get a <challenge/> we need to do the grunt
-#                       work to return a <response/>.
-#
-##############################################################################
-sub SASLAnswerChallenge
-{
-    my $self = shift;
-    my $sid = shift;
-    my $node = shift;
-
-    my $challenge64 = &XPath($node,"text()");
-    my $challenge = MIME::Base64::decode_base64($challenge64);
-    
-    #-------------------------------------------------------------------------
-    # As far as I can tell, if the challenge contains rspauth, then we authed.
-    # If you try to send that to Authen::SASL, it will spew warnings about
-    # the missing qop, nonce, etc...  However, in order for jabberd2 to think
-    # that you answered, you have to send back an empty response.  Not sure
-    # which approach is right... So let's hack for now.
-    #-------------------------------------------------------------------------
-    my $response = "";
-    if ($challenge !~ /rspauth\=/)
-    {
-        $response = $self->{SIDS}->{$sid}->{sasl}->{client}->client_step($challenge);
-    }
-
-    my $response64 = MIME::Base64::encode_base64($response,"");
-    $self->SASLResponse($sid,$response64);
-}
-
-
-##############################################################################
-#
-# SASLAuth - send an <auth/> in the SASL namespace
-#
-##############################################################################
-sub SASLAuth
-{
-    my $self = shift;
-    my $sid = shift;
-
-    my $first_step = $self->{SIDS}->{$sid}->{sasl}->{client}->client_start();
-    my $first_step64 = MIME::Base64::encode_base64($first_step,"");
-
-    $self->Send($sid,"<auth xmlns='".&ConstXMLNS('xmpp-sasl')."' mechanism='".$self->{SIDS}->{$sid}->{sasl}->{client}->mechanism()."'>".$first_step64."</auth>");
-}
-
-
-##############################################################################
-#
-# SASLChallenge - Send a <challenge/> in the SASL namespace
-#
-##############################################################################
-sub SASLChallenge
-{
-    my $self = shift;
-    my $sid = shift;
-    my $challenge = shift;
-
-    $self->Send($sid,"<challenge xmlns='".&ConstXMLNS('xmpp-sasl')."'>${challenge}</challenge>");
-}
-
-
-###############################################################################
-#
-# SASLClient - This is a helper function to perform all of the required steps
-#              for doing SASL with the server.
-#
-###############################################################################
-sub SASLClient
-{
-    my $self = shift;
-    my $sid = shift;
-    my $username = shift;
-    my $password = shift;
-
-    my $mechanisms = $self->GetStreamFeature($sid,"xmpp-sasl");
-
-    return unless defined($mechanisms);
-    
-    my $sasl = new Authen::SASL(mechanism=>join(" ",@{$mechanisms}),
-                                callback=>{
-#                                           authname => $username."@".$self->{SIDS}->{$sid}->{hostname},
-                                           user     => $username,
-                                           pass     => $password
-                                          }
-                               );
-
-    $self->{SIDS}->{$sid}->{sasl}->{client} = $sasl->client_new('xmpp', $self->{SIDS}->{$sid}->{hostname});
-    $self->{SIDS}->{$sid}->{sasl}->{username} = $username;
-    $self->{SIDS}->{$sid}->{sasl}->{password} = $password;
-    $self->{SIDS}->{$sid}->{sasl}->{authed} = 0;
-    $self->{SIDS}->{$sid}->{sasl}->{done} = 0;
-
-    $self->SASLAuth($sid);
-}
-
-
-##############################################################################
-#
-# SASLClientAuthed - return 1 if we authed via SASL, 0 otherwise
-#
-##############################################################################
-sub SASLClientAuthed
-{
-    my $self = shift;
-    my $sid = shift;
-    
-    return $self->{SIDS}->{$sid}->{sasl}->{authed};
-}
-
-
-##############################################################################
-#
-# SASLClientDone - return 1 if the SASL process is finished
-#
-##############################################################################
-sub SASLClientDone
-{
-    my $self = shift;
-    my $sid = shift;
-    
-    return $self->{SIDS}->{$sid}->{sasl}->{done};
-}
-
-
-##############################################################################
-#
-# SASLClientError - return the error if any
-#
-##############################################################################
-sub SASLClientError
-{
-    my $self = shift;
-    my $sid = shift;
-    
-    return $self->{SIDS}->{$sid}->{sasl}->{error};
-}
-
-
-##############################################################################
-#
-# SASLClientFailure - handle a received <failure/>
-#
-##############################################################################
-sub SASLClientFailure
-{
-    my $self = shift;
-    my $sid = shift;
-    my $node = shift;
-    
-    my $type = &XPath($node,"*/name()");
-
-    $self->{SIDS}->{$sid}->{sasl}->{error} = $type;
-    $self->{SIDS}->{$sid}->{sasl}->{done} = 1;
-}
-
-
-##############################################################################
-#
-# SASLClientSuccess - handle a received <success/>
-#
-##############################################################################
-sub SASLClientSuccess
-{
-    my $self = shift;
-    my $sid = shift;
-    my $node = shift;
-    
-    $self->{SIDS}->{$sid}->{sasl}->{authed} = 1;
-    $self->{SIDS}->{$sid}->{sasl}->{done} = 1;
-}
-
-
-##############################################################################
-#
-# SASLFailure - Send a <failure/> tag in the SASL namespace
-#
-##############################################################################
-sub SASLFailure
-{
-    my $self = shift;
-    my $sid = shift;
-    my $type = shift;
-    
-    $self->Send($sid,"<failure xmlns='".&ConstXMLNS('xmpp-sasl')."'><${type}/></failure>");
-}
-
-
-##############################################################################
-#
-# SASLResponse - Send a <response/> tag in the SASL namespace
-#
-##############################################################################
-sub SASLResponse
-{
-    my $self = shift;
-    my $sid = shift;
-    my $response = shift;
-
-    $self->Send($sid,"<response xmlns='".&ConstXMLNS('xmpp-sasl')."'>${response}</response>");
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Packet Handlers
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-
-##############################################################################
-#
-# ProcessStreamPacket - process the <stream:XXXX/> packet
-#
-##############################################################################
-sub ProcessStreamPacket
-{
-    my $self = shift;
-    my $sid = shift;
-    my $node = shift;
-
-    my $tag = &XPath($node,"name()");
-    my $stream_prefix = $self->StreamPrefix($sid);
-    my ($type) = ($tag =~ /^${stream_prefix}\:(.+)$/);
-
-    $self->ProcessStreamError($sid,$node) if ($type eq "error");
-    $self->ProcessStreamFeatures($sid,$node) if ($type eq "features");
-}
-
-
-##############################################################################
-#
-# _handle_root - handles a root tag and checks that it is a stream:stream tag
-#                with the proper namespace.  If not then it sets the STATUS
-#                to -1 and let's the outer code know that an error occurred.
-#                Then it changes the Start tag handlers to the methond listed
-#                in $self->{DATASTYLE}
-#
-##############################################################################
-sub _handle_root
-{
-    my $self = shift;
-    my ($sax, $tag, %att) = @_;
-    my $sid = $sax->getSID();
-
-    $self->debug(2,"_handle_root: sid($sid) sax($sax) tag($tag) att(",%att,")");
-
-    $self->{SIDS}->{$sid}->{rootTag} = $tag;
-
-    if ($self->{SIDS}->{$sid}->{connectiontype} ne "file")
-    {
-        #---------------------------------------------------------------------
-        # Make sure we are receiving a valid stream on the same namespace.
-        #---------------------------------------------------------------------
-        
-        $self->debug(3,"_handle_root: ($self->{SIDS}->{$self->{SIDS}->{$sid}->{serverid}}->{namespace})");
-        $self->{SIDS}->{$sid}->{status} =
-            ((($tag eq "stream:stream") &&
-               exists($att{'xmlns'}) &&
-               ($att{'xmlns'} eq $self->{SIDS}->{$self->{SIDS}->{$sid}->{serverid}}->{namespace})
-              ) ?
-              1 :
-              -1
-            );
-        $self->debug(3,"_handle_root: status($self->{SIDS}->{$sid}->{status})");
-    }
-    else
-    {
-        $self->{SIDS}->{$sid}->{status} = 1;
-    }
-
-    #-------------------------------------------------------------------------
-    # Get the root tag attributes and save them for later.  You never know when
-    # you'll need to check the namespace or the from attributes sent by the
-    # server.
-    #-------------------------------------------------------------------------
-    $self->{SIDS}->{$sid}->{root} = \%att;
-
-    #-------------------------------------------------------------------------
-    # Run through the various xmlns:*** attributes and register the namespace
-    # to prefix map.
-    #-------------------------------------------------------------------------
-    foreach my $key (keys(%att))
-    {
-        if ($key =~ /^xmlns\:(.+?)$/)
-        {
-            $self->debug(5,"_handle_root: RegisterPrefix: prefix($att{$key}) ns($1)");
-            $self->RegisterPrefix($sid,$att{$key},$1);
-        }
-    }
-    
-    #-------------------------------------------------------------------------
-    # Sometimes we will get an error, so let's parse the tag assuming that we
-    # got a stream:error
-    #-------------------------------------------------------------------------
-    my $stream_prefix = $self->StreamPrefix($sid);
-    $self->debug(5,"_handle_root: stream_prefix($stream_prefix)");
-    
-    if ($tag eq $stream_prefix.":error")
-    {
-        &XML::Stream::Tree::_handle_element($self,$sax,$tag,%att)
-            if ($self->{DATASTYLE} eq "tree");
-        &XML::Stream::Node::_handle_element($self,$sax,$tag,%att)
-            if ($self->{DATASTYLE} eq "node");
-    }
-
-    #---------------------------------------------------------------------------
-    # Now that we have gotten a root tag, let's look for the tags that make up
-    # the stream.  Change the handler for a Start tag to another function.
-    #---------------------------------------------------------------------------
-    $sax->setHandlers(startElement=>sub{ &{$HANDLERS{$self->{DATASTYLE}}->{startElement}}($self,@_) },
-                endElement=>sub{ &{$HANDLERS{$self->{DATASTYLE}}->{endElement}}($self,@_) },
-                characters=>sub{ &{$HANDLERS{$self->{DATASTYLE}}->{characters}}($self,@_) },
-             );
-}
-
-
-##############################################################################
-#
-# _node - internal callback for nodes.  All it does is place the nodes in a
-#         list so that Process() can return them later.
-#
-##############################################################################
-sub _node
-{
-    my $self = shift;
-    my $sid = shift;
-    my @node = shift;
-
-    if (ref($node[0]) eq "XML::Stream::Node")
-    {
-        push(@{$self->{SIDS}->{$sid}->{nodes}},$node[0]);
-    }
-    else
-    {
-        push(@{$self->{SIDS}->{$sid}->{nodes}},\@node);
-    }
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Error Functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# GetErrorCode - if you are returned an undef, you can call this function
-#                and hopefully learn more information about the problem.
-#
-##############################################################################
-sub GetErrorCode
-{
-    my $self = shift;
-    my $sid = shift;
-
-    $sid = "newconnection" unless defined($sid);
-
-    $self->debug(3,"GetErrorCode: sid($sid)");
-    return ((exists($self->{SIDS}->{$sid}->{errorcode}) &&
-             (ref($self->{SIDS}->{$sid}->{errorcode}) eq "HASH")) ?
-            $self->{SIDS}->{$sid}->{errorcode} :
-            { type=>"system",
-              text=>$!,
-            }
-           );
-}
-
-
-##############################################################################
-#
-# SetErrorCode - sets the error code so that the caller can find out more
-#                information about the problem
-#
-##############################################################################
-sub SetErrorCode
-{
-    my $self = shift;
-    my $sid = shift;
-    my $errorcode = shift;
-
-    $self->{SIDS}->{$sid}->{errorcode} = $errorcode;
-}
-
-
-##############################################################################
-#
-# ProcessStreamError - Take the XML packet and extract out the error.
-#
-##############################################################################
-sub ProcessStreamError
-{
-    my $self = shift;
-    my $sid = shift;
-    my $node = shift;
-
-    $self->{SIDS}->{$sid}->{streamerror}->{type} = "unknown";
-    $self->{SIDS}->{$sid}->{streamerror}->{node} = $node;
-    
-    #-------------------------------------------------------------------------
-    # Check for older 0.9 streams and handle the errors for them.
-    #-------------------------------------------------------------------------
-    if (!exists($self->{SIDS}->{$sid}->{root}->{version}) ||
-        ($self->{SIDS}->{$sid}->{root}->{version} eq "") ||
-        ($self->{SIDS}->{$sid}->{root}->{version} < 1.0)
-       )
-    {
-        $self->{SIDS}->{$sid}->{streamerror}->{text} =
-            &XPath($node,"text()");
-        return;
-    }
-
-    #-------------------------------------------------------------------------
-    # Otherwise we are in XMPP land with real stream errors.
-    #-------------------------------------------------------------------------
-    my @errors = &XPath($node,'*[@xmlns="'.&ConstXMLNS("xmppstreams").'"]');
-
-    my $type;
-    my $text;
-    foreach my $error (@errors)
-    {
-        if (&XPath($error,"name()") eq "text")
-        {
-            $self->{SIDS}->{$sid}->{streamerror}->{text} =
-                &XPath($error,"text()");
-        }
-        else
-        {
-            $self->{SIDS}->{$sid}->{streamerror}->{type} =
-                &XPath($error,"name()");
-        }
-    }
-}
-
-
-##############################################################################
-#
-# StreamError - Given a type and text, generate a <stream:error/> packet to
-#               send back to the other side.
-#
-##############################################################################
-sub StreamError
-{
-    my $self = shift;
-    my $sid = shift;
-    my $type = shift;
-    my $text = shift;
-
-    my $root = $self->GetRoot($sid);
-    my $stream_base = $self->StreamPrefix($sid);
-    my $error = "<${stream_base}:error>";
-
-    if (exists($root->{version}) && ($root->{version} ne ""))
-    {
-        $error .= "<${type} xmlns='".&ConstXMLNS('xmppstreams')."'/>";
-        if (defined($text))
-        {
-            $error .= "<text xmlns='".&ConstXMLNS('xmppstreams')."'>";
-            $error .= $text;
-            $error .= "</text>";
-        }
-    }
-    else
-    {
-        $error .= $text;
-    }
-
-    $error .= "</${stream_base}:error>";
-
-    return $error;
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Activity Monitoring Functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# IgnoreActivity - Set the flag that will ignore the activity monitor.
-#
-##############################################################################
-sub IgnoreActivity
-{
-    my $self = shift;
-    my $sid = shift;
-    my $ignoreActivity = shift;
-    $ignoreActivity = 1 unless defined($ignoreActivity);
-
-    $self->debug(3,"IgnoreActivity: ignoreActivity($ignoreActivity)");
-    $self->debug(4,"IgnoreActivity: sid($sid)");
-
-    $self->{SIDS}->{$sid}->{ignoreActivity} = $ignoreActivity;
-}
-
-
-##############################################################################
-#
-# LastActivity - Return the time of the last activity.
-#
-##############################################################################
-sub LastActivity
-{
-    my $self = shift;
-    my $sid = shift;
-
-    $self->debug(3,"LastActivity: sid($sid)");
-    $self->debug(1,"LastActivity: lastActivity($self->{SIDS}->{$sid}->{lastActivity})");
-
-    return $self->{SIDS}->{$sid}->{lastActivity};
-}
-
-
-##############################################################################
-#
-# MarkActivity - Record the current time for this sid.
-#
-##############################################################################
-sub MarkActivity
-{
-    my $self = shift;
-    my $sid = shift;
-
-    return if (exists($self->{SIDS}->{$sid}->{ignoreActivity}) &&
-               ($self->{SIDS}->{$sid}->{ignoreActivity} == 1));
-
-    $self->debug(3,"MarkActivity: sid($sid)");
-
-    $self->{SIDS}->{$sid}->{lastActivity} = time;
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| XML Node Interface functions
-#|
-#|   These are generic wrappers around the Tree and Node data types.  The
-#| problem being that the Tree class cannot support methods.
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# SetXMLData - takes a host of arguments and sets a portion of the specified
-#              data strucure with that data.  The function works in two
-#              modes "single" or "multiple".  "single" denotes that the
-#              function should locate the current tag that matches this
-#              data and overwrite it's contents with data passed in.
-#              "multiple" denotes that a new tag should be created even if
-#              others exist.
-#
-#              type    - single or multiple
-#              XMLTree - pointer to XML::Stream data object (tree or node)
-#              tag     - name of tag to create/modify (if blank assumes
-#                        working with top level tag)
-#              data    - CDATA to set for tag
-#              attribs - attributes to ADD to tag
-#
-##############################################################################
-sub SetXMLData
-{
-    return &XML::Stream::Node::SetXMLData(@_) if (ref($_[1]) eq "XML::Stream::Node");
-    return &XML::Stream::Tree::SetXMLData(@_) if (ref($_[1]) eq "ARRAY");
-}
-
-
-##############################################################################
-#
-# GetXMLData - takes a host of arguments and returns various data structures
-#              that match them.
-#
-#              type - "existence" - returns 1 or 0 if the tag exists in the
-#                                   top level.
-#                     "value" - returns either the CDATA of the tag, or the
-#                               value of the attribute depending on which is
-#                               sought.  This ignores any mark ups to the data
-#                               and just returns the raw CDATA.
-#                     "value array" - returns an array of strings representing
-#                                     all of the CDATA in the specified tag.
-#                                     This ignores any mark ups to the data
-#                                     and just returns the raw CDATA.
-#                     "tree" - returns a data structure that represents the
-#                              XML with the specified tag as the root tag.
-#                              Depends on the format that you are working with.
-#                     "tree array" - returns an array of data structures each
-#                                    with the specified tag as the root tag.
-#                     "child array" - returns a list of all children nodes
-#                                     not including CDATA nodes.
-#                     "attribs" - returns a hash with the attributes, and
-#                                 their values, for the things that match
-#                                 the parameters
-#                     "count" - returns the number of things that match
-#                               the arguments
-#                     "tag" - returns the root tag of this tree
-#              XMLTree - pointer to XML::Stream data structure
-#              tag     - tag to pull data from.  If blank then the top level
-#                        tag is accessed.
-#              attrib  - attribute value to retrieve.  Ignored for types
-#                        "value array", "tree", "tree array".  If paired
-#                        with value can be used to filter tags based on
-#                        attributes and values.
-#              value   - only valid if an attribute is supplied.  Used to
-#                        filter for tags that only contain this attribute.
-#                        Useful to search through multiple tags that all
-#                        reference different name spaces.
-#
-##############################################################################
-sub GetXMLData
-{
-    return &XML::Stream::Node::GetXMLData(@_) if (ref($_[1]) eq "XML::Stream::Node");
-    return &XML::Stream::Tree::GetXMLData(@_) if (ref($_[1]) eq "ARRAY");
-}
-
-
-##############################################################################
-#
-# XPath - run an xpath query on a node and return back the result.
-#
-##############################################################################
-sub XPath
-{
-    my $tree = shift;
-    my $path = shift;
-    
-    my $query = new XML::Stream::XPath::Query($path);
-    my $result = $query->execute($tree);
-    if ($result->check())
-    {
-        my %attribs = $result->getAttribs();
-        return %attribs if (scalar(keys(%attribs)) > 0);
-        
-        my @values = $result->getValues();
-        @values = $result->getList() unless ($#values > -1);
-        return @values if wantarray;
-        return $values[0];
-    }
-    return;
-}
-
-
-##############################################################################
-#
-# XPathCheck - run an xpath query on a node and return 1 or 0 if the path is
-#              valid.
-#
-##############################################################################
-sub XPathCheck
-{
-    my $tree = shift;
-    my $path = shift;
-    
-    my $query = new XML::Stream::XPath::Query($path);
-    my $result = $query->execute($tree);
-    return $result->check();
-}
-
-
-##############################################################################
-#
-# XML2Config - takes an XML data tree and turns it into a hash of hashes.
-#              This only works for certain kinds of XML trees like this:
-#
-#                <foo>
-#                  <bar>1</bar>
-#                  <x>
-#                    <y>foo</y>
-#                  </x>
-#                  <z>5</z>
-#                  <z>6</z>
-#                </foo>
-#
-#              The resulting hash would be:
-#
-#                $hash{bar} = 1;
-#                $hash{x}->{y} = "foo";
-#                $hash{z}->[0] = 5;
-#                $hash{z}->[1] = 6;
-#
-#              Good for config files.
-#
-##############################################################################
-sub XML2Config
-{
-    return &XML::Stream::Node::XML2Config(@_) if (ref($_[0]) eq "XML::Stream::Node");
-    return &XML::Stream::Tree::XML2Config(@_) if (ref($_[0]) eq "ARRAY");
-}
-
-
-##############################################################################
-#
-# Config2XML - takes a hash and produces an XML string from it.  If the hash
-#              looks like this:
-#
-#                $hash{bar} = 1;
-#                $hash{x}->{y} = "foo";
-#                $hash{z}->[0] = 5;
-#                $hash{z}->[1] = 6;
-#
-#              The resulting xml would be:
-#
-#                <foo>
-#                  <bar>1</bar>
-#                  <x>
-#                    <y>foo</y>
-#                  </x>
-#                  <z>5</z>
-#                  <z>6</z>
-#                </foo>
-#
-#              Good for config files.
-#
-##############################################################################
-sub Config2XML
-{
-    my ($tag,$hash,$indent) = @_;
-    $indent = "" unless defined($indent);
-
-    my $xml;
-
-    if (ref($hash) eq "ARRAY")
-    {
-        foreach my $item (@{$hash})
-        {
-            $xml .= &XML::Stream::Config2XML($tag,$item,$indent);
-        }
-    }
-    else
-    {
-        if ((ref($hash) eq "HASH") && ((scalar keys(%{$hash})) == 0))
-        {
-            $xml .= "$indent<$tag/>\n";
-        }
-        else
-        {
-            if (ref($hash) eq "")
-            {
-                if ($hash eq "")
-                {
-                    return "$indent<$tag/>\n";
-                }
-                else
-                {
-                    return "$indent<$tag>$hash</$tag>\n";
-                }
-            }
-            else
-            {
-                $xml .= "$indent<$tag>\n";
-                foreach my $item (sort {$a cmp $b} keys(%{$hash}))
-                {
-                    $xml .= &XML::Stream::Config2XML($item,$hash->{$item},"  $indent");
-                }
-                $xml .= "$indent</$tag>\n";
-            }
-        }
-    }
-    return $xml;
-}
-
-
-##############################################################################
-#
-# EscapeXML - Simple function to make sure that no bad characters make it into
-#             in the XML string that might cause the string to be
-#             misinterpreted.
-#
-##############################################################################
-sub EscapeXML
-{
-    my $data = shift;
-
-    if (defined($data))
-    {
-        $data =~ s/&/&amp;/g;
-        $data =~ s/</&lt;/g;
-        $data =~ s/>/&gt;/g;
-        $data =~ s/\"/&quot;/g;
-        $data =~ s/\'/&apos;/g;
-    }
-
-    return $data;
-}
-
-
-##############################################################################
-#
-# UnescapeXML - Simple function to take an escaped string and return it to
-#               normal.
-#
-##############################################################################
-sub UnescapeXML
-{
-    my $data = shift;
-
-    if (defined($data))
-    {
-        $data =~ s/&amp;/&/g;
-        $data =~ s/&lt;/</g;
-        $data =~ s/&gt;/>/g;
-        $data =~ s/&quot;/\"/g;
-        $data =~ s/&apos;/\'/g;
-    }
-
-    return $data;
-}
-
-
-##############################################################################
-#
-# BuildXML - takes one of the data formats that XML::Stream supports and call
-#            the proper BuildXML_xxx function on it.
-#
-##############################################################################
-sub BuildXML
-{
-    return &XML::Stream::Node::BuildXML(@_) if (ref($_[0]) eq "XML::Stream::Node");
-    return &XML::Stream::Tree::BuildXML(@_) if (ref($_[0]) eq "ARRAY");
-    return &XML::Stream::Tree::BuildXML(@_) if (ref($_[1]) eq "ARRAY");
-}
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Namespace/Prefix Functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# ConstXMLNS - Return the namespace from the constant string.
-#
-##############################################################################
-sub ConstXMLNS
-{
-    my $const = shift;
-    
-    return $XMLNS{$const};
-}
-
-
-##############################################################################
-#
-# StreamPrefix - Return the prefix of the <stream:stream/>
-#
-##############################################################################
-sub StreamPrefix
-{
-    my $self = shift;
-    my $sid = shift;
-    
-    return $self->ns2prefix($sid,&ConstXMLNS("stream"));
-}
-
-
-##############################################################################
-#
-# RegisterPrefix - setup the map for namespace to prefix
-#
-##############################################################################
-sub RegisterPrefix
-{
-    my $self = shift;
-    my $sid = shift;
-    my $ns = shift;
-    my $prefix = shift;
-
-    $self->{SIDS}->{$sid}->{ns2prefix}->{$ns} = $prefix;
-}
-
-
-##############################################################################
-#
-# ns2prefix - for a stream, return the prefix for the given namespace
-#
-##############################################################################
-sub ns2prefix
-{
-    my $self = shift;
-    my $sid = shift;
-    my $ns = shift;
-
-    return $self->{SIDS}->{$sid}->{ns2prefix}->{$ns};
-}
-
-
-
-
-##############################################################################
-#+----------------------------------------------------------------------------
-#|
-#| Helper Functions
-#|
-#+----------------------------------------------------------------------------
-##############################################################################
-
-##############################################################################
-#
-# GetRoot - returns the hash of attributes for the root <stream:stream/> tag
-#           so that any attributes returned can be accessed.  from and any
-#           xmlns:foobar might be important.
-#
-##############################################################################
-sub GetRoot
-{
-    my $self = shift;
-    my $sid = shift;
-    return unless exists($self->{SIDS}->{$sid}->{root});
-    return $self->{SIDS}->{$sid}->{root};
-}
-
-
-##############################################################################
-#
-# GetSock - returns the Socket so that an outside function can access it if
-#           desired.
-#
-##############################################################################
-sub GetSock
-{
-    my $self = shift;
-    my $sid = shift;
-    return $self->{SIDS}->{$sid}->{sock};
-}
-
-
-##############################################################################
-#
-# LoadSSL - simple call to set everything up for SSL one time.
-#
-##############################################################################
-sub LoadSSL
-{
-    my $self = shift;
-
-    $self->debug(1,"LoadSSL: Load the IO::Socket::SSL module");
-    
-    if (defined($SSL) && ($SSL == 1))
-    {
-        $self->debug(1,"LoadSSL: Success");
-        return 1;
-    }
-    
-    if (defined($SSL) && ($SSL == 0))
-    {
-        $self->debug(1,"LoadSSL: Failure");
-        return;
-    }
-
-    my $SSL_Version = "0.81";
-    eval "use IO::Socket::SSL $SSL_Version";
-    if ($@)
-    {
-        croak("You requested that XML::Stream turn the socket into an SSL socket, but you don't have the correct version of IO::Socket::SSL v$SSL_Version.");
-    }
-    IO::Socket::SSL::context_init({SSL_verify_mode=>0x00});
-    $SSL = 1;
-
-    $self->debug(1,"LoadSSL: Success");
-    return 1;
-}
-
-
-##############################################################################
-#
-# Host2SID - For a server this allows you to lookup the SID of a stream server
-#            based on the hostname that is is listening on.
-#
-##############################################################################
-sub Host2SID
-{
-    my $self = shift;
-    my $hostname = shift;
-
-    foreach my $sid (keys(%{$self->{SIDS}}))
-    {
-        next if ($sid eq "default");
-        next if ($sid =~ /^server/);
-
-        return $sid if ($self->{SIDS}->{$sid}->{hostname} eq $hostname);
-    }
-    return;
-}
-
-
-##############################################################################
-#
-# NewSID - returns a session ID to send to an incoming stream in the return
-#          header.  By default it just increments a counter and returns that,
-#          or you can define a function and set it using the SetCallBacks
-#          function.
-#
-##############################################################################
-sub NewSID
-{
-    my $self = shift;
-    return &{$self->{CB}->{sid}}() if (exists($self->{CB}->{sid}) &&
-                       defined($self->{CB}->{sid}));
-    return $$.time.$self->{IDCOUNT}++;
-}
-
-
-###########################################################################
-#
-# SetCallBacks - Takes a hash with top level tags to look for as the keys
-#                and pointers to functions as the values.
-#
-###########################################################################
-sub SetCallBacks
-{
-    my $self = shift;
-    while($#_ >= 0) {
-        my $func = pop(@_);
-        my $tag = pop(@_);
-        if (($tag eq "node") && !defined($func))
-        {
-            $self->SetCallBacks(node=>sub { $self->_node(@_) });
-        }
-        else
-        {
-            $self->debug(1,"SetCallBacks: tag($tag) func($func)");
-            $self->{CB}->{$tag} = $func;
-        }
-    }
-}
-
-
-##############################################################################
-#
-# StreamHeader - Given the arguments, return the opening stream header.
-#
-##############################################################################
-sub StreamHeader
-{
-    my $self = shift;
-    my (%args) = @_;
-
-    my $stream;
-    $stream .= "<?xml version='1.0'?>";
-    $stream .= "<stream:stream ";
-    $stream .= "version='1.0' ";
-    $stream .= "xmlns:stream='".&ConstXMLNS("stream")."' ";
-    $stream .= "xmlns='$args{xmlns}' ";
-    $stream .= "to='$args{to}' " if exists($args{to});
-    $stream .= "from='$args{from}' " if exists($args{from});
-    $stream .= "xml:lang='$args{xmllang}' " if exists($args{xmllang});
-
-    foreach my $ns (@{$args{namespaces}})
-    {
-        $stream .= " ".$ns->GetStream();
-    }
-    
-    $stream .= ">";
-
-    return $stream;
-}
-
-
-###########################################################################
-#
-# debug - prints the arguments to the debug log if debug is turned on.
-#
-###########################################################################
-sub debug
-{
-    return if ($_[1] > $_[0]->{DEBUGLEVEL});
-    my $self = shift;
-    my ($limit,@args) = @_;
-    return if ($self->{DEBUGFILE} eq "");
-    my $fh = $self->{DEBUGFILE};
-    if ($self->{DEBUGTIME} == 1)
-    {
-        my ($sec,$min,$hour) = localtime(time);
-        print $fh sprintf("[%02d:%02d:%02d] ",$hour,$min,$sec);
-    }
-    print $fh "XML::Stream: @args\n";
-}
-
-
-##############################################################################
-#
-# nonblock - set the socket to be non-blocking.
-#
-##############################################################################
-sub nonblock
-{
-    my $self = shift;
-    my $socket = shift;
-
-    #--------------------------------------------------------------------------
-    # Code copied from POE::Wheel::SocketFactory...
-    # Win32 does things one way...
-    #--------------------------------------------------------------------------
-    if ($^O eq "MSWin32")
-    {
-        ioctl( $socket, 0x80000000 | (4 << 16) | (ord('f') << 8) | 126, 1) ||
-            croak("Can't make socket nonblocking (win32): $!");
-        return;
-    }
-
-    #--------------------------------------------------------------------------
-    # And UNIX does them another
-    #--------------------------------------------------------------------------
-    my $flags = fcntl($socket, F_GETFL, 0)
-        or die "Can't get flags for socket: $!\n";
-    fcntl($socket, F_SETFL, $flags | O_NONBLOCK)
-        or die "Can't make socket nonblocking: $!\n";
-}
-
-
-##############################################################################
-#
-# printData - debugging function to print out any data structure in an
-#             organized manner.  Very useful for debugging XML::Parser::Tree
-#             objects.  This is a private function that will only exist in
-#             in the development version.
-#
-##############################################################################
-sub printData
-{
-    print &sprintData(@_);
-}
-
-
-##############################################################################
-#
-# sprintData - debugging function to build a string out of any data structure
-#              in an organized manner.  Very useful for debugging
-#              XML::Parser::Tree objects and perl hashes of hashes.
-#
-#              This is a private function.
-#
-##############################################################################
-sub sprintData
-{
-    my ($preString,$data) = @_;
-
-    my $outString = "";
-
-    if (ref($data) eq "HASH")
-    {
-        my $key;
-        foreach $key (sort { $a cmp $b } keys(%{$data}))
-        {
-            if (ref($$data{$key}) eq "")
-            {
-                my $value = defined($$data{$key}) ? $$data{$key} : "";
-                $outString .= $preString."{'$key'} = \"".$value."\";\n";
-            }
-            else
-            {
-                if (ref($$data{$key}) =~ /Net::Jabber/)
-                {
-                    $outString .= $preString."{'$key'} = ".ref($$data{$key}).";\n";
-                }
-                else
-                {
-                    $outString .= $preString."{'$key'};\n";
-                    $outString .= &sprintData($preString."{'$key'}->",$$data{$key});
-                }
-            }
-        }
-    }
-    else
-    {
-        if (ref($data) eq "ARRAY")
-        {
-            my $index;
-            foreach $index (0..$#{$data})
-            {
-                if (ref($$data[$index]) eq "")
-                {
-                    $outString .= $preString."[$index] = \"$$data[$index]\";\n";
-                }
-                else
-                {
-                    if (ref($$data[$index]) =~ /Net::Jabber/)
-                    {
-                        $outString .= $preString."[$index] = ".ref($$data[$index]).";\n";
-                    }
-                    else
-                    {
-                        $outString .= $preString."[$index];\n";
-                        $outString .= &sprintData($preString."[$index]->",$$data[$index]);
-                    }
-                }
-            }
-        }
-        else
-        {
-            if (ref($data) eq "REF")
-            {
-                $outString .= &sprintData($preString."->",$$data);
-            }
-            else
-            {
-                if (ref($data) eq "")
-                {
-                    $outString .= $preString." = \"$data\";\n";
-                }
-                else
-                {
-                     $outString .= $preString." = ".ref($data).";\n";
-                }
-            }
-        }
-    }
-
-    return $outString;
-}
-
-
-1;
Index: rl/modules/Jabber/lib/XML/Stream/Namespace.pm
===================================================================
--- perl/modules/Jabber/lib/XML/Stream/Namespace.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,190 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package XML::Stream::Namespace;
-
-=head1 NAME
-
-XML::Stream::Namespace - Object to make defining Namespaces easier in 
-                         XML::Stream.
-
-=head1 SYNOPSIS
-
-XML::Stream::Namespace is a helper package to XML::Stream.  It provides
-a clean way of defining Namespaces for XML::Stream to use when connecting.
-
-=head1 DESCRIPTION
-
-  This module allows you to set and read elements from an XML::Stream
-  Namespace.
-
-=head1 METHODS
-
-  SetNamespace("mynamespace");
-  SetXMLNS("http://www.mynamespace.com/xmlns");
-  SetAttributes(attrib1=>"value1",
-                attrib2=>"value2");
-
-  GetNamespace() returns "mynamespace"
-  GetXMLNS() returns "http://www.mynamespace.com/xmlns"
-  GetAttributes() returns a hash ( attrib1=>"value1",attrib2=>"value2")
-  GetStream() returns the following string:
-    "xmlns:mynamespace='http://www.nynamespace.com/xmlns' 
-     mynamespace:attrib1='value1' 
-     mynamespace:attrib2='value2'"
-
-=head1 EXAMPLES
-
-
-  $myNamespace = new XML::Stream::Namespace("mynamspace");
-  $myNamespace->SetXMLNS("http://www.mynamespace.org/xmlns");
-  $myNamespace->SetAttributes(foo=>"bar",
-                              bob=>"vila");
-
-  $stream = new XML::Stream;
-  $stream->Connect(name=>"foo.bar.org",
-                   port=>1234,
-                   namespace=>"foo:bar",
-                   namespaces=>[ $myNamespace ]);
-
-  #
-  # The above Connect will send the following as the opening string
-  # of the stream to foo.bar.org:1234...
-  #
-  #   <stream:stream 
-  #    xmlns:stream="http://etherx.jabber.org/streams"
-  #    to="foo.bar.org"
-  #    xmlns="foo:bar" 
-  #    xmlns:mynamespace="http://www.mynamespace.org/xmlns"
-  #    mynamespace:foo="bar"
-  #    mynamespace:bob="vila">
-  #
-    
-
-=head1 AUTHOR
-
-Written by Ryan Eatmon in February 2000
-Idea By Thomas Charron in January of 2000 for http://etherx.jabber.org/streams/
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use Carp;
-use vars qw( $VERSION );
-
-$VERSION = "1.22";
-
-sub new
-{
-  my $proto = shift;
-  my $self = { };
-
-  ($self->{Namespace}) = @_ if ($#_ > -1);
-
-  $self->{Attributes} = {};
-
-  bless($self,$proto);
-  return $self;
-}
-
-
-sub SetNamespace
-{
-  my $self = shift;
-  my ($namespace) = @_;
-
-  $self->{Namespace} = $namespace;
-}
-
-
-sub SetXMLNS
-{
-  my $self = shift;
-  my ($xmlns) = @_;
-
-  $self->{XMLNS} = $xmlns;
-}
-
-
-sub SetAttributes
-{
-  my $self = shift;
-  my %att = @_;
-
-  my $key;
-  foreach $key (keys(%att))
-  {
-    $self->{Attributes}->{$key} = $att{$key};
-  }
-}
-
-
-sub GetNamespace
-{
-  my $self = shift;
-
-  return $self->{Namespace};
-}
-
-sub GetXMLNS
-{
-  my $self = shift;
-
-  return $self->{XMLNS};
-}
-
-sub GetAttributes
-{
-  my $self = shift;
-  my ($attrib) = @_;
-
-  return $self->{Attributes} if ($attrib eq "");
-  return $self->{Attributes}->{$attrib};
-}
-
-
-sub GetStream
-{
-  my $self = shift;
-
-  my $string = "";
-
-  $string .= "xmlns:".$self->GetNamespace();
-  $string .= "='".$self->GetXMLNS()."'";
-  my $attrib;
-  foreach $attrib (keys(%{$self->GetAttributes()}))
-  {
-    $string .= " ".$self->GetNamespace().":";
-    $string .= $attrib;
-    $string .= "='".$self->GetAttributes($attrib)."'";
-  }
-    
-  return $string;
-}
-
-1;
-
Index: rl/modules/Jabber/lib/XML/Stream/Node.pm
===================================================================
--- perl/modules/Jabber/lib/XML/Stream/Node.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,944 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package XML::Stream::Node;
-
-=head1 NAME
-
-XML::Stream::Node - Functions to make building and parsing the tree easier
-to work with.
-
-=head1 SYNOPSIS
-
-  Just a collection of functions that do not need to be in memory if you
-choose one of the other methods of data storage.
-
-  This creates a hierarchy of Perl objects and provides various methods
-to manipulate the structure of the tree.  It is much like the C library
-libxml.
-
-=head1 FORMAT
-
-The result of parsing:
-
-  <foo><head id="a">Hello <em>there</em></head><bar>Howdy<ref/></bar>do</foo>
-
-would be:
-
-  [ tag:       foo
-    att:       {}
-    children:  [ tag:      head
-                 att:      {id=>"a"}
-                 children: [ tag:      "__xmlstream__:node:cdata"
-                             children: "Hello "
-                           ]
-                           [ tag:      em
-                             children: [ tag:      "__xmlstream__:node:cdata"
-                                         children: "there"
-                                       ]
-                           ]
-               ]
-               [ tag:      bar
-                 children: [ tag:      "__xmlstream__:node:cdata"
-                             children: "Howdy "
-                           ]
-                           [ tag:      ref
-                           ]
-               ]
-               [ tag:      "__xmlstream__:node:cdata"
-                 children: "do"
-               ]
-  ]
-
-=head1 METHODS
-
-  new()          - creates a new node.  If you specify tag, then the root
-  new(tag)         tag is set.  If you specify data, then cdata is added
-  new(tag,cdata)   to the node as well.  Returns the created node.
-
-  get_tag() - returns the root tag of the node.
-
-  set_tag(tag) - set the root tag of the node to tag.
-
-  add_child(node)      - adds the specified node as a child to the current
-  add_child(tag)         node, or creates a new node with the specified tag
-  add_child(tag,cdata)   as the root node.  Returns the node added.
-
-  remove_child(node) - removes the child node from the current node.
-  
-  remove_cdata() - removes all of the cdata children from the current node.
-
-  add_cdata(string) - adds the string as cdata onto the current nodes
-                      child list.
-
-  get_cdata() - returns all of the cdata children concatenated together
-                into one string.
-
-  get_attrib(attrib) - returns the value of the attrib if it is valid,
-                       or returns undef is attrib is not a real
-                       attribute.
-
-  put_attrib(hash) - for each key/value pair specified, create an
-                     attribute in the node.
-
-  remove_attrib(attrib) - remove the specified attribute from the node.
-
-  add_raw_xml(string,[string,...]) - directly add a string into the XML
-                                     packet as the last child, with no
-                                     translation.
-
-  get_raw_xml() - return all of the XML in a single string, undef if there
-                  is no raw XML to include.
-
-  remove_raw_xml() - remove all raw XML strings.
-
-  children() - return all of the children of the node in a list.
-
-  attrib() - returns a hash containing all of the attributes on this
-             node.
-
-  copy() - return a recursive copy of the node.
-
-  XPath(path) - run XML::Stream::XPath on this node.
-  
-  XPathCheck(path) - run XML::Stream::XPath on this node and return 1 or 0
-                     to see if it matches or not.
-
-  GetXML() - return the node in XML string form.
-
-=head1 AUTHOR
-
-By Ryan Eatmon in June 2002 for http://jabber.org/
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use vars qw( $VERSION $LOADED );
-
-$VERSION = "1.22";
-$LOADED = 1;
-
-sub new
-{
-    my $proto = shift;
-    my $class = ref($proto) || $proto;
-
-    if (ref($_[0]) eq "XML::Stream::Node")
-    {
-        return $_[0];
-    }
-
-    my $self = {};
-    bless($self, $proto);
-
-    my ($tag,$data) = @_;
-
-    $self->set_tag($tag) if defined($tag);
-    $self->add_cdata($data) if defined($data);
-    $self->remove_raw_xml();
-
-    return $self;
-}
-
-
-sub debug
-{
-    my $self = shift;
-    my ($indent) = @_;
-
-    $indent = "" unless defined($indent);
-
-    if ($self->{TAG} eq "__xmlstream__:node:cdata")
-    {
-        print        $indent,"cdata(",join("",@{$self->{CHILDREN}}),")\n";
-    }
-    else
-    {
-        print        $indent,"packet($self):\n";
-        print        $indent,"tag:     <$self->{TAG}\n";
-        if (scalar(keys(%{$self->{ATTRIBS}})) > 0)
-        {
-            print      $indent,"attribs:\n";
-            foreach my $key (sort {$a cmp $b} keys(%{$self->{ATTRIBS}}))
-            {
-                print    $indent,"           $key = '$self->{ATTRIBS}->{$key}'\n";
-            }
-        }
-        if ($#{$self->{CHILDREN}} == -1)
-        {
-            print      $indent,"         />\n";
-        }
-        else
-        {
-            print      $indent,"         >\n";
-            print      $indent,"children:\n";
-            foreach my $child (@{$self->{CHILDREN}})
-            {
-                $child->debug($indent."  ");
-            }
-        }
-        print      $indent,"         </$self->{TAG}>\n";
-    }
-}
-
-
-sub children
-{
-    my $self = shift;
-
-    return () unless exists($self->{CHILDREN});
-    return @{$self->{CHILDREN}};
-}
-
-
-sub add_child
-{
-    my $self = shift;
-
-    my $child = new XML::Stream::Node(@_);
-    push(@{$self->{CHILDREN}},$child);
-    return $child;
-}
-
-
-sub remove_child
-{
-    my $self = shift;
-    my $child = shift;
-
-    foreach my $index (0..$#{$self->{CHILDREN}})
-    {
-        if ($child == $self->{CHILDREN}->[$index])
-        {
-            splice(@{$self->{CHILDREN}},$index,1);
-            last;
-        }
-    }
-}
-
-
-sub add_cdata
-{
-    my $self = shift;
-    my $child = new XML::Stream::Node("__xmlstream__:node:cdata");
-    foreach my $cdata (@_)
-    {
-        push(@{$child->{CHILDREN}},$cdata);
-    }
-    push(@{$self->{CHILDREN}},$child);
-    return $child;
-}
-
-
-sub get_cdata
-{
-    my $self = shift;
-
-    my $cdata = "";
-    foreach my $child (@{$self->{CHILDREN}})
-    {
-        $cdata .= join("",$child->children())
-            if ($child->get_tag() eq "__xmlstream__:node:cdata");
-    }
-
-    return $cdata;
-} 
-
-
-sub remove_cdata
-{
-    my $self = shift;
-
-    my @remove = ();
-    foreach my $index (0..$#{$self->{CHILDREN}})
-    {
-        if ($self->{CHILDREN}->[$index]->get_tag() eq "__xmlstream__:node:cdata")
-        {
-
-            unshift(@remove,$index);
-        }
-    }
-    foreach my $index (@remove)
-    {
-        splice(@{$self->{CHILDREN}},$index,1);
-    }
-} 
-
-
-sub attrib
-{
-    my $self = shift;
-    return () unless exists($self->{ATTRIBS});
-    return %{$self->{ATTRIBS}};
-} 
-
-
-sub get_attrib
-{
-    my $self = shift;
-    my ($key) = @_;
-
-    return unless exists($self->{ATTRIBS}->{$key});
-    return $self->{ATTRIBS}->{$key};
-}
-
-
-sub put_attrib
-{ 
-    my $self = shift;
-    my (%att) = @_;
-
-    foreach my $key (keys(%att))
-    {
-        $self->{ATTRIBS}->{$key} = $att{$key};
-    }
-}
-
-
-sub remove_attrib
-{
-    my $self = shift;
-    my ($key) = @_;
-
-    return unless exists($self->{ATTRIBS}->{$key});
-    delete($self->{ATTRIBS}->{$key});
-}
-
-
-sub add_raw_xml
-{
-    my $self = shift;
-    my (@raw) = @_;
-
-    push(@{$self->{RAWXML}},@raw);
-}
-
-sub get_raw_xml
-{
-    my $self = shift;
-
-    return if ($#{$self->{RAWXML}} == -1);
-    return join("",@{$self->{RAWXML}});
-}
-
-
-sub remove_raw_xml
-{
-    my $self = shift;
-    $self->{RAWXML} = [];
-}
-
-
-sub get_tag
-{
-    my $self = shift;
-
-    return $self->{TAG};
-}
-
-
-sub set_tag
-{
-    my $self = shift;
-    my ($tag) = @_;
-
-    $self->{TAG} = $tag; 
-}
-
-
-sub XPath
-{
-    my $self = shift;
-    my @results = &XML::Stream::XPath($self,@_);
-    return unless ($#results > -1);
-    return $results[0] unless wantarray;
-    return @results;
-}
-
-
-sub XPathCheck
-{
-    my $self = shift;
-    return &XML::Stream::XPathCheck($self,@_);
-}
-
-
-sub GetXML
-{
-    my $self = shift;
-
-    return &BuildXML($self,@_);
-}
-
-
-sub copy
-{
-    my $self = shift;
-
-    my $new_node = new XML::Stream::Node();
-    $new_node->set_tag($self->get_tag());
-    $new_node->put_attrib($self->attrib());
-
-    foreach my $child ($self->children())
-    {
-        if ($child->get_tag() eq "__xmlstream__:node:cdata")
-        {
-            $new_node->add_cdata($self->get_cdata());
-        }
-        else
-        {
-            $new_node->add_child($child->copy());
-        }
-    }
-
-    return $new_node;
-}
-
-
-
-
-
-##############################################################################
-#
-# _handle_element - handles the main tag elements sent from the server.
-#                   On an open tag it creates a new XML::Parser::Node so
-#                   that _handle_cdata and _handle_element can add data
-#                   and tags to it later.
-#
-##############################################################################
-sub _handle_element
-{
-    my $self;
-    $self = $_[0] if (ref($_[0]) eq "XML::Stream::Parser");
-    $self = shift unless (ref($_[0]) eq "XML::Stream::Parser");
-    my ($sax, $tag, %att) = @_;
-    my $sid = $sax->getSID();
-
-    $self->debug(2,"Node: _handle_element: sid($sid) sax($sax) tag($tag) att(",%att,")");
-
-    my $node = new XML::Stream::Node($tag);
-    $node->put_attrib(%att);
-
-    $self->debug(2,"Node: _handle_element: check(",$#{$self->{SIDS}->{$sid}->{node}},")");
-
-    if ($#{$self->{SIDS}->{$sid}->{node}} >= 0)
-    {
-        $self->{SIDS}->{$sid}->{node}->[$#{$self->{SIDS}->{$sid}->{node}}]->
-            add_child($node);
-    }
-
-    push(@{$self->{SIDS}->{$sid}->{node}},$node);
-}
-
-
-##############################################################################
-#
-# _handle_cdata - handles the CDATA that is encountered.  Also, in the
-#                      spirit of XML::Parser::Node it combines any sequential
-#                      CDATA into one tag.
-#
-##############################################################################
-sub _handle_cdata
-{
-    my $self;
-    $self = $_[0] if (ref($_[0]) eq "XML::Stream::Parser");
-    $self = shift unless (ref($_[0]) eq "XML::Stream::Parser");
-    my ($sax, $cdata) = @_;
-    my $sid = $sax->getSID();
-
-    $self->debug(2,"Node: _handle_cdata: sid($sid) sax($sax) cdata($cdata)");
-
-    return if ($#{$self->{SIDS}->{$sid}->{node}} == -1);
-
-    $self->debug(2,"Node: _handle_cdata: sax($sax) cdata($cdata)");
-
-    $self->{SIDS}->{$sid}->{node}->[$#{$self->{SIDS}->{$sid}->{node}}]->
-        add_cdata($cdata);
-}
-
-
-##############################################################################
-#
-# _handle_close - when we see a close tag we need to pop the last element
-#                      from the list and push it onto the end of the previous
-#                      element.  This is how we build our hierarchy.
-#
-##############################################################################
-sub _handle_close
-{
-    my $self;
-    $self = $_[0] if (ref($_[0]) eq "XML::Stream::Parser");
-    $self = shift unless (ref($_[0]) eq "XML::Stream::Parser");
-    my ($sax, $tag) = @_;
-    my $sid = $sax->getSID();
-
-    $self->debug(2,"Node: _handle_close: sid($sid) sax($sax) tag($tag)");
-
-    $self->debug(2,"Node: _handle_close: check(",$#{$self->{SIDS}->{$sid}->{node}},")");
-
-    if ($#{$self->{SIDS}->{$sid}->{node}} == -1)
-    {
-        $self->debug(2,"Node: _handle_close: rootTag($self->{SIDS}->{$sid}->{rootTag}) tag($tag)");
-        if ($self->{SIDS}->{$sid}->{rootTag} ne $tag)
-        {
-            $self->{SIDS}->{$sid}->{streamerror} = "Root tag mis-match: <$self->{SIDS}->{$sid}->{rootTag}> ... </$tag>\n";
-        }
-        return;
-    }
-
-    my $CLOSED = pop @{$self->{SIDS}->{$sid}->{node}};
-
-    $self->debug(2,"Node: _handle_close: check2(",$#{$self->{SIDS}->{$sid}->{node}},")");
-    
-    if($#{$self->{SIDS}->{$sid}->{node}} == -1)
-    {
-        push @{$self->{SIDS}->{$sid}->{node}}, $CLOSED;
-
-        if (ref($self) ne "XML::Stream::Parser")
-        {
-            my $stream_prefix = $self->StreamPrefix($sid);
-            
-            if(defined($self->{SIDS}->{$sid}->{node}->[0]) &&
-               ($self->{SIDS}->{$sid}->{node}->[0]->get_tag() =~ /^${stream_prefix}\:/))
-            {
-                my $node = $self->{SIDS}->{$sid}->{node}->[0];
-                $self->{SIDS}->{$sid}->{node} = [];
-                $self->ProcessStreamPacket($sid,$node);
-            }
-            else
-            {
-                my $node = $self->{SIDS}->{$sid}->{node}->[0];
-                $self->{SIDS}->{$sid}->{node} = [];
-
-                my @special =
-                    &XML::Stream::XPath(
-                        $node,
-                        '[@xmlns="'.&XML::Stream::ConstXMLNS("xmpp-sasl").'" or @xmlns="'.&XML::Stream::ConstXMLNS("xmpp-tls").'"]'
-                    );
-                if ($#special > -1)
-                {
-                    my $xmlns = $node->get_attrib("xmlns");
-                    
-                    $self->ProcessSASLPacket($sid,$node)
-                        if ($xmlns eq &XML::Stream::ConstXMLNS("xmpp-sasl"));
-                    $self->ProcessTLSPacket($sid,$node)
-                        if ($xmlns eq &XML::Stream::ConstXMLNS("xmpp-tls"));
-                }
-                else
-                {
-                    &{$self->{CB}->{node}}($sid,$node);
-                }
-            }
-        }
-    }
-}
-
-
-##############################################################################
-#
-# SetXMLData - takes a host of arguments and sets a portion of the specified
-#              XML::Parser::Node object with that data.  The function works
-#              in two modes "single" or "multiple".  "single" denotes that
-#              the function should locate the current tag that matches this
-#              data and overwrite it's contents with data passed in.
-#              "multiple" denotes that a new tag should be created even if
-#              others exist.
-#
-#              type    - single or multiple
-#              XMLTree - pointer to XML::Stream Node object
-#              tag     - name of tag to create/modify (if blank assumes
-#                        working with top level tag)
-#              data    - CDATA to set for tag
-#              attribs - attributes to ADD to tag
-#
-##############################################################################
-sub SetXMLData
-{
-    my ($type,$XMLTree,$tag,$data,$attribs) = @_;
-
-    if ($tag ne "")
-    {
-        if ($type eq "single")
-        {
-            foreach my $child ($XMLTree->children())
-            {
-                if ($$XMLTree[1]->[$child] eq $tag)
-                {
-                    $XMLTree->remove_child($child);
-
-                    my $newChild = $XMLTree->add_child($tag);
-                    $newChild->put_attrib(%{$attribs});
-                    $newChild->add_cdata($data) if ($data ne "");
-                    return;
-                }
-            }
-        }
-        my $newChild = $XMLTree->add_child($tag);
-        $newChild->put_attrib(%{$attribs});
-        $newChild->add_cdata($data) if ($data ne "");
-    }
-    else
-    {
-        $XMLTree->put_attrib(%{$attribs});
-        $XMLTree->add_cdata($data) if ($data ne "");
-    }
-}
-
-
-##############################################################################
-#
-# GetXMLData - takes a host of arguments and returns various data structures
-#              that match them.
-#
-#              type - "existence" - returns 1 or 0 if the tag exists in the
-#                                   top level.
-#                     "value" - returns either the CDATA of the tag, or the
-#                               value of the attribute depending on which is
-#                               sought.  This ignores any mark ups to the data
-#                               and just returns the raw CDATA.
-#                     "value array" - returns an array of strings representing
-#                                     all of the CDATA in the specified tag.
-#                                     This ignores any mark ups to the data
-#                                     and just returns the raw CDATA.
-#                     "tree" - returns an XML::Parser::Node object with the
-#                              specified tag as the root tag.
-#                     "tree array" - returns an array of XML::Parser::Node
-#                                    objects each with the specified tag as
-#                                    the root tag.
-#                     "child array" - returns a list of all children nodes
-#                                     not including CDATA nodes.
-#                     "attribs" - returns a hash with the attributes, and
-#                                 their values, for the things that match
-#                                 the parameters
-#                     "count" - returns the number of things that match
-#                               the arguments
-#                     "tag" - returns the root tag of this tree
-#              XMLTree - pointer to XML::Parser::Node object
-#              tag     - tag to pull data from.  If blank then the top level
-#                        tag is accessed.
-#              attrib  - attribute value to retrieve.  Ignored for types
-#                        "value array", "tree", "tree array".  If paired
-#                        with value can be used to filter tags based on
-#                        attributes and values.
-#              value   - only valid if an attribute is supplied.  Used to
-#                        filter for tags that only contain this attribute.
-#                        Useful to search through multiple tags that all
-#                        reference different name spaces.
-#
-##############################################################################
-sub GetXMLData
-{
-    my ($type,$XMLTree,$tag,$attrib,$value) = @_;
-
-    $tag = "" if !defined($tag);
-    $attrib = "" if !defined($attrib);
-    $value = "" if !defined($value);
-
-    my $skipthis = 0;
-
-    #-------------------------------------------------------------------------
-    # Check if a child tag in the root tag is being requested.
-    #-------------------------------------------------------------------------
-    if ($tag ne "")
-    {
-        my $count = 0;
-        my @array;
-        foreach my $child ($XMLTree->children())
-        {
-            if (($child->get_tag() eq $tag) || ($tag eq "*"))
-            {
-                #-------------------------------------------------------------
-                # Filter out tags that do not contain the attribute and value.
-                #-------------------------------------------------------------
-                next if (($value ne "") && ($attrib ne "") && $child->get_attrib($attrib) && ($XMLTree->get_attrib($attrib) ne $value));
-                next if (($attrib ne "") && !$child->get_attrib($attrib));
-
-                #-------------------------------------------------------------
-                # Check for existence
-                #-------------------------------------------------------------
-                if ($type eq "existence")
-                {
-                    return 1;
-                }
-                #-------------------------------------------------------------
-                # Return the raw CDATA value without mark ups, or the value of
-                # the requested attribute.
-                #-------------------------------------------------------------
-                if ($type eq "value")
-                {
-                    if ($attrib eq "")
-                    {
-                        my $str = $child->get_cdata();
-                        return $str;
-                    }
-                    return $XMLTree->get_attrib($attrib)
-                        if defined($XMLTree->get_attrib($attrib));
-                }
-                #-------------------------------------------------------------
-                # Return an array of values that represent the raw CDATA without
-                # mark up tags for the requested tags.
-                #-------------------------------------------------------------
-                if ($type eq "value array")
-                {
-                    if ($attrib eq "")
-                    {
-                        my $str = $child->get_cdata();
-                        push(@array,$str);
-                    }
-                    else
-                    {
-                        push(@array, $XMLTree->get_attrib($attrib))
-                        if defined($XMLTree->get_attrib($attrib));
-                    }
-                }
-                #-------------------------------------------------------------
-                # Return a pointer to a new XML::Parser::Tree object that has
-                # the requested tag as the root tag.
-                #-------------------------------------------------------------
-                if ($type eq "tree")
-                {
-                    return $child;
-                }
-                #-------------------------------------------------------------
-                # Return an array of pointers to XML::Parser::Tree objects
-                # that have the requested tag as the root tags.
-                #-------------------------------------------------------------
-                if ($type eq "tree array")
-                {
-                    push(@array,$child);
-                }
-                #-------------------------------------------------------------
-                # Return an array of pointers to XML::Parser::Tree objects
-                # that have the requested tag as the root tags.
-                #-------------------------------------------------------------
-                if ($type eq "child array")
-                {
-                    push(@array,$child) if ($child->get_tag() ne "__xmlstream__:node:cdata");
-                }
-                #-------------------------------------------------------------
-                # Return a count of the number of tags that match
-                #-------------------------------------------------------------
-                if ($type eq "count")
-                {
-                    $count++;
-                }
-                #-------------------------------------------------------------
-                # Return the attribute hash that matches this tag
-                #-------------------------------------------------------------
-                if ($type eq "attribs")
-                {
-                    return $XMLTree->attrib();
-                }
-            }
-        }
-        #---------------------------------------------------------------------
-        # If we are returning arrays then return array.
-        #---------------------------------------------------------------------
-        if (($type eq "tree array") || ($type eq "value array") ||
-            ($type eq "child array"))
-        {
-            return @array;
-        }
-
-        #---------------------------------------------------------------------
-        # If we are returning then count, then do so
-        #---------------------------------------------------------------------
-        if ($type eq "count")
-        {
-            return $count;
-        }
-    }
-    else
-    {
-        #---------------------------------------------------------------------
-        # This is the root tag, so handle things a level up.
-        #---------------------------------------------------------------------
-
-        #---------------------------------------------------------------------
-        # Return the raw CDATA value without mark ups, or the value of the
-        # requested attribute.
-        #---------------------------------------------------------------------
-        if ($type eq "value")
-        {
-            if ($attrib eq "")
-            {
-                my $str = $XMLTree->get_cdata();
-                return $str;
-            }
-            return $XMLTree->get_attrib($attrib)
-                if $XMLTree->get_attrib($attrib);
-        }
-        #---------------------------------------------------------------------
-        # Return a pointer to a new XML::Parser::Tree object that has the
-        # requested tag as the root tag.
-        #---------------------------------------------------------------------
-        if ($type eq "tree")
-        {
-            return $XMLTree;
-        }
-
-        #---------------------------------------------------------------------
-        # Return the 1 if the specified attribute exists in the root tag.
-        #---------------------------------------------------------------------
-        if ($type eq "existence")
-        {
-            if ($attrib ne "")
-            {
-                return ($XMLTree->get_attrib($attrib) eq $value) if ($value ne "");
-                return defined($XMLTree->get_attrib($attrib));
-            }
-            return 0;
-        }
-
-        #---------------------------------------------------------------------
-        # Return the attribute hash that matches this tag
-        #---------------------------------------------------------------------
-        if ($type eq "attribs")
-        {
-            return $XMLTree->attrib();
-        }
-        #---------------------------------------------------------------------
-        # Return the tag of this node
-        #---------------------------------------------------------------------
-        if ($type eq "tag")
-        {
-            return $XMLTree->get_tag();
-        }
-    }
-    #-------------------------------------------------------------------------
-    # Return 0 if this was a request for existence, or "" if a request for
-    # a "value", or [] for "tree", "value array", and "tree array".
-    #-------------------------------------------------------------------------
-    return 0 if ($type eq "existence");
-    return "" if ($type eq "value");
-    return [];
-}
-
-
-##############################################################################
-#
-# BuildXML - takes an XML::Parser::Tree object and builds the XML string
-#                 that it represents.
-#
-##############################################################################
-sub BuildXML
-{
-    my ($node,$rawXML) = @_;
-
-    my $str = "<".$node->get_tag();
-
-    my %attrib = $node->attrib();
-
-    foreach my $att (sort {$a cmp $b} keys(%attrib))
-    {
-        $str .= " ".$att."='".&XML::Stream::EscapeXML($attrib{$att})."'";
-    }
-
-    my @children = $node->children();
-    if (($#children > -1) ||
-        (defined($rawXML) && ($rawXML ne "")) ||
-        (defined($node->get_raw_xml()) && ($node->get_raw_xml() ne ""))
-       )
-    {
-        $str .= ">";
-        foreach my $child (@children)
-        {
-            if ($child->get_tag() eq "__xmlstream__:node:cdata")
-            {
-                $str .= &XML::Stream::EscapeXML(join("",$child->children()));
-            }
-            else
-            {
-                $str .= &XML::Stream::Node::BuildXML($child);
-            }
-        }
-        $str .= $node->get_raw_xml()
-            if (defined($node->get_raw_xml()) &&
-                ($node->get_raw_xml() ne "")
-               );
-        $str .= $rawXML if (defined($rawXML) && ($rawXML ne ""));
-        $str .= "</".$node->get_tag().">";
-    }
-    else
-    {
-        $str .= "/>";
-    }
-
-    return $str;
-}
-
-
-##############################################################################
-#
-# XML2Config - takes an XML data tree and turns it into a hash of hashes.
-#              This only works for certain kinds of XML trees like this:
-#
-#                <foo>
-#                  <bar>1</bar>
-#                  <x>
-#                    <y>foo</y>
-#                  </x>
-#                  <z>5</z>
-#                </foo>
-#
-#              The resulting hash would be:
-#
-#                $hash{bar} = 1;
-#                $hash{x}->{y} = "foo";
-#                $hash{z} = 5;
-#
-#              Good for config files.
-#
-##############################################################################
-sub XML2Config
-{
-    my ($XMLTree) = @_;
-
-    my %hash;
-    foreach my $tree (&XML::Stream::GetXMLData("tree array",$XMLTree,"*"))
-    {
-        if ($tree->get_tag() eq "__xmlstream__:node:cdata")
-        {
-            my $str = join("",$tree->children());
-            return $str unless ($str =~ /^\s*$/);
-        }
-        else
-        {
-            if (&XML::Stream::GetXMLData("count",$XMLTree,$tree->get_tag()) > 1)
-            {
-                push(@{$hash{$tree->get_tag()}},&XML::Stream::XML2Config($tree));
-            }
-            else
-            {
-                $hash{$tree->get_tag()} = &XML::Stream::XML2Config($tree);
-            }
-        }
-    }
-    return \%hash;
-}
-
-
-1;
Index: rl/modules/Jabber/lib/XML/Stream/Parser.pm
===================================================================
--- perl/modules/Jabber/lib/XML/Stream/Parser.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,570 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package XML::Stream::Parser;
-
-=head1 NAME
-
-  XML::Stream::Parser - SAX XML Parser for XML Streams
-
-=head1 SYNOPSIS
-
-  Light weight XML parser that builds XML::Parser::Tree objects from the
-  incoming stream and passes them to a function to tell whoever is using
-  it that there are new packets.
-
-=head1 DESCRIPTION
-
-  This module provides a very light weight parser
-
-=head1 METHODS
-
-=head1 EXAMPLES
-
-=head1 AUTHOR
-
-By Ryan Eatmon in January of 2001 for http://jabber.org/
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use vars qw( $VERSION );
-
-$VERSION = "1.22";
-
-sub new
-{
-    my $self = { };
-
-    bless($self);
-
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $self->{PARSING} = 0;
-    $self->{DOC} = 0;
-    $self->{XML} = "";
-    $self->{CNAME} = ();
-    $self->{CURR} = 0;
-
-    $args{nonblocking} = 0 unless exists($args{nonblocking});
-
-    $self->{NONBLOCKING} = delete($args{nonblocking});
-
-    $self->{DEBUGTIME} = 0;
-    $self->{DEBUGTIME} = $args{debugtime} if exists($args{debugtime});
-
-    $self->{DEBUGLEVEL} = 0;
-    $self->{DEBUGLEVEL} = $args{debuglevel} if exists($args{debuglevel});
-
-    $self->{DEBUGFILE} = "";
-
-    if (exists($args{debugfh}) && ($args{debugfh} ne ""))
-    {
-        $self->{DEBUGFILE} = $args{debugfh};
-        $self->{DEBUG} = 1;
-    }
-
-    if ((exists($args{debugfh}) && ($args{debugfh} eq "")) ||
-        (exists($args{debug}) && ($args{debug} ne "")))
-        {
-        $self->{DEBUG} = 1;
-        if (lc($args{debug}) eq "stdout")
-        {
-            $self->{DEBUGFILE} = new FileHandle(">&STDERR");
-            $self->{DEBUGFILE}->autoflush(1);
-        }
-        else
-        {
-            if (-e $args{debug})
-            {
-                if (-w $args{debug})
-                {
-                    $self->{DEBUGFILE} = new FileHandle(">$args{debug}");
-                    $self->{DEBUGFILE}->autoflush(1);
-                }
-                else
-                {
-                    print "WARNING: debug file ($args{debug}) is not writable by you\n";
-                    print "         No debug information being saved.\n";
-                    $self->{DEBUG} = 0;
-                }
-            }
-            else
-            {
-                $self->{DEBUGFILE} = new FileHandle(">$args{debug}");
-                if (defined($self->{DEBUGFILE}))
-                {
-                    $self->{DEBUGFILE}->autoflush(1);
-                }
-                else
-                {
-                    print "WARNING: debug file ($args{debug}) does not exist \n";
-                    print "         and is not writable by you.\n";
-                    print "         No debug information being saved.\n";
-                    $self->{DEBUG} = 0;
-                }
-            }
-        }
-    }
-
-    $self->{SID} = exists($args{sid}) ? $args{sid} : "__xmlstream__:sid";
-
-    $self->{STYLE} = (exists($args{style}) ? lc($args{style}) : "tree");
-    $self->{DTD} = (exists($args{dtd}) ? lc($args{dtd}) : 0);
-
-    if ($self->{STYLE} eq "tree")
-    {
-        $self->{HANDLER}->{startDocument} = sub{ $self->startDocument(@_); };
-        $self->{HANDLER}->{endDocument} = sub{ $self->endDocument(@_); };
-        $self->{HANDLER}->{startElement} = sub{ &XML::Stream::Tree::_handle_element(@_); };
-        $self->{HANDLER}->{endElement} = sub{ &XML::Stream::Tree::_handle_close(@_); };
-        $self->{HANDLER}->{characters} = sub{ &XML::Stream::Tree::_handle_cdata(@_); };
-    }
-    elsif ($self->{STYLE} eq "node")
-    {
-        $self->{HANDLER}->{startDocument} = sub{ $self->startDocument(@_); };
-        $self->{HANDLER}->{endDocument} = sub{ $self->endDocument(@_); };
-        $self->{HANDLER}->{startElement} = sub{ &XML::Stream::Node::_handle_element(@_); };
-        $self->{HANDLER}->{endElement} = sub{ &XML::Stream::Node::_handle_close(@_); };
-        $self->{HANDLER}->{characters} = sub{ &XML::Stream::Node::_handle_cdata(@_); };
-    }
-    $self->setHandlers(%{$args{handlers}});
-
-    $self->{XMLONHOLD} = "";
-
-    return $self;
-}
-
-
-###########################################################################
-#
-# debug - prints the arguments to the debug log if debug is turned on.
-#
-###########################################################################
-sub debug
-{
-    return if ($_[1] > $_[0]->{DEBUGLEVEL});
-    my $self = shift;
-    my ($limit,@args) = @_;
-    return if ($self->{DEBUGFILE} eq "");
-    my $fh = $self->{DEBUGFILE};
-    if ($self->{DEBUGTIME} == 1)
-    {
-        my ($sec,$min,$hour) = localtime(time);
-        print $fh sprintf("[%02d:%02d:%02d] ",$hour,$min,$sec);
-    }
-    print $fh "XML::Stream::Parser: $self->{STYLE}: @args\n";
-}
-
-
-sub setSID
-{
-    my $self = shift;
-    my $sid = shift;
-    $self->{SID} = $sid;
-}
-
-
-sub getSID
-{
-    my $self = shift;
-    return $self->{SID};
-}
-
-
-sub setHandlers
-{
-    my $self = shift;
-    my (%handlers) = @_;
-
-    foreach my $handler (keys(%handlers))
-    {
-        $self->{HANDLER}->{$handler} = $handlers{$handler};
-    }
-}
-
-
-sub parse
-{
-    my $self = shift;
-    my $xml = shift;
-
-    return unless defined($xml);
-    return if ($xml eq "");
-
-    if ($self->{XMLONHOLD} ne "")
-    {
-        $self->{XML} = $self->{XMLONHOLD};
-        $self->{XMLONHOLD} = "";
-    }
-
-    # XXX change this to not use regex?
-    while($xml =~ s/<\!--.*?-->//gs) {}
-
-    $self->{XML} .= $xml;
-
-    return if ($self->{PARSING} == 1);
-
-    $self->{PARSING} = 1;
-
-    if(!$self->{DOC} == 1)
-    {
-        my $start = index($self->{XML},"<");
-
-        if ((substr($self->{XML},$start,3) eq "<?x") ||
-            (substr($self->{XML},$start,3) eq "<?X"))
-        {
-            my $close = index($self->{XML},"?>");
-            if ($close == -1)
-            {
-                $self->{PARSING} = 0;
-                return;
-            }
-            $self->{XML} = substr($self->{XML},$close+2,length($self->{XML})-$close-2);
-        }
-
-        &{$self->{HANDLER}->{startDocument}}($self);
-        $self->{DOC} = 1;
-    }
-
-    while(1)
-    {
-        if (length($self->{XML}) == 0)
-        {
-            $self->{PARSING} = 0;
-            return $self->returnData(0);
-        }
-        my $eclose = -1;
-        $eclose = index($self->{XML},"</".$self->{CNAME}->[$self->{CURR}].">")
-            if ($#{$self->{CNAME}} > -1);
-
-        if ($eclose == 0)
-        {
-            $self->{XML} = substr($self->{XML},length($self->{CNAME}->[$self->{CURR}])+3,length($self->{XML})-length($self->{CNAME}->[$self->{CURR}])-3);
-
-            $self->{PARSING} = 0 if ($self->{NONBLOCKING} == 1);
-            &{$self->{HANDLER}->{endElement}}($self,$self->{CNAME}->[$self->{CURR}]);
-            $self->{PARSING} = 1 if ($self->{NONBLOCKING} == 1);
-
-            $self->{CURR}--;
-            if ($self->{CURR} == 0)
-            {
-                $self->{DOC} = 0;
-                $self->{PARSING} = 0;
-                &{$self->{HANDLER}->{endDocument}}($self);
-                return $self->returnData(0);
-            }
-            next;
-        }
-
-        my $estart = index($self->{XML},"<");
-        my $cdatastart = index($self->{XML},"<![CDATA[");
-        if (($estart == 0) && ($cdatastart != 0))
-        {
-            my $close = index($self->{XML},">");
-            if ($close == -1)
-            {
-                $self->{PARSING} = 0;
-                return $self->returnData(0);
-            }
-            my $empty = (substr($self->{XML},$close-1,1) eq "/");
-            my $starttag = substr($self->{XML},1,$close-($empty ? 2 : 1));
-            my $nextspace = index($starttag," ");
-            my $attribs;
-            my $name;
-            if ($nextspace != -1)
-            {
-                $name = substr($starttag,0,$nextspace);
-                $attribs = substr($starttag,$nextspace+1,length($starttag)-$nextspace-1);
-            }
-            else
-            {
-                $name = $starttag;
-            }
-
-            my %attribs = $self->attribution($attribs);
-            if (($self->{DTD} == 1) && (exists($attribs{xmlns})))
-            {
-            }
-
-            &{$self->{HANDLER}->{startElement}}($self,$name,%attribs);
-
-            if($empty == 1)
-            {
-                &{$self->{HANDLER}->{endElement}}($self,$name);
-            }
-            else
-            {
-                $self->{CURR}++;
-                $self->{CNAME}->[$self->{CURR}] = $name;
-            }
-    
-            $self->{XML} = substr($self->{XML},$close+1,length($self->{XML})-$close-1);
-            next;
-        }
-
-        if ($cdatastart == 0)
-        {
-            my $cdataclose = index($self->{XML},"]]>");
-            if ($cdataclose == -1)
-            {
-                $self->{PARSING} = 0;
-                return $self->returnData(0);
-            }
-            
-            &{$self->{HANDLER}->{characters}}($self,substr($self->{XML},9,$cdataclose-9));
-            
-            $self->{XML} = substr($self->{XML},$cdataclose+3,length($self->{XML})-$cdataclose-3);
-            next;
-         }
-
-        if ($estart == -1)
-        {
-            $self->{XMLONHOLD} = $self->{XML};
-            $self->{XML} = "";
-        }
-        elsif (($cdatastart == -1) || ($cdatastart > $estart))
-        {
-            &{$self->{HANDLER}->{characters}}($self,$self->entityCheck(substr($self->{XML},0,$estart)));
-            $self->{XML} = substr($self->{XML},$estart,length($self->{XML})-$estart);
-        }
-    }
-}
-
-
-sub attribution
-{
-    my $self = shift;
-    my $str = shift;
-
-    $str = "" unless defined($str);
-
-    my %attribs;
-
-    while(1)
-    {
-        my $eq = index($str,"=");
-        if((length($str) == 0) || ($eq == -1))
-        {
-            return %attribs;
-        }
-
-        my $ids;
-        my $id;
-        my $id1 = index($str,"\'");
-        my $id2 = index($str,"\"");
-
-	return %attribs if ($id1 == -1 && $id2 == -1);
-
-        if((($id1 < $id2) && ($id1 != -1)) || ($id2 == -1))
-        {
-            $ids = $id1;
-            $id = "\'";
-        }
-        if((($id2 < $id1) && ($id2 != -1)) || ($id1 == -1))
-        {
-            $ids = $id2;
-            $id = "\"";
-        }
-
-        my $nextid = index($str,$id,$ids+1);
-        my $val = substr($str,$ids+1,$nextid-$ids-1);
-        my $key = substr($str,0,$eq);
-
-        while($key =~ s/\s//) {}
-
-        $attribs{$key} = $self->entityCheck($val);
-        $str = substr($str,$nextid+1,length($str)-$nextid-1);
-    }
-
-    return %attribs;
-}
-
-
-sub entityCheck
-{
-    my $self = shift;
-    my $str = shift;
-
-    while($str =~ s/\&lt\;/\</) {}
-    while($str =~ s/\&gt\;/\>/) {}
-    while($str =~ s/\&quot\;/\"/) {}
-    while($str =~ s/\&apos\;/\'/) {}
-    while($str =~ s/\&amp\;/\&/) {}
-
-    return $str;
-}
-
-
-sub parsefile
-{
-    my $self = shift;
-    my $fileName = shift;
-
-    open(FILE,"<",$fileName);
-    my $file;
-    while(<FILE>) { $file .= $_; }
-    $self->parse($file);
-    close(FILE);
-
-    return $self->returnData();
-}
-
-
-sub returnData
-{
-    my $self = shift;
-    my $clearData = shift;
-    $clearData = 1 unless defined($clearData);
-
-    my $sid = $self->{SID};
-
-    if ($self->{STYLE} eq "tree")
-    {
-        return unless exists($self->{SIDS}->{$sid}->{tree});
-        my @tree = @{$self->{SIDS}->{$sid}->{tree}};
-        delete($self->{SIDS}->{$sid}->{tree}) if ($clearData == 1);
-        return ( \@tree );
-    }
-    if ($self->{STYLE} eq "node")
-    {
-        return unless exists($self->{SIDS}->{$sid}->{node});
-        my $node = $self->{SIDS}->{$sid}->{node}->[0];
-        delete($self->{SIDS}->{$sid}->{node}) if ($clearData == 1);
-        return $node;
-    }
-}
-
-
-sub startDocument
-{
-    my $self = shift;
-}
-
-
-sub endDocument
-{
-    my $self = shift;
-}
-
-
-sub startElement
-{
-    my $self = shift;
-    my ($sax, $tag, %att) = @_;
-
-    return unless ($self->{DOC} == 1);
-
-    if ($self->{STYLE} eq "debug")
-    {
-        print "$self->{DEBUGHEADER} \\\\ (",join(" ",%att),")\n";
-        $self->{DEBUGHEADER} .= $tag." ";
-    }
-    else
-    {
-        my @NEW;
-        if($#{$self->{TREE}} < 0)
-        {
-            push @{$self->{TREE}}, $tag;
-        }
-        else
-        {
-            push @{ $self->{TREE}[ $#{$self->{TREE}}]}, $tag;
-        }
-        push @NEW, \%att;
-        push @{$self->{TREE}}, \@NEW;
-    }
-}
-
-
-sub characters
-{
-    my $self = shift;
-    my ($sax, $cdata) = @_;
-
-    return unless ($self->{DOC} == 1);
-
-    if ($self->{STYLE} eq "debug") 
-    {
-        my $str = $cdata;
-        $str =~ s/\n/\#10\;/g;
-        print "$self->{DEBUGHEADER} || $str\n";
-    }
-    else
-    {
-        return if ($#{$self->{TREE}} == -1);
-
-        my $pos = $#{$self->{TREE}};
-
-        if ($pos > 0 && $self->{TREE}[$pos - 1] eq "0")
-        {
-            $self->{TREE}[$pos - 1] .= $cdata;
-        }
-        else
-        {
-            push @{$self->{TREE}[$#{$self->{TREE}}]}, 0;
-            push @{$self->{TREE}[$#{$self->{TREE}}]}, $cdata;
-        }  
-    }
-}
-
-
-sub endElement
-{
-    my $self = shift;
-    my ($sax, $tag) = @_;
-
-    return unless ($self->{DOC} == 1);
-
-    if ($self->{STYLE} eq "debug")
-    {
-        $self->{DEBUGHEADER} =~ s/\S+\ $//;
-        print "$self->{DEBUGHEADER} //\n";
-    }
-    else
-    {
-        my $CLOSED = pop @{$self->{TREE}};
-
-        if($#{$self->{TREE}} < 1)
-        {
-            push @{$self->{TREE}}, $CLOSED;
-
-            if($self->{TREE}->[0] eq "stream:error")
-            {
-                $self->{STREAMERROR} = $self->{TREE}[1]->[2];
-            }
-        }
-        else
-        {
-            push @{$self->{TREE}[$#{$self->{TREE}}]}, $CLOSED;
-        }
-    }
-}
-
-
-1;
Index: rl/modules/Jabber/lib/XML/Stream/Parser/DTD.pm
===================================================================
--- perl/modules/Jabber/lib/XML/Stream/Parser/DTD.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,769 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package XML::Stream::Parser::DTD;
-
-=head1 NAME
-
-  XML::Stream::Parser::DTD - XML DTD Parser and Verifier
-
-=head1 SYNOPSIS
-
-  This is a work in progress.  I had need for a DTD parser and verifier
-  and so am working on it here.  If you are reading this then you are
-  snooping.  =)
-
-=head1 DESCRIPTION
-
-  This module provides the initial code for a DTD parser and verifier.
-
-=head1 METHODS
-
-=head1 EXAMPLES
-
-=head1 AUTHOR
-
-By Ryan Eatmon in February of 2001 for http://jabber.org/
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use strict;
-use vars qw( $VERSION );
-
-$VERSION = "1.22";
-
-sub new
-{
-    my $self = { };
-
-    bless($self);
-
-    my %args;
-    while($#_ >= 0) { $args{ lc pop(@_) } = pop(@_); }
-
-    $self->{URI} = $args{uri};
-
-    $self->{PARSING} = 0;
-    $self->{DOC} = 0;
-    $self->{XML} = "";
-    $self->{CNAME} = ();
-    $self->{CURR} = 0;
-
-    $self->{ENTITY}->{"&lt;"} = "<";
-    $self->{ENTITY}->{"&gt;"} = ">";
-    $self->{ENTITY}->{"&quot;"} = "\"";
-    $self->{ENTITY}->{"&apos;"} = "'";
-    $self->{ENTITY}->{"&amp;"} = "&";
-
-    $self->{HANDLER}->{startDocument} = sub{ $self->startDocument(@_); };
-    $self->{HANDLER}->{endDocument} = sub{ $self->endDocument(@_); };
-    $self->{HANDLER}->{startElement} = sub{ $self->startElement(@_); };
-    $self->{HANDLER}->{endElement} = sub{ $self->endElement(@_); };
-
-    $self->{STYLE} = "debug";
-
-    open(DTD,$args{uri});
-    my $dtd = join("",<DTD>);
-    close(DTD);
-
-    $self->parse($dtd);
-
-    return $self;
-}
-
-
-sub parse
-{
-    my $self = shift;
-    my $xml = shift;
-
-    while($xml =~ s/<\!--.*?-->//gs) {}
-    while($xml =~ s/\n//g) {}
-
-    $self->{XML} .= $xml;
-
-    return if ($self->{PARSING} == 1);
-
-    $self->{PARSING} = 1;
-
-    if(!$self->{DOC} == 1)
-    {
-        my $start = index($self->{XML},"<");
-
-        if (substr($self->{XML},$start,3) =~ /^<\?x$/i)
-        {
-            my $close = index($self->{XML},"?>");
-            if ($close == -1)
-            {
-                $self->{PARSING} = 0;
-                return;
-            }
-            $self->{XML} = substr($self->{XML},$close+2,length($self->{XML})-$close-2);
-        }
-
-        &{$self->{HANDLER}->{startDocument}}($self);
-        $self->{DOC} = 1;
-    }
-
-    while(1)
-    {
-
-        if (length($self->{XML}) == 0)
-        {
-            $self->{PARSING} = 0;
-            return;
-        }
-
-        my $estart = index($self->{XML},"<");
-        if ($estart == -1)
-        {
-            $self->{PARSING} = 0;
-            return;
-        }
-
-        my $close = index($self->{XML},">");
-        my $dtddata = substr($self->{XML},$estart+1,$close-1);
-        my $nextspace = index($dtddata," ");
-        my $attribs;
-
-        my $type = substr($dtddata,0,$nextspace);
-        $dtddata = substr($dtddata,$nextspace+1,length($dtddata)-$nextspace-1);
-        $nextspace = index($dtddata," ");
-
-        if ($type eq "!ENTITY")
-        {
-            $self->entity($type,$dtddata);
-        }
-        else
-        {
-            my $tag = substr($dtddata,0,$nextspace);
-            $dtddata = substr($dtddata,$nextspace+1,length($dtddata)-$nextspace-1);
-            $nextspace = index($dtddata," ");
-
-            $self->element($type,$tag,$dtddata) if ($type eq "!ELEMENT");
-            $self->attlist($type,$tag,$dtddata) if ($type eq "!ATTLIST");
-        }
-
-        $self->{XML} = substr($self->{XML},$close+1,length($self->{XML})-$close-1);
-        next;
-    }
-}
-
-
-sub startDocument
-{
-    my $self = shift;
-}
-
-
-sub endDocument
-{
-    my $self = shift;
-}
-
-
-sub entity
-{
-    my $self = shift;
-    my ($type, $data) = @_;
-
-    foreach my $entity (keys(%{$self->{ENTITY}}))
-    {
-        $data =~ s/$entity/$self->{ENTITY}->{$entity}/g;
-    }
-
-    my ($symbol,$tag,undef,$string) = ($data =~ /^\s*(\S+)\s+(\S+)\s+(\"|\')([^\3]*)\3\s*$/);
-    $self->{ENTITY}->{"${symbol}${tag}\;"} = $string;
-}
-
-sub element
-{
-    my $self = shift;
-    my ($type, $tag, $data) = @_;
-
-    foreach my $entity (keys(%{$self->{ENTITY}}))
-    {
-        $data =~ s/$entity/$self->{ENTITY}->{$entity}/g;
-    }
-
-    $self->{COUNTER}->{$tag} = 0 unless exists($self->{COUNTER}->{$tag});
-
-    $self->parsegrouping($tag,\$self->{ELEMENT}->{$tag},$data);
-    $self->flattendata(\$self->{ELEMENT}->{$tag});
-
-}
-
-
-sub flattendata
-{
-    my $self = shift;
-    my $dstr = shift;
-
-    if ($$dstr->{type} eq "list")
-    {
-        foreach my $index (0..$#{$$dstr->{list}})
-        {
-            $self->flattendata(\$$dstr->{list}->[$index]);
-        }
-
-        if (!exists($$dstr->{repeat}) && ($#{$$dstr->{list}} == 0))
-        {
-            $$dstr = $$dstr->{list}->[0];
-        }
-    }
-}
-
-sub parsegrouping
-{
-    my $self = shift;
-    my ($tag,$dstr,$data) = @_;
-
-    $data =~ s/^\s*//;
-    $data =~ s/\s*$//;
-
-    if ($data =~ /[\*\+\?]$/)
-    {
-        ($$dstr->{repeat}) = ($data =~ /(.)$/);
-        $data =~ s/.$//;
-    }
-
-    if ($data =~ /^\(.*\)$/)
-    {
-        my ($seperator) = ($data =~ /^\(\s*\S+\s*(\,|\|)/);
-        $$dstr->{ordered} = "yes" if ($seperator eq ",");
-        $$dstr->{ordered} = "no" if ($seperator eq "|");
-
-        my $count = 0;
-        $$dstr->{type} = "list";
-        foreach my $grouping ($self->groupinglist($data,$seperator))
-        {
-            $self->parsegrouping($tag,\$$dstr->{list}->[$count],$grouping);
-            $count++;
-        }
-    }
-    else
-    {
-        $$dstr->{type} = "element";
-        $$dstr->{element} = $data;
-        $self->{COUNTER}->{$data} = 0 unless exists($self->{COUNTER}->{$data});
-        $self->{COUNTER}->{$data}++;
-        $self->{CHILDREN}->{$tag}->{$data} = 1;
-    }
-}
-
-
-sub attlist
-{
-    my $self = shift;
-    my ($type, $tag, $data) = @_;
-
-    foreach my $entity (keys(%{$self->{ENTITY}}))
-    {
-        $data =~ s/$entity/$self->{ENTITY}->{$entity}/g;
-    }
-
-    while($data ne "")
-    {
-        my ($att) = ($data =~ /^\s*(\S+)/);
-        $data =~ s/^\s*\S+\s*//;
-
-        my $value;
-        if ($data =~ /^\(/)
-        {
-            $value = $self->getgrouping($data);
-            $data = substr($data,length($value)+1,length($data));
-            $data =~ s/^\s*//;
-            $self->{ATTLIST}->{$tag}->{$att}->{type} = "list";
-            foreach my $val (split(/\s*\|\s*/,substr($value,1,length($value)-2))) {
-$self->{ATTLIST}->{$tag}->{$att}->{value}->{$val} = 1;
-            }
-        }
-        else
-        {
-            ($value) = ($data =~ /^(\S+)/);
-            $data =~ s/^\S+\s*//;
-            $self->{ATTLIST}->{$tag}->{$att}->{type} = $value;
-        }
-
-        my $default;
-        if ($data =~ /^\"|^\'/)
-        {
-            my($sq,$val) = ($data =~ /^(\"|\')([^\"\']*)\1/);
-            $default = $val;
-            $data =~ s/^$sq$val$sq\s*//;
-        }
-        else
-        {
-            ($default) = ($data =~ /^(\S+)/);
-            $data =~ s/^\S+\s*//;
-        }
-
-        $self->{ATTLIST}->{$tag}->{$att}->{default} = $default;
-    }
-}
-
-
-
-sub getgrouping
-{
-    my $self = shift;
-    my ($data) = @_;
-
-    my $count = 0;
-    my $parens = 0;
-    foreach my $char (split("",$data))
-    {
-        $parens++ if ($char eq "(");
-        $parens-- if ($char eq ")");
-        $count++;
-        last if ($parens == 0);
-    }
-    return substr($data,0,$count);
-}
-
-
-sub groupinglist
-{
-    my $self = shift;
-    my ($grouping,$seperator) = @_;
-
-    my @list;
-    my $item = "";
-    my $parens = 0;
-    my $word = "";
-    $grouping = substr($grouping,1,length($grouping)-2) if ($grouping =~ /^\(/);
-    foreach my $char (split("",$grouping))
-    {
-        $parens++ if ($char eq "(");
-        $parens-- if ($char eq ")");
-        if (($parens == 0) && ($char eq $seperator))
-        {
-            push(@list,$word);
-            $word = "";
-        }
-        else
-        {
-            $word .= $char;
-        }
-    }
-    push(@list,$word) unless ($word eq "");
-    return @list;
-}
-
-
-sub root
-{
-    my $self = shift;
-    my $tag = shift;
-    my @root;
-    foreach my $tag (keys(%{$self->{COUNTER}}))
-    {
-        push(@root,$tag) if ($self->{COUNTER}->{$tag} == 0);
-    }
-
-    print "ERROR:  Too many root tags... Check the DTD...\n"
-        if ($#root > 0);
-    return $root[0];
-}
-
-
-sub children
-{
-    my $self = shift;
-    my ($tag,$tree) = @_;
-
-    return unless exists ($self->{CHILDREN}->{$tag});
-    return if (exists($self->{CHILDREN}->{$tag}->{EMPTY}));
-    if (defined($tree))
-    {
-        my @current;
-        foreach my $current (&XML::Stream::GetXMLData("tree array",$tree,"*","",""))
-        {
-            push(@current,$$current[0]);
-        }
-        return $self->allowedchildren($self->{ELEMENT}->{$tag},\@current);
-    }
-    return $self->allowedchildren($self->{ELEMENT}->{$tag});
-}
-
-
-sub allowedchildren
-{
-    my $self = shift;
-    my ($dstr,$current) = @_;
-
-    my @allowed;
-
-    if ($dstr->{type} eq "element")
-    {
-        my $test = (defined($current) && $#{@{$current}} > -1) ? $$current[0] : "";
-        shift(@{$current}) if ($dstr->{element} eq $test);
-        if ($self->repeatcheck($dstr,$test) == 1)
-        {
-            return $dstr->{element};
-        }
-    }
-    else
-    {
-        foreach my $index (0..$#{$dstr->{list}})
-        {
-            push(@allowed,$self->allowedchildren($dstr->{list}->[$index],$current));
-        }
-    }
-
-    return @allowed;
-}
-
-
-sub repeatcheck
-{
-    my $self = shift;
-    my ($dstr,$tag) = @_;
-
-    $dstr = $self->{ELEMENT}->{$dstr} if exists($self->{ELEMENT}->{$dstr});
-
-#  print "repeatcheck: tag($tag)\n";
-#  print "repeatcheck: repeat($dstr->{repeat})\n"
-#    if exists($dstr->{repeat});
-
-    my $return = 0;
-    $return = ((!defined($tag) ||
-                ($tag eq $dstr->{element})) ?
-               0 :
-               1)
-        if (!exists($dstr->{repeat}) ||
-            ($dstr->{repeat} eq "?"));
-    $return = ((defined($tag) ||
-                (exists($dstr->{ordered}) &&
-                ($dstr->{ordered} eq "yes"))) ?
-               1 :
-               0)
-        if (exists($dstr->{repeat}) &&
-            (($dstr->{repeat} eq "+") ||
-             ($dstr->{repeat} eq "*")));
-
-#  print "repeatcheck: return($return)\n";
-    return $return;
-}
-
-
-sub required
-{
-    my $self = shift;
-    my ($dstr,$tag,$count) = @_;
-
-    $dstr = $self->{ELEMENT}->{$dstr} if exists($self->{ELEMENT}->{$dstr});
-
-    if ($dstr->{type} eq "element")
-    {
-        return 0 if ($dstr->{element} ne $tag);
-        return 1 if !exists($dstr->{repeat});
-        return 1 if (($dstr->{repeat} eq "+") && ($count == 1)) ;
-    }
-    else
-    {
-        return 0 if (($dstr->{repeat} eq "*") || ($dstr->{repeat} eq "?"));
-        my $test = 0;
-        foreach my $index (0..$#{$dstr->{list}})
-        {
-            $test = $test | $self->required($dstr->{list}->[$index],$tag,$count);
-        }
-        return $test;
-    }
-    return 0;
-}
-
-
-sub addchild
-{
-    my $self = shift;
-    my ($tag,$child,$tree) = @_;
-
-#  print "addchild: tag($tag) child($child)\n";
-
-    my @current;
-    if (defined($tree))
-    {
-#    &Net::Jabber::printData("\$tree",$tree);
-
-        @current = &XML::Stream::GetXMLData("index array",$tree,"*","","");
-
-#    &Net::Jabber::printData("\$current",\@current);
-    }
-
-    my @newBranch = $self->addchildrecurse($self->{ELEMENT}->{$tag},$child,\@current);
-
-    return $tree unless ("@newBranch" ne "");
-
-#  &Net::Jabber::printData("\$newBranch",\@newBranch);
-
-    my $location = shift(@newBranch);
-
-    if ($location eq "end")
-    {
-        splice(@{$$tree[1]},@{$$tree[1]},0,@newBranch);
-    }
-    else
-    {
-        splice(@{$$tree[1]},$location,0,@newBranch);
-    }
-    return $tree;
-}
-
-
-sub addcdata
-{
-    my $self = shift;
-    my ($tag,$child,$tree) = @_;
-
-#  print "addchild: tag($tag) child($child)\n";
-
-    my @current;
-    if (defined($tree))
-    {
-#    &Net::Jabber::printData("\$tree",$tree);
-
-        @current = &XML::Stream::GetXMLData("index array",$tree,"*","","");
-
-#    &Net::Jabber::printData("\$current",\@current);
-    }
-
-    my @newBranch = $self->addchildrecurse($self->{ELEMENT}->{$tag},$child,\@current);
-
-    return $tree unless ("@newBranch" ne "");
-
-#  &Net::Jabber::printData("\$newBranch",\@newBranch);
-
-    my $location = shift(@newBranch);
-
-    if ($location eq "end")
-    {
-        splice(@{$$tree[1]},@{$$tree[1]},0,@newBranch);
-    }
-    else
-    {
-        splice(@{$$tree[1]},$location,0,@newBranch);
-    }
-    return $tree;
-}
-
-
-sub addchildrecurse
-{
-    my $self = shift;
-    my ($dstr,$child,$current) = @_;
-
-#  print "addchildrecurse: child($child) type($dstr->{type})\n";
-
-    if ($dstr->{type} eq "element")
-    {
-#    print "addchildrecurse: tag($dstr->{element})\n";
-        my $count = 0;
-        while(($#{@{$current}} > -1) && ($dstr->{element} eq $$current[0]))
-        {
-            shift(@{$current});
-            shift(@{$current});
-            $count++;
-        }
-        if (($dstr->{element} eq $child) &&
-            ($self->repeatcheck($dstr,(($count > 0) ? $child : "")) == 1))
-        {
-            my @return = ( "end" , $self->newbranch($child));
-            @return = ($$current[1], $self->newbranch($child))
-                if ($#{@{$current}} > -1);
-#      print "addchildrecurse: Found the spot! (",join(",",@return),")\n";
-
-            return @return;
-        }
-    }
-    else
-    {
-        foreach my $index (0..$#{$dstr->{list}})
-        {
-            my @newBranch = $self->addchildrecurse($dstr->{list}->[$index],$child,$current);
-            return @newBranch if ("@newBranch" ne "");
-        }
-    }
-#  print "Let's blow....\n";
-    return;
-}
-
-
-sub deletechild
-{
-    my $self = shift;
-    my ($tag,$parent,$parenttree,$tree) = @_;
-
-    return $tree unless exists($self->{ELEMENT}->{$tag});
-    return $tree if $self->required($parent,$tag,&XML::Stream::GetXMLData("count",$parenttree,$tag));
-
-    return [];
-}
-
-
-
-sub newbranch
-{
-    my $self = shift;
-    my $tag = shift;
-
-    $tag = $self->root() unless defined($tag);
-
-    my @tree = ();
-
-    return ("0","") if ($tag eq "#PCDATA");
-
-    push(@tree,$tag);
-    push(@tree,[ {} ]);
-
-    foreach my $att ($self->attribs($tag))
-    {
-        $tree[1]->[0]->{$att} = ""
-            if (($self->{ATTLIST}->{$tag}->{$att}->{default} eq "#REQUIRED") &&
-                ($self->{ATTLIST}->{$tag}->{$att}->{type} eq "CDATA"));
-    }
-
-    push(@{$tree[1]},$self->recursebranch($self->{ELEMENT}->{$tag}));
-    return @tree;
-}
-
-
-sub recursebranch
-{
-    my $self = shift;
-    my $dstr = shift;
-
-    my @tree;
-    if (($dstr->{type} eq "element") &&
-        ($dstr->{element} ne "EMPTY"))
-    {
-        @tree = $self->newbranch($dstr->{element})
-            if (!exists($dstr->{repeat}) ||
-                ($dstr->{repeat} eq "+"));
-    }
-    else
-    {
-        foreach my $index (0..$#{$dstr->{list}})
-        {
-            push(@tree,$self->recursebranch($dstr->{list}->[$index]))
-if (!exists($dstr->{repeat}) ||
-        ($dstr->{repeat} eq "+"));
-        }
-    }
-    return @tree;
-}
-
-
-sub attribs
-{
-    my $self = shift;
-    my ($tag,$tree) = @_;
-
-    return unless exists ($self->{ATTLIST}->{$tag});
-
-    if (defined($tree))
-    {
-        my %current = &XML::Stream::GetXMLData("attribs",$tree,"","","");
-        return $self->allowedattribs($tag,\%current);
-    }
-    return $self->allowedattribs($tag);
-}
-
-
-sub allowedattribs
-{
-    my $self = shift;
-    my ($tag,$current) = @_;
-
-    my %allowed;
-    foreach my $att (keys(%{$self->{ATTLIST}->{$tag}}))
-    {
-        $allowed{$att} = 1 unless (defined($current) &&
-                                   exists($current->{$att}));
-    }
-    return sort {$a cmp $b} keys(%allowed);
-}
-
-
-sub attribvalue
-{
-    my $self = shift;
-    my $tag = shift;
-    my $att = shift;
-
-    return $self->{ATTLIST}->{$tag}->{$att}->{type}
-        if ($self->{ATTLIST}->{$tag}->{$att}->{type} ne "list");
-    return sort {$a cmp $b} keys(%{$self->{ATTLIST}->{$tag}->{$att}->{value}});
-}
-
-
-sub addattrib
-{
-    my $self = shift;
-    my ($tag,$att,$tree) = @_;
-
-    return $tree unless exists($self->{ATTLIST}->{$tag});
-    return $tree unless exists($self->{ATTLIST}->{$tag}->{$att});
-
-    my $default = $self->{ATTLIST}->{$tag}->{$att}->{default};
-    $default = "" if ($default eq "#REQUIRED");
-    $default = "" if ($default eq "#IMPLIED");
-
-    $$tree[1]->[0]->{$att} = $default;
-
-    return $tree;
-}
-
-
-sub attribrequired
-{
-    my $self = shift;
-    my ($tag,$att) = @_;
-
-    return 0 unless exists($self->{ATTLIST}->{$tag});
-    return 0 unless exists($self->{ATTLIST}->{$tag}->{$att});
-
-    return 1 if ($self->{ATTLIST}->{$tag}->{$att}->{default} eq "#REQUIRED");
-    return 0;
-}
-
-
-sub deleteattrib
-{
-    my $self = shift;
-    my ($tag,$att,$tree) = @_;
-
-    return $tree unless exists($self->{ATTLIST}->{$tag});
-    return $tree unless exists($self->{ATTLIST}->{$tag}->{$att});
-
-    return if $self->attribrequired($tag,$att);
-
-    delete($$tree[1]->[0]->{$att});
-
-    return $tree;
-}
-
Index: rl/modules/Jabber/lib/XML/Stream/Tree.pm
===================================================================
--- perl/modules/Jabber/lib/XML/Stream/Tree.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,682 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package XML::Stream::Tree;
-
-=head1 NAME
-
-XML::Stream::Tree - Functions to make building and parsing the tree easier
-to work with.
-
-=head1 SYNOPSIS
-
-  Just a collection of functions that do not need to be in memory if you
-choose one of the other methods of data storage.
-
-=head1 FORMAT
-
-The result of parsing:
-
-  <foo><head id="a">Hello <em>there</em></head><bar>Howdy<ref/></bar>do</foo>
-
-would be:
-         Tag   Content
-  ==================================================================
-  [foo, [{},
-         head, [{id => "a"},
-                0, "Hello ",
-                em, [{},
-                     0, "there"
-                    ]
-               ],
-         bar, [{},
-               0, "Howdy",
-               ref, [{}]
-              ],
-         0, "do"
-        ]
-  ]
-
-The above was copied from the XML::Parser man page.  Many thanks to
-Larry and Clark.
-
-=head1 AUTHOR
-
-By Ryan Eatmon in March 2001 for http://jabber.org/
-
-=head1 COPYRIGHT
-
-This module is free software; you can redistribute it and/or modify
-it under the same terms as Perl itself.
-
-=cut
-
-use vars qw( $VERSION $LOADED );
-
-$VERSION = "1.22";
-$LOADED = 1;
-
-##############################################################################
-#
-# _handle_element - handles the main tag elements sent from the server.
-#                   On an open tag it creates a new XML::Parser::Tree so
-#                   that _handle_cdata and _handle_element can add data
-#                   and tags to it later.
-#
-##############################################################################
-sub _handle_element
-{
-    my $self;
-    $self = $_[0] if (ref($_[0]) eq "XML::Stream::Parser");
-    $self = shift unless (ref($_[0]) eq "XML::Stream::Parser");
-    my ($sax, $tag, %att) = @_;
-    my $sid = $sax->getSID();
-
-    $self->debug(2,"_handle_element: sid($sid) sax($sax) tag($tag) att(",%att,")");
-
-    my @NEW;
-    if($#{$self->{SIDS}->{$sid}->{tree}} < 0)
-    {
-        push @{$self->{SIDS}->{$sid}->{tree}}, $tag;
-    }
-    else
-    {
-        push @{ $self->{SIDS}->{$sid}->{tree}[ $#{$self->{SIDS}->{$sid}->{tree}}]}, $tag;
-    }
-    push @NEW, \%att;
-    push @{$self->{SIDS}->{$sid}->{tree}}, \@NEW;
-}
-
-
-##############################################################################
-#
-# _handle_cdata - handles the CDATA that is encountered.  Also, in the
-#                      spirit of XML::Parser::Tree it combines any sequential
-#                      CDATA into one tag.
-#
-##############################################################################
-sub _handle_cdata
-{
-    my $self;
-    $self = $_[0] if (ref($_[0]) eq "XML::Stream::Parser");
-    $self = shift unless (ref($_[0]) eq "XML::Stream::Parser");
-    my ($sax, $cdata) = @_;
-    my $sid = $sax->getSID();
-
-    $self->debug(2,"_handle_cdata: sid($sid) sax($sax) cdata($cdata)");
-
-    return if ($#{$self->{SIDS}->{$sid}->{tree}} == -1);
-
-    $self->debug(2,"_handle_cdata: sax($sax) cdata($cdata)");
-
-    my $pos = $#{$self->{SIDS}->{$sid}->{tree}};
-    $self->debug(2,"_handle_cdata: pos($pos)");
-
-    if ($pos > 0 && $self->{SIDS}->{$sid}->{tree}[$pos - 1] eq "0")
-    {
-        $self->debug(2,"_handle_cdata: append cdata");
-        $self->{SIDS}->{$sid}->{tree}[$pos - 1] .= $cdata;
-    }
-    else
-    {
-        $self->debug(2,"_handle_cdata: new cdata");
-        push @{$self->{SIDS}->{$sid}->{tree}[$#{$self->{SIDS}->{$sid}->{tree}}]}, 0;
-        push @{$self->{SIDS}->{$sid}->{tree}[$#{$self->{SIDS}->{$sid}->{tree}}]}, $cdata;
-    }  
-}
-
-
-##############################################################################
-#
-# _handle_close - when we see a close tag we need to pop the last element
-#                      from the list and push it onto the end of the previous
-#                      element.  This is how we build our hierarchy.
-#
-##############################################################################
-sub _handle_close
-{
-    my $self;
-    $self = $_[0] if (ref($_[0]) eq "XML::Stream::Parser");
-    $self = shift unless (ref($_[0]) eq "XML::Stream::Parser");
-    my ($sax, $tag) = @_;
-    my $sid = $sax->getSID();
-
-    $self->debug(2,"_handle_close: sid($sid) sax($sax) tag($tag)");
-
-    my $CLOSED = pop @{$self->{SIDS}->{$sid}->{tree}};
-
-    $self->debug(2,"_handle_close: check(",$#{$self->{SIDS}->{$sid}->{tree}},")");
-
-    if ($#{$self->{SIDS}->{$sid}->{tree}} == -1)
-    {
-        if ($self->{SIDS}->{$sid}->{rootTag} ne $tag)
-        {
-            $self->{SIDS}->{$sid}->{streamerror} = "Root tag mis-match: <$self->{SIDS}->{$sid}->{rootTag}> ... </$tag>\n";
-        }
-        return;
-    }
-
-    if($#{$self->{SIDS}->{$sid}->{tree}} < 1)
-    {
-
-        push @{$self->{SIDS}->{$sid}->{tree}}, $CLOSED;
-
-        if (ref($self) ne "XML::Stream::Parser")
-        {
-            my $stream_prefix = $self->StreamPrefix($sid);
-
-            if(defined($self->{SIDS}->{$sid}->{tree}->[0]) &&
-               ($self->{SIDS}->{$sid}->{tree}->[0] =~ /^${stream_prefix}\:/))
-            { 
-                my @tree = @{$self->{SIDS}->{$sid}->{tree}};
-                $self->{SIDS}->{$sid}->{tree} = [];
-                $self->ProcessStreamPacket($sid,\@tree);
-            }
-            else
-            {
-                my @tree = @{$self->{SIDS}->{$sid}->{tree}};
-                $self->{SIDS}->{$sid}->{tree} = [];
-                
-                my @special =
-                    &XML::Stream::XPath(
-                        \@tree,
-                        '[@xmlns="'.&XML::Stream::ConstXMLNS("xmpp-sasl").'" or @xmlns="'.&XML::Stream::ConstXMLNS("xmpp-tls").'"]'
-                    );
-                if ($#special > -1)
-                {
-                    my $xmlns = &GetXMLData("value",\@tree,"","xmlns");
-
-                    $self->ProcessSASLPacket($sid,\@tree)
-                        if ($xmlns eq &XML::Stream::ConstXMLNS("xmpp-sasl"));
-                    $self->ProcessTLSPacket($sid,\@tree)
-                        if ($xmlns eq &XML::Stream::ConstXMLNS("xmpp-tls"));
-                }
-                else
-                {
-                    &{$self->{CB}->{node}}($sid,\@tree);
-                }
-            }
-        }
-    }
-    else
-    {
-        push @{$self->{SIDS}->{$sid}->{tree}[$#{$self->{SIDS}->{$sid}->{tree}}]}, $CLOSED;
-    }
-}
-
-
-##############################################################################
-#
-# SetXMLData - takes a host of arguments and sets a portion of the specified
-#              XML::Parser::Tree object with that data.  The function works
-#              in two modes "single" or "multiple".  "single" denotes that
-#              the function should locate the current tag that matches this
-#              data and overwrite it's contents with data passed in.
-#              "multiple" denotes that a new tag should be created even if
-#              others exist.
-#
-#              type    - single or multiple
-#              XMLTree - pointer to XML::Stream Tree object
-#              tag     - name of tag to create/modify (if blank assumes
-#                        working with top level tag)
-#              data    - CDATA to set for tag
-#              attribs - attributes to ADD to tag
-#
-##############################################################################
-sub SetXMLData
-{
-    my ($type,$XMLTree,$tag,$data,$attribs) = @_;
-    my ($key);
-
-    if ($tag ne "")
-    {
-        if ($type eq "single")
-        {
-            my ($child);
-            foreach $child (1..$#{$$XMLTree[1]})
-            {
-                if ($$XMLTree[1]->[$child] eq $tag)
-                {
-                    if ($data ne "")
-                    {
-                        #todo: add code to handle writing the cdata again and appending it.
-                        $$XMLTree[1]->[$child+1]->[1] = 0;
-                        $$XMLTree[1]->[$child+1]->[2] = $data;
-                    }
-                    foreach $key (keys(%{$attribs}))
-                    {
-                        $$XMLTree[1]->[$child+1]->[0]->{$key} = $$attribs{$key};
-                    }
-                    return;
-                }
-            }
-        }
-        $$XMLTree[1]->[($#{$$XMLTree[1]}+1)] = $tag;
-        $$XMLTree[1]->[($#{$$XMLTree[1]}+1)]->[0] = {};
-        foreach $key (keys(%{$attribs}))
-        {
-            $$XMLTree[1]->[$#{$$XMLTree[1]}]->[0]->{$key} = $$attribs{$key};
-        }
-        if ($data ne "")
-        {
-            $$XMLTree[1]->[$#{$$XMLTree[1]}]->[1] = 0;
-            $$XMLTree[1]->[$#{$$XMLTree[1]}]->[2] = $data;
-        }
-    }
-    else
-    {
-        foreach $key (keys(%{$attribs}))
-        {
-            $$XMLTree[1]->[0]->{$key} = $$attribs{$key};
-        }
-        if ($data ne "")
-        {
-            if (($#{$$XMLTree[1]} > 0) &&
-                ($$XMLTree[1]->[($#{$$XMLTree[1]}-1)] eq "0"))
-            {
-                $$XMLTree[1]->[$#{$$XMLTree[1]}] .= $data;
-            }
-            else
-            {
-                $$XMLTree[1]->[($#{$$XMLTree[1]}+1)] = 0;
-                $$XMLTree[1]->[($#{$$XMLTree[1]}+1)] = $data;
-            }
-        }
-    }
-}
-
-
-##############################################################################
-#
-# GetXMLData - takes a host of arguments and returns various data structures
-#              that match them.
-#
-#              type - "existence" - returns 1 or 0 if the tag exists in the
-#                                   top level.
-#                     "value" - returns either the CDATA of the tag, or the
-#                               value of the attribute depending on which is
-#                               sought.  This ignores any mark ups to the data
-#                               and just returns the raw CDATA.
-#                     "value array" - returns an array of strings representing
-#                                     all of the CDATA in the specified tag.
-#                                     This ignores any mark ups to the data
-#                                     and just returns the raw CDATA.
-#                     "tree" - returns an XML::Parser::Tree object with the
-#                              specified tag as the root tag.
-#                     "tree array" - returns an array of XML::Parser::Tree
-#                                    objects each with the specified tag as
-#                                    the root tag.
-#                     "child array" - returns a list of all children nodes
-#                                     not including CDATA nodes.
-#                     "attribs" - returns a hash with the attributes, and
-#                                 their values, for the things that match
-#                                 the parameters
-#                     "count" - returns the number of things that match
-#                               the arguments
-#                     "tag" - returns the root tag of this tree
-#              XMLTree - pointer to XML::Parser::Tree object
-#              tag     - tag to pull data from.  If blank then the top level
-#                        tag is accessed.
-#              attrib  - attribute value to retrieve.  Ignored for types
-#                        "value array", "tree", "tree array".  If paired
-#                        with value can be used to filter tags based on
-#                        attributes and values.
-#              value   - only valid if an attribute is supplied.  Used to
-#                        filter for tags that only contain this attribute.
-#                        Useful to search through multiple tags that all
-#                        reference different name spaces.
-#
-##############################################################################
-sub GetXMLData
-{
-    my ($type,$XMLTree,$tag,$attrib,$value) = @_;
-
-    $tag = "" if !defined($tag);
-    $attrib = "" if !defined($attrib);
-    $value = "" if !defined($value);
-
-    my $skipthis = 0;
-
-    #---------------------------------------------------------------------------
-    # Check if a child tag in the root tag is being requested.
-    #---------------------------------------------------------------------------
-    if ($tag ne "")
-    {
-        my $count = 0;
-        my @array;
-        foreach my $child (1..$#{$$XMLTree[1]})
-        {
-            next if (($child/2) !~ /\./);
-            if (($$XMLTree[1]->[$child] eq $tag) || ($tag eq "*"))
-            {
-                next if (ref($$XMLTree[1]->[$child]) eq "ARRAY");
-
-                #---------------------------------------------------------------------
-                # Filter out tags that do not contain the attribute and value.
-                #---------------------------------------------------------------------
-                next if (($value ne "") && ($attrib ne "") && exists($$XMLTree[1]->[$child+1]->[0]->{$attrib}) && ($$XMLTree[1]->[$child+1]->[0]->{$attrib} ne $value));
-                next if (($attrib ne "") && ((ref($$XMLTree[1]->[$child+1]) ne "ARRAY") || !exists($$XMLTree[1]->[$child+1]->[0]->{$attrib})));
-
-                #---------------------------------------------------------------------
-                # Check for existence
-                #---------------------------------------------------------------------
-                if ($type eq "existence")
-                {
-                    return 1;
-                }
-                
-                #---------------------------------------------------------------------
-                # Return the raw CDATA value without mark ups, or the value of the
-                # requested attribute.
-                #---------------------------------------------------------------------
-                if ($type eq "value")
-                {
-                    if ($attrib eq "")
-                    {
-                        my $str = "";
-                        my $next = 0;
-                        my $index;
-                        foreach $index (1..$#{$$XMLTree[1]->[$child+1]}) {
-                            if ($next == 1) { $next = 0; next; }
-                            if ($$XMLTree[1]->[$child+1]->[$index] eq "0") {
-                                $str .= $$XMLTree[1]->[$child+1]->[$index+1];
-                                $next = 1;
-                            }
-                        }
-                        return $str;
-                    }
-                    return $$XMLTree[1]->[$child+1]->[0]->{$attrib}
-                        if (exists $$XMLTree[1]->[$child+1]->[0]->{$attrib});
-                }
-                #---------------------------------------------------------------------
-                # Return an array of values that represent the raw CDATA without
-                # mark up tags for the requested tags.
-                #---------------------------------------------------------------------
-                if ($type eq "value array")
-                {
-                    if ($attrib eq "")
-                    {
-                        my $str = "";
-                        my $next = 0;
-                        my $index;
-                        foreach $index (1..$#{$$XMLTree[1]->[$child+1]})
-                        {
-                            if ($next == 1) { $next = 0;  next; }
-                            if ($$XMLTree[1]->[$child+1]->[$index] eq "0")
-                            {
-                                $str .= $$XMLTree[1]->[$child+1]->[$index+1];
-                                $next = 1;
-                            }
-                        }
-                        push(@array,$str);
-                    }
-                    else
-                    {
-                        push(@array,$$XMLTree[1]->[$child+1]->[0]->{$attrib})
-                            if (exists $$XMLTree[1]->[$child+1]->[0]->{$attrib});
-                    }
-                }
-                #---------------------------------------------------------------------
-                # Return a pointer to a new XML::Parser::Tree object that has the
-                # requested tag as the root tag.
-                #---------------------------------------------------------------------
-                if ($type eq "tree")
-                {
-                    my @tree = ( $$XMLTree[1]->[$child] , $$XMLTree[1]->[$child+1] );
-                    return @tree;
-                }
-                #---------------------------------------------------------------------
-                # Return an array of pointers to XML::Parser::Tree objects that have
-                # the requested tag as the root tags.
-                #---------------------------------------------------------------------
-                if ($type eq "tree array")
-                {
-                    my @tree = ( $$XMLTree[1]->[$child] , $$XMLTree[1]->[$child+1] );
-                    push(@array,\@tree);
-                }
-                #---------------------------------------------------------------------
-                # Return a count of the number of tags that match
-                #---------------------------------------------------------------------
-                if ($type eq "count")
-                {
-                    if ($$XMLTree[1]->[$child] eq "0")
-                    {
-                        $skipthis = 1;
-                        next;
-                    }
-                    if ($skipthis == 1)
-                    {
-                        $skipthis = 0;
-                        next;
-                    }
-                    $count++;
-                }
-                #---------------------------------------------------------------------
-                # Return a count of the number of tags that match
-                #---------------------------------------------------------------------
-                if ($type eq "child array")
-                {
-                    my @tree = ( $$XMLTree[1]->[$child] , $$XMLTree[1]->[$child+1] );
-                    push(@array,\@tree) if ($tree[0] ne "0");
-                }
-                #---------------------------------------------------------------------
-                # Return the attribute hash that matches this tag
-                #---------------------------------------------------------------------
-                if ($type eq "attribs")
-                {
-                    return (%{$$XMLTree[1]->[$child+1]->[0]});
-                }
-            }
-        }
-        #-------------------------------------------------------------------------
-        # If we are returning arrays then return array.
-        #-------------------------------------------------------------------------
-        if (($type eq "tree array") || ($type eq "value array") ||
-            ($type eq "child array"))
-        {
-            return @array;
-        }
-
-        #-------------------------------------------------------------------------
-        # If we are returning then count, then do so
-        #-------------------------------------------------------------------------
-        if ($type eq "count")
-        {
-            return $count;
-        }
-    }
-    else
-    {
-        #-------------------------------------------------------------------------
-        # This is the root tag, so handle things a level up.
-        #-------------------------------------------------------------------------
-
-        #-------------------------------------------------------------------------
-        # Return the raw CDATA value without mark ups, or the value of the
-        # requested attribute.
-        #-------------------------------------------------------------------------
-        if ($type eq "value")
-        {
-            if ($attrib eq "")
-            {
-                my $str = "";
-                my $next = 0;
-                my $index;
-                foreach $index (1..$#{$$XMLTree[1]})
-                {
-                    if ($next == 1) { $next = 0; next; }
-                    if ($$XMLTree[1]->[$index] eq "0")
-                    {
-                        $str .= $$XMLTree[1]->[$index+1];
-                        $next = 1;
-                    }
-                }
-                return $str;
-            }
-            return $$XMLTree[1]->[0]->{$attrib}
-                if (exists $$XMLTree[1]->[0]->{$attrib});
-        }
-        #-------------------------------------------------------------------------
-        # Return a pointer to a new XML::Parser::Tree object that has the
-        # requested tag as the root tag.
-        #-------------------------------------------------------------------------
-        if ($type eq "tree")
-        {
-            my @tree =  @{$$XMLTree};
-            return @tree;
-        }
-
-        #-------------------------------------------------------------------------
-        # Return the 1 if the specified attribute exists in the root tag.
-        #-------------------------------------------------------------------------
-        if ($type eq "existence")
-        {
-            return 1 if (($attrib ne "") && (exists($$XMLTree[1]->[0]->{$attrib})));
-        }
-
-        #-------------------------------------------------------------------------
-        # Return the attribute hash that matches this tag
-        #-------------------------------------------------------------------------
-        if ($type eq "attribs")
-        {
-            return %{$$XMLTree[1]->[0]};
-        }
-        #-------------------------------------------------------------------------
-        # Return the tag of this node
-        #-------------------------------------------------------------------------
-        if ($type eq "tag")
-        {
-            return $$XMLTree[0];
-        }
-    }
-    #---------------------------------------------------------------------------
-    # Return 0 if this was a request for existence, or "" if a request for
-    # a "value", or [] for "tree", "value array", and "tree array".
-    #---------------------------------------------------------------------------
-    return 0 if ($type eq "existence");
-    return "" if ($type eq "value");
-    return [];
-}
-
-
-##############################################################################
-#
-# BuildXML - takes an XML::Parser::Tree object and builds the XML string
-#                 that it represents.
-#
-##############################################################################
-sub BuildXML
-{
-    my ($parseTree,$rawXML) = @_;
-
-    return "" if $#{$parseTree} == -1;
-
-    my $str = "";
-    if (ref($parseTree->[0]) eq "") 
-    {
-        if ($parseTree->[0] eq "0")
-        {
-            return &XML::Stream::EscapeXML($parseTree->[1]);
-        }
-
-        $str = "<".$parseTree->[0];
-        foreach my $att (sort {$a cmp $b} keys(%{$parseTree->[1]->[0]}))
-        {
-            $str .= " ".$att."='".&XML::Stream::EscapeXML($parseTree->[1]->[0]->{$att})."'";
-        }
-
-        if (($#{$parseTree->[1]} > 0) || (defined($rawXML) && ($rawXML ne "")))
-        {
-            $str .= ">";
-            
-            my $index = 1;
-            while($index <= $#{$parseTree->[1]})
-            {
-                my @newTree = ( $parseTree->[1]->[$index], $parseTree->[1]->[$index+1] );
-                $str .= &XML::Stream::Tree::BuildXML(\@newTree);
-                $index += 2;
-            }
-            
-            $str .= $rawXML if defined($rawXML);
-            $str .= "</".$parseTree->[0].">";
-        }
-        else
-        {
-            $str .= "/>";
-        }
-
-    }
-
-    return $str;
-}
-
-
-##############################################################################
-#
-# XML2Config - takes an XML data tree and turns it into a hash of hashes.
-#              This only works for certain kinds of XML trees like this:
-#
-#                <foo>
-#                  <bar>1</bar>
-#                  <x>
-#                    <y>foo</y>
-#                  </x>
-#                  <z>5</z>
-#                </foo>
-#
-#              The resulting hash would be:
-#
-#                $hash{bar} = 1;
-#                $hash{x}->{y} = "foo";
-#                $hash{z} = 5;
-#
-#              Good for config files.
-#
-##############################################################################
-sub XML2Config
-{
-    my ($XMLTree) = @_;
-
-    my %hash;
-    foreach my $tree (&XML::Stream::GetXMLData("tree array",$XMLTree,"*"))
-    {
-        if ($tree->[0] eq "0")
-        {
-            return $tree->[1] unless ($tree->[1] =~ /^\s*$/);
-        }
-        else
-        {
-            if (&XML::Stream::GetXMLData("count",$XMLTree,$tree->[0]) > 1)
-            {
-                push(@{$hash{$tree->[0]}},&XML::Stream::XML2Config($tree));
-            }
-            else
-            {
-                $hash{$tree->[0]} = &XML::Stream::XML2Config($tree);
-            }
-        }
-    }
-    return \%hash;
-}
-
-
-1;
Index: rl/modules/Jabber/lib/XML/Stream/XPath.pm
===================================================================
--- perl/modules/Jabber/lib/XML/Stream/XPath.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,50 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package XML::Stream::XPath;
-
-use 5.006_001;
-use strict;
-use vars qw( $VERSION %FUNCTIONS );
-
-$VERSION = "1.22";
-
-use XML::Stream::XPath::Value;
-use XML::Stream::XPath::Op;
-use XML::Stream::XPath::Query;
-
-sub AddFunction
-{
-    my $function = shift;
-    my $code = shift;
-    if (!defined($code))
-    {
-        delete($FUNCTIONS{$code});
-        return;
-    }
-
-    $FUNCTIONS{$function} = $code;
-}
-
-
-1;
-
Index: rl/modules/Jabber/lib/XML/Stream/XPath/Op.pm
===================================================================
--- perl/modules/Jabber/lib/XML/Stream/XPath/Op.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,919 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-
-##############################################################################
-#
-# Op - Base Op class
-#
-##############################################################################
-package XML::Stream::XPath::Op;
-
-use 5.006_001;
-use strict;
-use vars qw( $VERSION );
-
-$VERSION = "1.22";
-
-sub new
-{
-    my $proto = shift;
-    return &allocate($proto,@_);
-}
-
-sub allocate
-{
-    my $proto = shift;
-    my $self = { };
-
-    bless($self,$proto);
-
-    $self->{TYPE} = shift;
-    $self->{VALUE} = shift;
-    
-    return $self;
-}
-
-sub getValue
-{
-    my $self = shift;
-    return $self->{VALUE};
-}
-
-sub calcStr
-{
-    my $self = shift;
-    return $self->{VALUE};
-}
-
-sub getType
-{
-    my $self = shift;
-    return $self->{TYPE};
-}
-
-
-sub isValid
-{
-    my $self = shift;
-    my $ctxt = shift;
-    return 1;
-}
-
-sub display
-{
-    my $self = shift;
-    my $space = shift;
-    $space = "" unless defined($space);
-
-    print $space,"OP: type($self->{TYPE}) value($self->{VALUE})\n";
-}
-
-
-
-##############################################################################
-#
-# PositionOp - class to handle [0] ops
-#
-##############################################################################
-package XML::Stream::XPath::PositionOp;
-
-use vars qw (@ISA);
-@ISA = ( "XML::Stream::XPath::Op" );
-
-sub new
-{
-    my $proto = shift;
-    my $self = $proto->allocate("POSITION","");
-    $self->{POS} = shift;
-
-    return $self;
-}
-
-
-sub isValid
-{
-    my $self = shift;
-    my $ctxt = shift;
-
-    my @elems = $$ctxt->getList();
-    my @valid_elems;
-    if ($#elems+1 < $self->{POS})
-    {
-        return;
-    }
-
-    push(@valid_elems, $elems[$self->{POS}-1]);
-
-    $$ctxt->setList(@valid_elems);
-
-    return 1;
-}
-
-
-
-##############################################################################
-#
-# ContextOp - class to handle [...] ops
-#
-##############################################################################
-package XML::Stream::XPath::ContextOp;
-
-use vars qw (@ISA);
-@ISA = ( "XML::Stream::XPath::Op" );
-
-sub new
-{
-    my $proto = shift;
-    my $self = $proto->allocate("CONTEXT","");
-    $self->{OP} = shift;
-    return $self;
-}
-
-
-sub isValid
-{
-    my $self = shift;
-    my $ctxt = shift;
-
-    my @elems = $$ctxt->getList();
-    my @valid_elems;
-    foreach my $elem (@elems)
-    {
-        my $tmp_ctxt = new XML::Stream::XPath::Value($elem);
-        $tmp_ctxt->in_context(1);
-        if ($self->{OP}->isValid(\$tmp_ctxt))
-        {
-            push(@valid_elems,$elem);
-        }   
-    }
-
-    $$ctxt->setList(@valid_elems);
-    
-    if ($#valid_elems == -1)
-    {
-        return;
-    }
-
-    return 1;
-}
-
-
-sub display
-{
-    my $self = shift;
-    my $space = shift;
-    $space = "" unless defined($space);
-
-    print "${space}OP: type(CONTEXT) op: \n";
-    $self->{OP}->display("$space    ");
-}
-
-
-
-
-##############################################################################
-#
-# AllOp - class to handle // ops
-#
-##############################################################################
-package XML::Stream::XPath::AllOp;
-
-use vars qw (@ISA);
-@ISA = ( "XML::Stream::XPath::Op" );
-
-sub new
-{
-    my $proto = shift;
-    my $name = shift;
-    my $self = $proto->allocate("ALL",$name);
-    return $self;
-}
-
-
-sub isValid
-{
-    my $self = shift;
-    my $ctxt = shift;
-
-    my @elems = $$ctxt->getList();
-
-    if ($#elems == -1)
-    {
-        return;
-    }
-
-    my @valid_elems;
-    
-    foreach my $elem (@elems)
-    {
-        push(@valid_elems,$self->descend($elem));
-    }
-    
-    $$ctxt->setList(@valid_elems);
-
-    if ($#valid_elems == -1)
-    {
-        return;
-    }
-
-    return 1;
-}
-
-
-sub descend
-{
-    my $self = shift;
-    my $elem = shift;
-
-    my @valid_elems;
-    
-    if (($self->{VALUE} eq "*") || (&XML::Stream::GetXMLData("tag",$elem) eq $self->{VALUE}))
-    {
-        push(@valid_elems,$elem);
-    }
-    
-    foreach my $child (&XML::Stream::GetXMLData("child array",$elem,"*"))
-    {
-        push(@valid_elems,$self->descend($child));
-    }
-    
-    return @valid_elems;
-}
-
-
-
-##############################################################################
-#
-# NodeOp - class to handle ops based on node names
-#
-##############################################################################
-package XML::Stream::XPath::NodeOp;
-
-use vars qw (@ISA);
-@ISA = ( "XML::Stream::XPath::Op" );
-
-sub new
-{
-    my $proto = shift;
-    my $name = shift;
-    my $is_root = shift;
-    $is_root = 0 unless defined($is_root);
-    my $self = $proto->allocate("NODE",$name);
-    $self->{ISROOT} = $is_root;
-    return $self;
-}
-
-
-sub isValid
-{
-    my $self = shift;
-    my $ctxt = shift;
-
-    if ($self->{ISROOT})
-    {
-        my $elem = $$ctxt->getFirstElem();
-        if (&XML::Stream::GetXMLData("tag",$elem) ne $self->{VALUE})
-        {
-            return;
-        }
-        return 1;
-    }
-
-    my @valid_elems;
-
-    foreach my $elem ($$ctxt->getList())
-    {
-        my $valid = 0;
-
-        foreach my $child (&XML::Stream::GetXMLData("child array",$elem,"*"))
-        {
-            if (($self->{VALUE} eq "*") ||
-                (&XML::Stream::GetXMLData("tag",$child) eq $self->{VALUE}))
-            {
-                if ($$ctxt->in_context())
-                {
-                    $valid = 1;
-                }
-                else
-                {
-                    push(@valid_elems,$child);
-                }
-            }
-        }
-        if ($valid)
-        {
-            push(@valid_elems,$elem);
-        }
-    }
-    
-    $$ctxt->setList(@valid_elems);
-
-    if ($#valid_elems == -1)
-    {
-        return;
-    }
-
-    return 1;
-}
-
-
-sub calcStr
-{
-    my $self = shift;
-    my $elem = shift;
-    return &XML::Stream::GetXMLData("value",$elem);
-} 
-
-
-##############################################################################
-#
-# EqualOp - class to handle [ x = y ] ops
-#
-##############################################################################
-package XML::Stream::XPath::EqualOp;
-
-use vars qw (@ISA);
-@ISA = ( "XML::Stream::XPath::Op" );
-
-sub new
-{
-    my $proto = shift;
-    my $self = $proto->allocate("EQUAL","");
-    $self->{OP_L} = shift;
-    $self->{OP_R} = shift;
-    return $self;
-}
-
-
-sub isValid
-{
-    my $self = shift;
-    my $ctxt = shift;
-
-    my $tmp_ctxt = new XML::Stream::XPath::Value();
-    $tmp_ctxt->setList($$ctxt->getList());
-    $tmp_ctxt->in_context(0);
-    
-    if (!$self->{OP_L}->isValid(\$tmp_ctxt) || !$self->{OP_R}->isValid(\$tmp_ctxt))
-    {
-        return;
-    }
-
-    my @valid_elems;
-    foreach my $elem ($tmp_ctxt->getList)
-    {
-        if ($self->{OP_L}->calcStr($elem) eq $self->{OP_R}->calcStr($elem))
-        {
-            push(@valid_elems,$elem);
-        }
-    }
-
-    if ( $#valid_elems > -1)
-    {
-        @valid_elems = $$ctxt->getList();
-    }
-    
-    $$ctxt->setList(@valid_elems);
-
-    if ($#valid_elems == -1)
-    {
-        return;
-    }
-
-    return 1;
-}
-
-
-sub display
-{
-    my $self = shift;
-    my $space = shift;
-    $space = "" unless defined($space);
-
-    print $space,"OP: type(EQUAL)\n";
-    print $space,"    op_l: ";
-    $self->{OP_L}->display($space."    ");
-    
-    print $space,"    op_r: ";
-    $self->{OP_R}->display($space."    ");
-}
-
-
-
-##############################################################################
-#
-# NotEqualOp - class to handle [ x != y ] ops
-#
-##############################################################################
-package XML::Stream::XPath::NotEqualOp;
-
-use vars qw (@ISA);
-@ISA = ( "XML::Stream::XPath::Op" );
-
-sub new
-{
-    my $proto = shift;
-    my $self = $proto->allocate("NOTEQUAL","");
-    $self->{OP_L} = shift;
-    $self->{OP_R} = shift;
-    return $self;
-}
-
-
-sub isValid
-{
-    my $self = shift;
-    my $ctxt = shift;
-
-    my $tmp_ctxt = new XML::Stream::XPath::Value();
-    $tmp_ctxt->setList($$ctxt->getList());
-    $tmp_ctxt->in_context(0);
-    
-    if (!$self->{OP_L}->isValid(\$tmp_ctxt) || !$self->{OP_R}->isValid(\$tmp_ctxt))
-    {
-        return;
-    }
-
-    my @valid_elems;
-    foreach my $elem ($tmp_ctxt->getList)
-    {
-        if ($self->{OP_L}->calcStr($elem) ne $self->{OP_R}->calcStr($elem))
-        {
-            push(@valid_elems,$elem);
-        }
-    }
-
-    if ( $#valid_elems > -1)
-    {
-        @valid_elems = $$ctxt->getList();
-    }
-    
-    $$ctxt->setList(@valid_elems);
-
-    if ($#valid_elems == -1)
-    {
-        return;
-    }
-
-    return 1;
-}
-
-
-sub display
-{
-    my $self = shift;
-    my $space = shift;
-    $space = "" unless defined($space);
-
-    print $space,"OP: type(NOTEQUAL)\n";
-    print $space,"    op_l: ";
-    $self->{OP_L}->display($space."    ");
-    
-    print $space,"    op_r: ";
-    $self->{OP_R}->display($space."    ");
-}
-
-
-
-##############################################################################
-#
-# AttributeOp - class to handle @foo ops.
-#
-##############################################################################
-package XML::Stream::XPath::AttributeOp;
-
-use vars qw (@ISA);
-@ISA = ( "XML::Stream::XPath::Op" );
-
-sub new
-{
-    my $proto = shift;
-    my $name = shift;
-    my $self = $proto->allocate("ATTRIBUTE",$name);
-    return $self;
-}
-
-
-sub isValid
-{
-    my $self = shift;
-    my $ctxt = shift;
-
-    my @elems = $$ctxt->getList();
-    my @valid_elems;
-    my @values;
-    my %attribs;
-    
-    foreach my $elem (@elems)
-    {
-        if ($self->{VALUE} ne "*")
-        {
-            if (&XML::Stream::GetXMLData("value",$elem,"",$self->{VALUE}))
-            {
-                $self->{VAL} = $self->calcStr($elem);
-                push(@valid_elems,$elem);
-                push(@values,$self->{VAL});
-            }
-        }
-        else
-        {
-            my %attrib = &XML::Stream::GetXMLData("attribs",$elem);
-            if (scalar(keys(%attrib)) > 0)
-            {
-                push(@valid_elems,$elem);
-                foreach my $key (keys(%attrib))
-                {
-                    $attribs{$key} = $attrib{$key};
-                }
-            }
-        }
-    }
-
-    $$ctxt->setList(@valid_elems);
-    $$ctxt->setValues(@values);
-    $$ctxt->setAttribs(%attribs);
-
-    if ($#valid_elems == -1)
-    {
-        return;
-    }
-    
-    return 1;
-}
-
-
-sub getValue
-{
-    my $self = shift;
-    return $self->{VAL};
-}
-
-
-sub calcStr
-{
-    my $self = shift;
-    my $elem = shift;
-    return &XML::Stream::GetXMLData("value",$elem,"",$self->{VALUE});
-}
-
-
-
-
-##############################################################################
-#
-# AndOp - class to handle [ .... and .... ] ops
-#
-##############################################################################
-package XML::Stream::XPath::AndOp;
-
-use vars qw (@ISA);
-@ISA = ( "XML::Stream::XPath::Op" );
-
-sub new
-{
-    my $proto = shift;
-    my $self = $proto->allocate("AND","and");
-    $self->{OP_L} = shift;
-    $self->{OP_R} = shift;
-    return $self;
-}
-
-
-sub isValid
-{
-    my $self = shift;
-    my $ctxt = shift;
-
-    my $opl = $self->{OP_L}->isValid($ctxt);
-    my $opr = $self->{OP_R}->isValid($ctxt);
-    
-    if ($opl && $opr)
-    {
-        return 1;
-    }
-    else
-    {
-        return;
-    }
-}
-
-
-sub display
-{
-    my $self = shift;
-    my $space = shift;
-    $space = "" unless defined($space);
-
-    print $space,"OP: type(AND)\n";
-    print $space,"  op_l: \n";
-    $self->{OP_L}->display($space."    ");
-    
-    print $space,"  op_r: \n";
-    $self->{OP_R}->display($space."    ");
-}
-
-
-
-##############################################################################
-#
-# OrOp - class to handle [ .... or .... ] ops
-#
-##############################################################################
-package XML::Stream::XPath::OrOp;
-
-use vars qw (@ISA);
-@ISA = ( "XML::Stream::XPath::Op" );
-
-sub new
-{
-    my $proto = shift;
-    my $self = $proto->allocate("OR","or");
-    $self->{OP_L} = shift;
-    $self->{OP_R} = shift;
-    return $self;
-}
-
-
-sub isValid
-{
-    my $self = shift;
-    my $ctxt = shift;
-
-    my @elems = $$ctxt->getList();
-    my @valid_elems;
-
-    foreach my $elem (@elems)
-    {
-        my $tmp_ctxt_l = new XML::Stream::XPath::Value($elem);
-        $tmp_ctxt_l->in_context(1);
-        my $tmp_ctxt_r = new XML::Stream::XPath::Value($elem);
-        $tmp_ctxt_r->in_context(1);
-
-        my $opl = $self->{OP_L}->isValid(\$tmp_ctxt_l);
-        my $opr = $self->{OP_R}->isValid(\$tmp_ctxt_r);
-    
-        if ($opl || $opr)
-        {
-            push(@valid_elems,$elem);
-        }   
-    }
-
-    $$ctxt->setList(@valid_elems);
-    
-    if ($#valid_elems == -1)
-    {
-        return;
-    }
-
-    return 1;
-}
-
-
-sub display
-{
-    my $self = shift;
-    my $space = shift;
-    $space = "" unless defined($space);
-
-    print "${space}OP: type(OR)\n";
-    print "$space    op_l: ";
-    $self->{OP_L}->display("$space    ");
-    
-    print "$space    op_r: ";
-    $self->{OP_R}->display("$space    ");
-}
-
-
-
-##############################################################################
-#
-# FunctionOp - class to handle xxxx(...) ops
-#
-##############################################################################
-package XML::Stream::XPath::FunctionOp;
-
-use vars qw (@ISA);
-@ISA = ( "XML::Stream::XPath::Op" );
-
-sub new
-{
-    my $proto = shift;
-    my $function = shift;
-    my $self = $proto->allocate("FUNCTION",$function);
-    $self->{CLOSED} = 0;
-    return $self;
-}
-
-
-sub addArg
-{
-    my $self = shift;
-    my $arg = shift;
-
-    push(@{$self->{ARGOPS}},$arg);
-}
-
-
-sub isValid
-{
-    my $self = shift;
-    my $ctxt = shift;
-
-    my $result;
-    eval("\$result = &{\$XML::Stream::XPath::FUNCTIONS{\$self->{VALUE}}}(\$ctxt,\@{\$self->{ARGOPS}});");
-    return $result;
-}
-
-
-sub calcStr
-{
-    my $self = shift;
-    my $elem = shift;
-    
-    my $result;
-    eval("\$result = &{\$XML::Stream::XPath::VALUES{\$self->{VALUE}}}(\$elem);");
-    return $result;
-
-}
-
-
-sub display
-{
-    my $self = shift;
-    my $space = shift;
-    $space = "" unless defined($space);
-
-    print $space,"OP: type(FUNCTION)\n";
-    print $space,"    $self->{VALUE}(\n";
-    foreach my $arg (@{$self->{ARGOPS}})
-    {
-        print $arg,"\n";
-        $arg->display($space."        ");
-    }
-    print "$space    )\n";
-}
-
-
-sub function_name
-{
-    my $ctxt = shift;
-    my (@args) = @_;
-
-    my @elems = $$ctxt->getList();
-    my @valid_elems;
-    my @valid_values;
-    foreach my $elem (@elems)
-    {
-        my $text = &value_name($elem);
-        if (defined($text))
-        {
-            push(@valid_elems,$elem);
-            push(@valid_values,$text);
-        }   
-    }
-
-    $$ctxt->setList(@valid_elems);
-    $$ctxt->setValues(@valid_values);
-    
-    if ($#valid_elems == -1)
-    {
-        return;
-    }
-
-    return 1;
-}
-
-
-sub function_not
-{
-    my $ctxt = shift;
-    my (@args) = @_;
-
-    my @elems = $$ctxt->getList();
-    my @valid_elems;
-    foreach my $elem (@elems)
-    {
-        my $tmp_ctxt = new XML::Stream::XPath::Value($elem);
-        $tmp_ctxt->in_context(1);
-        if (!($args[0]->isValid(\$tmp_ctxt)))
-        {
-            push(@valid_elems,$elem);
-        }   
-    }
-
-    $$ctxt->setList(@valid_elems);
-    
-    if ($#valid_elems == -1)
-    {
-        return;
-    }
-
-    return 1;
-}
-
-
-sub function_text
-{
-    my $ctxt = shift;
-    my (@args) = @_;
-
-    my @elems = $$ctxt->getList();
-    my @valid_elems;
-    my @valid_values;
-    foreach my $elem (@elems)
-    {
-        my $text = &value_text($elem);
-        if (defined($text))
-        {
-            push(@valid_elems,$elem);
-            push(@valid_values,$text);
-        }   
-    }
-
-    $$ctxt->setList(@valid_elems);
-    $$ctxt->setValues(@valid_values);
-    
-    if ($#valid_elems == -1)
-    {
-        return;
-    }
-
-    return 1;
-}
-
-
-sub function_startswith
-{
-    my $ctxt = shift;
-    my (@args) = @_;
-
-    my @elems = $$ctxt->getList();
-    my @valid_elems;
-    foreach my $elem (@elems)
-    {
-        my $val1 = $args[0]->calcStr($elem);
-        my $val2 = $args[1]->calcStr($elem);
-
-        if (substr($val1,0,length($val2)) eq $val2)
-        {
-            push(@valid_elems,$elem);
-        }   
-    }
-
-    $$ctxt->setList(@valid_elems);
-    
-    if ($#valid_elems == -1)
-    {
-        return;
-    }
-
-    return 1;
-}
-
-
-sub value_name
-{
-    my $elem = shift;
-    return &XML::Stream::GetXMLData("tag",$elem);
-}
-
-
-sub value_text
-{
-    my $elem = shift;
-    return &XML::Stream::GetXMLData("value",$elem);
-}
-
-
-
-$XML::Stream::XPath::FUNCTIONS{'name'} = \&function_name;
-$XML::Stream::XPath::FUNCTIONS{'not'} = \&function_not;
-$XML::Stream::XPath::FUNCTIONS{'text'} = \&function_text;
-$XML::Stream::XPath::FUNCTIONS{'starts-with'} = \&function_startswith;
-
-$XML::Stream::XPath::VALUES{'name'} = \&value_name;
-$XML::Stream::XPath::VALUES{'text'} = \&value_text;
-
-1;
-
-
Index: rl/modules/Jabber/lib/XML/Stream/XPath/Query.pm
===================================================================
--- perl/modules/Jabber/lib/XML/Stream/XPath/Query.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,374 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package XML::Stream::XPath::Query;
-
-use 5.006_001;
-use strict;
-use Carp;
-use vars qw( $VERSION );
-
-$VERSION = "1.22";
-
-sub new
-{
-    my $proto = shift;
-    my $self = { };
-
-    bless($self,$proto);
-
-    $self->{TOKENS} = [ '/','[',']','@','"',"'",'=','!','(',')',':',' ',',']; 
-    $self->{QUERY} = shift;
-    
-    if (!defined($self->{QUERY}) || ($self->{QUERY} eq ""))
-    {
-        confess("No query string specified");
-    }
-    
-    $self->parseQuery();
-    
-    return $self;
-}
-
-
-sub getNextToken
-{ 
-    my $self = shift;
-    my $pos = shift;
-
-    my @toks = grep{ $_ eq substr($self->{QUERY},$$pos,1)} @{$self->{TOKENS}};
-    while( $#toks == -1 )
-    {
-        $$pos++;
-        if ($$pos > length($self->{QUERY}))
-        {
-            $$pos = length($self->{QUERY});
-            return 0;
-        }
-        @toks = grep{ $_ eq substr($self->{QUERY},$$pos,1)} @{$self->{TOKENS}};
-    }
-
-    return $toks[0];
-}
-
-
-sub getNextIdentifier
-{
-    my $self = shift;
-    my $pos = shift;
-    my $sp = $$pos;
-    $self->getNextToken($pos);
-    return substr($self->{QUERY},$sp,$$pos-$sp);
-}
-
-
-sub getOp
-{
-    my $self = shift;
-    my $pos = shift;
-    my $in_context = shift;
-    $in_context = 0 unless defined($in_context);
-
-    my $ret_op;
-
-    my $loop = 1;
-    while( $loop )
-    {
-        my $pos_start = $$pos;
-
-        my $token = $self->getNextToken($pos);
-        if (($token eq "0") && $in_context)
-        {
-            return;
-        }
-
-        my $token_start = ++$$pos;
-        my $ident;
-     
-        if (defined($token))
-        {
-
-            if ($pos_start != ($token_start-1))
-            {
-                $$pos = $pos_start;
-                my $temp_ident = $self->getNextIdentifier($pos);
-                $ret_op = new XML::Stream::XPath::NodeOp($temp_ident,"0");
-            }
-            elsif ($token eq "/")
-            {
-                if (substr($self->{QUERY},$token_start,1) eq "/")
-                {
-                    $$pos++;
-                    my $temp_ident = $self->getNextIdentifier($pos);
-                    $ret_op = new XML::Stream::XPath::AllOp($temp_ident);
-                }
-                else
-                {
-                    my $temp_ident = $self->getNextIdentifier($pos);
-                    if ($temp_ident ne "")
-                    {
-                        $ret_op = new XML::Stream::XPath::NodeOp($temp_ident,($pos_start == 0 ? "1" : "0"));
-                    }
-                }
-            }
-            elsif ($token eq "\@")
-            {
-                $ret_op = new XML::Stream::XPath::AttributeOp($self->getNextIdentifier($pos));
-            }
-            elsif ($token eq "]")
-            {
-                if ($in_context eq "[")
-                {
-                    $ret_op = pop(@{$self->{OPS}});
-                    $in_context = 0;
-                }
-                else
-                {
-                    confess("Found ']' but not in context");
-                    return;
-                }
-            }
-            elsif (($token eq "\"") || ($token eq "\'"))
-            {
-                $$pos = index($self->{QUERY},$token,$token_start);
-                $ret_op = new XML::Stream::XPath::Op("LITERAL",substr($self->{QUERY},$token_start,$$pos-$token_start));
-                $$pos++;
-            }
-            elsif ($token eq " ")
-            {
-                $ident = $self->getNextIdentifier($pos);
-                if ($ident eq "and")
-                {
-                    $$pos++;
-                    my $tmp_op = $self->getOp($pos,$in_context);
-                    if (!defined($tmp_op))
-                    {
-                        confess("Invalid 'and' operation");
-                        return;
-                    }
-                    $ret_op = new XML::Stream::XPath::AndOp($self->{OPS}->[$#{$self->{OPS}}],$tmp_op);
-                    $in_context = 0;
-                    pop(@{$self->{OPS}});
-                }
-                elsif ($ident eq "or")
-                {
-                    $$pos++;
-                    my $tmp_op = $self->getOp($pos,$in_context);
-                    if (!defined($tmp_op))
-                    {
-                        confess("Invalid 'or' operation");
-                        return;
-                    }
-                    $ret_op = new XML::Stream::XPath::OrOp($self->{OPS}->[$#{$self->{OPS}}],$tmp_op);
-                    $in_context = 0;
-                    pop(@{$self->{OPS}});
-                }
-            }
-            elsif ($token eq "[")
-            {
-                if ($self->getNextToken($pos) eq "]")
-                {
-                    if ($$pos == $token_start)
-                    {
-                        confess("Nothing in the []");
-                        return;
-                    }
-                    
-                    $$pos = $token_start;
-                    my $val = $self->getNextIdentifier($pos);
-                    if ($val =~ /^\d+$/)
-                    {
-                        $ret_op = new XML::Stream::XPath::PositionOp($val);
-                        $$pos++;
-                    }
-                    else
-                    {
-                        $$pos = $pos_start + 1;
-                        $ret_op = new XML::Stream::XPath::ContextOp($self->getOp($pos,$token));
-                    }
-                }
-                else
-                {
-                    $$pos = $pos_start + 1;
-                    $ret_op = new XML::Stream::XPath::ContextOp($self->getOp($pos,$token));
-                }
-            }
-            elsif ($token eq "(")
-            {
-                #-------------------------------------------------------------
-                # The function name would have been mistaken for a NodeOp.
-                # Pop it off the back and get the function name.
-                #-------------------------------------------------------------
-                my $op = pop(@{$self->{OPS}});
-                if ($op->getType() ne "NODE")
-                {
-                    confess("No function name specified.");
-                }
-                my $function = $op->getValue();
-                if (!exists($XML::Stream::XPath::FUNCTIONS{$function}))
-                {
-                    confess("Undefined function \"$function\"");
-                }
-                $ret_op = new XML::Stream::XPath::FunctionOp($function);
-
-                my $op_pos = $#{$self->{OPS}} + 1;
-
-                $self->getOp($pos,$token);
-                
-                foreach my $arg ($op_pos..$#{$self->{OPS}})
-                {
-                    $ret_op->addArg($self->{OPS}->[$arg]);
-                }
-
-                splice(@{$self->{OPS}},$op_pos);
-                
-            }
-            elsif ($token eq ")")
-            {
-                if ($in_context eq "(")
-                {
-                    $ret_op = undef;
-                    $in_context = 0;
-                }
-                else
-                {
-                    confess("Found ')' but not in context");
-                }
-            }
-            elsif ($token eq ",")
-            {
-                if ($in_context ne "(")
-                {
-                    confess("Found ',' but not in a function");
-                }
-  
-            }
-            elsif ($token eq "=")
-            {
-                my $tmp_op;
-                while(!defined($tmp_op))
-                {
-                    $tmp_op = $self->getOp($pos);
-                }
-                $ret_op = new XML::Stream::XPath::EqualOp($self->{OPS}->[$#{$self->{OPS}}],$tmp_op);
-                pop(@{$self->{OPS}});
-            }
-            elsif ($token eq "!")
-            {
-                if (substr($self->{QUERY},$token_start,1) ne "=")
-                {
-                    confess("Badly formed !=");
-                }
-                $$pos++;
-                
-                my $tmp_op;
-                while(!defined($tmp_op))
-                {
-                    $tmp_op = $self->getOp($pos);
-                }
-                $ret_op = new XML::Stream::XPath::NotEqualOp($self->{OPS}->[$#{$self->{OPS}}],$tmp_op);
-                pop(@{$self->{OPS}});
-            }
-            else
-            {
-                confess("Unhandled \"$token\"");
-            }
-
-            if ($in_context)
-            {
-                if (defined($ret_op))
-                {
-                    push(@{$self->{OPS}},$ret_op);
-                }
-                $ret_op = undef;
-            }
-        }
-        else
-        {
-            confess("Token undefined");
-        }
-        
-        $loop = 0 unless $in_context;
-    }
-
-    return $ret_op;
-}
-
-
-sub parseQuery
-{
-    my $self = shift;
-    my $query = shift;
-
-    my $op;
-    my $pos = 0;
-    while($pos < length($self->{QUERY}))
-    {
-        $op = $self->getOp(\$pos);
-        if (defined($op))
-        {
-            push(@{$self->{OPS}},$op);
-        }
-    }
-
-    #foreach my $op (@{$self->{OPS}})
-    #{
-    #    $op->display();
-    #}
-
-    return 1;
-}
-
-
-sub execute
-{
-    my $self = shift;
-    my $root = shift;
-
-    my $ctxt = new XML::Stream::XPath::Value($root);
-
-    foreach my $op (@{$self->{OPS}})
-    {
-        if (!$op->isValid(\$ctxt))
-        {
-            $ctxt->setValid(0);
-            return $ctxt;
-        }
-    }
-
-    $ctxt->setValid(1);
-    return $ctxt;
-}
-
-
-sub check
-{
-    my $self = shift;
-    my $root = shift;
-
-    my $ctxt = $self->execute($root);
-    return $ctxt->check();
-}
-
-
-1;
-
Index: rl/modules/Jabber/lib/XML/Stream/XPath/Value.pm
===================================================================
--- perl/modules/Jabber/lib/XML/Stream/XPath/Value.pm	(revision c2bed5539d456612d69de33e1dacc3afe5f70395)
+++ 	(revision )
@@ -1,153 +1,0 @@
-##############################################################################
-#
-#  This library is free software; you can redistribute it and/or
-#  modify it under the terms of the GNU Library General Public
-#  License as published by the Free Software Foundation; either
-#  version 2 of the License, or (at your option) any later version.
-#
-#  This library is distributed in the hope that it will be useful,
-#  but WITHOUT ANY WARRANTY; without even the implied warranty of
-#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-#  Library General Public License for more details.
-#
-#  You should have received a copy of the GNU Library General Public
-#  License along with this library; if not, write to the
-#  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-#  Boston, MA  02111-1307, USA.
-#
-#  Jabber
-#  Copyright (C) 1998-2004 Jabber Software Foundation http://jabber.org/
-#
-##############################################################################
-
-package XML::Stream::XPath::Value;
-
-use 5.006_001;
-use strict;
-use vars qw( $VERSION );
-
-$VERSION = "1.22";
-
-sub new
-{
-    my $proto = shift;
-    my $self = { };
-
-    bless($self,$proto);
-
-    $self->setList(@_);
-    $self->setValues();
-    $self->setAttribs();
-    $self->setValid(0);
-    $self->in_context(0);
-
-    return $self;
-}
-
-
-sub setList
-{
-    my $self = shift;
-    my (@values) = @_;
-    $self->{LIST} = \@values;
-}
-
-
-sub getList
-{
-    my $self = shift;
-    return unless ($#{$self->{LIST}} > -1);
-    return @{$self->{LIST}};
-}
-
-
-sub getFirstElem
-{
-    my $self = shift;
-    return unless ($#{$self->{LIST}} > -1);
-    return $self->{LIST}->[0];
-}
-
-
-sub setValues
-{
-    my $self = shift;
-    my (@values) = @_;
-    $self->{VALUES} = \@values;
-}
-
-
-sub getValues
-{
-    my $self = shift;
-    return unless ($#{$self->{VALUES}} > -1);
-    return $self->{VALUES}->[0] if !wantarray;
-    return @{$self->{VALUES}};
-}
-
-
-sub setAttribs
-{
-    my $self = shift;
-    my (%attribs) = @_;
-    $self->{ATTRIBS} = \%attribs;
-}
-
-
-sub getAttribs
-{ 
-    my $self = shift;
-    return unless (scalar(keys(%{$self->{ATTRIBS}})) > 0);
-    return %{$self->{ATTRIBS}};
-}
-
-
-sub setValid
-{
-    my $self = shift;
-    my $valid = shift;
-    $self->{VALID} = $valid;
-}
-
-
-sub check
-{
-    my $self = shift;
-    return $self->{VALID};
-}
-
-
-sub in_context
-{
-    my $self = shift;
-    my $in_context = shift;
-
-    if (defined($in_context))
-    {
-        $self->{INCONTEXT} = $in_context;
-    }
-    return $self->{INCONTEXT};
-}
-
-
-sub display
-{
-    my $self = shift;
-    if (0)
-    {
-        print "VALUE: list(",join(",",@{$self->{LIST}}),")\n";
-    }
-    else
-    {
-        print "VALUE: list(\n";
-        foreach my $elem (@{$self->{LIST}})
-        {
-            print "VALUE:      ",$elem->GetXML(),"\n";
-        }
-        print "VALUE:     )\n";
-    }
-    print "VALUE: values(",join(",",@{$self->{VALUES}}),")\n";
-}
-
-1;
-
Index: rlconfig.c
===================================================================
--- perlconfig.c	(revision 5b37c063d5a6a7a9fdfe3cde5a21e30d94beee7b)
+++ 	(revision )
@@ -1,537 +1,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#define OWL_PERL
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-extern char *owl_perlwrap_codebuff;
-
-extern XS(boot_BarnOwl);
-extern XS(boot_DynaLoader);
-/* extern XS(boot_DBI); */
-
-static void owl_perl_xs_init(pTHX)
-{
-  char *file = __FILE__;
-  dXSUB_SYS;
-  {
-    newXS("BarnOwl::bootstrap", boot_BarnOwl, file);
-    newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
-  }
-}
-
-SV *owl_perlconfig_message2hashref(owl_message *m)
-{
-  HV *h, *stash;
-  SV *hr;
-  char *ptr, *blessas, *type;
-  int i, j;
-  owl_pair *pair;
-  owl_filter *wrap;
-
-  if (!m) return &PL_sv_undef;
-  wrap = owl_global_get_filter(&g, "wordwrap");
-  if(!wrap) {
-      owl_function_error("wrap filter is not defined");
-      return &PL_sv_undef;
-  }
-
-  h = newHV();
-
-#define MSG2H(h,field) (void)hv_store(h, #field, strlen(#field),        \
-                                      newSVpv(owl_message_get_##field(m),0), 0)
-
-  if (owl_message_is_type_zephyr(m)
-      && owl_message_is_direction_in(m)) {
-    /* Handle zephyr-specific fields... */
-    AV *av_zfields;
-
-    av_zfields = newAV();
-    j=owl_zephyr_get_num_fields(owl_message_get_notice(m));
-    for (i=0; i<j; i++) {
-      ptr=owl_zephyr_get_field_as_utf8(owl_message_get_notice(m), i+1);
-      av_push(av_zfields, newSVpvn(ptr, strlen(ptr)));
-      owl_free(ptr);
-    }
-    (void)hv_store(h, "fields", strlen("fields"), newRV_noinc((SV*)av_zfields), 0);
-
-    (void)hv_store(h, "auth", strlen("auth"), 
-                   newSVpv(owl_zephyr_get_authstr(owl_message_get_notice(m)),0),0);
-  }
-
-  j=owl_list_get_size(&(m->attributes));
-  for(i=0; i<j; i++) {
-    pair=owl_list_get_element(&(m->attributes), i);
-    (void)hv_store(h, owl_pair_get_key(pair), strlen(owl_pair_get_key(pair)),
-                   newSVpv(owl_pair_get_value(pair),0),0);
-  }
-  
-  MSG2H(h, type);
-  MSG2H(h, direction);
-  MSG2H(h, class);
-  MSG2H(h, instance);
-  MSG2H(h, sender);
-  MSG2H(h, realm);
-  MSG2H(h, recipient);
-  MSG2H(h, opcode);
-  MSG2H(h, hostname);
-  MSG2H(h, body);
-  MSG2H(h, login);
-  MSG2H(h, zsig);
-  MSG2H(h, zwriteline);
-  if (owl_message_get_header(m)) {
-    MSG2H(h, header); 
-  }
-  (void)hv_store(h, "time", strlen("time"), newSVpv(owl_message_get_timestr(m),0),0);
-  (void)hv_store(h, "id", strlen("id"), newSViv(owl_message_get_id(m)),0);
-  (void)hv_store(h, "deleted", strlen("deleted"), newSViv(owl_message_is_delete(m)),0);
-  (void)hv_store(h, "private", strlen("private"), newSViv(owl_message_is_private(m)),0);
-  (void)hv_store(h, "should_wordwrap",
-                 strlen("should_wordwrap"), newSViv(
-                                                    owl_filter_message_match(wrap, m)),0);
-
-  type = owl_message_get_type(m);
-  if(!type || !*type) type = "generic";
-  type = owl_strdup(type);
-  type[0] = toupper(type[0]);
-  blessas = owl_sprintf("BarnOwl::Message::%s", type);
-
-  hr = newRV_noinc((SV*)h);
-  stash =  gv_stashpv(blessas,0);
-  if(!stash) {
-    owl_function_error("No such class: %s for message type %s", blessas, owl_message_get_type(m));
-    stash = gv_stashpv("BarnOwl::Message", 1);
-  }
-  hr = sv_bless(hr,stash);
-  owl_free(type);
-  owl_free(blessas);
-  return hr;
-}
-
-SV *owl_perlconfig_curmessage2hashref(void) /*noproto*/
-{
-  int curmsg;
-  owl_view *v;
-  v=owl_global_get_current_view(&g);
-  if (owl_view_get_size(v) < 1) {
-    return &PL_sv_undef;
-  }
-  curmsg=owl_global_get_curmsg(&g);
-  return owl_perlconfig_message2hashref(owl_view_get_element(v, curmsg));
-}
-
-/* XXX TODO: Messages should round-trip properly between
-   message2hashref and hashref2message. Currently we lose
-   zephyr-specific properties stored in the ZNotice_t
- */
-owl_message * owl_perlconfig_hashref2message(SV *msg)
-{
-  owl_message * m;
-  HE * ent;
-  I32 count, len;
-  char *key,*val;
-  HV * hash;
-  struct tm tm;
-
-  hash = (HV*)SvRV(msg);
-
-  m = owl_malloc(sizeof(owl_message));
-  owl_message_init(m);
-
-  count = hv_iterinit(hash);
-  while((ent = hv_iternext(hash))) {
-    key = hv_iterkey(ent, &len);
-    val = SvPV_nolen(hv_iterval(hash, ent));
-    if(!strcmp(key, "type")) {
-      owl_message_set_type(m, val);
-    } else if(!strcmp(key, "direction")) {
-      owl_message_set_direction(m, owl_message_parse_direction(val));
-    } else if(!strcmp(key, "private")) {
-      SV * v = hv_iterval(hash, ent);
-      if(SvTRUE(v)) {
-        owl_message_set_isprivate(m);
-      }
-    } else if (!strcmp(key, "hostname")) {
-      owl_message_set_hostname(m, val);
-    } else if (!strcmp(key, "zwriteline")) {
-      owl_message_set_zwriteline(m, val);
-    } else if (!strcmp(key, "time")) {
-      m->timestr = owl_strdup(val);
-      strptime(val, "%a %b %d %T %Y", &tm);
-      m->time = mktime(&tm);
-    } else {
-      owl_message_set_attribute(m, key, val);
-    }
-  }
-  if(owl_message_is_type_admin(m)) {
-    if(!owl_message_get_attribute_value(m, "adminheader"))
-      owl_message_set_attribute(m, "adminheader", "");
-  }
-  return m;
-}
-
-/* Calls in a scalar context, passing it a hash reference.
-   If return value is non-null, caller must free. */
-char *owl_perlconfig_call_with_message(char *subname, owl_message *m)
-{
-  dSP ;
-  int count;
-  SV *msgref, *srv;
-  char *out;
-  
-  ENTER ;
-  SAVETMPS;
-  
-  PUSHMARK(SP) ;
-  msgref = owl_perlconfig_message2hashref(m);
-  XPUSHs(sv_2mortal(msgref));
-  PUTBACK ;
-  
-  count = call_pv(subname, G_SCALAR|G_EVAL|G_KEEPERR);
-  
-  SPAGAIN ;
-
-  if (SvTRUE(ERRSV)) {
-    owl_function_error("Perl Error: '%s'", SvPV_nolen(ERRSV));
-    /* and clear the error */
-    sv_setsv (ERRSV, &PL_sv_undef);
-  }
-
-  if (count != 1) {
-    fprintf(stderr, "bad perl!  no biscuit!  returned wrong count!\n");
-    abort();
-  }
-
-  srv = POPs;
-
-  if (srv) {
-    out = owl_strdup(SvPV_nolen(srv));
-  } else {
-    out = NULL;
-  }
-  
-  PUTBACK ;
-  FREETMPS ;
-  LEAVE ;
-
-  return out;
-}
-
-
-/* Calls a method on a perl object representing a message.
-   If the return value is non-null, the caller must free it.
- */
-char * owl_perlconfig_message_call_method(owl_message *m, char *method, int argc, char ** argv)
-{
-  dSP;
-  unsigned int count, i;
-  SV *msgref, *srv;
-  char *out;
-
-  msgref = owl_perlconfig_message2hashref(m);
-
-  ENTER;
-  SAVETMPS;
-
-  PUSHMARK(SP);
-  XPUSHs(sv_2mortal(msgref));
-  for(i=0;i<argc;i++) {
-    XPUSHs(sv_2mortal(newSVpv(argv[i], 0)));
-  }
-  PUTBACK;
-
-  count = call_method(method, G_SCALAR|G_KEEPERR|G_EVAL);
-
-  SPAGAIN;
-
-  if(count != 1) {
-    fprintf(stderr, "perl returned wrong count %d\n", count);
-    abort();
-  }
-
-  if (SvTRUE(ERRSV)) {
-    owl_function_error("Error: '%s'", SvPV_nolen(ERRSV));
-    /* and clear the error */
-    sv_setsv (ERRSV, &PL_sv_undef);
-  }
-
-  srv = POPs;
-
-  if (srv) {
-    out = owl_strdup(SvPV_nolen(srv));
-  } else {
-    out = NULL;
-  }
-
-  PUTBACK;
-  FREETMPS;
-  LEAVE;
-
-  return out;
-}
-
-
-char *owl_perlconfig_initperl(char * file, int *Pargc, char ***Pargv, char *** Penv)
-{
-  int ret;
-  PerlInterpreter *p;
-  char *err;
-  char *args[4] = {"", "-e", "0;", NULL};
-
-  /* create and initialize interpreter */
-  PERL_SYS_INIT3(Pargc, Pargv, Penv);
-  p=perl_alloc();
-  owl_global_set_perlinterp(&g, (void*)p);
-  perl_construct(p);
-
-  owl_global_set_no_have_config(&g);
-
-
-  ret=perl_parse(p, owl_perl_xs_init, 2, args, NULL);
-  if (ret || SvTRUE(ERRSV)) {
-    err=owl_strdup(SvPV_nolen(ERRSV));
-    sv_setsv(ERRSV, &PL_sv_undef);     /* and clear the error */
-    return(err);
-  }
-
-  ret=perl_run(p);
-  if (ret || SvTRUE(ERRSV)) {
-    err=owl_strdup(SvPV_nolen(ERRSV));
-    sv_setsv(ERRSV, &PL_sv_undef);     /* and clear the error */
-    return(err);
-  }
-
-  owl_global_set_have_config(&g);
-
-  /* create legacy variables */
-  perl_get_sv("BarnOwl::id", TRUE);
-  perl_get_sv("BarnOwl::class", TRUE);
-  perl_get_sv("BarnOwl::instance", TRUE);
-  perl_get_sv("BarnOwl::recipient", TRUE);
-  perl_get_sv("BarnOwl::sender", TRUE);
-  perl_get_sv("BarnOwl::realm", TRUE);
-  perl_get_sv("BarnOwl::opcode", TRUE);
-  perl_get_sv("BarnOwl::zsig", TRUE);
-  perl_get_sv("BarnOwl::msg", TRUE);
-  perl_get_sv("BarnOwl::time", TRUE);
-  perl_get_sv("BarnOwl::host", TRUE);
-  perl_get_av("BarnOwl::fields", TRUE);
-
-  if(file) {
-    SV * cfg = get_sv("BarnOwl::configfile", TRUE);
-    sv_setpv(cfg, file);
-  }
-
-  perl_eval_pv(owl_perlwrap_codebuff, FALSE);
-
-  if (SvTRUE(ERRSV)) {
-    err=owl_strdup(SvPV_nolen(ERRSV));
-    sv_setsv (ERRSV, &PL_sv_undef);     /* and clear the error */
-    return(err);
-  }
-
-  /* check if we have the formatting function */
-  if (owl_perlconfig_is_function("BarnOwl::format_msg")) {
-    owl_global_set_config_format(&g, 1);
-  }
-
-  return(NULL);
-}
-
-/* returns whether or not a function exists */
-int owl_perlconfig_is_function(char *fn) {
-  if (perl_get_cv(fn, FALSE)) return(1);
-  else return(0);
-}
-
-/* returns 0 on success */
-int owl_perlconfig_get_hashkeys(char *hashname, owl_list *l)
-{
-  HV *hv;
-  HE *he;
-  char *key;
-  I32 i;
-
-  if (owl_list_create(l)) return(-1);
-  hv = get_hv(hashname, FALSE);
-  if (!hv) return(-1);
-  i = hv_iterinit(hv);
-  while ((he = hv_iternext(hv))) {
-    key = hv_iterkey(he, &i);
-    if (key) {
-      owl_list_append_element(l, owl_strdup(key));
-    }
-  }
-  return(0);
-}
-
-/* caller is responsible for freeing returned string */
-char *owl_perlconfig_execute(char *line)
-{
-  STRLEN len;
-  SV *response;
-  char *out, *preout;
-
-  if (!owl_global_have_config(&g)) return NULL;
-
-  /* execute the subroutine */
-  response = perl_eval_pv(line, FALSE);
-
-  if (SvTRUE(ERRSV)) {
-    owl_function_error("Perl Error: '%s'", SvPV_nolen(ERRSV));
-    sv_setsv (ERRSV, &PL_sv_undef);     /* and clear the error */
-  }
-
-  preout=SvPV(response, len);
-  if (len == 0 || preout[len - 1] != '\n')
-    out = owl_sprintf("%s\n", preout);
-  else
-    out = owl_strdup(preout);
-
-  return(out);
-}
-
-void owl_perlconfig_getmsg(owl_message *m, char *subname)
-{
-  char *ptr = NULL;
-  if (owl_perlconfig_is_function("BarnOwl::Hooks::_receive_msg")) {
-    ptr = owl_perlconfig_call_with_message(subname?subname
-                                           :"BarnOwl::_receive_msg_legacy_wrap", m);
-  }
-  if (ptr) owl_free(ptr);
-}
-
-/* Called on all new messages; receivemsg is only called on incoming ones */
-void owl_perlconfig_newmsg(owl_message *m, char *subname)
-{
-  char *ptr = NULL;
-  if (owl_perlconfig_is_function("BarnOwl::Hooks::_new_msg")) {
-    ptr = owl_perlconfig_call_with_message(subname?subname
-                                           :"BarnOwl::Hooks::_new_msg", m);
-  }
-  if (ptr) owl_free(ptr);
-}
-
-char *owl_perlconfig_perlcmd(owl_cmd *cmd, int argc, char **argv)
-{
-  int i, count;
-  char * ret = NULL;
-  SV *rv;
-  dSP;
-
-  ENTER;
-  SAVETMPS;
-
-  PUSHMARK(SP);
-  for(i=0;i<argc;i++) {
-    SV *tmp = newSVpv(argv[i], 0);
-    SvUTF8_on(tmp);
-    XPUSHs(sv_2mortal(tmp));
-  }
-  PUTBACK;
-
-  count = call_sv(cmd->cmd_perl, G_SCALAR|G_EVAL);
-
-  SPAGAIN;
-
-  if(SvTRUE(ERRSV)) {
-    owl_function_error("%s", SvPV_nolen(ERRSV));
-    (void)POPs;
-  } else {
-    if(count != 1)
-      croak("Perl command %s returned more than one value!", cmd->name);
-    rv = POPs;
-    if(SvTRUE(rv)) {
-      ret = owl_strdup(SvPV_nolen(rv));
-    }
-  }
-
-  FREETMPS;
-  LEAVE;
-
-  return ret;
-}
-
-void owl_perlconfig_cmd_free(owl_cmd *cmd)
-{
-  SvREFCNT_dec(cmd->cmd_perl);
-}
-
-void owl_perlconfig_dispatch_free(owl_dispatch *d)
-{
-  SvREFCNT_dec(d->pfunc);
-}
-
-void owl_perlconfig_edit_callback(owl_editwin *e)
-{
-  SV *cb = (SV*)(e->cbdata);
-  SV *text;
-  dSP;
-
-  if(cb == NULL) {
-    owl_function_error("Perl callback is NULL!");
-  }
-  text = newSVpv(owl_editwin_get_text(e), 0);
-  SvUTF8_on(text);
-
-  ENTER;
-  SAVETMPS;
-
-  PUSHMARK(SP);
-  XPUSHs(sv_2mortal(text));
-  PUTBACK;
-  
-  call_sv(cb, G_DISCARD|G_KEEPERR|G_EVAL);
-
-  if(SvTRUE(ERRSV)) {
-    owl_function_error("%s", SvPV_nolen(ERRSV));
-  }
-
-  FREETMPS;
-  LEAVE;
-
-  SvREFCNT_dec(cb);
-  e->cbdata = NULL;
-}
-
-void owl_perlconfig_mainloop()
-{
-  dSP;
-  if (!owl_perlconfig_is_function("BarnOwl::Hooks::_mainloop_hook"))
-    return;
-  PUSHMARK(SP) ;
-  call_pv("BarnOwl::Hooks::_mainloop_hook", G_DISCARD|G_EVAL);
-  if(SvTRUE(ERRSV)) {
-    owl_function_error("%s", SvPV_nolen(ERRSV));
-  }
-  return;
-}
-
-void owl_perlconfig_do_dispatch(owl_dispatch *d)
-{
-  SV *cb = d->pfunc;
-  dSP;
-  if(cb == NULL) {
-    owl_function_error("Perl callback is NULL!");
-  }
-
-  ENTER;
-  SAVETMPS;
-
-  PUSHMARK(SP);
-  PUTBACK;
-  
-  call_sv(cb, G_DISCARD|G_KEEPERR|G_EVAL);
-
-  if(SvTRUE(ERRSV)) {
-    owl_function_error("%s", SvPV_nolen(ERRSV));
-  }
-
-  FREETMPS;
-  LEAVE;
-}
Index: rlglue.xs
===================================================================
--- perlglue.xs	(revision 5d2248c62dd7715238ac8948f05c0b8fd2963856)
+++ 	(revision )
@@ -1,400 +1,0 @@
-/* -*- mode: c; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-static const char fileIdent[] = "$Id$";
-
-#ifdef HAVE_LIBZEPHYR
-#include <zephyr/zephyr.h>
-#endif
-#include <EXTERN.h>
-
-#define OWL_PERL
-#include "owl.h"
-SV *owl_perlconfig_curmessage2hashref(void);
-
-#define SV_IS_CODEREF(sv) (SvROK((sv)) && SvTYPE(SvRV((sv))) == SVt_PVCV)
-
-	/*************************************************************
-	 * NOTE
-	 *************************************************************
-	 * These functions, when they are intended to be user-visible,
-	 * are documented in perlwrap.pm. If you add functions to this
-	 * file, add the appropriate documentation there!
-	 *
-	 * If the function is simple enough, we simply define its
-	 * entire functionality here in XS. If, however, it needs
-	 * complex argument processing or something, we define a
-	 * simple version here that takes arguments in as flat a
-	 * manner as possible, to simplify the XS code, put it in
-	 * BarnOwl::Intenal::, and write a perl wrapper in perlwrap.pm
-	 * that munges the arguments as appropriate and calls the
-	 * internal version.
-	 */
-
-MODULE = BarnOwl		PACKAGE = BarnOwl
-
-char *
-command(cmd, ...)
-	char *cmd
-	PREINIT:
-		char *rv = NULL;
-		char **argv;
-		int i;
-	CODE:
-	{
-		if (items == 1) {
-			rv = owl_function_command(cmd);
-		} else {
-			argv = owl_malloc((items + 1) * sizeof *argv);
-			argv[0] = cmd;
-			for(i = 1; i < items; i++) {
-				argv[i] = SvPV_nolen(ST(i));
-			}
-			rv = owl_function_command_argv(argv, items);
-			owl_free(argv);
-		}
-		RETVAL = rv;
-	}
-	OUTPUT:
-		RETVAL
-	CLEANUP:
-		if (rv) owl_free(rv);
-
-SV *
-getcurmsg()
-	CODE:
-		RETVAL = owl_perlconfig_curmessage2hashref();
-	OUTPUT:
-		RETVAL
-
-int
-getnumcols()
-	CODE:
-		RETVAL = owl_global_get_cols(&g);
-	OUTPUT:
-		RETVAL
-		
-time_t
-getidletime()
-	CODE:
-		RETVAL = owl_global_get_idletime(&g);
-	OUTPUT:
-		RETVAL
-
-char *
-zephyr_getrealm()
-	CODE:
-		RETVAL = owl_zephyr_get_realm();
-	OUTPUT:
-		RETVAL
-
-char *
-zephyr_getsender()
-	CODE:
-		RETVAL = owl_zephyr_get_sender();
-	OUTPUT:
-		RETVAL
-
-void
-zephyr_zwrite(cmd,msg)
-	char *cmd
-	char *msg
-	PREINIT:
-		int i;
-	CODE:
-		i = owl_zwrite_create_and_send_from_line(cmd, msg);
-
-char *
-ztext_stylestrip(ztext)
-	char *ztext
-	PREINIT:
-		char *rv = NULL;
-	CODE:
-		rv = owl_function_ztext_stylestrip(ztext);
-		RETVAL = rv;
-	OUTPUT:
-		RETVAL
-	CLEANUP:
-		if (rv) owl_free(rv);
-
-char *
-zephyr_smartstrip_user(in)
-	char *in
-	PREINIT:
-		char *rv = NULL;
-	CODE:
-	{
-		rv = owl_zephyr_smartstripped_user(in);
-		RETVAL = rv;
-	}
-	OUTPUT:
-		RETVAL
-	CLEANUP:
-		owl_free(rv);
-
-char *
-zephyr_getsubs()
-	PREINIT:
-		char *rv = NULL;
-	CODE:
-		rv = owl_zephyr_getsubs();
-		RETVAL = rv;
-    OUTPUT:
-		RETVAL
-    CLEANUP:
-		if (rv) owl_free(rv);
-
-void queue_message(msg) 
-	SV *msg
-	PREINIT:
-		owl_message *m;
-	CODE:
-	{
-		if(!SvROK(msg) || SvTYPE(SvRV(msg)) != SVt_PVHV) {
-			croak("Usage: BarnOwl::queue_message($message)");
-		}
-
-		m = owl_perlconfig_hashref2message(msg);
-
-		owl_global_messagequeue_addmsg(&g, m);
-	}
-
-void admin_message(header, body) 
-	char *header
-	char *body
-	CODE:
-	{
-		owl_function_adminmsg(header, body);		
-	}
-
-void start_question(line, callback)
-	char *line
-	SV *callback
-	PREINIT:
-	CODE:
-	{
-		if(!SV_IS_CODEREF(callback))
-			croak("Callback must be a subref");
-
-		owl_function_start_question(line);
-
-		SvREFCNT_inc(callback);
-		owl_editwin_set_cbdata(owl_global_get_typwin(&g), callback);
-		owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
-	}
-
-void start_password(line, callback)
-	char *line
-	SV *callback
-	PREINIT:
-	CODE:
-	{
-		if(!SV_IS_CODEREF(callback))
-			croak("Callback must be a subref");
-
-		owl_function_start_password(line);
-
-		SvREFCNT_inc(callback);
-		owl_editwin_set_cbdata(owl_global_get_typwin(&g), callback);
-		owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
-	}
-
-void start_edit_win(line, callback)
-	char *line
-	SV *callback
-	PREINIT:
-		owl_editwin * e;
-		char buff[1024];
-	CODE:
-	{
-		if(!SV_IS_CODEREF(callback))
-			croak("Callback must be a subref");
-
-		e = owl_global_get_typwin(&g);
-		owl_editwin_new_style(e, OWL_EDITWIN_STYLE_MULTILINE,
-				      owl_global_get_msg_history(&g));
-		owl_editwin_clear(e);
-		owl_editwin_set_dotsend(e);
-		snprintf(buff, 1023, "----> %s\n", line);
-		owl_editwin_set_locktext(e, buff);
-
-		owl_global_set_typwin_active(&g);
-
-		SvREFCNT_inc(callback);
-		owl_editwin_set_cbdata(owl_global_get_typwin(&g), callback);
-		owl_editwin_set_callback(owl_global_get_typwin(&g), owl_perlconfig_edit_callback);
-	}
-
-
-char * 
-get_data_dir ()
-	CODE:
-		RETVAL = (char *) owl_get_datadir();
-	OUTPUT:
-	RETVAL
-
-char * 
-get_config_dir ()
-	CODE:
-		RETVAL = (char *) owl_global_get_confdir(&g);
-	OUTPUT:
-	RETVAL	
-
-void
-popless_text(text) 
-	char *text
-	CODE:
-	{
-		owl_function_popless_text(text);
-	}
-
-void
-popless_ztext(text) 
-	char *text
-	CODE:
-	{
-		owl_fmtext fm;
-		owl_fmtext_init_null(&fm);
-		owl_fmtext_append_ztext(&fm, text);
-		owl_function_popless_fmtext(&fm);
-		owl_fmtext_free(&fm);
-	}
-
-void
-error(text) 
-	char *text
-	CODE:
-	{
-		owl_function_error("%s", text);
-	}
-
-void
-create_style(name, object)
-     char *name
-     SV  *object
-     PREINIT:
-		owl_style *s;
-     CODE:
-	{
-		s = owl_malloc(sizeof(owl_style));
-		owl_style_create_perl(s, name, object);
-		owl_global_add_style(&g, s);
-	}
-
-int
-getnumcolors()
-	CODE:
-		RETVAL = owl_function_get_color_count();
-	OUTPUT:
-		RETVAL
-
-void
-_remove_filter(filterName)
-	char *filterName
-	CODE:
-	{
-		/* Don't delete the current view, or the 'all' filter */
-		if (strcmp(filterName, owl_view_get_filtname(owl_global_get_current_view(&g)))
-		    && strcmp(filterName, "all")) {
-			owl_global_remove_filter(&g,filterName);
-		}
-	}
-
-char *
-wordwrap(in, cols)
-	char *in
-	int cols
-	PREINIT:
-		char *rv = NULL;
-	CODE:
-		rv = owl_text_wordwrap(in, cols);
-		RETVAL = rv;	
-	OUTPUT:
-		RETVAL
-	CLEANUP:
-		if (rv) owl_free(rv);
-
-void
-add_dispatch(fd, cb)
-	int fd
-	SV * cb
-	CODE:
-        SvREFCNT_inc(cb);
-	owl_select_add_perl_dispatch(fd, cb);
-
-void
-remove_dispatch(fd)
-	int fd
-	CODE:
-	owl_select_remove_perl_dispatch(fd);
-
-MODULE = BarnOwl		PACKAGE = BarnOwl::Internal
-
-
-void
-new_command(name, func, summary, usage, description)
-	char *name
-	SV *func
-	char *summary
-	char *usage
-	char *description
-	PREINIT:
-		owl_cmd cmd;
-	CODE:
-	{
-		if(!SV_IS_CODEREF(func)) {
-			croak("Command function must be a coderef!");
-		}
-		SvREFCNT_inc(func);
-		cmd.name = name;
-		cmd.cmd_perl = func;
-		cmd.summary = summary;
-		cmd.usage = usage;
-		cmd.description = description;
-		cmd.validctx = OWL_CTX_ANY;
-		cmd.cmd_aliased_to = NULL;
-		cmd.cmd_args_fn = NULL;
-		cmd.cmd_v_fn = NULL;
-		cmd.cmd_i_fn = NULL;
-		cmd.cmd_ctxargs_fn = NULL;
-		cmd.cmd_ctxv_fn = NULL;
-		cmd.cmd_ctxi_fn = NULL;
-		owl_cmddict_add_cmd(owl_global_get_cmddict(&g), &cmd);
-	   }
-
-void
-new_variable_string(name, ival, summ, desc)
-	char * name
-	char * ival
-	char * summ
-	char * desc
-	CODE:
-	owl_variable_dict_newvar_string(owl_global_get_vardict(&g),
-					name,
-					summ,
-					desc,
-					ival);
-
-void
-new_variable_int(name, ival, summ, desc)
-	char * name
-	int ival
-	char * summ
-	char * desc
-	CODE:
-	owl_variable_dict_newvar_int(owl_global_get_vardict(&g),
-				     name,
-				     summ,
-				     desc,
-				     ival);
-
-void
-new_variable_bool(name, ival, summ, desc)
-	char * name
-	int ival
-	char * summ
-	char * desc
-	CODE:
-	owl_variable_dict_newvar_bool(owl_global_get_vardict(&g),
-				      name,
-				      summ,
-				      desc,
-				      ival);
Index: rlwrap.pm
===================================================================
--- perlwrap.pm	(revision 5d2248c62dd7715238ac8948f05c0b8fd2963856)
+++ 	(revision )
@@ -1,1240 +1,0 @@
-# $Id$
-#
-# This is all linked into the binary and evaluated when perl starts up...
-#
-#####################################################################
-#####################################################################
-# XXX NOTE: This file is sourced before almost any barnowl
-# architecture is loaded. This means, for example, that it cannot
-# execute any owl commands. Any code that needs to do so should live
-# in BarnOwl::Hooks::_startup
-
-use strict;
-use warnings;
-
-package BarnOwl;
-
-=head1 NAME
-
-BarnOwl
-
-=head1 DESCRIPTION
-
-The BarnOwl module contains the core of BarnOwl's perl
-bindings. Source in this module is also run at startup to bootstrap
-barnowl by defining things like the default style.
-
-=for NOTE
-These following functions are defined in perlglue.xs. Keep the
-documentation here in sync with the user-visible commands defined
-there!
-
-=head2 command STRING
-
-Executes a BarnOwl command in the same manner as if the user had
-executed it at the BarnOwl command prompt. If the command returns a
-value, return it as a string, otherwise return undef.
-
-=head2 getcurmsg
-
-Returns the current message as a C<BarnOwl::Message> subclass, or
-undef if there is no message selected
-
-=head2 getnumcols
-
-Returns the width of the display window BarnOwl is currently using
-
-=head2 getidletime
-
-Returns the length of time since the user has pressed a key, in
-seconds.
-
-=head2 zephyr_getrealm
-
-Returns the zephyr realm barnowl is running in
-
-=head2 zephyr_getsender
-
-Returns the fully-qualified name of the zephyr sender barnowl is
-running as, e.g. C<nelhage@ATHENA.MIT.EDU>
-
-=head2 zephyr_zwrite COMMAND MESSAGE
-
-Sends a zephyr programmatically. C<COMMAND> should be a C<zwrite>
-command line, and C<MESSAGE> is the zephyr body to send.
-
-=head2 ztext_stylestrip STRING
-
-Strips zephyr formatting from a string and returns the result
-
-=head2 zephyr_getsubs
-
-Returns the list of subscription triples <class,instance,recipient>,
-separated by newlines.
-
-=head2 queue_message MESSAGE
-
-Enqueue a message in the BarnOwl message list, logging it and
-processing it appropriately. C<MESSAGE> should be an instance of
-BarnOwl::Message or a subclass.
-
-=head2 admin_message HEADER BODY
-
-Display a BarnOwl B<Admin> message, with the given header and body.
-
-=head2 start_question PROMPT CALLBACK
-
-Displays C<PROMPT> on the screen and lets the user enter a line of
-text, and calls C<CALLBACK>, which must be a perl subroutine
-reference, with the text the user entered
-
-=head2 start_password PROMPT CALLBACK
-
-Like C<start_question>, but echoes the user's input as C<*>s when they
-input.
-
-=head2 start_edit_win PROMPT CALLBACK
-
-Like C<start_question>, but displays C<PROMPT> on a line of its own
-and opens the editwin. If the user cancels the edit win, C<CALLBACK>
-is not invoked.
-
-=head2 get_data_dir
-
-Returns the BarnOwl system data directory, where system libraries and
-modules are stored
-
-=head2 get_config_dir
-
-Returns the BarnOwl user configuration directory, where user modules
-and configuration are stored (by default, C<$HOME/.owl>)
-
-=head2 popless_text TEXT
-
-Show a popup window containing the given C<TEXT>
-
-=head2 popless_ztext TEXT
-
-Show a popup window containing the provided zephyr-formatted C<TEXT>
-
-=head2 error STRING
-
-Reports an error and log it in `show errors'. Note that in any
-callback or hook called in perl code from BarnOwl, a C<die> will be
-caught and passed to C<error>.
-
-=head2 getnumcolors
-
-Returns the number of colors this BarnOwl is capable of displaying
-
-=head2 add_dispatch FD CALLBACK
-
-Adds a file descriptor to C<BarnOwl>'s internal C<select()>
-loop. C<CALLBACK> will be invoked whenever data is available to be
-read from C<FD>.
-
-=head2 remove_dispatch FD
-
-Remove a file descriptor previously registered via C<add_dispatch>
-
-=head2 create_style NAME OBJECT
-
-Creates a new barnowl style with the given NAME defined by the given
-object. The object must have a C<description> method which returns a
-string description of the style, and a and C<format_message> method
-which accepts a C<BarnOwl::Message> object and returns a string that
-is the result of formatting the message for display.
-
-=cut
-
-
-BEGIN {
-# bootstrap in C bindings and glue
-    *owl:: = \*BarnOwl::;
-    bootstrap BarnOwl 1.2;
-};
-
-use lib(get_data_dir() . "/lib");
-use lib(get_config_dir() . "/lib");
-
-# perlconfig.c will set this to the value of the -c command-line
-# switch, if present.
-our $configfile;
-
-if(!$configfile && -f $ENV{HOME} . "/.barnowlconf") {
-    $configfile = $ENV{HOME} . "/.barnowlconf";
-}
-$configfile ||= $ENV{HOME}."/.owlconf";
-
-# populate global variable space for legacy owlconf files
-sub _receive_msg_legacy_wrap {
-    my ($m) = @_;
-    $m->legacy_populate_global();
-    return &BarnOwl::Hooks::_receive_msg($m);
-}
-
-=head2 AUTOLOAD
-
-BarnOwl.pm has a C<AUTOLOAD> method that translates unused names in
-the BarnOwl:: namespace to a call to BarnOwl::command() with that
-command. Underscores are also translated to C<->s, so you can do
-e.g. C<BarnOwl::start_command()> and it will be translated into
-C<start-command>.
-
-So, if you're looking for functionality that you can't find in the
-perl interface, check C<:show commands> or C<commands.c> in the
-BarnOwl source tree -- there's a good chance it exists as a BarnOwl
-command.
-
-=head3 BUGS
-
-There are horrible quoting issues here. The AUTOLOAD simple joins your
-commands with spaces and passes them unmodified to C<::command>
-
-=cut
-
-# make BarnOwl::<command>("foo") be aliases to BarnOwl::command("<command> foo");
-sub AUTOLOAD {
-    our $AUTOLOAD;
-    my $called = $AUTOLOAD;
-    $called =~ s/.*:://;
-    $called =~ s/_/-/g;
-    return &BarnOwl::command("$called ".join(" ",@_));
-}
-
-=head2 new_command NAME FUNC [{ARGS}]
-
-Add a new owl command. When owl executes the command NAME, FUNC will
-be called with the arguments passed to the command, with NAME as the
-first argument.
-
-ARGS should be a hashref containing any or all of C<summary>,
-C<usage>, or C<description> keys:
-
-=over 4
-
-=item summary
-
-A one-line summary of the purpose of the command
-
-=item usage
-
-A one-line usage synopsis, showing available options and syntax
-
-=item description
-
-A longer description of the syntax and semantics of the command,
-explaining usage and options
-
-=back
-
-=cut
-
-sub new_command {
-    my $name = shift;
-    my $func = shift;
-    my $args = shift || {};
-    my %args = (
-        summary     => "",
-        usage       => "",
-        description => "",
-        %{$args}
-    );
-
-    BarnOwl::Internal::new_command($name, $func, $args{summary}, $args{usage}, $args{description});
-}
-
-=head2 new_variable_int NAME [{ARGS}]
-
-=head2 new_variable_bool NAME [{ARGS}]
-
-=head2 new_variable_string NAME [{ARGS}]
-
-Add a new owl variable, either an int, a bool, or a string, with the
-specified name.
-
-ARGS can optionally contain the following keys:
-
-=over 4
-
-=item default
-
-The default and initial value for the variable
-
-=item summary
-
-A one-line summary of the variable's purpose
-
-=item description
-
-A longer description of the function of the variable
-
-=back
-
-=cut
-
-sub new_variable_int {
-    unshift @_, \&BarnOwl::Internal::new_variable_int, 0;
-    goto \&_new_variable;
-}
-
-sub new_variable_bool {
-    unshift @_, \&BarnOwl::Internal::new_variable_bool, 0;
-    goto \&_new_variable;
-}
-
-sub new_variable_string {
-    unshift @_, \&BarnOwl::Internal::new_variable_string, "";
-    goto \&_new_variable;
-}
-
-sub _new_variable {
-    my $func = shift;
-    my $default_default = shift;
-    my $name = shift;
-    my $args = shift || {};
-    my %args = (
-        summary     => "",
-        description => "",
-        default     => $default_default,
-        %{$args});
-    $func->($name, $args{default}, $args{summary}, $args{description});
-}
-
-=head2 quote STRING
-
-Return a version of STRING fully quoted to survive processing by
-BarnOwl's command parser.
-
-=cut
-
-sub quote {
-    my $str = shift;
-    return "''" if $str eq '';
-    if ($str !~ /['" ]/) {
-        return "$str";
-    }
-    if ($str !~ /'/) {
-        return "'$str'";
-    }
-    $str =~ s/"/"'"'"/g;
-    return '"' . $str . '"';
-}
-
-#####################################################################
-#####################################################################
-
-package BarnOwl::Message;
-
-sub new {
-    my $class = shift;
-    my %args = (@_);
-    if($class eq __PACKAGE__ && $args{type}) {
-        $class = "BarnOwl::Message::" . ucfirst $args{type};
-    }
-    return bless {%args}, $class;
-}
-
-sub type        { return shift->{"type"}; }
-sub direction   { return shift->{"direction"}; }
-sub time        { return shift->{"time"}; }
-sub id          { return shift->{"id"}; }
-sub body        { return shift->{"body"}; }
-sub sender      { return shift->{"sender"}; }
-sub recipient   { return shift->{"recipient"}; }
-sub login       { return shift->{"login"}; }
-sub is_private  { return shift->{"private"}; }
-
-sub is_login    { return shift->login eq "login"; }
-sub is_logout   { return shift->login eq "logout"; }
-sub is_loginout { my $m=shift; return ($m->is_login or $m->is_logout); }
-sub is_incoming { return (shift->{"direction"} eq "in"); }
-sub is_outgoing { return (shift->{"direction"} eq "out"); }
-
-sub is_deleted  { return shift->{"deleted"}; }
-
-sub is_admin    { return (shift->{"type"} eq "admin"); }
-sub is_generic  { return (shift->{"type"} eq "generic"); }
-sub is_zephyr   { return (shift->{"type"} eq "zephyr"); }
-sub is_aim      { return (shift->{"type"} eq "AIM"); }
-sub is_jabber   { return (shift->{"type"} eq "jabber"); }
-sub is_icq      { return (shift->{"type"} eq "icq"); }
-sub is_yahoo    { return (shift->{"type"} eq "yahoo"); }
-sub is_msn      { return (shift->{"type"} eq "msn"); }
-sub is_loopback { return (shift->{"type"} eq "loopback"); }
-
-# These are overridden by appropriate message types
-sub is_ping     { return 0; }
-sub is_mail     { return 0; }
-sub is_personal { return shift->is_private; }
-sub class       { return undef; }
-sub instance    { return undef; }
-sub realm       { return undef; }
-sub opcode      { return undef; }
-sub header      { return undef; }
-sub host        { return undef; }
-sub hostname    { return undef; }
-sub auth        { return undef; }
-sub fields      { return undef; }
-sub zsig        { return undef; }
-sub zwriteline  { return undef; }
-sub login_host  { return undef; }
-sub login_tty   { return undef; }
-
-# This is for back-compat with old messages that set these properties
-# New protocol implementations are encourages to user override these
-# methods.
-sub replycmd         { return shift->{replycmd}};
-sub replysendercmd   { return shift->{replysendercmd}};
-
-sub pretty_sender    { return shift->sender; }
-sub pretty_recipient { return shift->recipient; }
-
-sub delete {
-    my ($m) = @_;
-    &BarnOwl::command("delete --id ".$m->id);
-}
-
-sub undelete {
-    my ($m) = @_;
-    &BarnOwl::command("undelete --id ".$m->id);
-}
-
-# Serializes the message into something similar to the zwgc->vt format
-sub serialize {
-    my ($this) = @_;
-    my $s;
-    for my $f (keys %$this) {
-	my $val = $this->{$f};
-	if (ref($val) eq "ARRAY") {
-	    for my $i (0..@$val-1) {
-		my $aval;
-		$aval = $val->[$i];
-		$aval =~ s/\n/\n$f.$i: /g;
-		$s .= "$f.$i: $aval\n";
-	    }
-	} else {
-	    $val =~ s/\n/\n$f: /g;
-	    $s .= "$f: $val\n";
-	}
-    }
-    return $s;
-}
-
-# Populate the annoying legacy global variables
-sub legacy_populate_global {
-    my ($m) = @_;
-    $BarnOwl::direction  = $m->direction ;
-    $BarnOwl::type       = $m->type      ;
-    $BarnOwl::id         = $m->id        ;
-    $BarnOwl::class      = $m->class     ;
-    $BarnOwl::instance   = $m->instance  ;
-    $BarnOwl::recipient  = $m->recipient ;
-    $BarnOwl::sender     = $m->sender    ;
-    $BarnOwl::realm      = $m->realm     ;
-    $BarnOwl::opcode     = $m->opcode    ;
-    $BarnOwl::zsig       = $m->zsig      ;
-    $BarnOwl::msg        = $m->body      ;
-    $BarnOwl::time       = $m->time      ;
-    $BarnOwl::host       = $m->host      ;
-    $BarnOwl::login      = $m->login     ;
-    $BarnOwl::auth       = $m->auth      ;
-    if ($m->fields) {
-	@BarnOwl::fields = @{$m->fields};
-	@main::fields = @{$m->fields};
-    } else {
-	@BarnOwl::fields = undef;
-	@main::fields = undef;
-    }
-}
-
-sub smartfilter {
-    die("smartfilter not supported for this message\n");
-}
-
-# Display fields -- overridden by subclasses when needed
-sub login_type {""}
-sub login_extra {""}
-sub long_sender {""}
-
-# The context in which a non-personal message was sent, e.g. a chat or
-# class
-sub context {""}
-
-# Some indicator of context *within* $self->context. e.g. the zephyr
-# instance
-sub subcontext {""}
-
-#####################################################################
-#####################################################################
-
-package BarnOwl::Message::Admin;
-
-use base qw( BarnOwl::Message );
-
-sub header       { return shift->{"header"}; }
-
-#####################################################################
-#####################################################################
-
-package BarnOwl::Message::Generic;
-
-use base qw( BarnOwl::Message );
-
-#####################################################################
-#####################################################################
-
-package BarnOwl::Message::Loopback;
-
-use base qw( BarnOwl::Message );
-
-# all loopback messages are private
-sub is_private {
-  return 1;
-}
-
-sub replycmd {return 'loopwrite';}
-sub replysendercmd {return 'loopwrite';}
-
-#####################################################################
-#####################################################################
-
-package BarnOwl::Message::AIM;
-
-use base qw( BarnOwl::Message );
-
-# all non-loginout AIM messages are private for now...
-sub is_private {
-    return !(shift->is_loginout);
-}
-
-sub replycmd {
-    my $self = shift;
-    if ($self->is_incoming) {
-        return "aimwrite " . BarnOwl::quote($self->sender);
-    } else {
-        return "aimwrite " . BarnOwl::quote($self->recipient);
-    }
-}
-
-sub replysendercmd {
-    return shift->replycmd;
-}
-
-#####################################################################
-#####################################################################
-
-package BarnOwl::Message::Zephyr;
-
-use constant WEBZEPHYR_PRINCIPAL => "daemon.webzephyr";
-use constant WEBZEPHYR_CLASS     => "webzephyr";
-use constant WEBZEPHYR_OPCODE    => "webzephyr";
-
-use base qw( BarnOwl::Message );
-
-sub strip_realm {
-    my $sender = shift;
-    my $realm = BarnOwl::zephyr_getrealm();
-    $sender =~ s/\@$realm$//;
-    return $sender;
-}
-
-sub login_type {
-    return (shift->zsig eq "") ? "(PSEUDO)" : "";
-}
-
-sub login_extra {
-    my $m = shift;
-    return undef if (!$m->is_loginout);
-    my $s = lc($m->host);
-    $s .= " " . $m->login_tty if defined $m->login_tty;
-    return $s;
-}
-
-sub long_sender {
-    my $m = shift;
-    return $m->zsig;
-}
-
-sub context {
-    return shift->class;
-}
-
-sub subcontext {
-    return shift->instance;
-}
-
-sub login_tty {
-    my ($m) = @_;
-    return undef if (!$m->is_loginout);
-    return $m->fields->[2];
-}
-
-sub login_host {
-    my ($m) = @_;
-    return undef if (!$m->is_loginout);
-    return $m->fields->[0];
-}
-
-sub zwriteline  { return shift->{"zwriteline"}; }
-
-sub is_ping     { return (lc(shift->opcode) eq "ping"); }
-
-sub is_personal {
-    my ($m) = @_;
-    return ((lc($m->class) eq "message")
-	    && (lc($m->instance) eq "personal")
-	    && $m->is_private);
-}
-
-sub is_mail {
-    my ($m) = @_;
-    return ((lc($m->class) eq "mail") && $m->is_private);
-}
-
-sub pretty_sender {
-    my ($m) = @_;
-    return strip_realm($m->sender);
-}
-
-sub pretty_recipient {
-    my ($m) = @_;
-    return strip_realm($m->recipient);
-}
-
-# These are arguably zephyr-specific
-sub class       { return shift->{"class"}; }
-sub instance    { return shift->{"instance"}; }
-sub realm       { return shift->{"realm"}; }
-sub opcode      { return shift->{"opcode"}; }
-sub host        { return shift->{"hostname"}; }
-sub hostname    { return shift->{"hostname"}; }
-sub header      { return shift->{"header"}; }
-sub auth        { return shift->{"auth"}; }
-sub fields      { return shift->{"fields"}; }
-sub zsig        { return shift->{"zsig"}; }
-
-sub zephyr_cc {
-    my $self = shift;
-    return $1 if $self->body =~ /^\s*cc:\s+([^\n]+)/i;
-    return undef;
-}
-
-sub replycmd {
-    my $self = shift;
-    my $sender = shift;
-    $sender = 0 unless defined $sender;
-    my ($class, $instance, $to, $cc);
-    if($self->is_outgoing) {
-        return $self->{zwriteline};
-    }
-
-    if($sender && $self->opcode eq WEBZEPHYR_OPCODE) {
-        $class = WEBZEPHYR_CLASS;
-        $instance = $self->sender;
-        $to = WEBZEPHYR_PRINCIPAL;
-    } elsif($self->class eq WEBZEPHYR_CLASS
-            && $self->is_loginout) {
-        $class = WEBZEPHYR_CLASS;
-        $instance = $self->instance;
-        $to = WEBZEPHYR_PRINCIPAL;
-    } elsif($self->is_loginout || $sender) {
-        $class = 'MESSAGE';
-        $instance = 'PERSONAL';
-        $to = $self->sender;
-    } else {
-        $class = $self->class;
-        $instance = $self->instance;
-        $to = $self->recipient;
-        $cc = $self->zephyr_cc();
-        if($to eq '*' || $to eq '') {
-            $to = '';
-        } elsif($to !~ /^@/) {
-            $to = $self->sender;
-        }
-    }
-
-    my $cmd;
-    if(lc $self->opcode eq 'crypt') {
-        $cmd = 'zcrypt';
-    } else {
-        $cmd = 'zwrite';
-    }
-
-    if (lc $class ne 'message') {
-        $cmd .= " -c " . BarnOwl::quote($self->class);
-    }
-    if (lc $instance ne 'personal') {
-        $cmd .= " -i " . BarnOwl::quote($self->instance);
-    }
-    if ($to ne '') {
-        $to = strip_realm($to);
-        if (defined $cc) {
-            my @cc = grep /^[^-]/, ($to, split /\s+/, $cc);
-            my %cc = map {$_ => 1} @cc;
-            delete $cc{strip_realm(BarnOwl::zephyr_getsender())};
-            @cc = keys %cc;
-            $cmd .= " -C " . join(" ", @cc);
-        } else {
-            if(BarnOwl::getvar('smartstrip') eq 'on') {
-                $to = BarnOwl::zephyr_smartstrip_user($to);
-            }
-            $cmd .= " $to";
-        }
-    }
-    return $cmd;
-}
-
-sub replysendercmd {
-    my $self = shift;
-    return $self->replycmd(1);
-}
-
-#####################################################################
-#####################################################################
-#####################################################################
-
-package BarnOwl::Hook;
-
-=head1 BarnOwl::Hook
-
-=head1 DESCRIPTION
-
-A C<BarnOwl::Hook> represents a list of functions to be triggered on
-some event. C<BarnOwl> exports a default set of these (see
-C<BarnOwl::Hooks>), but can also be created and used by module code.
-
-=head2 new
-
-Creates a new Hook object
-
-=cut
-
-sub new {
-    my $class = shift;
-    return bless [], $class;
-}
-
-=head2 run [ARGS]
-
-Calls each of the functions registered with this hook with the given
-arguments.
-
-=cut
-
-sub run {
-    my $self = shift;
-    my @args = @_;
-    return map {$self->_run($_,@args)} @$self;
-}
-
-sub _run {
-    my $self = shift;
-    my $fn = shift;
-    my @args = @_;
-    no strict 'refs';
-    return $fn->(@args);
-}
-
-=head2 add SUBREF
-
-Registers a given subroutine with this hook
-
-=cut
-
-sub add {
-    my $self = shift;
-    my $func = shift;
-    die("Not a coderef!") unless ref($func) eq 'CODE' || !ref($func);
-    return if grep {$_ eq $func} @$self;
-    push @$self, $func;
-}
-
-=head2 clear
-
-Remove all functions registered with this hook.
-
-=cut
-
-sub clear {
-    my $self = shift;
-    @$self = ();
-}
-
-package BarnOwl::Hooks;
-
-=head1 BarnOwl::Hooks
-
-=head1 DESCRIPTION
-
-C<BarnOwl::Hooks> exports a set of C<BarnOwl::Hook> objects made
-available by BarnOwl internally. 
-
-=head2 USAGE
-
-Modules wishing to respond to events in BarnOwl should register
-functions with these hooks.
-
-=head2 EXPORTS
-
-None by default. Either import the hooks you need explicitly, or refer
-to them with fully-qualified names. Available hooks are:
-
-=over 4
-
-=item $startup
-
-Called on BarnOwl startup, and whenever modules are
-reloaded. Functions registered with the C<$startup> hook get a true
-argument if this is a reload, and false if this is a true startup
-
-=item $shutdown
-
-Called before BarnOwl shutdown
-
-=item $receiveMessage
-
-Called with a C<BarnOwl::Message> object every time BarnOwl appends a
-new message to its message list
-
-=item $mainLoop
-
-Called on every pass through the C<BarnOwl> main loop. This is
-guaranteed to be called at least once/sec and may be called more
-frequently.
-
-=item $getBuddyList
-
-Called to display buddy lists for all protocol handlers. The result
-from every function registered with this hook will be appended and
-displayed in a popup window, with zephyr formatting parsed.
-
-=item $getQuickstart
-
-Called by :show quickstart to display 2-5 lines of help on how to
-start using the protocol. The result from every function registered
-with this hook will be appended and displayed in an admin message,
-with zephyr formatting parsed. The format should be
-"@b(Protocol:)\nSome text.\nMore text.\n"
-
-=back
-
-=cut
-
-use Exporter;
-
-our @EXPORT_OK = qw($startup $shutdown
-                    $receiveMessage $newMessage
-                    $mainLoop $getBuddyList
-                    $getQuickstart);
-
-our %EXPORT_TAGS = (all => [@EXPORT_OK]);
-
-our $startup = BarnOwl::Hook->new;
-our $shutdown = BarnOwl::Hook->new;
-our $receiveMessage = BarnOwl::Hook->new;
-our $newMessage = BarnOwl::Hook->new;
-our $mainLoop = BarnOwl::Hook->new;
-our $getBuddyList = BarnOwl::Hook->new;
-our $getQuickstart = BarnOwl::Hook->new;
-
-# Internal startup/shutdown routines called by the C code
-
-sub _load_perl_commands {
-    # Load builtin perl commands
-    BarnOwl::new_command(style => \&BarnOwl::Style::style_command,
-                       {
-                           summary => "creates a new style",
-                           usage   => "style <name> perl <function_name>",
-                           description =>
-                           "A style named <name> will be created that will\n" .
-                           "format messages using the perl function <function_name>.\n\n" .
-                           "SEE ALSO: show styles, view -s, filter -s\n\n" .
-                           "DEPRECATED in favor of BarnOwl::create_style(NAME, OBJECT)",
-                          });
-}
-
-sub _load_owlconf {
-    # load the config  file
-    if ( -r $BarnOwl::configfile ) {
-        undef $@;
-        package main;
-        do $BarnOwl::configfile;
-        if($@) {
-            BarnOwl::error("In startup: $@\n");
-            return;
-        }
-        package BarnOwl;
-        if(*BarnOwl::format_msg{CODE}) {
-            # if the config defines a legacy formatting function, add 'perl' as a style 
-            BarnOwl::create_style("perl", BarnOwl::Style::Legacy->new(
-                "BarnOwl::format_msg",
-                "User-defined perl style that calls BarnOwl::format_msg"
-                . " with legacy global variable support",
-                1));
-             BarnOwl::set("-q default_style perl");
-        }
-    }
-}
-
-# These are the internal hooks called by the barnowl C code, which
-# take care of dispatching to the appropriate perl hooks, and deal
-# with compatibility by calling the old, fixed-name hooks.
-
-sub _startup {
-    _load_perl_commands();
-    _load_owlconf();
-
-    if(eval {require BarnOwl::ModuleLoader}) {
-        eval {
-            BarnOwl::ModuleLoader->load_all;
-        };
-        BarnOwl::error("$@") if $@;
-
-    } else {
-        BarnOwl::error("Can't load BarnOwl::ModuleLoader, loadable module support disabled:\n$@");
-    }
-    
-    $startup->run(0);
-    BarnOwl::startup() if *BarnOwl::startup{CODE};
-}
-
-sub _shutdown {
-    $shutdown->run;
-    
-    BarnOwl::shutdown() if *BarnOwl::shutdown{CODE};
-}
-
-sub _receive_msg {
-    my $m = shift;
-
-    $receiveMessage->run($m);
-    
-    BarnOwl::receive_msg($m) if *BarnOwl::receive_msg{CODE};
-}
-
-sub _new_msg {
-    my $m = shift;
-
-    $newMessage->run($m);
-    
-    BarnOwl::new_msg($m) if *BarnOwl::new_msg{CODE};
-}
-
-sub _mainloop_hook {
-    $mainLoop->run;
-    BarnOwl::mainloop_hook() if *BarnOwl::mainloop_hook{CODE};
-}
-
-sub _get_blist {
-    return join("\n", $getBuddyList->run);
-}
-
-sub _get_quickstart {
-    return join("\n", $getQuickstart->run);
-}
-
-################################################################################
-# Built-in perl styles
-################################################################################
-package BarnOwl::Style::Default;
-################################################################################
-# Branching point for various formatting functions in this style.
-################################################################################
-sub format_message
-{
-    my $self = shift;
-    my $m    = shift;
-    my $fmt;
-
-    if ( $m->is_loginout) {
-        $fmt = $self->format_login($m);
-    } elsif($m->is_ping && $m->is_personal) {
-        $fmt = $self->format_ping($m);
-    } elsif($m->is_admin) {
-        $fmt = $self->format_admin($m);
-    } else {
-        $fmt = $self->format_chat($m);
-    }
-    $fmt = BarnOwl::Style::boldify($fmt) if $self->should_bold($m);
-    return $fmt;
-}
-
-sub should_bold {
-    my $self = shift;
-    my $m = shift;
-    return $m->is_personal && $m->direction eq "in";
-}
-
-sub description {"Default style";}
-
-BarnOwl::create_style("default", "BarnOwl::Style::Default");
-
-################################################################################
-
-sub format_time {
-    my $self = shift;
-    my $m = shift;
-    my ($time) = $m->time =~ /(\d\d:\d\d)/;
-    return $time;
-}
-
-sub format_login {
-    my $self = shift;
-    my $m = shift;
-    return sprintf(
-        '@b<%s%s> for @b(%s) (%s) %s',
-        uc( $m->login ),
-        $m->login_type,
-        $m->pretty_sender,
-        $m->login_extra,
-        $self->format_time($m)
-       );
-}
-
-sub format_ping {
-    my $self = shift;
-    my $m = shift;
-    return "\@b(PING) from \@b(" . $m->pretty_sender . ")";
-}
-
-sub format_admin {
-    my $self = shift;
-    my $m = shift;
-    return "\@bold(OWL ADMIN)\n" . $self->indent_body($m);
-}
-
-sub format_chat {
-    my $self = shift;
-    my $m = shift;
-    my $header = $self->chat_header($m);
-    return $header . "\n". $self->indent_body($m);
-}
-
-sub chat_header {
-    my $self = shift;
-    my $m = shift;
-    my $header;
-    if ( $m->is_personal ) {
-        if ( $m->direction eq "out" ) {
-            $header = ucfirst $m->type . " sent to " . $m->pretty_recipient;
-        } else {
-            $header = ucfirst $m->type . " from " . $m->pretty_sender;
-        }
-    } else {
-        $header = $m->context;
-        if(defined $m->subcontext) {
-            $header .= ' / ' . $m->subcontext;
-        }
-        $header .= ' / @b{' . $m->pretty_sender . '}';
-    }
-
-    if($m->opcode) {
-        $header .= " [" . $m->opcode . "]";
-    }
-    $header .= "  " . $self->format_time($m);
-    $header .= $self->format_sender($m);
-    return $header;
-}
-
-sub format_sender {
-    my $self = shift;
-    my $m = shift;
-    my $sender = $m->long_sender;
-    $sender =~ s/\n.*$//s;
-    return "  (" . $sender . '@color[default]' . ")";
-}
-
-sub indent_body
-{
-    my $self = shift;
-    my $m = shift;
-
-    my $body = $m->body;
-    if ($m->{should_wordwrap}) {
-      $body = BarnOwl::wordwrap($body, BarnOwl::getnumcols()-8);
-    }
-    # replace newline followed by anything with
-    # newline plus four spaces and that thing.
-    $body =~ s/\n(.)/\n    $1/g;
-    # Trim trailing newlines.
-    $body =~ s/\n*$//;
-    return "    ".$body;
-}
-
-package BarnOwl::Style::Basic;
-our @ISA=qw(BarnOwl::Style::Default);
-
-sub description {"Compatability alias for the default style";}
-
-BarnOwl::create_style("basic", "BarnOwl::Style::Basic");
-
-package BarnOwl::Style::OneLine;
-# Inherit format_message to dispatch
-our @ISA = qw(BarnOwl::Style::Default);
-
-use constant BASE_FORMAT => '%s %-13.13s %-11.11s %-12.12s ';
-
-sub description {"Formats for one-line-per-message"}
-
-BarnOwl::create_style("oneline", "BarnOwl::Style::OneLine");
-
-################################################################################
-
-sub format_login {
-  my $self = shift;
-  my $m = shift;
-  return sprintf(
-    BASE_FORMAT,
-    '<',
-    $m->type,
-    uc( $m->login ),
-    $m->pretty_sender)
-    . ($m->login_extra ? "at ".$m->login_extra : '');
-}
-
-sub format_ping {
-  my $self = shift;
-  my $m = shift;
-  return sprintf(
-    BASE_FORMAT,
-    '<',
-    $m->type,
-    'PING',
-    $m->pretty_sender)
-}
-
-sub format_chat
-{
-  my $self = shift;
-  my $m = shift;
-  my $dir = lc($m->{direction});
-  my $dirsym = '-';
-  if ($dir eq 'in') {
-    $dirsym = '<';
-  }
-  elsif ($dir eq 'out') {
-    $dirsym = '>';
-  }
-
-  my $line;
-  if ($m->is_personal) {
-    $line= sprintf(BASE_FORMAT,
-                   $dirsym,
-                   $m->type,
-                   '',
-                   ($dir eq 'out'
-                    ? $m->pretty_recipient
-                    : $m->pretty_sender));
-  }
-  else {
-    $line = sprintf(BASE_FORMAT,
-                    $dirsym,
-                    $m->context,
-                    $m->subcontext,
-                    ($dir eq 'out'
-                     ? $m->pretty_recipient
-                     : $m->pretty_sender));
-  }
-
-  my $body = $m->{body};
-  $body =~ tr/\n/ /;
-  $line .= $body;
-  return $line;
-}
-
-# Format owl admin messages
-sub format_admin
-{
-  my $self = shift;
-  my $m = shift;
-  my $line = sprintf(BASE_FORMAT, '<', 'ADMIN', '', '');
-  my $body = $m->{body};
-  $body =~ tr/\n/ /;
-  return $line.$body;
-}
-
-package BarnOwl::Style;
-
-# This takes a zephyr to be displayed and modifies it to be displayed
-# entirely in bold.
-sub boldify
-{
-    local $_ = shift;
-    if ( !(/\)/) ) {
-        return '@b(' . $_ . ')';
-    } elsif ( !(/\>/) ) {
-        return '@b<' . $_ . '>';
-    } elsif ( !(/\}/) ) {
-        return '@b{' . $_ . '}';
-    } elsif ( !(/\]/) ) {
-        return '@b[' . $_ . ']';
-    } else {
-        my $txt = "\@b($_";
-        $txt =~ s/\)/\)\@b\[\)\]\@b\(/g;
-        return $txt . ')';
-    }
-}
-
-sub style_command {
-    my $command = shift;
-    if(scalar @_ != 3 || $_[1] ne 'perl') {
-        die("Usage: style <name> perl <function>\n");
-    }
-    my $name = shift;
-    my $perl = shift;
-    my $fn   = shift;
-    {
-        # For historical reasons, assume unqualified references are
-        # in main::
-        package main;
-        no strict 'refs';
-        unless(*{$fn}{CODE}) {
-            die("Unable to create style '$name': no perl function '$fn'\n");
-        }
-    }
-    BarnOwl::create_style($name, BarnOwl::Style::Legacy->new($fn));
-}
-
-package BarnOwl::Style::Legacy;
-
-sub new {
-    my $class = shift;
-    my $func  = shift;
-    my $desc  = shift;
-    my $useglobals = shift;
-    $useglobals = 0 unless defined($useglobals);
-    return bless {function    => $func,
-                  description => $desc,
-                  useglobals  => $useglobals}, $class;
-}
-
-sub description {
-    my $self = shift;
-    return $self->{description} ||
-    ("User-defined perl style that calls " . $self->{function});
-};
-
-sub format_message {
-    my $self = shift;
-    if($self->{useglobals}) {
-        $_[0]->legacy_populate_global();
-    }
-    {
-      package main;
-      no strict 'refs';
-      goto \&{$self->{function}};
-    }
-}
-
-
-# switch to package main when we're done
-package main;
-
-# Shove a bunch of fake entries into @INC so modules can use or
-# require them without choking
-$::INC{$_} = 1 for (qw(BarnOwl.pm BarnOwl/Hooks.pm
-                       BarnOwl/Message.pm BarnOwl/Style.pm));
-
-1;
-
Index: pexec.c
===================================================================
--- popexec.c	(revision 44fc93be20484f09d5265df4bb55456979efd531)
+++ 	(revision )
@@ -1,193 +1,0 @@
-#include "owl.h"
-#ifdef HAVE_SYS_IOCTL_H
-#include <sys/ioctl.h>
-#endif
-#ifdef HAVE_SYS_FILIO_H
-#include <sys/filio.h>
-#endif
-#include <sys/wait.h>
-
-static const char fileIdent[] = "$Id$";
-
-/* starts up popexec in a new viewwin */
-owl_popexec *owl_popexec_new(char *command)
-{
-  owl_popexec *pe;
-  owl_popwin *pw;
-  owl_viewwin *v;
-  int pipefds[2], child_write_fd, parent_read_fd;
-  int pid;
-
-  pe = owl_malloc(sizeof(owl_popexec));
-  if (!pe) return NULL;
-  pe->winactive=0;
-  pe->pid=0;
-  pe->refcount=0;
-
-  pw=owl_global_get_popwin(&g);
-  pe->vwin=v=owl_global_get_viewwin(&g);
-
-  owl_popwin_up(pw);
-  owl_viewwin_init_text(v, owl_popwin_get_curswin(pw),
-			owl_popwin_get_lines(pw), owl_popwin_get_cols(pw),
-			"");
-  owl_popwin_refresh(pw);
-  owl_viewwin_redisplay(v, 0);
-  owl_global_set_needrefresh(&g);
-  owl_viewwin_set_onclose_hook(v, owl_popexec_viewwin_onclose, pe);
-  pe->refcount++;
-
-  if (0 != pipe(pipefds)) {
-    owl_function_error("owl_function_popless_exec: pipe failed\n");
-    return NULL;
-  }
-  parent_read_fd = pipefds[0];
-  child_write_fd = pipefds[1];
-  pid = fork();
-  if (pid == -1) {
-    close(pipefds[0]);
-    close(pipefds[1]);
-    owl_function_error("owl_function_popless_exec: fork failed\n");
-    return NULL;
-  } else if (pid != 0) {
-    /* still in owl */
-    int muxhandle;
-    pe->pid=pid;
-    pe->winactive=1;
-    pe->rfd = parent_read_fd;
-    close(child_write_fd);
-    muxhandle = owl_muxevents_add(owl_global_get_muxevents(&g),
-    				  parent_read_fd, OWL_MUX_READ|OWL_MUX_EXCEPT,
-    				  owl_popexec_inputhandler, (void*)pe);
-    pe->refcount++;
-  } else {
-    /* in the child process */
-    char *argv[4];
-    int i;
-    int fdlimit = sysconf(_SC_OPEN_MAX);
-
-    for (i=0; i<fdlimit; i++) {
-      if (i!=child_write_fd) close(i);
-    }
-    dup2(child_write_fd, 1 /*stdout*/);
-    dup2(child_write_fd, 2 /*stderr*/);
-    close(child_write_fd);
-
-    argv[0] = "sh";
-    argv[1] = "-c";
-    argv[2] = command;
-    argv[3] = 0;
-    execv("/bin/sh", argv);
-    _exit(127);
-  }
-
-  return pe;
-}
-
-void owl_popexec_inputhandler(int handle, int fd, int eventmask, void *data)
-{
-  owl_popexec *pe = (owl_popexec*)data;
-  int navail, bread, rv_navail;
-  char *buf;
-  int status;
-
-  if (!pe) return;
-
-  /* If pe->winactive is 0 then the vwin has closed. 
-   * If pe->pid is 0 then the child has already been reaped.
-   * if pe->rfd is -1 then the fd has been closed out.
-   * Under these cases we want to get to a state where:
-   *   - data read until end if child running
-   *   - child reaped
-   *   - fd closed
-   *   - callback removed
-   */
-
-  /* the viewwin has closed */
-  if (pe->rfd<0 && !pe->pid && !pe->winactive) {
-    owl_muxevents_remove(owl_global_get_muxevents(&g), handle);
-    owl_function_debugmsg("unref of %p from input handler at A", pe);
-    owl_popexec_unref(pe);
-    return;
-  }
-
-  if (0 != (rv_navail = ioctl(fd, FIONREAD, (void*)&navail))) {
-    owl_function_debugmsg("ioctl error");
-  }
-
-  /* check to see if the child has ended gracefully and no more data is
-   * ready to be read... */
-  if (navail==0 && pe->pid>0 && waitpid(pe->pid, &status, WNOHANG) > 0) {
-    owl_function_debugmsg("waitpid got child status: <%d>\n", status);
-    pe->pid = 0;
-    if (pe->winactive) { 
-      owl_viewwin_append_text(pe->vwin, "\n");
-      owl_viewwin_redisplay(pe->vwin, 1);
-    }
-    if (pe->rfd>0) {
-      close(pe->rfd);
-      pe->rfd = -1;
-    }
-    owl_muxevents_remove(owl_global_get_muxevents(&g), handle);
-    owl_function_debugmsg("unref of %p from input handler at B", pe);
-    owl_popexec_unref(pe);
-    return;
-  }
-
-  if (pe->rfd<0 || !pe->pid || !pe->winactive || rv_navail) {
-    owl_function_error("popexec should not have reached this point");
-    return;
-  }
-
-  if (navail<=0) return;
-  if (navail>1024) { navail = 1024; }
-  buf = owl_malloc(navail+1);
-  owl_function_debugmsg("about to read %d\n", navail);
-  bread = read(fd, buf, navail);
-  if (bread<0) {
-    perror("read");
-    owl_function_debugmsg("read error");
-  }
-  if (buf[navail-1] != '\0') {
-    buf[navail] = '\0';
-  }
-  owl_function_debugmsg("got data:  <%s>\n", buf);
-  if (pe->winactive) {
-    owl_viewwin_append_text(pe->vwin, buf);
-    owl_viewwin_redisplay(pe->vwin, 1);
-  }
-  owl_free(buf);
-  
-}
-
-void owl_popexec_viewwin_onclose(owl_viewwin *vwin, void *data)
-{
-  owl_popexec *pe = (owl_popexec*)data;
-  int status, rv;
-
-  pe->winactive = 0;
-  if (pe->rfd>0) {
-    close(pe->rfd);
-    pe->rfd = -1;
-  }
-  if (pe->pid) {
-    /* TODO: we should handle the case where SIGTERM isn't good enough */
-    rv = kill(pe->pid, SIGTERM);
-    owl_function_debugmsg("kill of pid %d returned %d", pe->pid, rv);
-    rv = waitpid(pe->pid, &status, 0);
-    owl_function_debugmsg("waidpid returned %d, status %d", rv, status);
-    pe->pid = 0;
-  }
-  owl_function_debugmsg("unref of %p from onclose", pe);
-  owl_popexec_unref(pe);
-}
-
-void owl_popexec_unref(owl_popexec *pe)
-{
-  owl_function_debugmsg("unref of %p was %d", pe, pe->refcount);
-  pe->refcount--;
-  if (pe->refcount<=0) {
-    owl_function_debugmsg("doing free of %p", pe);
-    owl_free(pe);
-  }
-}
Index: pwin.c
===================================================================
--- popwin.c	(revision 818a07348f30d7fbee5ff8c98ceca4886c9a710f)
+++ 	(revision )
@@ -1,132 +1,0 @@
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-int owl_popwin_init(owl_popwin *pw)
-{
-  pw->active=0;
-  pw->needsfirstrefresh=0;
-  pw->lines=0;
-  pw->cols=0;
-  return(0);
-}
-
-int owl_popwin_up(owl_popwin *pw)
-{
-  int glines, gcols, startcol, startline;
-
-  /* calculate the size of the popwin */
-  glines=owl_global_get_lines(&g);
-  gcols=owl_global_get_cols(&g);
-
-  pw->lines = owl_util_min(glines,24)*3/4 + owl_util_max(glines-24,0)/2;
-  startline = (glines-pw->lines)/2;
-
-  pw->cols = owl_util_min(gcols,90)*15/16 + owl_util_max(gcols-90,0)/2;
-  startcol = (gcols-pw->cols)/2;
-
-  pw->borderwin=newwin(pw->lines, pw->cols, startline, startcol);
-  pw->popwin=newwin(pw->lines-2, pw->cols-2, startline+1, startcol+1);
-  pw->needsfirstrefresh=1;
-  
-  meta(pw->popwin,TRUE);
-  nodelay(pw->popwin, 1);
-  keypad(pw->popwin, TRUE);
-
-  werase(pw->popwin);
-  werase(pw->borderwin);
-  if (owl_global_is_fancylines(&g)) {
-    box(pw->borderwin, 0, 0);
-  } else {
-    box(pw->borderwin, '|', '-');
-    wmove(pw->borderwin, 0, 0);
-    waddch(pw->borderwin, '+');
-    wmove(pw->borderwin, pw->lines-1, 0);
-    waddch(pw->borderwin, '+');
-    wmove(pw->borderwin, pw->lines-1, pw->cols-1);
-    waddch(pw->borderwin, '+');
-    wmove(pw->borderwin, 0, pw->cols-1);
-    waddch(pw->borderwin, '+');
-  }
-    
-  wnoutrefresh(pw->popwin);
-  wnoutrefresh(pw->borderwin);
-  owl_global_set_needrefresh(&g);
-  pw->active=1;
-  return(0);
-}
-
-int owl_popwin_display_text(owl_popwin *pw, char *text)
-{
-  waddstr(pw->popwin, text);
-  wnoutrefresh(pw->popwin);
-  touchwin(pw->borderwin);
-  wnoutrefresh(pw->borderwin);
-  owl_global_set_needrefresh(&g);
-  return(0);
-}	      
-
-int owl_popwin_close(owl_popwin *pw)
-{
-  delwin(pw->popwin);
-  delwin(pw->borderwin);
-  pw->active=0;
-  owl_global_set_needrefresh(&g);
-  owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-  owl_function_full_redisplay(&g);
-  return(0);
-}
-
-int owl_popwin_is_active(owl_popwin *pw)
-{
-  if (pw->active==1) return(1);
-  return(0);
-}
-
-/* this will refresh the border as well as the text area */
-int owl_popwin_refresh(owl_popwin *pw)
-{
-  touchwin(pw->borderwin);
-  touchwin(pw->popwin);
-
-  wnoutrefresh(pw->borderwin);
-  wnoutrefresh(pw->popwin);
-  owl_global_set_needrefresh(&g);
-  return(0);
-}
-
-void owl_popwin_set_handler(owl_popwin *pw, void (*func)(int ch))
-{
-  pw->handler=func;
-}
-
-void owl_popwin_unset_handler(owl_popwin *pw)
-{
-  pw->handler=NULL;
-}
-
-WINDOW *owl_popwin_get_curswin(owl_popwin *pw)
-{
-  return(pw->popwin);
-}
-
-int owl_popwin_get_lines(owl_popwin *pw)
-{
-  return(pw->lines-2);
-}
-
-int owl_popwin_get_cols(owl_popwin *pw)
-{
-  return(pw->cols-2);
-}
-
-int owl_popwin_needs_first_refresh(owl_popwin *pw)
-{
-  if (pw->needsfirstrefresh) return(1);
-  return(0);
-}
-
-void owl_popwin_no_needs_first_refresh(owl_popwin *pw)
-{
-  pw->needsfirstrefresh=0;
-}
Index: gex.c
===================================================================
--- regex.c	(revision 554a2b836ba40cb8a9fbbc1b1b8aeb195a334e78)
+++ 	(revision )
@@ -1,91 +1,0 @@
-#include <string.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-void owl_regex_init(owl_regex *re)
-{
-  re->negate=0;
-  re->string=NULL;
-}
-
-int owl_regex_create(owl_regex *re, char *string)
-{
-  int ret;
-  char buff1[LINE];
-  char *ptr;
-  
-  re->string=owl_strdup(string);
-
-  ptr=string;
-  re->negate=0;
-  if (string[0]=='!') {
-    ptr++;
-    re->negate=1;
-  }
-
-  /* set the regex */
-  ret=regcomp(&(re->re), ptr, REG_EXTENDED|REG_ICASE);
-  if (ret) {
-    regerror(ret, NULL, buff1, LINE);
-    owl_function_makemsg("Error in regular expression: %s", buff1);
-    owl_free(re->string);
-    re->string=NULL;
-    return(-1);
-  }
-
-  return(0);
-}
-
-int owl_regex_create_quoted(owl_regex *re, char *string)
-{
-  char *quoted;
-  
-  quoted=owl_text_quote(string, OWL_REGEX_QUOTECHARS, OWL_REGEX_QUOTEWITH);
-  owl_regex_create(re, quoted);
-  owl_free(quoted);
-  return(0);
-}
-
-int owl_regex_compare(owl_regex *re, char *string)
-{
-  int out, ret;
-
-  /* if the regex is not set we match */
-  if (!owl_regex_is_set(re)) {
-    return(0);
-  }
-  
-  ret=regexec(&(re->re), string, 0, NULL, 0);
-  out=ret;
-  if (re->negate) {
-    out=!out;
-  }
-  return(out);
-}
-
-int owl_regex_is_set(owl_regex *re)
-{
-  if (re->string) return(1);
-  return(0);
-}
-
-char *owl_regex_get_string(owl_regex *re)
-{
-  return(re->string);
-}
-
-void owl_regex_copy(owl_regex *a, owl_regex *b)
-{
-  b->negate=a->negate;
-  b->string=owl_strdup(a->string);
-  memcpy(&(b->re), &(a->re), sizeof(regex_t));
-}
-
-void owl_regex_free(owl_regex *re)
-{
-    if (re->string) {
-        owl_free(re->string);
-        regfree(&(re->re));
-    }
-}
Index: lect.c
===================================================================
--- select.c	(revision 2f690811f743b0ec04fdd98ce530c5a296c031df)
+++ 	(revision )
@@ -1,236 +1,0 @@
-#include "owl.h"
-
-static const char fileIdent[] = "$Id: select.c 894 2008-01-17 07:13:44Z asedeno $";
-
-/* Returns the index of the dispatch for the file descriptor. */
-int owl_select_find_dispatch(int fd)
-{
-  int i, len;
-  owl_list *dl;
-  owl_dispatch *d;
-  
-  dl = owl_global_get_dispatchlist(&g);
-  len = owl_list_get_size(dl);
-  for(i = 0; i < len; i++) {
-    d = (owl_dispatch*)owl_list_get_element(dl, i);
-    if (d->fd == fd) return i;
-  }
-  return -1;
-}
-
-/* Adds a new owl_dispatch to the list, replacing existing ones if needed. */
-void owl_select_add_dispatch(owl_dispatch *d)
-{
-  int elt;
-  owl_list *dl;
-
-  elt = owl_select_find_dispatch(d->fd);
-  dl = owl_global_get_dispatchlist(&g);
-  
-  if (elt != -1) {  /* If we have a dispatch for this FD */
-    owl_dispatch *d_old;
-    d_old = (owl_dispatch*)owl_list_get_element(dl, elt);
-    /* Ignore if we're adding the same dispatch again.  Otherwise
-       replace the old dispatch. */
-    if (d_old != d) {
-      owl_list_replace_element(dl, elt, d);
-      owl_free(d_old);
-    }
-  }
-  else {
-    owl_list_append_element(dl, d);
-  }
-}
-
-/* Removes an owl_dispatch to the list, based on it's file descriptor. */
-void owl_select_remove_dispatch(int fd)
-{
-  int elt;
-  owl_list *dl;
-
-  elt = owl_select_find_dispatch(fd);
-  dl = owl_global_get_dispatchlist(&g);
-  
-  if (elt != -1) {
-    owl_dispatch *d;
-    d = (owl_dispatch*)owl_list_get_element(dl, elt);
-    owl_list_remove_element(dl, elt);
-    if (d->pfunc) {
-      owl_perlconfig_dispatch_free(d);
-    }
-    owl_free(d);
-  }
-}
-
-int owl_select_dispatch_count()
-{
-  return owl_list_get_size(owl_global_get_dispatchlist(&g));
-}
-
-int owl_select_add_perl_dispatch(int fd, SV *cb)
-{
-  int elt;
-  owl_dispatch *d;
-  elt = owl_select_find_dispatch(fd);
-  if (elt != -1) {
-    d = (owl_dispatch*)owl_list_get_element(owl_global_get_dispatchlist(&g), elt);
-    if (d->pfunc == NULL) {
-      /* don't mess with non-perl dispatch functions from here. */
-      return 1;
-    }
-  }
-
-  d = malloc(sizeof(owl_dispatch));
-  d->fd = fd;
-  d->cfunc = NULL;
-  d->pfunc = cb;
-  owl_select_add_dispatch(d);
-  return 0;
-}
-
-int owl_select_remove_perl_dispatch(int fd)
-{
-  int elt;
-  owl_dispatch *d;
-  
-  elt = owl_select_find_dispatch(fd);
-  if (elt != -1) {
-    d = (owl_dispatch*)owl_list_get_element(owl_global_get_dispatchlist(&g), elt);
-    if (d->pfunc != NULL) {
-      owl_select_remove_dispatch(fd);
-      return 0;
-    }
-  }
-  return 1;
-}
-
-int owl_select_dispatch_prepare_fd_sets(fd_set *r, fd_set *e)
-{
-  int i, len, max_fd;
-  owl_dispatch *d;
-  owl_list *dl;
-
-  dl = owl_global_get_dispatchlist(&g);
-  FD_ZERO(r);
-  FD_ZERO(e);
-  max_fd = 0;
-  len = owl_select_dispatch_count(g);
-  for(i = 0; i < len; i++) {
-    d = (owl_dispatch*)owl_list_get_element(dl, i);
-    FD_SET(d->fd, r);
-    FD_SET(d->fd, e);
-    if (max_fd < d->fd) max_fd = d->fd;
-  }
-  return max_fd + 1;
-}
-
-void owl_select_dispatch(fd_set *fds, int max_fd)
-{
-  int i, len;
-  owl_dispatch *d;
-  owl_list *dl;
-
-  dl = owl_global_get_dispatchlist(&g);
-  len = owl_select_dispatch_count();
-  for(i = 0; i < len; i++) {
-    d = (owl_dispatch*)owl_list_get_element(dl, i);
-    /* While d shouldn't normally be null, the list may be altered by
-     * functions we dispatch to. */
-    if (d != NULL && FD_ISSET(d->fd, fds)) {
-      if (d->cfunc != NULL) {
-        (d->cfunc)();
-      }
-      else if (d->pfunc != NULL) {
-        owl_perlconfig_do_dispatch(d);
-      }
-    }
-  }
-}
-
-int owl_select_aim_hack(fd_set *rfds, fd_set *wfds)
-{
-  aim_conn_t *cur;
-  aim_session_t *sess;
-  int max_fd;
-
-  FD_ZERO(rfds);
-  FD_ZERO(wfds);
-  max_fd = 0;
-  sess = owl_global_get_aimsess(&g);
-  for (cur = sess->connlist, max_fd = 0; cur; cur = cur->next) {
-    if (cur->fd != -1) {
-      FD_SET(cur->fd, rfds);
-      if (cur->status & AIM_CONN_STATUS_INPROGRESS) {
-        /* Yes, we're checking writable sockets here. Without it, AIM
-           login is really slow. */
-        FD_SET(cur->fd, wfds);
-      }
-      
-      if (cur->fd > max_fd)
-        max_fd = cur->fd;
-    }
-  }
-  return max_fd;
-}
-
-void owl_select()
-{
-  int i, max_fd, aim_max_fd, aim_done;
-  fd_set r;
-  fd_set e;
-  fd_set aim_rfds, aim_wfds;
-  struct timeval timeout;
-
-  timeout.tv_sec = 1;
-  timeout.tv_usec = 0;
-
-  max_fd = owl_select_dispatch_prepare_fd_sets(&r, &e);
-
-  /* AIM HACK: 
-   *
-   *  The problem - I'm not sure where to hook into the owl/faim
-   *  interface to keep track of when the AIM socket(s) open and
-   *  close. In particular, the bosconn thing throws me off. So,
-   *  rather than register particular dispatchers for AIM, I look up
-   *  the relevant FDs and add them to select's watch lists, then
-   *  check for them individually before moving on to the other
-   *  dispatchers. --asedeno
-   */
-  aim_done = 1;
-  FD_ZERO(&aim_rfds);
-  FD_ZERO(&aim_wfds);
-  if (owl_global_is_doaimevents(&g)) {
-    aim_done = 0;
-    aim_max_fd = owl_select_aim_hack(&aim_rfds, &aim_wfds);
-    if (max_fd < aim_max_fd) max_fd = aim_max_fd;
-    for(i = 0; i <= aim_max_fd; i++) {
-      if (FD_ISSET(i, &aim_rfds)) {
-        FD_SET(i, &r);
-        FD_SET(i, &e);
-      }
-    }
-  }
-  /* END AIM HACK */
-
-  if ( select(max_fd+1, &r, &aim_wfds, &e, &timeout) ) {
-    /* Merge fd_sets and clear AIM FDs. */
-    for(i = 0; i <= max_fd; i++) {
-      /* Merge all interesting FDs into one set, since we have a
-         single dispatch per FD. */
-      if (FD_ISSET(i, &r) || FD_ISSET(i, &aim_wfds) || FD_ISSET(i, &e)) {
-        /* AIM HACK: no separate dispatch, just process here if
-           needed, and only once per run through. */
-        if (!aim_done && (FD_ISSET(i, &aim_rfds) || FD_ISSET(i, &aim_wfds))) {
-          owl_process_aim();
-          aim_done = 1;
-        }
-        else {
-          FD_SET(i, &r);
-        }
-      }
-    }
-    /* NOTE: the same dispatch function is called for both exceptional
-       and read ready FDs. */
-    owl_select_dispatch(&r, max_fd);
-  }
-}
Index: ubgen.pl
===================================================================
--- stubgen.pl	(revision 1aee7d914de75510e7cf09c452bad63b2dad2166)
+++ 	(revision )
@@ -1,44 +1,0 @@
-
-# $Id$
-
-if ($#ARGV eq -1) {
-    @ARGV=`ls *.c`;
-    chop(@ARGV);
-}
-
-print qq(/* THIS FILE WAS AUTOGENERATED BY STUBGEN.PL --- DO NOT EDIT BY HAND!!! */\n\n);
-print qq(#include "owl.h");
-
-foreach $file (@ARGV) {
-    open(FILE, $file);
-
-    print "/* -------------------------------- $file -------------------------------- */\n";
-    while (<FILE>) {
-	if (m|^\s*OWLVAR_([A-Z_0-9]+)\s*\(\s*"([^"]+)"\s*/\*\s*%OwlVarStub:?([a-z0-9_]+)?\s*\*/|) {   # "
-    my $vartype = $1;
-    my $varname = $2;
-    my $altvarname = $2;
-    $altvarname = $3 if ($3);
-    if ($vartype =~ /^BOOL/) {
-	print "void owl_global_set_${altvarname}_on(owl_global *g) {\n";
-	print "  owl_variable_set_bool_on(&g->vars, \"$varname\");\n}\n";
-	print "void owl_global_set_${altvarname}_off(owl_global *g) {\n";
-	print "  owl_variable_set_bool_off(&g->vars, \"$varname\");\n}\n";
-	print "int owl_global_is_$altvarname(owl_global *g) {\n";
-	print "  return owl_variable_get_bool(&g->vars, \"$varname\");\n}\n";
-    } elsif ($vartype =~ /^PATH/ or $vartype =~ /^STRING/) {
-	print "void owl_global_set_$altvarname(owl_global *g, char *text) {\n";
-	print "  owl_variable_set_string(&g->vars, \"$varname\", text);\n}\n";
-	print "char *owl_global_get_$altvarname(owl_global *g) {\n";
-	print "  return owl_variable_get_string(&g->vars, \"$varname\");\n}\n";
-    } elsif ($vartype =~ /^INT/ or $vartype =~ /^ENUM/) {
-	print "void owl_global_set_$altvarname(owl_global *g, int n) {\n";
-	print "  owl_variable_set_int(&g->vars, \"$varname\", n);\n}\n";
-	print "int owl_global_get_$altvarname(owl_global *g) {\n";
-	print "  return owl_variable_get_int(&g->vars, \"$varname\");\n}\n";
-    } 
-    }
-    }
-    close(FILE);
-    print "\n";
-}
Index: yle.c
===================================================================
--- style.c	(revision 864ed359c1c6fbc341ca8d3a273cb7c2ae4e0875)
+++ 	(revision )
@@ -1,93 +1,0 @@
-#define OWL_PERL
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-void owl_style_create_perl(owl_style *s, char *name, SV *obj)
-{
-  s->name=owl_strdup(name);
-  s->perlobj = SvREFCNT_inc(obj);
-}
-
-int owl_style_matches_name(owl_style *s, char *name)
-{
-  if (!strcmp(s->name, name)) return(1);
-  return(0);
-}
-
-char *owl_style_get_name(owl_style *s)
-{
-  return(s->name);
-}
-
-char *owl_style_get_description(owl_style *s)
-{
-  SV *sv = NULL;
-  OWL_PERL_CALL_METHOD(s->perlobj,
-                       "description",
-                       /* no args */,
-                       "Error in style_get_description: %s",
-                       0,
-                       sv = SvREFCNT_inc(POPs);
-                       );
-  if(sv) {
-    return SvPV_nolen(sv_2mortal(sv));
-  } else {
-    return "[error getting description]";
-  }
-}
-
-/* Use style 's' to format message 'm' into fmtext 'fm'.
- * 'fm' should already be be initialzed
- */
-void owl_style_get_formattext(owl_style *s, owl_fmtext *fm, owl_message *m)
-{
-  char *body, *indent;
-  int curlen;
-
-  SV *sv = NULL;
-  
-  /* Call the perl object */
-  OWL_PERL_CALL_METHOD(s->perlobj,
-                       "format_message",
-                       XPUSHs(owl_perlconfig_message2hashref(m));,
-                       "Error in format_message: %s",
-                       0,
-                       sv = SvREFCNT_inc(POPs);
-                       );
-
-  if(sv) {
-    body = SvPV_nolen(sv);
-  } else {
-    body = "<unformatted message>";
-  }
-
-  /* indent and ensure ends with a newline */
-  indent=owl_malloc(strlen(body)+(owl_text_num_lines(body))*OWL_TAB+10);
-  owl_text_indent(indent, body, OWL_TAB);
-  curlen = strlen(indent);
-  if (curlen==0 || indent[curlen-1] != '\n') {
-    indent[curlen] = '\n';
-    indent[curlen+1] = '\0';
-  }
-
-  /* fmtext_append.  This needs to change */
-  owl_fmtext_append_ztext(fm, indent);
-
-  owl_free(indent);
-  if(sv)
-    SvREFCNT_dec(body);
-}
-
-int owl_style_validate(owl_style *s) {
-  if (!s || !s->perlobj || !SvOK(s->perlobj)) {
-    return -1;
-  }
-  return 0;
-}
-
-void owl_style_free(owl_style *s)
-{
-  if (s->name) owl_free(s->name);
-  SvREFCNT_dec(s->perlobj);
-}
Index: 00-core-tests.t
===================================================================
--- t/00-core-tests.t	(revision 1cf3f8d3cf08ed3fb38d1c83459a1db140cb0d17)
+++ 	(revision )
@@ -1,3 +1,0 @@
-#!/usr/bin/env perl
-use File::Basename;
-system(dirname($0) . "/../tester");
Index: st.h
===================================================================
--- test.h	(revision 1cf3f8d3cf08ed3fb38d1c83459a1db140cb0d17)
+++ 	(revision )
@@ -1,8 +1,0 @@
-#ifndef __OWL_TEST_H__
-#define __OWL_TEST_H__
-
-#define FAIL_UNLESS(desc,pred) do { int __pred = (pred);                \
-    printf("%s %s", (__pred)?"ok":(numfailed++,"not ok"), desc);     \
-    if(!(__pred)) printf("\t(%s:%d)", __FILE__, __LINE__); printf("%c", '\n'); } while(0)
-
-#endif
Index: ster.c
===================================================================
--- tester.c	(revision 33813991523c10b91982179dd48f55b4dc3ce7b8)
+++ 	(revision )
@@ -1,32 +1,0 @@
-#include "owl.h"
-#include <unistd.h>
-#include <stdlib.h>
-
-static const char fileIdent[] = "$Id$";
-
-owl_global g;
-
-#define OWL_DICT_NTESTS  20
-#define OWL_UTIL_NTESTS  9
-#define OWL_OBARRAY_NTESTS  5
-#define OWL_VARIABLE_NTESTS  52
-#define OWL_FILTER_NTESTS  23
-
-int main(int argc, char **argv, char **env)
-{
-  owl_errqueue_init(owl_global_get_errqueue(&g));
-  owl_obarray_init(&(g.obarray));
-
-  int numfailures=0;
-  printf("1..%d\n", OWL_UTIL_NTESTS+OWL_DICT_NTESTS+OWL_VARIABLE_NTESTS
-         +OWL_FILTER_NTESTS+OWL_OBARRAY_NTESTS);
-  numfailures += owl_util_regtest();
-  numfailures += owl_dict_regtest();
-  numfailures += owl_variable_regtest();
-  numfailures += owl_filter_regtest();
-  numfailures += owl_obarray_regtest();
-  if (numfailures) {
-      fprintf(stderr, "# *** WARNING: %d failures total\n", numfailures);
-  }
-  return(numfailures);
-}
Index: xt.c
===================================================================
--- text.c	(revision 3bcf12527e47f730a032a807fd38018ae8b13c7e)
+++ 	(revision )
@@ -1,437 +1,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-/* start with line aline (where the first line is 1) and print 'lines'
- *  lines
- */
-int owl_text_truncate_lines(char *out, char *in, int aline, int lines)
-{
-  char *ptr1, *ptr2;
-  int i;
-
-  strcpy(out, "");
-  
-  if (aline==0) aline=1; /* really illegal use */
-
-  /* find the starting line */
-  ptr1=in;
-  if (aline!=1) {
-     for (i=0; i<aline-1; i++) {
-      ptr1=strchr(ptr1, '\n');
-      if (!ptr1) return(-1);
-      ptr1++;
-    }
-  }
-  /* ptr1 now holds the starting point */
-
-  /* copy in the next 'lines' lines */
-  if (lines<1) return(-1);
-  
-  for (i=0; i<lines; i++) {
-    ptr2=strchr(ptr1, '\n');
-    if (!ptr2) {
-      strcat(out, ptr1);
-      return(-1);
-    }
-    strncat(out, ptr1, ptr2-ptr1+1);
-    ptr1=ptr2+1;
-  }
-  return(0);
-}
-
-  
-/* the first column is column 0.  The message is expected to end in a
- * new line for now */
-void owl_text_truncate_cols(char *out, char *in, int acol, int bcol)
-{
-  char *ptr_s, *ptr_e, *ptr_c, *tmpbuff, *last;
-  int col, cnt, padding;
-  
-  tmpbuff=owl_malloc(strlen(in)+20);
-
-  strcpy(tmpbuff, "");
-  last=in+strlen(in)-1;
-  ptr_s=in;
-  while (ptr_s<last) {
-    ptr_e=strchr(ptr_s, '\n');
-    if (!ptr_e) {
-      /* but this shouldn't happen if we end in a \n */
-      break;
-    }
-    
-    if (ptr_e==ptr_s) {
-      strcat(tmpbuff, "\n");
-      ptr_s++;
-      continue;
-    }
-
-    col = 0;
-    cnt = 0;
-    padding = 0;
-    ptr_c = ptr_s;
-    while(col < bcol && ptr_c < ptr_e) {
-      gunichar c = g_utf8_get_char(ptr_c);
-      if (col + mk_wcwidth(c) > bcol) break;
-      col += mk_wcwidth(c);
-      ptr_c = g_utf8_next_char(ptr_c);
-      if (col >= acol) {
-	if (cnt == 0) {
-	  ptr_s = ptr_c;
-	  padding = col - acol;
-	}
-	++cnt;
-      }
-    }
-    if (cnt) {
-      while(padding-- > 0) {
-	strcat(tmpbuff, " ");
-      }
-      strncat(tmpbuff, ptr_s, ptr_c - ptr_s - 1);
-    }
-    strcat(tmpbuff, "\n");
-    ptr_s = ptr_e + 1;
-#if 0
-    /* we need to check that we won't run over here */
-    if ( (ptr_e-ptr_s) < (bcol-acol) ) {
-      len=ptr_e-(ptr_s+acol);
-    } else {
-      len=bcol-acol;
-    }
-    if ((ptr_s+len)>=last) {
-      len-=last-(ptr_s+len);
-    }
-
-    strncat(tmpbuff, ptr_s+acol, len);
-    strcat(tmpbuff, "\n");
-
-    ptr_s=ptr_e+1;
-#endif
-  }
-  strcpy(out, tmpbuff);
-  owl_free(tmpbuff);
-}
-
-
-void owl_text_indent(char *out, char *in, int n)
-{
-  char *ptr1, *ptr2, *last;
-  int i;
-
-  strcpy(out, "");
-
-  last=in+strlen(in)-1;
-  ptr1=in;
-  while (ptr1<=last) {
-    for (i=0; i<n; i++) {
-      strcat(out, " ");
-    }
-    ptr2=strchr(ptr1, '\n');
-    if (!ptr2) {
-      strcat(out, ptr1);
-      break;
-    } else {
-      strncat(out, ptr1, ptr2-ptr1+1);
-    }
-    ptr1=ptr2+1;
-  }
-}
-
-int owl_text_num_lines(char *in)
-{
-  int lines, i;
-
-  lines=0;
-  for (i=0; in[i]!='\0'; i++) {
-    if (in[i]=='\n') lines++;
-  }
-
-  /* if the last char wasn't a \n there's one more line */
-  if (i>0 && in[i-1]!='\n') lines++;
-
-  return(lines);
-}
-
-
-/* caller must free the return */
-char *owl_text_htmlstrip(char *in)
-{
-  char *ptr1, *end, *ptr2, *ptr3, *out, *out2;
-
-  out=owl_malloc(strlen(in)+30);
-  strcpy(out, "");
-
-  ptr1=in;
-  end=in+strlen(in);
-  
-  while(ptr1<end) {
-    /* look for an open bracket */
-    ptr2=strchr(ptr1, '<');
-
-    /* if none, copy in from here to end and exit */
-    if (ptr2==NULL) {
-      strcat(out, ptr1);
-      break;
-    }
-
-    /* otherwise copy in everything before the open bracket */
-    if (ptr2>ptr1) {
-      strncat(out, ptr1, ptr2-ptr1);
-    }
-
-    /* find the close bracket */
-    ptr3=strchr(ptr2, '>');
-    
-    /* if there is no close, copy as you are and exit */
-    if (!ptr3) {
-      strcat(out, ptr2);
-      break;
-    }
-
-    /* look for things we know */
-    if (!strncasecmp(ptr2, "<BODY", 5) ||
-	!strncasecmp(ptr2, "<FONT", 5) ||
-	!strncasecmp(ptr2, "<HTML", 5) ||
-	!strncasecmp(ptr2, "</FONT", 6) ||
-	!strncasecmp(ptr2, "</HTML", 6) ||
-	!strncasecmp(ptr2, "</BODY", 6)) {
-
-      /* advance to beyond the angle brakcet and go again */
-      ptr1=ptr3+1;
-      continue;
-    }
-    if (!strncasecmp(ptr2, "<BR>", 4)) {
-      strcat(out, "\n");
-      ptr1=ptr3+1;
-      continue;
-    }
-
-    /* if it wasn't something we know, copy to the > and  go again */
-    strncat(out, ptr2, ptr3-ptr2+1);
-    ptr1=ptr3+1;
-  }
-
-  out2=owl_text_substitute(out, "&lt;", "<");
-  owl_free(out);
-  out=owl_text_substitute(out2, "&gt;", ">");
-  owl_free(out2);
-  out2=owl_text_substitute(out, "&amp;", "&");
-  owl_free(out);
-  out=owl_text_substitute(out2, "&quot;", "\"");
-  owl_free(out2);
-  out2=owl_text_substitute(out, "&nbsp;", " ");
-  owl_free(out);
-  out=owl_text_substitute(out2, "&ensp;", "  ");
-  owl_free(out2);
-  out2=owl_text_substitute(out, "&emsp;", "   ");
-  owl_free(out);
-  out=owl_text_substitute(out2, "&endash;", "--");
-  owl_free(out2);
-  out2=owl_text_substitute(out, "&emdash;", "---");
-  owl_free(out);
-
-  return(out2);
-}
-
-/* caller must free the return */
-char *owl_text_wordwrap(char *in, int col)
-{
-  char *out;
-  int cur, lastspace, len, lastnewline;
-
-  out=owl_strdup(in);
-  len=strlen(in);
-  cur=0;
-  lastspace=-1;
-  lastnewline=-1;
-
-  while (cur<(len-1)) {
-    if (out[cur]==' ') {
-      lastspace=cur;
-      cur++;
-      continue;
-    } else if (out[cur]=='\n') {
-      lastnewline=cur;
-      cur++;
-      continue;
-    }
-
-    /* do we need to wrap? */
-    if ( (cur-(lastnewline+1)) > col ) {
-      if (lastspace==-1 ||
-	  (lastnewline>0 && (lastspace<=lastnewline))) {
-	/* we can't help, sorry */
-	cur++;
-	continue;
-      }
-
-      /* turn the last space into a newline */
-      out[lastspace]='\n';
-      lastnewline=lastspace;
-      lastspace=-1;
-      cur++;
-      continue;
-    }
-
-    cur++;
-    continue;
-  }
-  return(out);
-}
-
-/* this modifies 'in' */
-void owl_text_wordunwrap(char *in)
-{
-  int i, j;
-
-  j=strlen(in);
-  for (i=0; i<j; i++) {
-    if ( (in[i]=='\n') &&
-	 ((i>0) && (i<(j-1))) &&
-	 (in[i-1]!='\n') &&
-	 (in[i+1]!='\n') )
-      in[i]=' ';
-  }
-}
-
-/* exactly like strstr but case insensitive */
-char *stristr(char *a, char *b)
-{
-  char *x, *y;
-  char *ret = NULL;
-  if ((x = g_utf8_casefold(a, -1)) != NULL) {
-    if ((y = g_utf8_casefold(b, -1)) != NULL) {
-      ret = strstr(x, y);
-      if (ret != NULL) {
-	ret = ret - x + a;
-      }
-      g_free(y);
-    }
-    g_free(x);
-  }
-  return(ret);
-}
-
-/* return 1 if a string is only whitespace, otherwise 0 */
-int only_whitespace(char *s)
-{
-  if (g_utf8_validate(s,-1,NULL)) {
-    char *p;
-    for(p = s; p[0]; p=g_utf8_next_char(p)) {
-      if (!g_unichar_isspace(g_utf8_get_char(p))) return 0;
-    }
-  }
-  else {
-    int i;
-    for (i=0; s[i]; i++) {
-      if (!isspace((int) s[i])) return(0);
-    }
-  }
-  return(1);
-}
-
-char *owl_getquoting(char *line)
-{
-  if (line[0]=='\0') return("'");
-  if (strchr(line, '\'')) return("\"");
-  if (strchr(line, '"')) return("'");
-  if (strchr(line, ' ')) return("'");
-  return("");
-}
-
-/* Return a string with any occurances of 'from' replaced with 'to'.
- * Does not currently handle backslash quoting, but may in the future.
- * Caller must free returned string.
- */
-char *owl_text_substitute(char *in, char *from, char *to)
-{
-  
-  char *out;
-  int   outlen, tolen, fromlen, inpos=0, outpos=0;
-
-  if (!*from) return owl_strdup(in);
-
-  outlen = strlen(in)+1;
-  tolen  = strlen(to);
-  fromlen  = strlen(from);
-  out = owl_malloc(outlen);
-
-  while (in[inpos]) {
-    if (!strncmp(in+inpos, from, fromlen)) {
-      outlen += tolen;
-      out = owl_realloc(out, outlen);
-      strcpy(out+outpos, to);
-      inpos += fromlen;
-      outpos += tolen;
-    } else {
-      out[outpos] = in[inpos];
-      inpos++; outpos++;
-    }
-  }
-  out[outpos] = '\0';
-  return(out);
-}
-
-/* replace all instances of character a in buff with the character
- * b.  buff must be null terminated.
- */
-void owl_text_tr(char *buff, char a, char b)
-{
-  int i;
-
-  owl_function_debugmsg("In: %s", buff);
-  for (i=0; buff[i]!='\0'; i++) {
-    if (buff[i]==a) buff[i]=b;
-  }
-  owl_function_debugmsg("Out: %s", buff);
-}
-
-/* Return a string which is like 'in' except that every instance of
- * any character in 'toquote' found in 'in' is preceeded by the string
- * 'quotestr'.  For example, owl_text_quote(in, "+*.", "\") would
- * place a backslash before every '+', '*' or '.' in 'in'.  It is
- * permissable for a character in 'quotestr' to be in 'toquote'.
- * On success returns the string, on error returns NULL.
- */
-char *owl_text_quote(char *in, char *toquote, char *quotestr)
-{
-  int i, x, r, place, escape;
-  int in_len, toquote_len, quotestr_len;
-  char *out;
-
-  in_len=strlen(in);
-  toquote_len=strlen(toquote);
-  quotestr_len=strlen(quotestr);
-  out=owl_malloc((in_len*quotestr_len)+30);
-  place=0;
-  escape = 0;
-  for (i=0; i<in_len; i++) {
-    if(strchr(toquote, in[i]) != NULL)
-      escape++;
-  }
-  out = owl_malloc(in_len + quotestr_len*escape+1);
-  for (i=0; i<in_len; i++) {
-
-    /* check if it's a character that needs quoting */
-    for (x=0; x<toquote_len; x++) {
-      if (in[i]==toquote[x]) {
-	/* quote it */
-	for (r=0; r<quotestr_len; r++) {
-	  out[place+r]=quotestr[r];
-	}
-	place+=quotestr_len;
-	break;
-      }
-    }
-
-    /* either way, we now copy over the character */
-    out[place]=in[i];
-    place++;
-  }
-  out[place]='\0';
-  return(out);
-}
Index: mer.c
===================================================================
--- timer.c	(revision 6a415e91912b4795a141097f08a02c8a3229a908)
+++ 	(revision )
@@ -1,74 +1,0 @@
-#include "owl.h"
-
-#define OWL_TIMER_DIRECTION_COUNTUP    1
-#define OWL_TIMER_DIRECTION_COUNTDOWN  2
-
-
-/* Create a "counting up" timer.  The counter starts running as soon
- * as this is called.  Use owl_timer_reset() to reset it.
- */
-void owl_timer_create_countup(owl_timer *t)
-{
-  t->direction=OWL_TIMER_DIRECTION_COUNTUP;
-  t->starttime=time(NULL);
-}
-
-/* create a "counting down" timer, which counts down from 'start'
- * seconds.  The counter starts running as soon as this is called.
- * Use owl_timer_reset to reset it.
- */
-void owl_timer_create_countdown(owl_timer *t, int start)
-{
-  t->direction=OWL_TIMER_DIRECTION_COUNTDOWN;
-  t->start=start;
-  t->starttime=time(NULL);
-}
-
-/* Reset the timer.  For a "counting up" timer, it is reset to 0.  For
- * a "counting down" timer it is set to the value initially set with
- * owl_timer_create_countdown() or the last value set with
- * owl_timer_reset_newstart() */
-void owl_timer_reset(owl_timer *t)
-{
-  t->starttime=time(NULL);
-}
-
-/* Only for a countdown timer.  Rest the timer, but this time (and on
- * future resets) start with 'start' seconds.
- */
-void owl_timer_reset_newstart(owl_timer *t, int start)
-{
-  t->start=start;
-  t->starttime=time(NULL);
-}
-
-/* Return the number of seconds elapsed or remaining.  If using a
- * countdown timer, a negative value is never reported.  Once the
- * timer gets to 0 it stays at 0 */
-int owl_timer_get_time(owl_timer *t)
-{
-  time_t now;
-  int rem;
-
-  now=time(NULL);
-
-  if (t->direction==OWL_TIMER_DIRECTION_COUNTUP) {
-    return(now-t->starttime);
-  } else if (t->direction==OWL_TIMER_DIRECTION_COUNTDOWN) {
-    rem=t->start-(now-t->starttime);
-    if (rem<0) return(0);
-    return(rem);
-  }
-
-  /* never reached */
-  return(0);
-}
-
-/* Only for countdown timer.  Return true if time has run out (the
- * timer is at 0 seconds or less
- */
-int owl_timer_is_expired(owl_timer *t)
-{
-  if (owl_timer_get_time(t)==0) return(1);
-  return(0);
-}
Index: il.c
===================================================================
--- util.c	(revision 6eaf35b1b74b142244bdde7df41bb5891454bbb7)
+++ 	(revision )
@@ -1,895 +1,0 @@
-#include "owl.h"
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <pwd.h>
-
-static const char fileIdent[] = "$Id$";
-
-void sepbar(char *in)
-{
-  char buff[1024];
-  WINDOW *sepwin;
-  owl_messagelist *ml;
-  owl_view *v;
-  int x, y, i;
-  char *foo, *appendtosepbar;
-
-  sepwin=owl_global_get_curs_sepwin(&g);
-  ml=owl_global_get_msglist(&g);
-  v=owl_global_get_current_view(&g);
-
-  werase(sepwin);
-  wattron(sepwin, A_REVERSE);
-  if (owl_global_is_fancylines(&g)) {
-    whline(sepwin, ACS_HLINE, owl_global_get_cols(&g));
-  } else {
-    whline(sepwin, '-', owl_global_get_cols(&g));
-  }
-
-  if (owl_global_is_sepbar_disable(&g)) {
-    getyx(sepwin, y, x);
-    wmove(sepwin, y, owl_global_get_cols(&g)-1);
-    return;
-  }
-
-  wmove(sepwin, 0, 2);  
-
-  if (owl_messagelist_get_size(ml)==0) {
-    strcpy(buff, " (-/-) ");
-  } else {
-    snprintf(buff, 1024, " (%i/%i/%i) ", owl_global_get_curmsg(&g)+1,
-	    owl_view_get_size(v),
-	    owl_messagelist_get_size(ml));
-  }
-  waddstr(sepwin, buff);
-
-  foo=owl_view_get_filtname(v);
-  if (strcmp(foo, owl_global_get_view_home(&g))) wattroff(sepwin, A_REVERSE);
-  waddstr(sepwin, " ");
-  waddstr(sepwin, owl_view_get_filtname(v));
-  waddstr(sepwin, " ");
-  if (strcmp(foo, owl_global_get_view_home(&g))) wattron(sepwin, A_REVERSE);
-
-  if (owl_mainwin_is_curmsg_truncated(owl_global_get_mainwin(&g))) {
-    getyx(sepwin, y, x);
-    wmove(sepwin, y, x+2);
-    wattron(sepwin, A_BOLD);
-    waddstr(sepwin, " <truncated> ");
-    wattroff(sepwin, A_BOLD);
-  }
-
-  i=owl_mainwin_get_last_msg(owl_global_get_mainwin(&g));
-  if ((i != -1) &&
-      (i < owl_view_get_size(v)-1)) {
-    getyx(sepwin, y, x);
-    wmove(sepwin, y, x+2);
-    wattron(sepwin, A_BOLD);
-    waddstr(sepwin, " <more> ");
-    wattroff(sepwin, A_BOLD);
-  }
-
-  if (owl_global_get_rightshift(&g)>0) {
-    getyx(sepwin, y, x);
-    wmove(sepwin, y, x+2);
-    snprintf(buff, 1024, " right: %i ", owl_global_get_rightshift(&g));
-    waddstr(sepwin, buff);
-  }
-
-  if (owl_global_is_zaway(&g) || owl_global_is_aaway(&g)) {
-    getyx(sepwin, y, x);
-    wmove(sepwin, y, x+2);
-    wattron(sepwin, A_BOLD);
-    wattroff(sepwin, A_REVERSE);
-    if (owl_global_is_zaway(&g) && owl_global_is_aaway(&g)) {
-      waddstr(sepwin, " AWAY ");
-    } else if (owl_global_is_zaway(&g)) {
-      waddstr(sepwin, " Z-AWAY ");
-    } else if (owl_global_is_aaway(&g)) {
-      waddstr(sepwin, " A-AWAY ");
-    }
-    wattron(sepwin, A_REVERSE);
-    wattroff(sepwin, A_BOLD);
-  }
-
-  if (owl_global_get_curmsg_vert_offset(&g)) {
-    getyx(sepwin, y, x);
-    wmove(sepwin, y, x+2);
-    wattron(sepwin, A_BOLD);
-    wattroff(sepwin, A_REVERSE);
-    waddstr(sepwin, " SCROLL ");
-    wattron(sepwin, A_REVERSE);
-    wattroff(sepwin, A_BOLD);
-  }
-  
-  if (in) {
-    getyx(sepwin, y, x);
-    wmove(sepwin, y, x+2);
-    waddstr(sepwin, in);
-  }
-
-  appendtosepbar = owl_global_get_appendtosepbar(&g);
-  if (appendtosepbar && *appendtosepbar) {
-    getyx(sepwin, y, x);
-    wmove(sepwin, y, x+2);
-    waddstr(sepwin, " ");
-    waddstr(sepwin, owl_global_get_appendtosepbar(&g));
-    waddstr(sepwin, " ");
-  }
-
-  getyx(sepwin, y, x);
-  wmove(sepwin, y, owl_global_get_cols(&g)-1);
-    
-  wattroff(sepwin, A_BOLD);
-  wattroff(sepwin, A_REVERSE);
-  wnoutrefresh(sepwin);
-}
-
-
-void pophandler_quit(int ch)
-{
-  if (ch=='q') {
-    owl_popwin_close(owl_global_get_popwin(&g));
-  }
-}
-
-char **atokenize(char *buffer, char *sep, int *i)
-{
-  /* each element of return must be freed by user */
-  char **args;
-  char *workbuff, *foo;
-  int done=0, first=1, count=0;
-
-  workbuff=owl_malloc(strlen(buffer)+1);
-  memcpy(workbuff, buffer, strlen(buffer)+1);
-
-  args=NULL;
-  while (!done) {
-    if (first) {
-      first=0;
-      foo=(char *)strtok(workbuff, sep);
-    } else {
-      foo=(char *)strtok(NULL, sep);
-    }
-    if (foo==NULL) {
-      done=1;
-    } else {
-      args=(char **)owl_realloc(args, sizeof(char *) * (count+1));
-      args[count]=owl_malloc(strlen(foo)+1);
-      strcpy(args[count], foo);
-      count++;
-    }
-  }
-  *i=count;
-  owl_free(workbuff);
-  return(args);
-}
-
-char *skiptokens(char *buff, int n) {
-  /* skips n tokens and returns where that would be.
-   * TODO: handle quotes more sanely. */
-  
-  int inquotes=0;
-  while (*buff && n>0) {
-      while (*buff == ' ') buff++;
-      while (*buff && (inquotes || *buff != ' ')) { 
-	if (*buff == '"' || *buff == '\'') inquotes=!inquotes;
-	buff++;
-      }
-      while (*buff == ' ') buff++;
-      n--;
-  }
-  return buff;
-}
-
-/* Return a "nice" version of the path.  Tilde expansion is done, and
- * duplicate slashes are removed.  Caller must free the return.
- */
-char *owl_util_makepath(char *in)
-{
-  int i, j, x;
-  char *out, user[MAXPATHLEN];
-  struct passwd *pw;
-
-  out=owl_malloc(MAXPATHLEN+1);
-  out[0]='\0';
-  j=strlen(in);
-  x=0;
-  for (i=0; i<j; i++) {
-    if (in[i]=='~') {
-      if ( (i==(j-1)) ||          /* last character */
-	   (in[i+1]=='/') ) {     /* ~/ */
-	/* use my homedir */
-	pw=getpwuid(getuid());
-	if (!pw) {
-	  out[x]=in[i];
-	} else {
-	  out[x]='\0';
-	  strcat(out, pw->pw_dir);
-	  x+=strlen(pw->pw_dir);
-	}
-      } else {
-	/* another user homedir */
-	int a, b;
-	b=0;
-	for (a=i+1; i<j; a++) {
-	  if (in[a]==' ' || in[a]=='/') {
-	    break;
-	  } else {
-	    user[b]=in[a];
-	    i++;
-	    b++;
-	  }
-	}
-	user[b]='\0';
-	pw=getpwnam(user);
-	if (!pw) {
-	  out[x]=in[i];
-	} else {
-	  out[x]='\0';
-	  strcat(out, pw->pw_dir);
-	  x+=strlen(pw->pw_dir);
-	}
-      }
-    } else if (in[i]=='/') {
-      /* check for a double / */
-      if (i<(j-1) && (in[i+1]=='/')) {
-	/* do nothing */
-      } else {
-	out[x]=in[i];
-	x++;
-      }
-    } else {
-      out[x]=in[i];
-      x++;
-    }
-  }
-  out[x]='\0';
-  return(out);
-}
-
-void atokenize_free(char **tok, int nels)
-{
-  int i;
-  for (i=0; i<nels; i++) {
-    owl_free(tok[i]);
-  }
-  owl_free(tok);
-}
-
-
-void owl_parsefree(char **argv, int argc)
-{
-  int i;
-
-  if (!argv) return;
-  
-  for (i=0; i<argc; i++) {
-    if (argv[i]) owl_free(argv[i]);
-  }
-  owl_free(argv);
-}
-
-char **owl_parseline(char *line, int *argc)
-{
-  /* break a command line up into argv, argc.  The caller must free
-     the returned values.  If there is an error argc will be set to
-     -1, argv will be NULL and the caller does not need to free
-     anything */
-
-  char **argv;
-  int i, len, between=1;
-  char *curarg;
-  char quote;
-
-  argv=owl_malloc(sizeof(char *));
-  len=strlen(line);
-  curarg=owl_malloc(len+10);
-  strcpy(curarg, "");
-  quote='\0';
-  *argc=0;
-  for (i=0; i<len+1; i++) {
-    /* find the first real character */
-    if (between) {
-      if (line[i]==' ' || line[i]=='\t' || line[i]=='\0') {
-	continue;
-      } else {
-	between=0;
-	i--;
-	continue;
-      }
-    }
-
-    /* deal with a quote character */
-    if (line[i]=='"' || line[i]=="'"[0]) {
-      /* if this type of quote is open, close it */
-      if (quote==line[i]) {
-	quote='\0';
-	continue;
-      }
-
-      /* if no quoting is open then open with this */
-      if (quote=='\0') {
-	quote=line[i];
-	continue;
-      }
-
-      /* if another type of quote is open then treat this as a literal */
-      curarg[strlen(curarg)+1]='\0';
-      curarg[strlen(curarg)]=line[i];
-      continue;
-    }
-
-    /* if it's not a space or end of command, then use it */
-    if (line[i]!=' ' && line[i]!='\t' && line[i]!='\n' && line[i]!='\0') {
-      curarg[strlen(curarg)+1]='\0';
-      curarg[strlen(curarg)]=line[i];
-      continue;
-    }
-
-    /* otherwise, if we're not in quotes, add the whole argument */
-    if (quote=='\0') {
-      /* add the argument */
-      argv=owl_realloc(argv, sizeof(char *)*((*argc)+1));
-      argv[*argc]=owl_malloc(strlen(curarg)+2);
-      strcpy(argv[*argc], curarg);
-      *argc=*argc+1;
-      strcpy(curarg, "");
-      between=1;
-      continue;
-    }
-
-    /* if it is a space and we're in quotes, then use it */
-    curarg[strlen(curarg)+1]='\0';
-    curarg[strlen(curarg)]=line[i];
-  }
-
-  owl_free(curarg);
-
-  /* check for unbalanced quotes */
-  if (quote!='\0') {
-    owl_parsefree(argv, *argc);
-    *argc=-1;
-    return(NULL);
-  }
-
-  return(argv);
-}
-
-/* caller must free the return */
-char *owl_util_minutes_to_timestr(int in)
-{
-  int days, hours;
-  long run;
-  char *out;
-
-  run=in;
-
-  days=run/1440;
-  run-=days*1440;
-  hours=run/60;
-  run-=hours*60;
-
-  if (days>0) {
-    out=owl_sprintf("%i d %2.2i:%2.2li", days, hours, run);
-  } else {
-    out=owl_sprintf("    %2.2i:%2.2li", hours, run);
-  }
-  return(out);
-}
-
-/* return the index of the last char before a change from the first one */
-int owl_util_find_trans(char *in, int len)
-{
-  int i;
-  for (i=1; i<len; i++) {
-    if (in[i] != in[0]) return(i-1);
-  }
-  return(i);
-}
-
-int owl_util_find_trans_short(short *in, int len)
-{
-  int i;
-  for (i=1; i<len; i++) {
-    if (in[i] != in[0]) return(i-1);
-  }
-  return(i);
-}
-
-/* Caller must free response. 
- * Takes in strings which are space-separated lists of tokens
- * and returns a single string containing no token more than once.
- * If prohibit is non-null, no token may start with a character
- * in prohibit.
- */
-char *owl_util_uniq(char *A, char *B, char *prohibit)
-{
-  
-  char *cat, **tok;
-  int toklen, i, j, first=1;
-  cat = owl_malloc(strlen(A)+strlen(B)+3);
-  strcpy(cat, A);
-  strcat(cat, " ");
-  strcat(cat, B);
-  tok = atokenize(cat, " ", &toklen);
-  strcpy(cat, "");
-  for (i=0; i<toklen; i++) {
-    int dup=0;
-    for (j=0; j<i; j++) {
-      if (!strcmp(tok[i], tok[j])) dup=1;
-    }
-    if (!dup && (!prohibit || !strchr(prohibit, tok[i][0]))) {
-      if (!first) {
-	strcat(cat, " ");
-      }
-      first=0;
-      strcat(cat, tok[i]);
-    }
-  }
-  atokenize_free(tok, toklen);
-  return(cat);
-}
-
-/* hooks for doing memory allocation et. al. in owl */
-
-void *owl_malloc(size_t size)
-{
-  return(g_malloc(size));
-}
-
-void owl_free(void *ptr)
-{
-  g_free(ptr);
-}
-
-char *owl_strdup(const char *s1)
-{
-  return(g_strdup(s1));
-}
-
-void *owl_realloc(void *ptr, size_t size)
-{
-  return(g_realloc(ptr, size));
-}
-
-/* allocates memory and returns the string or null.
- * caller must free the string. 
- */
-char *owl_sprintf(const char *fmt, ...)
-{
-  va_list ap;
-  char *ret = NULL;
-  va_start(ap, fmt);
-  ret = g_strdup_vprintf(fmt, ap);
-  va_end(ap);
-  return ret;
-}
-
-
-/* Return the owl color associated with the named color.  Return -1
- * if the named color is not available
- */
-int owl_util_string_to_color(char *color)
-{
-  int c;
-  if (!strcasecmp(color, "black")) {
-    return(OWL_COLOR_BLACK);
-  } else if (!strcasecmp(color, "red")) {
-    return(OWL_COLOR_RED);
-  } else if (!strcasecmp(color, "green")) {
-    return(OWL_COLOR_GREEN);
-  } else if (!strcasecmp(color, "yellow")) {
-    return(OWL_COLOR_YELLOW);
-  } else if (!strcasecmp(color, "blue")) {
-    return(OWL_COLOR_BLUE);
-  } else if (!strcasecmp(color, "magenta")) {
-    return(OWL_COLOR_MAGENTA);
-  } else if (!strcasecmp(color, "cyan")) {
-    return(OWL_COLOR_CYAN);
-  } else if (!strcasecmp(color, "white")) {
-    return(OWL_COLOR_WHITE);
-  } else if (!strcasecmp(color, "default")) {
-    return(OWL_COLOR_DEFAULT);
-  }
-  c = atoi(color);
-  if (c >= -1 && c < COLORS) {
-    return(c);
-  }
-  return(OWL_COLOR_INVALID);
-}
-
-/* Return a string name of the given owl color */
-char *owl_util_color_to_string(int color)
-{
-  if (color==OWL_COLOR_BLACK)   return("black");
-  if (color==OWL_COLOR_RED)     return("red");
-  if (color==OWL_COLOR_GREEN)   return("green");
-  if (color==OWL_COLOR_YELLOW)  return("yellow");
-  if (color==OWL_COLOR_BLUE)    return("blue");
-  if (color==OWL_COLOR_MAGENTA) return("magenta");
-  if (color==OWL_COLOR_CYAN)    return("cyan");
-  if (color==OWL_COLOR_WHITE)   return("white");
-  if (color==OWL_COLOR_DEFAULT) return("default");
-  return("Unknown color");
-}
-
-/* Get the default tty name.  Caller must free the return */
-char *owl_util_get_default_tty()
-{
-  char *out, *tmp;
-
-  if (getenv("DISPLAY")) {
-    out=owl_strdup(getenv("DISPLAY"));
-  } else if ((tmp=ttyname(fileno(stdout)))!=NULL) {
-    out=owl_strdup(tmp);
-    if (!strncmp(out, "/dev/", 5)) {
-      owl_free(out);
-      out=owl_strdup(tmp+5);
-    }
-  } else {
-    out=owl_strdup("unknown");
-  }
-  return(out);
-}
-
-
-/* Animation hack */
-void owl_hack_animate()
-{
-  owl_messagelist *ml;
-  owl_message *m;
-  owl_fmtext *fm;
-  char *text, *ptr;
-  int place;
-
-  /* grab the first message and make sure its id is 0 */
-  ml=owl_global_get_msglist(&g);
-  m=owl_messagelist_get_element(ml, 0);
-  if (!m) return;
-  if (owl_message_get_id(m)!=0) return;
-
-  fm=owl_message_get_fmtext(m);
-  text=owl_fmtext_get_text(fm);
-
-  ptr=strstr(text, "OvO");
-  if (ptr) {
-    place=ptr-text;
-    owl_fmtext_set_char(fm, place, '-');
-    owl_fmtext_set_char(fm, place+2, '-');
-
-    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-    if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
-      owl_popwin_refresh(owl_global_get_popwin(&g));
-      /* TODO: this is a broken kludge */
-      if (owl_global_get_viewwin(&g)) {
-	owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
-      }
-    }
-    owl_global_set_needrefresh(&g);
-    return;
-  }
-
-  ptr=strstr(text, "-v-");
-  if (ptr) {
-    place=ptr-text;
-    owl_fmtext_set_char(fm, place, 'O');
-    owl_fmtext_set_char(fm, place+2, 'O');
-
-    owl_mainwin_redisplay(owl_global_get_mainwin(&g));
-    if (owl_popwin_is_active(owl_global_get_popwin(&g))) {
-      owl_popwin_refresh(owl_global_get_popwin(&g));
-      /* TODO: this is a broken kludge */
-      if (owl_global_get_viewwin(&g)) {
-	owl_viewwin_redisplay(owl_global_get_viewwin(&g), 0);
-      }
-    }
-    owl_global_set_needrefresh(&g);
-    return;
-  }
-}
-
-/* strip leading and trailing new lines.  Caller must free the
- * return.
- */
-char *owl_util_stripnewlines(char *in)
-{
-  
-  char  *tmp, *ptr1, *ptr2, *out;
-
-  ptr1=tmp=owl_strdup(in);
-  while (ptr1[0]=='\n') {
-    ptr1++;
-  }
-  ptr2=ptr1+strlen(ptr1)-1;
-  while (ptr2>ptr1 && ptr2[0]=='\n') {
-    ptr2[0]='\0';
-    ptr2--;
-  }
-
-  out=owl_strdup(ptr1);
-  owl_free(tmp);
-  return(out);
-}
-
-/* Delete the line matching "line" from the named file.  If no such
- * line is found the file is left intact.  If backup==1 then create a
- * backupfile containing the original contents.  This is an
- * inefficient impelementation which reads the entire file into
- * memory.
- */
-void owl_util_file_deleteline(char *filename, char *line, int backup)
-{
-  char buff[LINE], *text;
-  char *backupfilename="";
-  FILE *file, *backupfile=NULL;
-  int size, newline;
-
-  /* open the file for reading */
-  file=fopen(filename, "r");
-  if (!file) {
-    owl_function_error("Error opening file %s", filename);
-    return;
-  }
-
-  /* open the backup file for writing */
-  if (backup) {
-    backupfilename=owl_sprintf("%s.backup", filename);
-    backupfile=fopen(backupfilename, "w");
-    if (!backupfile) {
-      owl_function_error("Error opening file %s for writing", backupfilename);
-      owl_free(backupfilename);
-      return;
-    }
-    owl_free(backupfilename);
-  }
-
-  /* we'll read the entire file into memory, minus the line we don't want and
-   * and at the same time create the backup file if necessary
-   */
-  text=owl_malloc(LINE);
-  strcpy(text, "");
-  size=LINE;
-  while (fgets(buff, LINE, file)!=NULL) {
-    /* strip the newline */
-    newline=0;
-    if (buff[strlen(buff)-1]=='\n') {
-      buff[strlen(buff)-1]='\0';
-      newline=1;
-    }
-    
-    /* if we don't match the line, add to saved text in memory */
-    if (strcasecmp(buff, line)) {
-      size+=LINE;
-      text=owl_realloc(text, size);
-      strcat(text, buff);
-      if (newline) strcat(text, "\n");
-    }
-
-    /* write to backupfile if necessary */
-    if (backup) {
-      fputs(buff, backupfile);
-      if (newline) fputs("\n", backupfile);
-    }
-  }
-  if (backup) fclose(backupfile);
-  fclose(file);
-
-  /* now rewrite the original file from memory */
-  file=fopen(filename, "w");
-  if (!file) {
-    owl_function_error("WARNING: Error opening %s for writing.  Use %s to restore.", filename, backupfilename);
-    owl_function_beep();
-    owl_free(line);
-    return;
-  }
-
-  fputs(text, file);
-  fclose(file);
-}
-
-/* add the string 'str' to the list 'list' of strings, only if it
- * is not already present
- */
-void owl_util_list_add_unique_string(owl_list *list, char *str)
-{
-  int i, j;
-
-  j=owl_list_get_size(list);
-  for (i=0; i<j; i++) {
-    if (!strcmp(str, owl_list_get_element(list, i))) return;
-  }
-  owl_list_append_element(list, owl_strdup(str));
-}
-
-int owl_util_common_strings_in_lists(owl_list *a, owl_list *b)
-{
-  int i, j, x, y;
-
-  j=owl_list_get_size(a);
-  for (i=0; i<j; i++) {
-    y=owl_list_get_size(b);
-    for (x=0; x<y; x++) {
-      if (!strcmp(owl_list_get_element(a, i), owl_list_get_element(b, x))) return(1);
-    }
-  }
-  return(0);
-}
-
-int owl_util_max(int a, int b)
-{
-  if (a>b) return(a);
-  return(b);
-}
-
-int owl_util_min(int a, int b)
-{
-  if (a<b) return(a);
-  return(b);
-}
-
-/* Return the base class or instance from a zephyr class, by removing
-   leading `un' or trailing `.d'.
-   The caller is responsible for freeing the allocated string.
-*/
-char * owl_util_baseclass(char * class)
-{
-  char *start, *end;
-
-  start = class;
-  while(!strncmp(start, "un", 2)) {
-    start += 2;
-  }
-
-  start = owl_strdup(start);
-  end = start + strlen(start) - 1;
-  while(end > start && *end == 'd' && *(end-1) == '.') {
-    end -= 2;
-  }
-  *(end + 1) = 0;
-
-  return start;
-}
-
-char * owl_get_datadir()
-{
-  char * datadir = getenv("BARNOWL_DATA_DIR");
-  if(datadir != NULL)
-    return strchr(datadir, '=') + 1;
-  return DATADIR;
-}
-
-/* Strips format characters from a valid utf-8 string. Returns the
-   empty string if 'in' does not validate. */
-char * owl_strip_format_chars(char *in)
-{
-  char *r;
-  if (g_utf8_validate(in, -1, NULL)) {
-    char *s, *p;
-    r = owl_malloc(strlen(in)+1);
-    r[0] = '\0';
-    s = in;
-    p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-    while(p) {
-      /* If it's a format character, copy up to it, and skip all
-	 immediately following format characters. */
-      if (owl_fmtext_is_format_char(g_utf8_get_char(p))) {
-	strncat(r, s, p-s);
-	p = g_utf8_next_char(p);
-	while (p && owl_fmtext_is_format_char(g_utf8_get_char(p))) {
-	  p = g_utf8_next_char(p);
-	}
-	s = p;
-	p = strchr(s, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-      }
-      else {
-	p = strchr(p+1, OWL_FMTEXT_UC_STARTBYTE_UTF8);
-      }
-    }
-    if (s) strcat(r,s);
-  }
-  else {
-    r = owl_strdup("");
-  }
-  return r;
-}
-
-/* If in is not UTF-8, convert from ISO-8859-1. We may want to allow
- * the caller to specify an alternative in the future. We also strip
- * out characters in Unicode Plane 16, as we use that plane internally
- * for formatting.
- */
-char * owl_validate_or_convert(char *in)
-{
-  if (g_utf8_validate(in, -1, NULL)) {
-    return owl_strip_format_chars(in);
-  }
-  else {
-    return g_convert(in, -1,
-		     "UTF-8", "ISO-8859-1",
-		     NULL, NULL, NULL);
-  }
-}
-/* Attempts to convert 'in' to ISO-8859-1. Returns that if possible,
-   else returns UTF-8.
- */
-char * owl_get_iso_8859_1_if_possible(char *in)
-{
-  char *out;
-  if (g_utf8_validate(in, -1, NULL)) {
-    out = g_convert(in, -1,
-		    "ISO-8859-1", "UTF-8",
-		    NULL, NULL, NULL);
-    if (!out) {
-      out = owl_strdup(in);
-    }
-  }
-  else {
-    out = owl_strdup("");
-  }
-  return out;
-}
-
-/* This is based on _extract() and _isCJ() from perl's Text::WrapI18N */
-int owl_util_can_break_after(gunichar c)
-{
-  
-  if (c == ' ') return 1;
-  if (c >= 0x3000 && c <= 0x312f) {
-    /* CJK punctuations, Hiragana, Katakana, Bopomofo */
-    if (c == 0x300a || c == 0x300c || c == 0x300e ||
-        c == 0x3010 || c == 0x3014 || c == 0x3016 ||
-        c == 0x3018 || c == 0x301a)
-      return 0;
-    return 1;
-  }
-  if (c >= 0x31a0 && c <= 0x31bf) {return 1;}  /* Bopomofo */
-  if (c >= 0x31f0 && c <= 0x31ff) {return 1;}  /* Katakana extension */
-  if (c >= 0x3400 && c <= 0x9fff) {return 1;}  /* Han Ideogram */
-  if (c >= 0xf900 && c <= 0xfaff) {return 1;}  /* Han Ideogram */
-  if (c >= 0x20000 && c <= 0x2ffff) {return 1;}  /* Han Ideogram */
-  return 0;
-}
-
-/**************************************************************************/
-/************************* REGRESSION TESTS *******************************/
-/**************************************************************************/
-
-#ifdef OWL_INCLUDE_REG_TESTS
-
-#include "test.h"
-
-int owl_util_regtest(void)
-{
-  int numfailed=0;
-
-  printf("# BEGIN testing owl_util\n");
-
-  FAIL_UNLESS("owl_util_substitute 1",
-	      !strcmp("foo", owl_text_substitute("foo", "", "Y")));
-  FAIL_UNLESS("owl_text_substitute 2",
-	      !strcmp("fYZYZ", owl_text_substitute("foo", "o", "YZ")));
-  FAIL_UNLESS("owl_text_substitute 3",
-	      !strcmp("foo", owl_text_substitute("fYZYZ", "YZ", "o")));
-  FAIL_UNLESS("owl_text_substitute 4",
-	      !strcmp("/u/foo/meep", owl_text_substitute("~/meep", "~", "/u/foo")));
-
-  FAIL_UNLESS("skiptokens 1", 
-	      !strcmp("bar quux", skiptokens("foo bar quux", 1)));
-  FAIL_UNLESS("skiptokens 2", 
-	      !strcmp("meep", skiptokens("foo 'bar quux' meep", 2)));
-
-  FAIL_UNLESS("owl_util_uniq 1", 
-	      !strcmp("foo bar x", owl_util_uniq("foo", "bar x", "-")));
-  FAIL_UNLESS("owl_util_uniq 2", 
-	      !strcmp("foo bar x", owl_util_uniq("foo", "bar -y x", "-")));
-  FAIL_UNLESS("owl_util_uniq 3", 
-	      !strcmp("meep foo bar", owl_util_uniq("meep foo", "bar foo meep", "-")));
-
-  /* if (numfailed) printf("*** WARNING: failures encountered with owl_util\n"); */
-  printf("# END testing owl_util (%d failures)\n", numfailed);
-  return(numfailed);
-}
-
-#endif /* OWL_INCLUDE_REG_TESTS */
Index: riable.c
===================================================================
--- variable.c	(revision 160d3f421ceb80ae77fe01b5158f58cba7f61960)
+++ 	(revision )
@@ -1,1078 +1,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <ctype.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-static int in_regtest = 0;
-
-#define OWLVAR_BOOL(name,default,summary,description) \
-        { name, OWL_VARIABLE_BOOL, NULL, default, "on,off", summary,description, NULL, \
-        NULL, NULL, NULL, NULL, NULL }
-
-#define OWLVAR_BOOL_FULL(name,default,summary,description,validate,set,get) \
-        { name, OWL_VARIABLE_BOOL, NULL, default, "on,off", summary,description, NULL, \
-        validate, set, NULL, get, NULL }
-
-#define OWLVAR_INT(name,default,summary,description) \
-        { name, OWL_VARIABLE_INT, NULL, default, "<int>", summary,description, NULL, \
-        NULL, NULL, NULL, NULL, NULL, NULL }
-
-#define OWLVAR_INT_FULL(name,default,summary,description,validset,validate,set,get) \
-        { name, OWL_VARIABLE_INT, NULL, default, validset, summary,description, NULL, \
-        validate, set, NULL, get, NULL, NULL }
-
-#define OWLVAR_PATH(name,default,summary,description) \
-        { name, OWL_VARIABLE_STRING, default, 0, "<path>", summary,description,  NULL, \
-        NULL, NULL, NULL, NULL, NULL, NULL }
-
-#define OWLVAR_STRING(name,default,summary,description) \
-        { name, OWL_VARIABLE_STRING, default, 0, "<string>", summary,description, NULL, \
-        NULL, NULL, NULL, NULL, NULL, NULL }
-
-#define OWLVAR_STRING_FULL(name,default,summary,description,validate,set,get) \
-        { name, OWL_VARIABLE_STRING, default, 0, "<string>", summary,description, NULL, \
-        validate, set, NULL, get, NULL, NULL }
-
-/* enums are really integers, but where validset is a comma-separated
- * list of strings which can be specified.  The tokens, starting at 0,
- * correspond to the values that may be specified. */
-#define OWLVAR_ENUM(name,default,summary,description,validset) \
-        { name, OWL_VARIABLE_INT, NULL, default, validset, summary,description, NULL, \
-        owl_variable_enum_validate, \
-        NULL, owl_variable_enum_set_fromstring, \
-        NULL, owl_variable_enum_get_tostring, \
-        NULL }
-
-#define OWLVAR_ENUM_FULL(name,default,summary,description,validset,validate, set, get) \
-        { name, OWL_VARIABLE_INT, NULL, default, validset, summary,description, NULL, \
-        validate, \
-        set, owl_variable_enum_set_fromstring, \
-        get, owl_variable_enum_get_tostring, \
-        NULL }
-
-static owl_variable variables_to_init[] = {
-
-  OWLVAR_STRING( "personalbell" /* %OwlVarStub */, "off",
-		 "ring the terminal bell when personal messages are received",
-		 "Can be set to 'on', 'off', or the name of a filter which\n"
-		 "messages need to match in order to ring the bell"),
-
-  OWLVAR_BOOL( "bell" /* %OwlVarStub */, 1,
-	       "enable / disable the terminal bell", "" ),
-
-  OWLVAR_BOOL_FULL( "debug" /* %OwlVarStub */, OWL_DEBUG,
-		    "whether debugging is enabled",
-		    "If set to 'on', debugging messages are logged to the\n"
-		    "file specified by the debugfile variable.\n",
-		    NULL, owl_variable_debug_set, NULL),
-
-  OWLVAR_BOOL( "startuplogin" /* %OwlVarStub */, 1,
-	       "send a login message when owl starts", "" ),
-
-  OWLVAR_BOOL( "shutdownlogout" /* %OwlVarStub */, 1,
-	       "send a logout message when owl exits", "" ),
-
-  OWLVAR_BOOL( "rxping" /* %OwlVarStub */, 0,
-	       "display received pings", "" ),
-
-  OWLVAR_BOOL( "txping" /* %OwlVarStub */, 1,
-	       "send pings", "" ),
-
-  OWLVAR_BOOL( "sepbar_disable" /* %OwlVarStub */, 0,
-	       "disable printing information in the separator bar", "" ),
-
-  OWLVAR_BOOL( "smartstrip" /* %OwlVarStub */, 1,
-	       "strip kerberos instance for reply", ""),
-
-  OWLVAR_BOOL( "newlinestrip" /* %OwlVarStub */, 1,
-	       "strip leading and trailing newlines", ""),
-
-  OWLVAR_BOOL( "displayoutgoing" /* %OwlVarStub */, 1,
-	       "display outgoing messages", "" ),
-
-  OWLVAR_BOOL( "loginsubs" /* %OwlVarStub */, 1,
-	       "load logins from .anyone on startup", "" ),
-
-  OWLVAR_BOOL( "logging" /* %OwlVarStub */, 0,
-	       "turn personal logging on or off", 
-	       "If this is set to on, personal messages are\n"
-	       "logged in the directory specified\n"
-	       "by the 'logpath' variable.  The filename in that\n"
-	       "directory is derived from the sender of the message.\n" ),
-
-  OWLVAR_BOOL( "classlogging" /* %OwlVarStub */, 0,
-	       "turn class logging on or off",
-	       "If this is set to on, class messages are\n"
-	       "logged in the directory specified\n"
-	       "by the 'classlogpath' variable.\n" 
-	       "The filename in that directory is derived from\n"
-	       "the name of the class to which the message was sent.\n" ),
-
-  OWLVAR_ENUM( "loggingdirection" /* %OwlVarStub */, OWL_LOGGING_DIRECTION_BOTH,
-	       "specifices which kind of messages should be logged",
-	       "Can be one of 'both', 'in', or 'out'.  If 'in' is\n"
-	       "selected, only incoming messages are logged, if 'out'\n"
-	       "is selected only outgoing messages are logged.  If 'both'\n"
-	       "is selected both incoming and outgoing messages are\n"
-	       "logged.",
-	       "both,in,out"),
-
-  OWLVAR_BOOL( "colorztext" /* %OwlVarStub */, 1,
-	       "allow @color() in zephyrs to change color",
-	       "Note that only messages received after this variable\n"
-	       "is set will be affected." ),
-
-  OWLVAR_BOOL( "fancylines" /* %OwlVarStub */, 1,
-	       "Use 'nice' line drawing on the terminal.",
-	       "If turned off, dashes, pipes and pluses will be used\n"
-	       "to draw lines on the screen.  Useful when the terminal\n"
-	       "is causing problems" ),
-
-  OWLVAR_BOOL( "zcrypt" /* %OwlVarStub */, 1,
-	       "Do automatic zcrypt processing",
-	       "" ),
-
-  OWLVAR_BOOL_FULL( "pseudologins" /* %OwlVarStub */, 0,
-		    "Enable zephyr pseudo logins",
-		    "When this is enabled, Owl will periodically check the zephyr\n"
-		    "location of users in your .anyone file.  If a user is present\n"
-		    "but sent no login message, or a user is not present that sent no\n"
-		    "logout message, a pseudo login or logout message wil be created\n",
-		    NULL, owl_variable_pseudologins_set, NULL),
-
-  OWLVAR_BOOL( "ignorelogins" /* %OwlVarStub */, 0,
-	       "Enable printing of login notifications",
-	       "When this is enabled, Owl will print login and logout notifications\n"
-	       "for AIM, zephyr, or other protocols.  If disabled Owl will not print\n"
-	       "login or logout notifications.\n"),
-
-  OWLVAR_STRING( "logfilter" /* %OwlVarStub */, "",
-		 "name of a filter controlling which messages to log",
-
-		 "If non empty, any messages matching the given filter will be logged.\n"
-		 "This is a completely separate mechanisim from the other logging\n"
-		 "variables like logging, classlogging, loglogins, loggingdirection,\n"
-		 "etc.  If you want this variable to control all logging, make sure\n"
-		 "all other logging variables are in their default state.\n"),
-
-  OWLVAR_BOOL( "loglogins" /* %OwlVarStub */, 0,
-	       "Enable logging of login notifications",
-	       "When this is enabled, Owl will login login and logout notifications\n"
-	       "for AIM, zephyr, or other protocols.  If disabled Owl will not print\n"
-	       "login or logout notifications.\n"),
-
-  OWLVAR_ENUM_FULL( "disable-ctrl-d" /* %OwlVarStub:lockout_ctrld */, 1,
-		    "don't send zephyrs on C-d",
-		    "If set to 'off', C-d won't send a zephyr from the edit\n"
-		    "window.  If set to 'on', C-d will always send a zephyr\n"
-		    "being composed in the edit window.  If set to 'middle',\n"
-		    "C-d will only ever send a zephyr if the cursor is at\n"
-		    "the end of the message being composed.\n\n"
-		    "Note that this works by changing the C-d keybinding\n"
-		    "in the editmulti keymap.\n",
-		    "off,middle,on",
-		    NULL, owl_variable_disable_ctrl_d_set, NULL),
-
-  OWLVAR_PATH( "logpath" /* %OwlVarStub */, "~/zlog/people",
-	       "path for logging personal zephyrs", 
-	       "Specifies a directory which must exist.\n"
-	       "Files will be created in the directory for each sender.\n"),
-
-  OWLVAR_PATH( "classlogpath" /* %OwlVarStub:classlogpath */, "~/zlog/class",
-	       "path for logging class zephyrs",
-	       "Specifies a directory which must exist.\n"
-	       "Files will be created in the directory for each class.\n"),
-
-  OWLVAR_PATH( "debug_file" /* %OwlVarStub */, OWL_DEBUG_FILE,
-	       "path for logging debug messages when debugging is enabled",
-	       "This file will be logged to if 'debug' is set to 'on'.\n"),
-  
-  OWLVAR_PATH( "zsigproc" /* %OwlVarStub:zsigproc */, NULL,
-	       "name of a program to run that will generate zsigs",
-	       "This program should produce a zsig on stdout when run.\n"
-	       "Note that it is important that this program not block.\n" ),
-
-  OWLVAR_PATH( "newmsgproc" /* %OwlVarStub:newmsgproc */, NULL,
-	       "name of a program to run when new messages are present",
-	       "The named program will be run when owl recevies new.\n"
-	       "messages.  It will not be run again until the first\n"
-	       "instance exits"),
-
-  OWLVAR_STRING( "zsender" /* %OwlVarStub */, "",
-             "zephyr sender name",
-         "Allows you to customize the outgoing username in\n"
-         "zephyrs.  If this is unset, it will use your Kerberos\n"
-         "principal. Note that customizing the sender name will\n"
-         "cause your zephyrs to be sent unauthenticated."),
-
-  OWLVAR_STRING( "zsig" /* %OwlVarStub */, "",
-	         "zephyr signature", 
-		 "If 'zsigproc' is not set, this string will be used\n"
-		 "as a zsig.  If this is also unset, the 'zwrite-signature'\n"
-		 "zephyr variable will be used instead.\n"),
-
-  OWLVAR_STRING( "appendtosepbar" /* %OwlVarStub */, "",
-	         "string to append to the end of the sepbar",
-		 "The sepbar is the bar separating the top and bottom\n"
-		 "of the owl screen.  Any string specified here will\n"
-		 "be displayed on the right of the sepbar\n"),
-
-  OWLVAR_BOOL( "zaway" /* %OwlVarStub */, 0,
-	       "turn zaway on or off", "" ),
-
-  OWLVAR_STRING( "zaway_msg" /* %OwlVarStub */, 
-		 OWL_DEFAULT_ZAWAYMSG,
-	         "zaway msg for responding to zephyrs when away", "" ),
-
-  OWLVAR_STRING( "zaway_msg_default" /* %OwlVarStub */, 
-		 OWL_DEFAULT_ZAWAYMSG,
-	         "default zaway message", "" ),
-
-  OWLVAR_BOOL_FULL( "aaway" /* %OwlVarStub */, 0,
-		    "Set AIM away status",
-		    "",
-		    NULL, owl_variable_aaway_set, NULL),
-
-  OWLVAR_STRING( "aaway_msg" /* %OwlVarStub */, 
-		 OWL_DEFAULT_AAWAYMSG,
-	         "AIM away msg for responding when away", "" ),
-
-  OWLVAR_STRING( "aaway_msg_default" /* %OwlVarStub */, 
-		 OWL_DEFAULT_AAWAYMSG,
-	         "default AIM away message", "" ),
-
-  OWLVAR_STRING( "view_home" /* %OwlVarStub */, "all",
-	         "home view to switch to after 'X' and 'V'", 
-		 "SEE ALSO: view, filter\n" ),
-
-  OWLVAR_STRING( "alert_filter" /* %OwlVarStub */, "none",
-		 "filter on which to trigger alert actions",
-		 "" ),
-
-  OWLVAR_STRING( "alert_action" /* %OwlVarStub */, "nop",
-		 "owl command to execute for alert actions",
-		 "" ),
-
-  OWLVAR_STRING_FULL( "tty" /* %OwlVarStub */, "", "tty name for zephyr location", "",
-		      NULL, owl_variable_tty_set, NULL),
-
-  OWLVAR_STRING( "default_style" /* %OwlVarStub */, "__unspecified__",
-		 "name of the default formatting style",
-		 "This sets the default message formatting style.\n"
-		 "Styles may be created with the 'style' command.\n"
-		 "Some built-in styles include:\n"
-		 "   default  - the default owl formatting\n"
-		 "   oneline  - one line per-message\n"
-		 "   perl     - legacy perl interface\n"
-		 "\nSEE ALSO: style, show styles, view -s <style>\n"
-		 ),
-
-
-  OWLVAR_INT(    "edit:maxfillcols" /* %OwlVarStub:edit_maxfillcols */, 70,
-	         "maximum number of columns for M-q to fill text to",
-		 "This specifies the maximum number of columns for M-q\n"
-		 "to fill text to.  If set to 0, ther will be no maximum\n"
-		 "limit.  In all cases, the current width of the screen\n"
-		 "will also be taken into account.  It will be used instead\n"
-		 "if it is narrower than the maximum, or if this\n"
-		 "is set to 0.\n" ),
-
-  OWLVAR_INT(    "edit:maxwrapcols" /* %OwlVarStub:edit_maxwrapcols */, 0,
-	         "maximum number of columns for line-wrapping",
-		 "This specifies the maximum number of columns for\n"
-		 "auto-line-wrapping.  If set to 0, ther will be no maximum\n"
-		 "limit.  In all cases, the current width of the screen\n"
-		 "will also be taken into account.  It will be used instead\n"
-		 "if it is narrower than the maximum, or if this\n"
-		 "is set to 0.\n\n"
-		 "It is recommended that outgoing messages be no wider\n"
-		 "than 60 columns, as a courtesy to recipients.\n"),
-
-  OWLVAR_INT( "aim_ignorelogin_timer" /* %OwlVarStub */, 15,
-	      "number of seconds after AIM login to ignore login messages",
-	      "This specifies the number of seconds to wait after an\n"
-	      "AIM login before allowing the recipt of AIM login notifications.\n"
-	      "By default this is set to 15.  If you would like to view login\n"
-	      "notifications of buddies as soon as you login, set it to 0 instead."),
-
-	      
-  OWLVAR_INT_FULL( "typewinsize" /* %OwlVarStub:typwin_lines */, 
-		   OWL_TYPWIN_SIZE,
-		  "number of lines in the typing window", 
-		   "This specifies the height of the window at the\n"
-		   "bottom of the screen where commands are entered\n"
-		   "and where messages are composed.\n",
-		   "int > 0",
-		   owl_variable_int_validate_gt0,
-		   owl_variable_typewinsize_set,
-		   NULL /* use default for get */
-		   ),
-
-  OWLVAR_INT( "typewindelta" /* %OwlVarStub */, 0,
-		  "number of lines to add to the typing window when in use",
-		   "On small screens you may want the typing window to\n"
-		   "auto-hide when not entering a command or message.\n"
-		   "This variable is the number of lines to add to the\n"
-           "typing window when it is in use; you can then set\n"
-           "typewinsize to 1.\n\n"
-           "This works a lot better with a non-default scrollmode;\n"
-           "try :set scrollmode pagedcenter.\n"),
-
-  OWLVAR_ENUM( "scrollmode" /* %OwlVarStub */, OWL_SCROLLMODE_NORMAL,
-	       "how to scroll up and down",
-	       "This controls how the screen is scrolled as the\n"
-	       "cursor moves between messages being displayed.\n"
-	       "The following modes are supported:\n\n"
-	       "   normal      - This is the owl default.  Scrolling happens\n"
-	       "                 when it needs to, and an attempt is made to\n"
-	       "                 keep the current message roughly near\n"
-	       "                 the middle of the screen.\n"
-	       "   top         - The current message will always be the\n"
-	       "                 the top message displayed.\n"
-	       "   neartop     - The current message will be one down\n"
-	       "                 from the top message displayed,\n"
-	       "                 where possible.\n"
-	       "   center      - An attempt is made to keep the current\n"
-	       "                 message near the center of the screen.\n"
-	       "   paged       - The top message displayed only changes\n"
-	       "                 when user moves the cursor to the top\n"
-	       "                 or bottom of the screen.  When it moves,\n"
-	       "                 the screen will be paged up or down and\n"
-	       "                 the cursor will be near the top or\n"
-	       "                 the bottom.\n"
-	       "   pagedcenter - The top message displayed only changes\n"
-	       "                 when user moves the cursor to the top\n"
-	       "                 or bottom of the screen.  When it moves,\n"
-	       "                 the screen will be paged up or down and\n"
-	       "                 the cursor will be near the center.\n",
-	       "normal,top,neartop,center,paged,pagedcenter" ),
-
-
-  OWLVAR_BOOL( "_followlast" /* %OwlVarStub */, 0,
-	       "enable automatic following of the last zephyr",
-	       "If the cursor is at the last message, it will\n"
-	       "continue to follow the last message if this is set.\n"
-	       "Note that this is currently risky as you might accidentally\n"
-	       "delete a message right as it came in.\n" ),
-
-  /* This MUST be last... */
-  { NULL, 0, NULL, 0, NULL, NULL, NULL, NULL,
-    NULL, NULL, NULL, NULL, NULL, NULL }
-
-};
-
-/**************************************************************************/
-/*********************** SPECIFIC TO VARIABLES ****************************/
-/**************************************************************************/
-
-
-/* commonly useful */
-
-int owl_variable_int_validate_gt0(owl_variable *v, void *newval)
-{
-  if (newval == NULL) return(0);
-  else if (*(int*)newval < 1) return(0);
-  else return (1);
-}
-
-int owl_variable_int_validate_positive(owl_variable *v, void *newval)
-{
-  if (newval == NULL) return(0);
-  else if (*(int*)newval < 0) return(0);
-  else return (1);
-}
-
-/* typewinsize */
-int owl_variable_typewinsize_set(owl_variable *v, void *newval)
-{
-  int rv;
-  rv = owl_variable_int_set_default(v, newval);
-  if (0 == rv) owl_function_resize();
-  return(rv);
-}
-
-/* debug (cache value in g->debug) */
-int owl_variable_debug_set(owl_variable *v, void *newval)
-{
-  if (newval && (*(int*)newval == 1 || *(int*)newval == 0)) {
-    g.debug = *(int*)newval;
-  }
-  return owl_variable_bool_set_default(v, newval);
-}
-
-/* When 'aaway' is changed, need to notify the AIM server */
-int owl_variable_aaway_set(owl_variable *v, void *newval)
-{
-  if (newval) {
-    if (*(int*)newval == 1) {
-      owl_aim_set_awaymsg(owl_global_get_aaway_msg(&g));
-    } else if (*(int*)newval == 0) {
-      owl_aim_set_awaymsg("");
-    }
-  }
-  return owl_variable_bool_set_default(v, newval);
-}
-
-int owl_variable_pseudologins_set(owl_variable *v, void *newval)
-{
-  if (newval) {
-    if (*(int*)newval == 1) {
-      owl_function_zephyr_buddy_check(0);
-    }
-  }
-  return owl_variable_bool_set_default(v, newval);
-}
-
-/* note that changing the value of this will clobber 
- * any user setting of this */
-int owl_variable_disable_ctrl_d_set(owl_variable *v, void *newval)
-{
-
-  if (in_regtest) return owl_variable_int_set_default(v, newval);
-
-  if (newval && !owl_context_is_startup(owl_global_get_context(&g))) {
-    if (*(int*)newval == 2) {
-      owl_function_command_norv("bindkey editmulti C-d command edit:delete-next-char");
-    } else if (*(int*)newval == 1) {
-      owl_function_command_norv("bindkey editmulti C-d command editmulti:done-or-delete");
-    } else {
-      owl_function_command_norv("bindkey editmulti C-d command editmulti:done");
-    }
-  }  
-  return owl_variable_int_set_default(v, newval);  
-}
-
-int owl_variable_tty_set(owl_variable *v, void *newval)
-{
-  owl_zephyr_set_locationinfo(owl_global_get_hostname(&g), newval);
-  return(owl_variable_string_set_default(v, newval));
-}
-
-
-/**************************************************************************/
-/****************************** GENERAL ***********************************/
-/**************************************************************************/
-
-int owl_variable_dict_setup(owl_vardict *vd) {
-  owl_variable *var, *cur;
-  if (owl_dict_create(vd)) return(-1);
-  for (var = variables_to_init; var->name != NULL; var++) {
-    cur = owl_malloc(sizeof(owl_variable));
-    memcpy(cur, var, sizeof(owl_variable));
-    switch (cur->type) {
-    case OWL_VARIABLE_OTHER:
-      cur->set_fn(cur, cur->pval_default);
-      break;
-    case OWL_VARIABLE_STRING:
-      if (!cur->validate_fn) 
-	cur->validate_fn = owl_variable_string_validate_default;
-      if (!cur->set_fn) 
-	cur->set_fn = owl_variable_string_set_default;
-      if (!cur->set_fromstring_fn) 
-	cur->set_fromstring_fn = owl_variable_string_set_fromstring_default;
-      if (!cur->get_fn) 
-	cur->get_fn = owl_variable_get_default;
-      if (!cur->get_tostring_fn) 
-	cur->get_tostring_fn = owl_variable_string_get_tostring_default;      
-      if (!cur->free_fn) 
-	cur->free_fn = owl_variable_free_default;
-      cur->set_fn(cur, cur->pval_default);
-      break;
-    case OWL_VARIABLE_BOOL:
-      if (!cur->validate_fn) 
-	cur->validate_fn = owl_variable_bool_validate_default;
-      if (!cur->set_fn) 
-	cur->set_fn = owl_variable_bool_set_default;
-      if (!cur->set_fromstring_fn) 
-	cur->set_fromstring_fn = owl_variable_bool_set_fromstring_default;
-      if (!cur->get_fn) 
-	cur->get_fn = owl_variable_get_default;
-      if (!cur->get_tostring_fn) 
-	cur->get_tostring_fn = owl_variable_bool_get_tostring_default;      
-      if (!cur->free_fn) 
-	cur->free_fn = owl_variable_free_default;
-      cur->val = owl_malloc(sizeof(int));
-      cur->set_fn(cur, &cur->ival_default);
-      break;
-    case OWL_VARIABLE_INT:
-      if (!cur->validate_fn) 
-	cur->validate_fn = owl_variable_int_validate_default;
-      if (!cur->set_fn) 
-	cur->set_fn = owl_variable_int_set_default;
-      if (!cur->set_fromstring_fn) 
-	cur->set_fromstring_fn = owl_variable_int_set_fromstring_default;
-      if (!cur->get_fn) 
-	cur->get_fn = owl_variable_get_default;
-      if (!cur->get_tostring_fn) 
-	cur->get_tostring_fn = owl_variable_int_get_tostring_default;      
-      if (!cur->free_fn) 
-	cur->free_fn = owl_variable_free_default;
-      cur->val = owl_malloc(sizeof(int));
-      cur->set_fn(cur, &cur->ival_default);
-      break;
-    default:
-      fprintf(stderr, "owl_variable_setup: invalid variable type\n");
-      return(-2);
-    }
-    owl_dict_insert_element(vd, cur->name, (void*)cur, NULL);
-  }
-  return 0;
-}
-
-void owl_variable_dict_add_variable(owl_vardict * vardict,
-                                    owl_variable * var) {
-  owl_dict_insert_element(vardict, var->name, (void*)var, (void(*)(void*))owl_variable_free);
-}
-
-owl_variable * owl_variable_newvar(char *name, char *summary, char * description) {
-  owl_variable * var = (owl_variable*)owl_malloc(sizeof(owl_variable));
-  memset(var, 0, sizeof(owl_variable));
-  var->name = owl_strdup(name);
-  var->summary = owl_strdup(summary);
-  var->description = owl_strdup(description);
-  return var;
-}
-
-void owl_variable_update(owl_variable *var, char *summary, char *desc) {
-  if(var->summary) owl_free(var->summary);
-  var->summary = owl_strdup(summary);
-  if(var->description) owl_free(var->description);
-  var->description = owl_strdup(desc);
-}
-
-void owl_variable_dict_newvar_string(owl_vardict * vd, char *name, char *summ, char * desc, char * initval) {
-  owl_variable *old = owl_variable_get_var(vd, name, OWL_VARIABLE_STRING);
-  if(old) {
-    owl_variable_update(old, summ, desc);
-    if(old->pval_default) owl_free(old->pval_default);
-    old->pval_default = owl_strdup(initval);
-  } else {
-    owl_variable * var = owl_variable_newvar(name, summ, desc);
-    var->type = OWL_VARIABLE_STRING;
-    var->pval_default = owl_strdup(initval);
-    var->set_fn = owl_variable_string_set_default;
-    var->set_fromstring_fn = owl_variable_string_set_fromstring_default;
-    var->get_fn = owl_variable_get_default;
-    var->get_tostring_fn = owl_variable_string_get_tostring_default;
-    var->free_fn = owl_variable_free_default;
-    var->set_fn(var, initval);
-    owl_variable_dict_add_variable(vd, var);
-  }
-}
-
-void owl_variable_dict_newvar_int(owl_vardict * vd, char *name, char *summ, char * desc, int initval) {
-  owl_variable *old = owl_variable_get_var(vd, name, OWL_VARIABLE_INT);
-  if(old) {
-    owl_variable_update(old, summ, desc);
-    old->ival_default = initval;
-  } else {
-    owl_variable * var = owl_variable_newvar(name, summ, desc);
-    var->type = OWL_VARIABLE_INT;
-    var->ival_default = initval;
-    var->validate_fn = owl_variable_int_validate_default;
-    var->set_fn = owl_variable_int_set_default;
-    var->set_fromstring_fn = owl_variable_int_set_fromstring_default;
-    var->get_fn = owl_variable_get_default;
-    var->get_tostring_fn = owl_variable_int_get_tostring_default;
-    var->free_fn = owl_variable_free_default;
-    var->val = owl_malloc(sizeof(int));
-    var->set_fn(var, &initval);
-    owl_variable_dict_add_variable(vd, var);
-  }
-}
-
-void owl_variable_dict_newvar_bool(owl_vardict * vd, char *name, char *summ, char * desc, int initval) {
-  owl_variable *old = owl_variable_get_var(vd, name, OWL_VARIABLE_BOOL);
-  if(old) {
-    owl_variable_update(old, summ, desc);
-    old->ival_default = initval;
-  } else {
-    owl_variable * var = owl_variable_newvar(name, summ, desc);
-    var->type = OWL_VARIABLE_BOOL;
-    var->ival_default = initval;
-    var->validate_fn = owl_variable_bool_validate_default;
-    var->set_fn = owl_variable_bool_set_default;
-    var->set_fromstring_fn = owl_variable_bool_set_fromstring_default;
-    var->get_fn = owl_variable_get_default;
-    var->get_tostring_fn = owl_variable_bool_get_tostring_default;
-    var->free_fn = owl_variable_free_default;
-    var->val = owl_malloc(sizeof(int));
-    var->set_fn(var, &initval);
-    owl_variable_dict_add_variable(vd, var);
-  }
-}
-
-void owl_variable_dict_free(owl_vardict *d) {
-  owl_dict_free_all(d, (void(*)(void*))owl_variable_free);
-}
-
-/* free the list with owl_variable_dict_namelist_free */
-void owl_variable_dict_get_names(owl_vardict *d, owl_list *l) {
-  owl_dict_get_keys(d, l);
-}
-
-void owl_variable_dict_namelist_free(owl_list *l) {
-  owl_list_free_all(l, owl_free);
-}
-
-void owl_variable_free(owl_variable *v) {
-  if (v->free_fn) v->free_fn(v);
-  owl_free(v);
-}
-
-
-char *owl_variable_get_description(owl_variable *v) {
-  return v->description;
-}
-
-char *owl_variable_get_summary(owl_variable *v) {
-  return v->summary;
-}
-
-char *owl_variable_get_validsettings(owl_variable *v) {
-  if (v->validsettings) {
-    return v->validsettings;
-  } else {
-    return "";
-  }
-}
-
-/* functions for getting and setting variable values */
-
-/* returns 0 on success, prints a status msg if msg is true */
-int owl_variable_set_fromstring(owl_vardict *d, char *name, char *value, int msg, int requirebool) {
-  owl_variable *v;
-  char buff2[1024];
-  if (!name) return(-1);
-  v = owl_dict_find_element(d, name);
-  if (v == NULL) {
-    if (msg) owl_function_error("Unknown variable %s", name);
-    return -1;
-  }
-  if (!v->set_fromstring_fn) {
-    if (msg) owl_function_error("Variable %s is read-only", name);
-    return -1;   
-  }
-  if (requirebool && v->type!=OWL_VARIABLE_BOOL) {
-    if (msg) owl_function_error("Variable %s is not a boolean", name);
-    return -1;   
-  }
-  if (0 != v->set_fromstring_fn(v, value)) {
-    if (msg) owl_function_error("Unable to set %s (must be %s)", name, 
-				  owl_variable_get_validsettings(v));
-    return -1;
-  }
-  if (msg && v->get_tostring_fn) {
-    v->get_tostring_fn(v, buff2, 1024, v->val);
-    owl_function_makemsg("%s = '%s'", name, buff2);
-  }    
-  return 0;
-}
- 
-int owl_variable_set_string(owl_vardict *d, char *name, char *newval) {
-  owl_variable *v;
-  if (!name) return(-1);
-  v = owl_dict_find_element(d, name);
-  if (v == NULL || !v->set_fn) return(-1);
-  if (v->type!=OWL_VARIABLE_STRING) return(-1);
-  return v->set_fn(v, (void*)newval);
-}
- 
-int owl_variable_set_int(owl_vardict *d, char *name, int newval) {
-  owl_variable *v;
-  if (!name) return(-1);
-  v = owl_dict_find_element(d, name);
-  if (v == NULL || !v->set_fn) return(-1);
-  if (v->type!=OWL_VARIABLE_INT && v->type!=OWL_VARIABLE_BOOL) return(-1);
-  return v->set_fn(v, &newval);
-}
- 
-int owl_variable_set_bool_on(owl_vardict *d, char *name) {
-  return owl_variable_set_int(d,name,1);
-}
-
-int owl_variable_set_bool_off(owl_vardict *d, char *name) {
-  return owl_variable_set_int(d,name,0);
-}
-
-int owl_variable_get_tostring(owl_vardict *d, char *name, char *buf, int bufsize) {
-  owl_variable *v;
-  if (!name) return(-1);
-  v = owl_dict_find_element(d, name);
-  if (v == NULL || !v->get_tostring_fn) return(-1);
-  return v->get_tostring_fn(v, buf, bufsize, v->val);
-}
-
-int owl_variable_get_default_tostring(owl_vardict *d, char *name, char *buf, int bufsize) {
-  owl_variable *v;
-  if (!name) return(-1);
-  v = owl_dict_find_element(d, name);
-  if (v == NULL || !v->get_tostring_fn) return(-1);
-  if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
-    return v->get_tostring_fn(v, buf, bufsize, &(v->ival_default));
-  } else {
-    return v->get_tostring_fn(v, buf, bufsize, v->pval_default);
-  }
-}
-
-owl_variable *owl_variable_get_var(owl_vardict *d, char *name, int require_type) {
-  owl_variable *v;
-  if (!name) return(NULL);
-  v = owl_dict_find_element(d, name);
-  if (v == NULL || !v->get_fn || v->type != require_type) return(NULL);
-  return v;
-}
-
-/* returns a reference */
-void *owl_variable_get(owl_vardict *d, char *name, int require_type) {
-  owl_variable *v = owl_variable_get_var(d, name, require_type);
-  if(v == NULL) return NULL;
-  return v->get_fn(v);
-}
-
-/* returns a reference */
-char *owl_variable_get_string(owl_vardict *d, char *name) {
-  return (char*)owl_variable_get(d,name, OWL_VARIABLE_STRING);
-}
-
-/* returns a reference */
-void *owl_variable_get_other(owl_vardict *d, char *name) {
-  return (char*)owl_variable_get(d,name, OWL_VARIABLE_OTHER);
-}
-
-int owl_variable_get_int(owl_vardict *d, char *name) {
-  int *pi;
-  pi = (int*)owl_variable_get(d,name,OWL_VARIABLE_INT);
-  if (!pi) return(-1);
-  return(*pi);
-}
-
-int owl_variable_get_bool(owl_vardict *d, char *name) {
-  int *pi;
-  pi = (int*)owl_variable_get(d,name,OWL_VARIABLE_BOOL);
-  if (!pi) return(-1);
-  return(*pi);
-}
-
-void owl_variable_describe(owl_vardict *d, char *name, owl_fmtext *fm) {
-  char defaultbuf[50];
-  char buf[1024];
-  int buflen = 1023;
-  owl_variable *v;
-
-  if (!name
-      || (v = owl_dict_find_element(d, name)) == NULL 
-      || !v->get_fn) {
-    snprintf(buf, buflen, "     No such variable '%s'\n", name);     
-    owl_fmtext_append_normal(fm, buf);
-    return;
-  }
-  if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
-    v->get_tostring_fn(v, defaultbuf, 50, &(v->ival_default));
-  } else {
-    v->get_tostring_fn(v, defaultbuf, 50, v->pval_default);
-  }
-  snprintf(buf, buflen, OWL_TABSTR "%-20s - %s (default: '%s')\n", 
-		  v->name, 
-		  owl_variable_get_summary(v), defaultbuf);
-  owl_fmtext_append_normal(fm, buf);
-}
-
-void owl_variable_get_help(owl_vardict *d, char *name, owl_fmtext *fm) {
-  char buff[1024];
-  int bufflen = 1023;
-  owl_variable *v;
-
-  if (!name
-      || (v = owl_dict_find_element(d, name)) == NULL 
-      || !v->get_fn) {
-    owl_fmtext_append_normal(fm, "No such variable...\n");
-    return;
-  }
-
-  owl_fmtext_append_bold(fm, "OWL VARIABLE\n\n");
-  owl_fmtext_append_normal(fm, OWL_TABSTR);
-  owl_fmtext_append_normal(fm, name);
-  owl_fmtext_append_normal(fm, " - ");
-  owl_fmtext_append_normal(fm, v->summary);
-  owl_fmtext_append_normal(fm, "\n\n");
-
-  owl_fmtext_append_normal(fm, "Current:        ");
-  owl_variable_get_tostring(d, name, buff, bufflen);
-  owl_fmtext_append_normal(fm, buff);
-  owl_fmtext_append_normal(fm, "\n\n");
-
-
-  if (v->type == OWL_VARIABLE_INT || v->type == OWL_VARIABLE_BOOL) {
-    v->get_tostring_fn(v, buff, bufflen, &(v->ival_default));
-  } else {
-    v->get_tostring_fn(v, buff, bufflen, v->pval_default);
-  }
-  owl_fmtext_append_normal(fm, "Default:        ");
-  owl_fmtext_append_normal(fm, buff);
-  owl_fmtext_append_normal(fm, "\n\n");
-
-  owl_fmtext_append_normal(fm, "Valid Settings: ");
-  owl_fmtext_append_normal(fm, owl_variable_get_validsettings(v));
-  owl_fmtext_append_normal(fm, "\n\n");
-
-  if (v->description && *v->description) {
-    owl_fmtext_append_normal(fm, "Description:\n");
-    owl_fmtext_append_normal(fm, owl_variable_get_description(v));
-    owl_fmtext_append_normal(fm, "\n\n");
-  }
-}
-
-
-
-
-/**************************************************************************/
-/*********************** GENERAL TYPE-SPECIFIC ****************************/
-/**************************************************************************/
-
-/* default common functions */
-
-void *owl_variable_get_default(owl_variable *v) {
-  return v->val;
-}
-
-void owl_variable_free_default(owl_variable *v) {
-  if (v->val) owl_free(v->val);
-}
-
-/* default functions for booleans */
-
-int owl_variable_bool_validate_default(owl_variable *v, void *newval) {
-  if (newval == NULL) return(0);
-  else if (*(int*)newval==1 || *(int*)newval==0) return(1);
-  else return (0);
-}
-
-int owl_variable_bool_set_default(owl_variable *v, void *newval) {
-  if (v->validate_fn) {
-    if (!v->validate_fn(v, newval)) return(-1);
-  }
-  *(int*)v->val = *(int*)newval;
-  return(0);
-}
-
-int owl_variable_bool_set_fromstring_default(owl_variable *v, char *newval) {
-  int i;
-  if (!strcmp(newval, "on")) i=1;
-  else if (!strcmp(newval, "off")) i=0;
-  else return(-1);
-  return (v->set_fn(v, &i));
-}
-
-int owl_variable_bool_get_tostring_default(owl_variable *v, char* buf, int bufsize, void *val) {
-  if (val == NULL) {
-    snprintf(buf, bufsize, "<null>");
-    return -1;
-  } else if (*(int*)val == 0) {
-    snprintf(buf, bufsize, "off");
-    return 0;
-  } else if (*(int*)val == 1) {
-    snprintf(buf, bufsize, "on");
-    return 0;
-  } else {
-    snprintf(buf, bufsize, "<invalid>");
-    return -1;
-  }
-}
-
-/* default functions for integers */
-
-int owl_variable_int_validate_default(owl_variable *v, void *newval) {
-  if (newval == NULL) return(0);
-  else return (1);
-}
-
-int owl_variable_int_set_default(owl_variable *v, void *newval) {
-  if (v->validate_fn) {
-    if (!v->validate_fn(v, newval)) return(-1);
-  }
-  *(int*)v->val = *(int*)newval;
-  return(0);
-}
-
-int owl_variable_int_set_fromstring_default(owl_variable *v, char *newval) {
-  int i;
-  char *ep = "x";
-  i = strtol(newval, &ep, 10);
-  if (*ep || ep==newval) return(-1);
-  return (v->set_fn(v, &i));
-}
-
-int owl_variable_int_get_tostring_default(owl_variable *v, char* buf, int bufsize, void *val) {
-  if (val == NULL) {
-    snprintf(buf, bufsize, "<null>");
-    return -1;
-  } else {
-    snprintf(buf, bufsize, "%d", *(int*)val);
-    return 0;
-  } 
-}
-
-/* default functions for enums (a variant of integers) */
-
-int owl_variable_enum_validate(owl_variable *v, void *newval) {  
-  char **enums;
-  int nenums, val;
-  if (newval == NULL) return(0);
-  enums = atokenize(v->validsettings, ",", &nenums);
-  if (enums == NULL) return(0);
-  atokenize_free(enums, nenums);
-  val = *(int*)newval;
-  if (val < 0 || val >= nenums) {
-    return(0);
-  }
-  return(1);
-}
-
-int owl_variable_enum_set_fromstring(owl_variable *v, char *newval) {
-  char **enums;
-  int nenums, i, val=-1;
-  if (newval == NULL) return(-1);
-  enums = atokenize(v->validsettings, ",", &nenums);
-  if (enums == NULL) return(-1);
-  for (i=0; i<nenums; i++) {
-    if (0==strcmp(newval, enums[i])) {
-      val = i;
-    }
-  }
-  atokenize_free(enums, nenums);
-  if (val == -1) return(-1);
-  return (v->set_fn(v, &val));
-}
-
-int owl_variable_enum_get_tostring(owl_variable *v, char* buf, int bufsize, void *val) {
-  char **enums;
-  int nenums, i;
-
-  if (val == NULL) {
-    snprintf(buf, bufsize, "<null>");
-    return -1;
-  }
-  enums = atokenize(v->validsettings, ",", &nenums);
-  i = *(int*)val;
-  if (i<0 || i>=nenums) {
-    snprintf(buf, bufsize, "<invalid:%d>",i);
-    atokenize_free(enums, nenums);
-    return(-1);
-  }
-  snprintf(buf, bufsize, "%s", enums[i]);
-  return 0;
-}
-
-/* default functions for stringeans */
-
-int owl_variable_string_validate_default(struct _owl_variable *v, void *newval) {
-  if (newval == NULL) return(0);
-  else return (1);
-}
-
-int owl_variable_string_set_default(owl_variable *v, void *newval) {
-  if (v->validate_fn) {
-    if (!v->validate_fn(v, newval)) return(-1);
-  }
-  if (v->val) owl_free(v->val);
-  v->val = owl_strdup(newval);
-  return(0);
-}
-
-int owl_variable_string_set_fromstring_default(owl_variable *v, char *newval) {
-  return (v->set_fn(v, newval));
-}
-
-int owl_variable_string_get_tostring_default(owl_variable *v, char* buf, int bufsize, void *val) {
-  if (val == NULL) {
-    snprintf(buf, bufsize, "<null>");
-    return -1;
-  } else {
-    snprintf(buf, bufsize, "%s", (char*)val);
-    return 0;
-  }
-}
-
-
-
-/**************************************************************************/
-/************************* REGRESSION TESTS *******************************/
-/**************************************************************************/
-
-#ifdef OWL_INCLUDE_REG_TESTS
-
-#include "test.h"
-
-int owl_variable_regtest(void) {
-  owl_vardict vd;
-  int numfailed=0;
-  char buf[1024];
-  owl_variable * v;
-
-  in_regtest = 1;
-
-  printf("# BEGIN testing owl_variable\n");
-  FAIL_UNLESS("setup", 0==owl_variable_dict_setup(&vd));
-
-  FAIL_UNLESS("get bool", 0==owl_variable_get_bool(&vd,"rxping"));
-  FAIL_UNLESS("get bool (no such)", -1==owl_variable_get_bool(&vd,"mumble"));
-  FAIL_UNLESS("get bool as string 1", 0==owl_variable_get_tostring(&vd,"rxping", buf, 1024));
-  FAIL_UNLESS("get bool as string 2", 0==strcmp(buf,"off"));
-  FAIL_UNLESS("set bool 1", 0==owl_variable_set_bool_on(&vd,"rxping"));
-  FAIL_UNLESS("get bool 2", 1==owl_variable_get_bool(&vd,"rxping"));
-  FAIL_UNLESS("set bool 3", 0==owl_variable_set_fromstring(&vd,"rxping","off",0,0));
-  FAIL_UNLESS("get bool 4", 0==owl_variable_get_bool(&vd,"rxping"));
-  FAIL_UNLESS("set bool 5", -1==owl_variable_set_fromstring(&vd,"rxping","xxx",0,0));
-  FAIL_UNLESS("get bool 6", 0==owl_variable_get_bool(&vd,"rxping"));
-
-
-  FAIL_UNLESS("get string", 0==strcmp("~/zlog/people", owl_variable_get_string(&vd,"logpath")));
-  FAIL_UNLESS("set string 7", 0==owl_variable_set_string(&vd,"logpath","whee"));
-  FAIL_UNLESS("get string", 0==strcmp("whee", owl_variable_get_string(&vd,"logpath")));
-
-  FAIL_UNLESS("get int", 8==owl_variable_get_int(&vd,"typewinsize"));
-  FAIL_UNLESS("get int (no such)", -1==owl_variable_get_int(&vd,"mmble"));
-  FAIL_UNLESS("get int as string 1", 0==owl_variable_get_tostring(&vd,"typewinsize", buf, 1024));
-  FAIL_UNLESS("get int as string 2", 0==strcmp(buf,"8"));
-  FAIL_UNLESS("set int 1", 0==owl_variable_set_int(&vd,"typewinsize",12));
-  FAIL_UNLESS("get int 2", 12==owl_variable_get_int(&vd,"typewinsize"));
-  FAIL_UNLESS("set int 1b", -1==owl_variable_set_int(&vd,"typewinsize",-3));
-  FAIL_UNLESS("get int 2b", 12==owl_variable_get_int(&vd,"typewinsize"));
-  FAIL_UNLESS("set int 3", 0==owl_variable_set_fromstring(&vd,"typewinsize","9",0,0));
-  FAIL_UNLESS("get int 4", 9==owl_variable_get_int(&vd,"typewinsize"));
-  FAIL_UNLESS("set int 5", -1==owl_variable_set_fromstring(&vd,"typewinsize","xxx",0,0));
-  FAIL_UNLESS("set int 6", -1==owl_variable_set_fromstring(&vd,"typewinsize","",0,0));
-  FAIL_UNLESS("get int 7", 9==owl_variable_get_int(&vd,"typewinsize"));
-
-  owl_variable_dict_newvar_string(&vd, "stringvar", "", "", "testval");
-  FAIL_UNLESS("get new string var", NULL != (v = owl_variable_get(&vd, "stringvar", OWL_VARIABLE_STRING)));
-  FAIL_UNLESS("get new string val", !strcmp("testval", owl_variable_get_string(&vd, "stringvar")));
-  owl_variable_set_string(&vd, "stringvar", "new val");
-  FAIL_UNLESS("update string val", !strcmp("new val", owl_variable_get_string(&vd, "stringvar")));
-
-  owl_variable_dict_newvar_int(&vd, "intvar", "", "", 47);
-  FAIL_UNLESS("get new int var", NULL != (v = owl_variable_get(&vd, "intvar", OWL_VARIABLE_INT)));
-  FAIL_UNLESS("get new int val", 47 == owl_variable_get_int(&vd, "intvar"));
-  owl_variable_set_int(&vd, "intvar", 17);
-  FAIL_UNLESS("update bool val", 17 == owl_variable_get_int(&vd, "intvar"));
-
-  owl_variable_dict_newvar_bool(&vd, "boolvar", "", "", 1);
-  FAIL_UNLESS("get new bool var", NULL != (v = owl_variable_get(&vd, "boolvar", OWL_VARIABLE_BOOL)));
-  FAIL_UNLESS("get new bool val", owl_variable_get_bool(&vd, "boolvar"));
-  owl_variable_set_bool_off(&vd, "boolvar");
-  FAIL_UNLESS("update string val", !owl_variable_get_bool(&vd, "boolvar"));
-
-  owl_variable_dict_free(&vd);
-
-  /* if (numfailed) printf("*** WARNING: failures encountered with owl_variable\n"); */
-  printf("# END testing owl_variable (%d failures)\n", numfailed);
-  return(numfailed);
-}
-
-
-#endif /* OWL_INCLUDE_REG_TESTS */
Index: ew.c
===================================================================
--- view.c	(revision 801b7ac63b962640debbcfd422cb9a60da5fea31)
+++ 	(revision )
@@ -1,167 +1,0 @@
-#include <stdlib.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-void owl_view_create(owl_view *v, char *name, owl_filter *f, owl_style *s)
-{
-  v->name=owl_strdup(name);
-  v->filter=f;
-  v->style=s;
-  owl_messagelist_create(&(v->ml));
-  owl_view_recalculate(v);
-}
-
-char *owl_view_get_name(owl_view *v)
-{
-  return(v->name);
-}
-
-/* if the message matches the filter then add to view */
-void owl_view_consider_message(owl_view *v, owl_message *m)
-{
-  if (owl_filter_message_match(v->filter, m)) {
-    owl_messagelist_append_element(&(v->ml), m);
-  }
-}
-
-/* remove all messages, add all the global messages that match the
- * filter.
- */
-void owl_view_recalculate(owl_view *v)
-{
-  int i, j;
-  owl_messagelist *gml;
-  owl_messagelist *ml;
-  owl_message *m;
-
-  gml=owl_global_get_msglist(&g);
-  ml=&(v->ml);
-
-  /* nuke the old list */
-  owl_list_free_simple((owl_list *) ml);
-  owl_messagelist_create(&(v->ml));
-
-  /* find all the messages we want */
-  j=owl_messagelist_get_size(gml);
-  for (i=0; i<j; i++) {
-    m=owl_messagelist_get_element(gml, i);
-    if (owl_filter_message_match(v->filter, m)) {
-      owl_messagelist_append_element(ml, m);
-    }
-  }
-}
-
-void owl_view_new_filter(owl_view *v, owl_filter *f)
-{
-  v->filter=f;
-  owl_view_recalculate(v);
-}
-
-void owl_view_set_style(owl_view *v, owl_style *s)
-{
-  v->style=s;
-}
-
-owl_style *owl_view_get_style(owl_view *v)
-{
-  return(v->style);
-}
-
-char *owl_view_get_style_name(owl_view *v) {
-  return(owl_style_get_name(v->style));
-}
-
-owl_message *owl_view_get_element(owl_view *v, int index)
-{
-  return(owl_messagelist_get_element(&(v->ml), index));
-}
-
-void owl_view_delete_element(owl_view *v, int index)
-{
-  owl_messagelist_delete_element(&(v->ml), index);
-}
-
-void owl_view_undelete_element(owl_view *v, int index)
-{
-  owl_messagelist_undelete_element(&(v->ml), index);
-}
-
-int owl_view_get_size(owl_view *v)
-{
-  return(owl_messagelist_get_size(&(v->ml)));
-}
-
-/* Returns the position in the view with a message closest 
- * to the passed msgid. */
-int owl_view_get_nearest_to_msgid(owl_view *v, int targetid)
-{
-  int first, last, mid = 0, max, bestdist, curid = 0;
-
-  first = 0;
-  last = max = owl_view_get_size(v) - 1;
-  while (first <= last) {
-    mid = (first + last) / 2;
-    curid = owl_message_get_id(owl_view_get_element(v, mid));
-    if (curid == targetid) {
-      return(mid);
-    } else if (curid < targetid) {
-      first = mid + 1;
-    } else {
-      last = mid - 1;
-    }
-  }
-  bestdist = abs(targetid-curid);
-  if (curid < targetid && mid+1 < max) {
-    curid = owl_message_get_id(owl_view_get_element(v, mid+1));
-    mid = (bestdist < abs(targetid-curid)) ? mid : mid+1;
-  }
-  else if (curid > targetid && mid-1 >= 0) {
-    curid = owl_message_get_id(owl_view_get_element(v, mid-1));
-    mid = (bestdist < abs(targetid-curid)) ? mid : mid-1;
-  }
-  return mid;
-}
-
-int owl_view_get_nearest_to_saved(owl_view *v)
-{
-  int cachedid;
-
-  cachedid=owl_filter_get_cachedmsgid(v->filter);
-  if (cachedid<0) return(0);
-  return (owl_view_get_nearest_to_msgid(v, cachedid));
-}
-
-/* saves the current message position in the filter so it can 
- * be restored later if we switch back to this filter. */
-void owl_view_save_curmsgid(owl_view *v, int curid)
-{
-  owl_filter_set_cachedmsgid(v->filter, curid);
-}
-
-/* fmtext should already be initialized */
-void owl_view_to_fmtext(owl_view *v, owl_fmtext *fm)
-{
-  owl_fmtext_append_normal(fm, "Name: ");
-  owl_fmtext_append_normal(fm, v->name);
-  owl_fmtext_append_normal(fm, "\n");
-
-  owl_fmtext_append_normal(fm, "Filter: ");
-  owl_fmtext_append_normal(fm, owl_filter_get_name(v->filter));
-  owl_fmtext_append_normal(fm, "\n");
-
-  owl_fmtext_append_normal(fm, "Style: ");
-  owl_fmtext_append_normal(fm, owl_style_get_name(v->style));
-  owl_fmtext_append_normal(fm, "\n");
-}
-
-char *owl_view_get_filtname(owl_view *v)
-{
-  return(owl_filter_get_name(v->filter));
-}
-
-void owl_view_free(owl_view *v)
-{
-  owl_list_free_simple((owl_list *) &(v->ml));
-  if (v->name) owl_free(v->name);
-}
Index: ewwin.c
===================================================================
--- viewwin.c	(revision 47519e1bcab60a6026c4192bf5b20290f37f4737)
+++ 	(revision )
@@ -1,154 +1,0 @@
-#include <string.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-#define BOTTOM_OFFSET 1
-
-/* initialize the viewwin e.  'win' is an already initialzed curses
- * window that will be used by viewwin
- */
-void owl_viewwin_init_text(owl_viewwin *v, WINDOW *win, int winlines, int wincols, char *text)
-{
-  owl_fmtext_init_null(&(v->fmtext));
-  if (text) {
-    owl_fmtext_append_normal(&(v->fmtext), text);
-    if (text[strlen(text)-1]!='\n' && text[0]!='\0') {
-      owl_fmtext_append_normal(&(v->fmtext), "\n");
-    }
-    v->textlines=owl_fmtext_num_lines(&(v->fmtext));
-  }
-  v->topline=0;
-  v->rightshift=0;
-  v->winlines=winlines;
-  v->wincols=wincols;
-  v->curswin=win;
-  v->onclose_hook = NULL;
-}
-
-void owl_viewwin_append_text(owl_viewwin *v, char *text) {
-    owl_fmtext_append_normal(&(v->fmtext), text);
-    v->textlines=owl_fmtext_num_lines(&(v->fmtext));  
-}
-
-/* initialize the viewwin e.  'win' is an already initialzed curses
- * window that will be used by viewwin
- */
-void owl_viewwin_init_fmtext(owl_viewwin *v, WINDOW *win, int winlines, int wincols, owl_fmtext *fmtext)
-{
-  owl_fmtext_copy(&(v->fmtext), fmtext);
-  v->textlines=owl_fmtext_num_lines(&(v->fmtext));
-  v->topline=0;
-  v->rightshift=0;
-  v->winlines=winlines;
-  v->wincols=wincols;
-  v->curswin=win;
-}
-
-void owl_viewwin_set_curswin(owl_viewwin *v, WINDOW *w, int winlines, int wincols)
-{
-  v->curswin=w;
-  v->winlines=winlines;
-  v->wincols=wincols;
-}
-
-void owl_viewwin_set_onclose_hook(owl_viewwin *v, void (*onclose_hook) (owl_viewwin *vwin, void *data), void *onclose_hook_data) {
-  v->onclose_hook = onclose_hook;
-  v->onclose_hook_data = onclose_hook_data;
-}
-
-/* regenerate text on the curses window. */
-/* if update == 1 then do a doupdate() */
-void owl_viewwin_redisplay(owl_viewwin *v, int update)
-{
-  owl_fmtext fm1, fm2;
-  
-  werase(v->curswin);
-  wmove(v->curswin, 0, 0);
-
-  owl_fmtext_init_null(&fm1);
-  owl_fmtext_init_null(&fm2);
-  
-  owl_fmtext_truncate_lines(&(v->fmtext), v->topline, v->winlines-BOTTOM_OFFSET, &fm1);
-  owl_fmtext_truncate_cols(&fm1, v->rightshift, v->wincols-1+v->rightshift, &fm2);
-
-  owl_fmtext_curs_waddstr_without_search(&fm2, v->curswin);
-
-  /* print the message at the bottom */
-  wmove(v->curswin, v->winlines-1, 0);
-  wattrset(v->curswin, A_REVERSE);
-  if (v->textlines - v->topline > v->winlines-BOTTOM_OFFSET) {
-    waddstr(v->curswin, "--More-- (Space to see more, 'q' to quit)");
-  } else {
-    waddstr(v->curswin, "--End-- (Press 'q' to quit)");
-  }
-  wattroff(v->curswin, A_REVERSE);
-  wnoutrefresh(v->curswin);
-
-  if (update==1) {
-    doupdate();
-  }
-
-  owl_fmtext_free(&fm1);
-  owl_fmtext_free(&fm2);
-}
-
-void owl_viewwin_pagedown(owl_viewwin *v)
-{
-  v->topline+=v->winlines - BOTTOM_OFFSET;
-  if ( (v->topline+v->winlines-BOTTOM_OFFSET) > v->textlines) {
-    v->topline = v->textlines - v->winlines + BOTTOM_OFFSET;
-  }
-}
-
-void owl_viewwin_linedown(owl_viewwin *v)
-{
-  v->topline++;
-  if ( (v->topline+v->winlines-BOTTOM_OFFSET) > v->textlines) {
-    v->topline = v->textlines - v->winlines + BOTTOM_OFFSET;
-  }
-}
-
-void owl_viewwin_pageup(owl_viewwin *v)
-{
-  v->topline-=v->winlines;
-  if (v->topline<0) v->topline=0;
-}
-
-void owl_viewwin_lineup(owl_viewwin *v)
-{
-  v->topline--;
-  if (v->topline<0) v->topline=0;
-}
-
-void owl_viewwin_right(owl_viewwin *v, int n)
-{
-  v->rightshift+=n;
-}
-
-void owl_viewwin_left(owl_viewwin *v, int n)
-{
-  v->rightshift-=n;
-  if (v->rightshift<0) v->rightshift=0;
-}
-
-void owl_viewwin_top(owl_viewwin *v)
-{
-  v->topline=0;
-  v->rightshift=0;
-}
-
-void owl_viewwin_bottom(owl_viewwin *v)
-{
-  v->topline = v->textlines - v->winlines + BOTTOM_OFFSET;
-}
-
-void owl_viewwin_free(owl_viewwin *v)
-{
-  if (v->onclose_hook) {
-    v->onclose_hook(v, v->onclose_hook_data);
-    v->onclose_hook = NULL;
-    v->onclose_hook_data = NULL;
-  }
-  owl_fmtext_free(&(v->fmtext));
-}
Index: width.c
===================================================================
--- wcwidth.c	(revision 44fc93be20484f09d5265df4bb55456979efd531)
+++ 	(revision )
@@ -1,309 +1,0 @@
-/*
- * This is an implementation of wcwidth() and wcswidth() (defined in
- * IEEE Std 1002.1-2001) for Unicode.
- *
- * http://www.opengroup.org/onlinepubs/007904975/functions/wcwidth.html
- * http://www.opengroup.org/onlinepubs/007904975/functions/wcswidth.html
- *
- * In fixed-width output devices, Latin characters all occupy a single
- * "cell" position of equal width, whereas ideographic CJK characters
- * occupy two such cells. Interoperability between terminal-line
- * applications and (teletype-style) character terminals using the
- * UTF-8 encoding requires agreement on which character should advance
- * the cursor by how many cell positions. No established formal
- * standards exist at present on which Unicode character shall occupy
- * how many cell positions on character terminals. These routines are
- * a first attempt of defining such behavior based on simple rules
- * applied to data provided by the Unicode Consortium.
- *
- * For some graphical characters, the Unicode standard explicitly
- * defines a character-cell width via the definition of the East Asian
- * FullWidth (F), Wide (W), Half-width (H), and Narrow (Na) classes.
- * In all these cases, there is no ambiguity about which width a
- * terminal shall use. For characters in the East Asian Ambiguous (A)
- * class, the width choice depends purely on a preference of backward
- * compatibility with either historic CJK or Western practice.
- * Choosing single-width for these characters is easy to justify as
- * the appropriate long-term solution, as the CJK practice of
- * displaying these characters as double-width comes from historic
- * implementation simplicity (8-bit encoded characters were displayed
- * single-width and 16-bit ones double-width, even for Greek,
- * Cyrillic, etc.) and not any typographic considerations.
- *
- * Much less clear is the choice of width for the Not East Asian
- * (Neutral) class. Existing practice does not dictate a width for any
- * of these characters. It would nevertheless make sense
- * typographically to allocate two character cells to characters such
- * as for instance EM SPACE or VOLUME INTEGRAL, which cannot be
- * represented adequately with a single-width glyph. The following
- * routines at present merely assign a single-cell width to all
- * neutral characters, in the interest of simplicity. This is not
- * entirely satisfactory and should be reconsidered before
- * establishing a formal standard in this area. At the moment, the
- * decision which Not East Asian (Neutral) characters should be
- * represented by double-width glyphs cannot yet be answered by
- * applying a simple rule from the Unicode database content. Setting
- * up a proper standard for the behavior of UTF-8 character terminals
- * will require a careful analysis not only of each Unicode character,
- * but also of each presentation form, something the author of these
- * routines has avoided to do so far.
- *
- * http://www.unicode.org/unicode/reports/tr11/
- *
- * Markus Kuhn -- 2007-05-26 (Unicode 5.0)
- *
- * Permission to use, copy, modify, and distribute this software
- * for any purpose and without fee is hereby granted. The author
- * disclaims all warranties with regard to this software.
- *
- * Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
- */
-
-#include <wchar.h>
-
-struct interval {               /* noproto */
-  int first;
-  int last;
-};
-
-/* auxiliary function for binary search in interval table */
-static int bisearch(wchar_t ucs, const struct interval *table, int max) {
-  int min = 0;
-  int mid;
-
-  if (ucs < table[0].first || ucs > table[max].last)
-    return 0;
-  while (max >= min) {
-    mid = (min + max) / 2;
-    if (ucs > table[mid].last)
-      min = mid + 1;
-    else if (ucs < table[mid].first)
-      max = mid - 1;
-    else
-      return 1;
-  }
-
-  return 0;
-}
-
-
-/* The following two functions define the column width of an ISO 10646
- * character as follows:
- *
- *    - The null character (U+0000) has a column width of 0.
- *
- *    - Other C0/C1 control characters and DEL will lead to a return
- *      value of -1.
- *
- *    - Non-spacing and enclosing combining characters (general
- *      category code Mn or Me in the Unicode database) have a
- *      column width of 0.
- *
- *    - SOFT HYPHEN (U+00AD) has a column width of 1.
- *
- *    - Other format characters (general category code Cf in the Unicode
- *      database) and ZERO WIDTH SPACE (U+200B) have a column width of 0.
- *
- *    - Hangul Jamo medial vowels and final consonants (U+1160-U+11FF)
- *      have a column width of 0.
- *
- *    - Spacing characters in the East Asian Wide (W) or East Asian
- *      Full-width (F) category as defined in Unicode Technical
- *      Report #11 have a column width of 2.
- *
- *    - All remaining characters (including all printable
- *      ISO 8859-1 and WGL4 characters, Unicode control characters,
- *      etc.) have a column width of 1.
- *
- * This implementation assumes that wchar_t characters are encoded
- * in ISO 10646.
- */
-
-int mk_wcwidth(wchar_t ucs)
-{
-  /* sorted list of non-overlapping intervals of non-spacing characters */
-  /* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
-  static const struct interval combining[] = {
-    { 0x0300, 0x036F }, { 0x0483, 0x0486 }, { 0x0488, 0x0489 },
-    { 0x0591, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
-    { 0x05C4, 0x05C5 }, { 0x05C7, 0x05C7 }, { 0x0600, 0x0603 },
-    { 0x0610, 0x0615 }, { 0x064B, 0x065E }, { 0x0670, 0x0670 },
-    { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
-    { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
-    { 0x07A6, 0x07B0 }, { 0x07EB, 0x07F3 }, { 0x0901, 0x0902 },
-    { 0x093C, 0x093C }, { 0x0941, 0x0948 }, { 0x094D, 0x094D },
-    { 0x0951, 0x0954 }, { 0x0962, 0x0963 }, { 0x0981, 0x0981 },
-    { 0x09BC, 0x09BC }, { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD },
-    { 0x09E2, 0x09E3 }, { 0x0A01, 0x0A02 }, { 0x0A3C, 0x0A3C },
-    { 0x0A41, 0x0A42 }, { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D },
-    { 0x0A70, 0x0A71 }, { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC },
-    { 0x0AC1, 0x0AC5 }, { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD },
-    { 0x0AE2, 0x0AE3 }, { 0x0B01, 0x0B01 }, { 0x0B3C, 0x0B3C },
-    { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 }, { 0x0B4D, 0x0B4D },
-    { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 }, { 0x0BC0, 0x0BC0 },
-    { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 }, { 0x0C46, 0x0C48 },
-    { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 }, { 0x0CBC, 0x0CBC },
-    { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
-    { 0x0CE2, 0x0CE3 }, { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D },
-    { 0x0DCA, 0x0DCA }, { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 },
-    { 0x0E31, 0x0E31 }, { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E },
-    { 0x0EB1, 0x0EB1 }, { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC },
-    { 0x0EC8, 0x0ECD }, { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 },
-    { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E },
-    { 0x0F80, 0x0F84 }, { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 },
-    { 0x0F99, 0x0FBC }, { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 },
-    { 0x1032, 0x1032 }, { 0x1036, 0x1037 }, { 0x1039, 0x1039 },
-    { 0x1058, 0x1059 }, { 0x1160, 0x11FF }, { 0x135F, 0x135F },
-    { 0x1712, 0x1714 }, { 0x1732, 0x1734 }, { 0x1752, 0x1753 },
-    { 0x1772, 0x1773 }, { 0x17B4, 0x17B5 }, { 0x17B7, 0x17BD },
-    { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x17DD, 0x17DD },
-    { 0x180B, 0x180D }, { 0x18A9, 0x18A9 }, { 0x1920, 0x1922 },
-    { 0x1927, 0x1928 }, { 0x1932, 0x1932 }, { 0x1939, 0x193B },
-    { 0x1A17, 0x1A18 }, { 0x1B00, 0x1B03 }, { 0x1B34, 0x1B34 },
-    { 0x1B36, 0x1B3A }, { 0x1B3C, 0x1B3C }, { 0x1B42, 0x1B42 },
-    { 0x1B6B, 0x1B73 }, { 0x1DC0, 0x1DCA }, { 0x1DFE, 0x1DFF },
-    { 0x200B, 0x200F }, { 0x202A, 0x202E }, { 0x2060, 0x2063 },
-    { 0x206A, 0x206F }, { 0x20D0, 0x20EF }, { 0x302A, 0x302F },
-    { 0x3099, 0x309A }, { 0xA806, 0xA806 }, { 0xA80B, 0xA80B },
-    { 0xA825, 0xA826 }, { 0xFB1E, 0xFB1E }, { 0xFE00, 0xFE0F },
-    { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF }, { 0xFFF9, 0xFFFB },
-    { 0x10A01, 0x10A03 }, { 0x10A05, 0x10A06 }, { 0x10A0C, 0x10A0F },
-    { 0x10A38, 0x10A3A }, { 0x10A3F, 0x10A3F }, { 0x1D167, 0x1D169 },
-    { 0x1D173, 0x1D182 }, { 0x1D185, 0x1D18B }, { 0x1D1AA, 0x1D1AD },
-    { 0x1D242, 0x1D244 }, { 0xE0001, 0xE0001 }, { 0xE0020, 0xE007F },
-    { 0xE0100, 0xE01EF }
-  };
-
-  /* test for 8-bit control characters */
-  if (ucs == 0)
-    return 0;
-  if (ucs < 32 || (ucs >= 0x7f && ucs < 0xa0))
-    return -1;
-
-  /* binary search in table of non-spacing characters */
-  if (bisearch(ucs, combining,
-	       sizeof(combining) / sizeof(struct interval) - 1))
-    return 0;
-
-  /* if we arrive here, ucs is not a combining or C0/C1 control character */
-
-  return 1 + 
-    (ucs >= 0x1100 &&
-     (ucs <= 0x115f ||                    /* Hangul Jamo init. consonants */
-      ucs == 0x2329 || ucs == 0x232a ||
-      (ucs >= 0x2e80 && ucs <= 0xa4cf &&
-       ucs != 0x303f) ||                  /* CJK ... Yi */
-      (ucs >= 0xac00 && ucs <= 0xd7a3) || /* Hangul Syllables */
-      (ucs >= 0xf900 && ucs <= 0xfaff) || /* CJK Compatibility Ideographs */
-      (ucs >= 0xfe10 && ucs <= 0xfe19) || /* Vertical forms */
-      (ucs >= 0xfe30 && ucs <= 0xfe6f) || /* CJK Compatibility Forms */
-      (ucs >= 0xff00 && ucs <= 0xff60) || /* Fullwidth Forms */
-      (ucs >= 0xffe0 && ucs <= 0xffe6) ||
-      (ucs >= 0x20000 && ucs <= 0x2fffd) ||
-      (ucs >= 0x30000 && ucs <= 0x3fffd)));
-}
-
-
-int mk_wcswidth(const wchar_t *pwcs, size_t n)
-{
-  int w, width = 0;
-
-  for (;*pwcs && n-- > 0; pwcs++)
-    if ((w = mk_wcwidth(*pwcs)) < 0)
-      return -1;
-    else
-      width += w;
-
-  return width;
-}
-
-
-/*
- * The following functions are the same as mk_wcwidth() and
- * mk_wcswidth(), except that spacing characters in the East Asian
- * Ambiguous (A) category as defined in Unicode Technical Report #11
- * have a column width of 2. This variant might be useful for users of
- * CJK legacy encodings who want to migrate to UCS without changing
- * the traditional terminal character-width behaviour. It is not
- * otherwise recommended for general use.
- */
-int mk_wcwidth_cjk(wchar_t ucs)
-{
-  /* sorted list of non-overlapping intervals of East Asian Ambiguous
-   * characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
-  static const struct interval ambiguous[] = {
-    { 0x00A1, 0x00A1 }, { 0x00A4, 0x00A4 }, { 0x00A7, 0x00A8 },
-    { 0x00AA, 0x00AA }, { 0x00AE, 0x00AE }, { 0x00B0, 0x00B4 },
-    { 0x00B6, 0x00BA }, { 0x00BC, 0x00BF }, { 0x00C6, 0x00C6 },
-    { 0x00D0, 0x00D0 }, { 0x00D7, 0x00D8 }, { 0x00DE, 0x00E1 },
-    { 0x00E6, 0x00E6 }, { 0x00E8, 0x00EA }, { 0x00EC, 0x00ED },
-    { 0x00F0, 0x00F0 }, { 0x00F2, 0x00F3 }, { 0x00F7, 0x00FA },
-    { 0x00FC, 0x00FC }, { 0x00FE, 0x00FE }, { 0x0101, 0x0101 },
-    { 0x0111, 0x0111 }, { 0x0113, 0x0113 }, { 0x011B, 0x011B },
-    { 0x0126, 0x0127 }, { 0x012B, 0x012B }, { 0x0131, 0x0133 },
-    { 0x0138, 0x0138 }, { 0x013F, 0x0142 }, { 0x0144, 0x0144 },
-    { 0x0148, 0x014B }, { 0x014D, 0x014D }, { 0x0152, 0x0153 },
-    { 0x0166, 0x0167 }, { 0x016B, 0x016B }, { 0x01CE, 0x01CE },
-    { 0x01D0, 0x01D0 }, { 0x01D2, 0x01D2 }, { 0x01D4, 0x01D4 },
-    { 0x01D6, 0x01D6 }, { 0x01D8, 0x01D8 }, { 0x01DA, 0x01DA },
-    { 0x01DC, 0x01DC }, { 0x0251, 0x0251 }, { 0x0261, 0x0261 },
-    { 0x02C4, 0x02C4 }, { 0x02C7, 0x02C7 }, { 0x02C9, 0x02CB },
-    { 0x02CD, 0x02CD }, { 0x02D0, 0x02D0 }, { 0x02D8, 0x02DB },
-    { 0x02DD, 0x02DD }, { 0x02DF, 0x02DF }, { 0x0391, 0x03A1 },
-    { 0x03A3, 0x03A9 }, { 0x03B1, 0x03C1 }, { 0x03C3, 0x03C9 },
-    { 0x0401, 0x0401 }, { 0x0410, 0x044F }, { 0x0451, 0x0451 },
-    { 0x2010, 0x2010 }, { 0x2013, 0x2016 }, { 0x2018, 0x2019 },
-    { 0x201C, 0x201D }, { 0x2020, 0x2022 }, { 0x2024, 0x2027 },
-    { 0x2030, 0x2030 }, { 0x2032, 0x2033 }, { 0x2035, 0x2035 },
-    { 0x203B, 0x203B }, { 0x203E, 0x203E }, { 0x2074, 0x2074 },
-    { 0x207F, 0x207F }, { 0x2081, 0x2084 }, { 0x20AC, 0x20AC },
-    { 0x2103, 0x2103 }, { 0x2105, 0x2105 }, { 0x2109, 0x2109 },
-    { 0x2113, 0x2113 }, { 0x2116, 0x2116 }, { 0x2121, 0x2122 },
-    { 0x2126, 0x2126 }, { 0x212B, 0x212B }, { 0x2153, 0x2154 },
-    { 0x215B, 0x215E }, { 0x2160, 0x216B }, { 0x2170, 0x2179 },
-    { 0x2190, 0x2199 }, { 0x21B8, 0x21B9 }, { 0x21D2, 0x21D2 },
-    { 0x21D4, 0x21D4 }, { 0x21E7, 0x21E7 }, { 0x2200, 0x2200 },
-    { 0x2202, 0x2203 }, { 0x2207, 0x2208 }, { 0x220B, 0x220B },
-    { 0x220F, 0x220F }, { 0x2211, 0x2211 }, { 0x2215, 0x2215 },
-    { 0x221A, 0x221A }, { 0x221D, 0x2220 }, { 0x2223, 0x2223 },
-    { 0x2225, 0x2225 }, { 0x2227, 0x222C }, { 0x222E, 0x222E },
-    { 0x2234, 0x2237 }, { 0x223C, 0x223D }, { 0x2248, 0x2248 },
-    { 0x224C, 0x224C }, { 0x2252, 0x2252 }, { 0x2260, 0x2261 },
-    { 0x2264, 0x2267 }, { 0x226A, 0x226B }, { 0x226E, 0x226F },
-    { 0x2282, 0x2283 }, { 0x2286, 0x2287 }, { 0x2295, 0x2295 },
-    { 0x2299, 0x2299 }, { 0x22A5, 0x22A5 }, { 0x22BF, 0x22BF },
-    { 0x2312, 0x2312 }, { 0x2460, 0x24E9 }, { 0x24EB, 0x254B },
-    { 0x2550, 0x2573 }, { 0x2580, 0x258F }, { 0x2592, 0x2595 },
-    { 0x25A0, 0x25A1 }, { 0x25A3, 0x25A9 }, { 0x25B2, 0x25B3 },
-    { 0x25B6, 0x25B7 }, { 0x25BC, 0x25BD }, { 0x25C0, 0x25C1 },
-    { 0x25C6, 0x25C8 }, { 0x25CB, 0x25CB }, { 0x25CE, 0x25D1 },
-    { 0x25E2, 0x25E5 }, { 0x25EF, 0x25EF }, { 0x2605, 0x2606 },
-    { 0x2609, 0x2609 }, { 0x260E, 0x260F }, { 0x2614, 0x2615 },
-    { 0x261C, 0x261C }, { 0x261E, 0x261E }, { 0x2640, 0x2640 },
-    { 0x2642, 0x2642 }, { 0x2660, 0x2661 }, { 0x2663, 0x2665 },
-    { 0x2667, 0x266A }, { 0x266C, 0x266D }, { 0x266F, 0x266F },
-    { 0x273D, 0x273D }, { 0x2776, 0x277F }, { 0xE000, 0xF8FF },
-    { 0xFFFD, 0xFFFD }, { 0xF0000, 0xFFFFD }, { 0x100000, 0x10FFFD }
-  };
-
-  /* binary search in table of non-spacing characters */
-  if (bisearch(ucs, ambiguous,
-	       sizeof(ambiguous) / sizeof(struct interval) - 1))
-    return 2;
-
-  return mk_wcwidth(ucs);
-}
-
-
-int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
-{
-  int w, width = 0;
-
-  for (;*pwcs && n-- > 0; pwcs++)
-    if ((w = mk_wcwidth_cjk(*pwcs)) < 0)
-      return -1;
-    else
-      width += w;
-
-  return width;
-}
Index: uddylist.c
===================================================================
--- zbuddylist.c	(revision dad943e01ddd0ff6a745465ef3035548b1e43c9b)
+++ 	(revision )
@@ -1,65 +1,0 @@
-#include "owl.h"
-
-static const char fileIdent[] = "$Id";
-
-void owl_zbuddylist_create(owl_zbuddylist *zb)
-{
-  owl_list_create(&(zb->zusers));
-}
-
-int owl_zbuddylist_adduser(owl_zbuddylist *zb, char *name)
-{
-  int i, j;
-  char *user;
-
-  user=long_zuser(name);
-
-  j=owl_list_get_size(&(zb->zusers));
-  for (i=0; i<j; i++) {
-    if (!strcasecmp(user, owl_list_get_element(&(zb->zusers), i))) {
-      owl_free(user);
-      return(-1);
-    }
-  }
-  owl_list_append_element(&(zb->zusers), user);
-  return(0);
-}
-
-int owl_zbuddylist_deluser(owl_zbuddylist *zb, char *name)
-{
-  int i, j;
-  char *user, *ptr;
-
-  user=long_zuser(name);
-
-  j=owl_list_get_size(&(zb->zusers));
-  for (i=0; i<j; i++) {
-    ptr=owl_list_get_element(&(zb->zusers), i);
-    if (!strcasecmp(user, ptr)) {
-      owl_list_remove_element(&(zb->zusers), i);
-      owl_free(ptr);
-      owl_free(user);
-      return(0);
-    }
-  }
-  owl_free(user);
-  return(-1);
-}
-
-int owl_zbuddylist_contains_user(owl_zbuddylist *zb, char *name)
-{
-  int i, j;
-  char *user;
-
-  user=long_zuser(name);
-
-  j=owl_list_get_size(&(zb->zusers));
-  for (i=0; i<j; i++) {
-    if (!strcasecmp(user, owl_list_get_element(&(zb->zusers), i))) {
-      owl_free(user);
-      return(1);
-    }
-  }
-  owl_free(user);
-  return(0);
-}
Index: rypt.c
===================================================================
--- zcrypt.c	(revision 5547211b2a49e2fe6b405d8b72af6474b2a7b1a6)
+++ 	(revision )
@@ -1,760 +1,0 @@
-/* This file is stolen and slightly modified code */
-
-/* zcrypt.c -- Read in a data stream from stdin & dump a decrypted/encrypted *
- *   datastream.  Reads the string to make the key from from the first       *
- *   parameter.  Encrypts or decrypts according to -d or -e flag.  (-e is    *
- *   default.)  Will invoke zwrite if the -c option is provided for          *
- *   encryption.  If a zephyr class is specified & the keyfile name omitted  *
- *   the ~/.crypt-table will be checked for "crypt-classname" and then       *
- *   "crypt-default" for the keyfile name.                                   */
-
-static const char fileIdent[] = "$Id$";
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include "owl.h"
-
-#ifdef OWL_ENABLE_ZCRYPT
-
-#define BASE_CODE 70
-#define LAST_CODE (BASE_CODE + 15)
-#define OUTPUT_BLOCK_SIZE 16
-#include <unistd.h>
-#include <sys/types.h>
-#include <des.h>
-
-#define MAX_KEY 128
-
-#ifndef TRUE
-#define TRUE -1
-#endif
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#define ZWRITE_OPT_NOAUTH     (1<<0)
-#define ZWRITE_OPT_SIGNATURE  (1<<1)
-#define ZWRITE_OPT_IGNOREVARS (1<<2)
-#define ZWRITE_OPT_VERBOSE    (1<<3)
-#define ZWRITE_OPT_QUIET      (1<<4)
-#define ZCRYPT_OPT_MESSAGE    (1<<5)
-#define ZCRYPT_OPT_IGNOREDOT  (1<<6)
-
-typedef struct
-{
-  int flags;
-  char *signature;
-  char *message;
-} ZWRITEOPTIONS;
-
-char *GetZephyrVarKeyFile(char *whoami, char *class, char *instance);
-char *BuildArgString(char **argv, int start, int end);
-static int do_encrypt(char *keystring, int zephyr, char *class, char *instance, ZWRITEOPTIONS *zoptions, char* keyfile);
-int do_decrypt(char *keystring);
-
-#ifndef HAVE_DES_ECB_ENCRYPT_PROTO
-int des_ecb_encrypt(char [], char [], des_key_schedule, int);
-#endif
-
-#define M_NONE            0
-#define M_ZEPHYR_ENCRYPT  1
-#define M_DECRYPT         2
-#define M_ENCRYPT         3
-#define M_RANDOMIZE       4
-#define M_SETKEY          5
-
-int zcrypt(int argc, char *argv[]) {
-  char *fname = NULL;
-  int error = FALSE;
-  int zephyr = FALSE;
-  char *class = NULL, *instance = NULL;
-  int mode = M_NONE;
-
-  extern int optind, opterr;
-  extern char *optarg;
-  char c;
-
-  int messageflag = FALSE;
-  ZWRITEOPTIONS zoptions;
-  zoptions.flags = 0;
-
-  while ((c = getopt(argc, argv, "ZDERSF:c:i:advqtluons:f:m")) != (char)EOF) {
-    switch(c) {
-      case 'Z':
-        /* Zephyr encrypt */
-        mode = M_ZEPHYR_ENCRYPT;
-	break;
-      case 'D':
-        /* Decrypt */
-	mode = M_DECRYPT;
-	break;
-      case 'E':
-	/* Encrypt */
-	mode = M_ENCRYPT;
-	break;
-      case 'R':
-	/* Randomize the keyfile */
-	mode = M_RANDOMIZE;
-	break;
-      case 'S':
-	/* Set a new key value from stdin */
-	mode = M_SETKEY;
-	break;
-      case 'F':
-	/* Specify the keyfile explicitly */
-	if (fname != NULL) error = TRUE;
-	fname = optarg;
-	break;
-      case 'c':
-	/* Zwrite/zcrypt: class name */
-	if (class != NULL) error = TRUE;
-	class = optarg;
-	break;
-      case 'i':
-	/* Zwrite/zcrypt: instance name */
-	if (instance != NULL) error = TRUE;
-	instance = optarg;
-	break;
-      case 'a':
-	/* Zwrite: authenticate (default) */
-	zoptions.flags &= ~ZWRITE_OPT_NOAUTH;
-	break;
-      case 'd':
-	/* Zwrite: do not authenticate */
-	zoptions.flags |= ZWRITE_OPT_NOAUTH;
-	break;
-      case 'v':
-	/* Zwrite: verbose */
-	zoptions.flags |= ZWRITE_OPT_VERBOSE;
-	break;
-      case 'q':
-	/* Zwrite: quiet */
-	zoptions.flags |= ZWRITE_OPT_QUIET;
-	break;
-      case 't':
-	/* Zwrite: no expand tabs (ignored) */
-	break;
-      case 'l':
-	/* Zwrite: ignore '.' on a line by itself (ignored) */
-	zoptions.flags |= ZCRYPT_OPT_IGNOREDOT;
-	break;
-      case 'u':
-	/* Zwrite: urgent message */
-	instance = "URGENT";
-	break;
-      case 'o':
-	/* Zwrite: ignore zephyr variables zwrite-class, zwrite-inst, */
-	/*         zwrite-opcode */
-	zoptions.flags |= ZWRITE_OPT_IGNOREVARS;
-	break;
-      case 'n':
-	/* Zwrite: prevent PING message (always used) */
-	break;
-      case 's':
-	/* Zwrite: signature */
-	zoptions.flags |= ZWRITE_OPT_SIGNATURE;
-	zoptions.signature = optarg;
-	break;
-      case 'f':
-	/* Zwrite: file system specification (ignored) */
-	break;
-      case 'm':
-	/* Message on rest of line */
-	messageflag = TRUE;
-	break;
-      case '?':
-	error = TRUE;
-	break;
-    }
-    if (error || messageflag) break;
-  }
-
-  if (class != NULL || instance != NULL) {
-    zephyr = TRUE;
-  }
-
-  if (messageflag) {
-    zoptions.flags |= ZCRYPT_OPT_MESSAGE;
-    zoptions.message = BuildArgString(argv, optind, argc);
-    if (!zoptions.message)
-    {
-      printf("Memory allocation error.\n");
-      error = TRUE;
-    }
-  } else if (optind < argc) {
-    error = TRUE;
-  }
-
-  if (mode == M_NONE) mode = (zephyr?M_ZEPHYR_ENCRYPT:M_ENCRYPT);
-
-  if (mode == M_ZEPHYR_ENCRYPT && !zephyr) error = TRUE;
-
-  if (!error && fname == NULL && (class != NULL || instance != NULL)) {
-    fname = GetZephyrVarKeyFile(argv[0], class, instance);
-  }
-
-  
-  if (error || fname == NULL) {
-    printf("Usage: %s [-Z|-D|-E|-R|-S] [-F Keyfile] [-c class] [-i instance]\n", argv[0]);
-    printf("       [-advqtluon] [-s signature] [-f arg] [-m message]\n");
-    printf("  One or more of class, instance, and keyfile must be specified.\n");
-  } else {
-    if (mode == M_RANDOMIZE) {
-      /* Choose a new, random key */
-/*
-      FILE *fkey = fopen(fname, "w");
-      if (!fkey)
-	printf("Could not open key file for writing: %s\n", fname);
-      else
-      {
-	char string[100];
-	fputs(fkey, string);
-	fclose(fkey);
-	}
- */
-      printf("Feature not yet implemented.\n");
-    } else if (mode == M_SETKEY) {
-      /* Set a new, user-entered key */
-      char newkey[MAX_KEY];
-      FILE *fkey;
-      
-      if (isatty(0)) {
-	printf("Enter new key: ");
-	/* Really should read without echo!!! */
-	fgets(newkey, MAX_KEY - 1, stdin);
-      } else {
-	fgets(newkey, MAX_KEY - 1, stdin);
-      }
-
-      fkey = fopen(fname, "w");
-      if (!fkey) {
-	printf("Could not open key file for writing: %s\n", fname);
-      } else {
-	if (fputs(newkey, fkey) != strlen(newkey) || putc('\n', fkey) != '\n') {
-	  printf("Error writing to key file.\n");
-	  fclose(fkey);
-	} else {
-	  fclose(fkey);
-	  printf("Key update complete.\n");
-	}
-      }
-    } else {
-      /* Encrypt/decrypt */
-      FILE *fkey = fopen(fname, "r");
-      if (!fkey) {
-	printf("Could not open key file: %s\n", fname);
-      } else {
-	char keystring[MAX_KEY];
-	fgets(keystring, MAX_KEY-1, fkey);
-	if (mode == M_ZEPHYR_ENCRYPT || mode == M_ENCRYPT) {
-	  do_encrypt(keystring, (mode == M_ZEPHYR_ENCRYPT), class, instance,
-		     &zoptions, fname);
-	} else {
-	  do_decrypt(keystring);
-	}
-	fclose(fkey);
-      }
-    }
-  }
-
-  /* Always print the **END** message if -D is specified. */
-  if (mode == M_DECRYPT) printf("**END**\n");
-
-  exit(0);
-}
-
-/* The 'owl_zcrypt_decrypt' function was written by kretch for Owl.
- * Decrypt the message in 'in' on class 'class' and instance
- * 'instance' and leave the result in 'out'.  Out must be a buffer
- * allocated by the caller.
- *
- * return 0 on success, otherwise -1
- */
-int owl_zcrypt_decrypt(char *out, char *in, char *class, char *instance) {
-  char *fname, keystring[MAX_KEY], *inptr, *endptr;
-  FILE *fkey;
-  des_cblock key;
-  des_key_schedule schedule;
-  char input[8], output[9];
-  int i, c1, c2;
-  
-  fname=GetZephyrVarKeyFile("zcrypt", class, instance);
-  if (!fname) return(-1);
-  fkey=fopen(fname, "r");
-  if (!fkey) return(-1);
-  fgets(keystring, MAX_KEY-1, fkey);
-  fclose(fkey);
-
-  strcpy(out, "");
-
-  output[0] = '\0';    /* In case no message at all                 */
-  output[8] = '\0';    /* NULL at end will limit string length to 8 */
-
-  des_string_to_key(keystring, key);
-  des_key_sched(key, schedule);
-
-  inptr=in;
-  endptr=in+strlen(in)-1;
-  while (inptr<endptr) {
-    for (i=0; i<8; i++) {
-      c1=(inptr[0])-BASE_CODE;
-      c2=(inptr[1])-BASE_CODE;
-      input[i]=c1 * 0x10 + c2;
-      inptr+=2;
-    }
-    des_ecb_encrypt(input, output, schedule, FALSE);
-    strcat(out, output);
-  }
-
-  if (output[0]) {
-    if (output[strlen(output)-1] != '\n') {
-      strcat(out, "\n");
-    }
-  } else {
-    strcat(out, "\n");
-  }
-  return(0);
-}
-
-int owl_zcrypt_encrypt(char *out, char *in, char *class, char *instance) {
-  /*  static int do_encrypt(char *keystring, int zephyr, char *class, char *instance, ZWRITEOPTIONS *zoptions, char* keyfile) { */
-  char *fname, keystring[MAX_KEY];
-  FILE *fkey;
-  des_cblock key;
-  des_key_schedule schedule;
-  char input[8], output[8];
-  int size, length, i;
-  char *inbuff = NULL, *inptr;
-  int use_buffer = FALSE;
-  int num_blocks=0, last_block_size=0;
-
-  fname=GetZephyrVarKeyFile("zcrypt", class, instance);
-  if (!fname) return(-1);
-  fkey=fopen(fname, "r");
-  if (!fkey) return(-1);
-  fgets(keystring, MAX_KEY-1, fkey);
-  fclose(fkey);
-
-  des_string_to_key(keystring, key);
-  des_key_sched(key, schedule);
-
-  inbuff=in;
-  length=strlen(inbuff);
-  num_blocks=(length+7)/8;
-  last_block_size=((length+7)%8)+1;
-  use_buffer=TRUE;
-
-  strcpy(out, "");
-  
-  inptr=inbuff;
-  while (TRUE) {
-    /* Get 8 bytes from buffer */
-    if (num_blocks > 1) {
-      size = 8;
-      memcpy(input, inptr, size);
-      inptr+=8;
-      num_blocks--;
-    } else if (num_blocks == 1) {
-      size=last_block_size;
-      memcpy(input, inptr, size);
-      num_blocks--;
-    } else {
-      size=0;
-    }
-
-    /* Check for EOF and pad the string to 8 chars, if needed */
-    if (size == 0) break;     /* END OF INPUT: BREAK FROM while LOOP! */
-      
-    if (size<8) memset(input + size, 0, 8 - size);
-
-    /* Encrypt and output the block */
-    des_ecb_encrypt(input, output, schedule, TRUE);
-
-    for (i = 0; i < 8; i++) {
-      sprintf(out + strlen(out), "%c", ((output[i] & 0xf0) >> 4) + BASE_CODE);
-      sprintf(out + strlen(out), "%c", (output[i] & 0x0f)        + BASE_CODE);
-    }
-
-    if (size < 8) break;
-  }
-  return(0);
-}
-
-/* Build a space-separated string from argv from elements between start  *
- * and end - 1.  owl_malloc()'s the returned string. */
-char *BuildArgString(char **argv, int start, int end) {
-  int len = 1;
-  int i;
-  char *result;
-
-  /* Compute the length of the string.  (Plus 1 or 2) */
-  for (i = start; i < end; i++) {
-    len += strlen(argv[i]) + 1;
-  }
-
-  /* Allocate memory */
-  result = (char *)owl_malloc(len);
-  if (result) {
-    /* Build the string */
-    char *ptr = result;
-    /* Start with an empty string, in case nothing is copied. */
-    *ptr = '\0';
-    /* Copy the arguments */
-    for (i = start; i < end; i++) {
-      char *temp = argv[i];
-      /* Add a space, if not the first argument */
-      if (i != start) *ptr++ = ' ';
-      /* Copy argv[i], leaving ptr pointing to the '\0' copied from temp */
-      while ((*ptr = *temp++)!=0) {
-	ptr++;
-      }
-    }
-  }
-
-  return(result);
-}
-
-#define MAX_BUFF 258
-#define MAX_SEARCH 3
-/* Find the class/instance in the .crypt-table */
-char *GetZephyrVarKeyFile(char *whoami, char *class, char *instance) {
-  char *keyfile = NULL;
-  char varname[MAX_SEARCH][128];
-  int length[MAX_SEARCH], i;
-  char buffer[MAX_BUFF];
-  char filename[MAX_BUFF];
-  char result[MAX_SEARCH][MAX_BUFF];
-  int numsearch = 0;
-  FILE *fsearch;
-
-  /* Determine names to look for in .crypt-table */
-  if (instance) {
-    sprintf(varname[numsearch++], "crypt-%s-%s:", (class?class:"message"), instance);
-  }
-  if (class) {
-    sprintf(varname[numsearch++], "crypt-%s:", class);
-  }
-  sprintf(varname[numsearch++], "crypt-default:");
-
-  /* Setup the result array, and determine string lengths */
-  for (i = 0; i < numsearch; i++) {
-    result[i][0] = '\0';
-    length[i] = strlen(varname[i]);
-  }
-
-  /* Open~/.crypt-table */
-  sprintf(filename, "%s/.crypt-table", getenv("HOME"));
-  fsearch = fopen(filename, "r");
-  if (fsearch) {
-    /* Scan file for a match */
-    while (!feof(fsearch)) {
-      fgets(buffer, MAX_BUFF - 3, fsearch);
-      for (i = 0; i < numsearch; i++) {
-	if (strncasecmp(varname[i], buffer, length[i]) == 0) {
-	  int j;
-	  for (j = length[i]; buffer[j] == ' '; j++)
-	    ;
-	  strcpy(result[i], &buffer[j]);
-	  if (*result[i]) {
-	    if (result[i][strlen(result[i])-1] == '\n') {
-	      result[i][strlen(result[i])-1] = '\0';
-	    }
-	  }
-	}
-      }
-    }
-
-    /* Pick the "best" match found */
-    keyfile = NULL;
-    for (i = 0; i < numsearch; i++) {
-      if (*result[i]) {
-	keyfile = result[i];
-	break;
-      }
-    }
-
-    if (keyfile == NULL) {
-      /* printf("Could not find key table entry.\n"); */
-    } else {
-      /* Prepare result to be returned */
-      char *temp = keyfile;
-      keyfile = (char *)owl_malloc(strlen(temp) + 1);
-      if (keyfile) {
-	strcpy(keyfile, temp);
-      } else {
-	/* printf("Memory allocation error.\n"); */
-      }
-    }
-    
-    fclose(fsearch);
-  } else {
-    /* printf("Could not open key table file: %s\n", filename); */
-  }
-
-  return(keyfile);
-}
-
-static pid_t zephyrpipe_pid = 0;
-
-/* Open a pipe to zwrite */
-static FILE *GetZephyrPipe(char *class, char *instance, ZWRITEOPTIONS *zoptions) {
-  int fildes[2];
-  pid_t pid;
-  FILE *result;
-  char *argv[20];
-  int argc = 0;
-
-  if (pipe(fildes) < 0) return(NULL);
-  pid = fork();
-
-  if (pid < 0) {
-    /* Error: clean up */
-    close(fildes[0]);
-    close(fildes[1]);
-    result = NULL;
-  } else if (pid == 0) {
-    /* Setup child process */
-    argv[argc++] = "zwrite";
-    argv[argc++] = "-n";     /* Always send without ping */
-    if (class) {
-      argv[argc++] = "-c";
-      argv[argc++] = class;
-    }
-    if (instance) {
-      argv[argc++] = "-i";
-      argv[argc++] = instance;
-    }
-    if (zoptions->flags & ZWRITE_OPT_NOAUTH) argv[argc++] = "-d";
-    if (zoptions->flags & ZWRITE_OPT_QUIET) argv[argc++] = "-q";
-    if (zoptions->flags & ZWRITE_OPT_VERBOSE) argv[argc++] = "-v";
-    if (zoptions->flags & ZWRITE_OPT_SIGNATURE) {
-      argv[argc++] = "-s";
-      argv[argc++] = zoptions->signature;
-    }
-    argv[argc++] = "-O";
-    argv[argc++] = "crypt";
-    argv[argc] = NULL;
-    close(fildes[1]);
-    if (fildes[0] != STDIN_FILENO) {
-      if (dup2(fildes[0], STDIN_FILENO) != STDIN_FILENO) exit(0);
-      close(fildes[0]);
-    }
-    close(fildes[0]);
-    execvp(argv[0], argv);
-    printf("Exec error: could not run zwrite\n");
-    exit(0);
-  } else {
-    close(fildes[0]);
-    /* Create a FILE * for the zwrite pipe */
-    result = (FILE *)fdopen(fildes[1], "w");
-    zephyrpipe_pid = pid;
-  }
-
-  return(result);
-}
-
-/* Close the pipe to zwrite */
-void CloseZephyrPipe(FILE *pipe) {
-  fclose(pipe);
-  waitpid(zephyrpipe_pid, NULL, 0);
-  zephyrpipe_pid = 0;
-}
-
-#define MAX_RESULT 2048
-
-
-void block_to_ascii(char *output, FILE *outfile) {
-  int i;
-  for (i = 0; i < 8; i++) {
-    putc(((output[i] & 0xf0) >> 4) + BASE_CODE, outfile);
-    putc( (output[i] & 0x0f)       + BASE_CODE, outfile);
-  }
-}
-
-#define MAX_LINE 128
-
-/* Encrypt stdin, with prompt if isatty, and send to stdout, or to zwrite
-   if zephyr is set. */
-static int do_encrypt(char *keystring, int zephyr, char *class, char *instance, ZWRITEOPTIONS *zoptions, char* keyfile) {
-  des_cblock key;
-  des_key_schedule schedule;
-  char input[8], output[8];
-  int size;
-  FILE *outfile = stdout;
-  int error = FALSE;
-  char *inbuff = NULL, *inptr;
-  int freein = FALSE;
-  int use_buffer = FALSE;
-  int num_blocks=0, last_block_size=0;
-
-  des_string_to_key(keystring, key);
-  des_key_sched(key, schedule);
-
-  if (zephyr) {
-    if (zoptions->flags & ZCRYPT_OPT_MESSAGE) {
-      /* Use the -m message */
-      int length;
-      inbuff = zoptions->message;      
-      length = strlen(inbuff);
-      num_blocks = (length + 7) / 8;
-      last_block_size = ((length + 7) % 8) + 1;
-      use_buffer = TRUE;
-    } else if (isatty(0)) {
-      /* tty input, so show the "Type your message now..." message */
-      if (zoptions->flags & ZCRYPT_OPT_IGNOREDOT) {
-	printf("Type your message now.  End with the end-of-file character.\n");
-      } else {
-	printf("Type your message now.  End with control-D or a dot on a line by itself.\n");
-      }
-      use_buffer = TRUE;
-      if ((inptr = inbuff = (char *)owl_malloc(MAX_RESULT)) == NULL) {
-	printf("Memory allocation error\n");
-	return FALSE;
-      }
-      while (inptr - inbuff < MAX_RESULT - MAX_LINE - 20) {
-	fgets(inptr, MAX_LINE, stdin);
-	if (inptr[0]) {
-	  if (inptr[0] == '.' && inptr[1] == '\n' && 
-	      !(zoptions->flags & ZCRYPT_OPT_IGNOREDOT)) {
-	    inptr[0] = '\0';
-	    break;
-	  } else {
-	    inptr += strlen(inptr);
-	  }
-	} else {
-	  break;
-	}
-      }
-      num_blocks = (inptr - inbuff + 7) / 8;
-      last_block_size = ((inptr - inbuff + 7) % 8) + 1;
-      freein = TRUE;
-    }
-
-    /* if (zephyr) */
-    outfile = GetZephyrPipe(class, instance, zoptions);
-    if (!outfile) {
-      printf("Could not run zwrite\n");
-      if (freein && inbuff) {
-	owl_free(inbuff);
-      }
-      return(FALSE);
-    }
-  }
-
-  inptr = inbuff;
-
-  /* Encrypt the input (inbuff or stdin) and send it to outfile */
-  while (TRUE) {
-    if (use_buffer) {
-      /* Get 8 bytes from buffer */
-      if (num_blocks > 1) {
-	size = 8;
-	memcpy(input, inptr, size);
-	inptr += 8;
-	num_blocks--;
-      } else if (num_blocks == 1) {
-	size = last_block_size;
-	memcpy(input, inptr, size);
-	num_blocks--;
-      } else {
-	size = 0;
-      }
-    } else {
-      /* Get 8 bytes from stdin */
-      size = fread(input, 1, 8, stdin);
-    }
-
-    /* Check for EOF and pad the string to 8 chars, if needed */
-    if (size == 0) break;     /* END OF INPUT: BREAK FROM while LOOP! */
-      
-    if (size < 8) memset(input + size, 0, 8 - size);
-
-    /* Encrypt and output the block */
-    des_ecb_encrypt(input, output, schedule, TRUE);
-    block_to_ascii(output, outfile);
-
-    if (size < 8) break;
-  }
-
-  /* Close out the output */
-  if (!error) putc('\n', outfile);
-  if (zephyr) CloseZephyrPipe(outfile);
-
-  /* Free the input buffer, if necessary */
-  if (freein && inbuff) owl_free(inbuff);
-
-  return(!error);
-}
-
-/* Read a half-byte from stdin, skipping invalid characters.  Returns -1
-   if at EOF or file error */
-int read_ascii_nybble() {
-  char c;
-
-  while (TRUE) {
-    if (fread(&c, 1, 1, stdin) == 0) {
-      return(-1);
-    } else if (c >= BASE_CODE && c <= LAST_CODE) {
-      return(c - BASE_CODE);
-    }
-  }
-}
-
-/* Read both halves of the byte and return the single byte.  Returns -1
-   if at EOF or file error. */
-int read_ascii_byte() {
-  int c1, c2;
-  c1 = read_ascii_nybble();
-  if (c1 >= 0) {
-    c2 = read_ascii_nybble();
-    if (c2 >= 0) {
-      return c1 * 0x10 + c2;
-    }
-  }
-  return(-1);
-}
-
-/* Read an 8-byte DES block from stdin */
-int read_ascii_block(char *input) {
-  int c, i;
-
-  for (i = 0; i < 8; i++) {
-    c = read_ascii_byte();
-    if (c < 0) return(FALSE);
-    input[i] = c;
-  }
-
-  return(TRUE);
-}
-
-/* Decrypt stdin */
-int do_decrypt(char *keystring) {
-  des_cblock key;
-  des_key_schedule schedule;
-  char input[8], output[9];
-
-  output[0] = '\0';    /* In case no message at all                 */
-  output[8] = '\0';    /* NULL at end will limit string length to 8 */
-
-  des_string_to_key(keystring, key);
-  des_key_sched(key, schedule);
-
-  while (read_ascii_block(input)) {
-    des_ecb_encrypt(input, output, schedule, FALSE);
-    printf("%s", output);
-  }
-
-  if (output[0]) {
-    if (output[strlen(output)-1] != '\n') {
-      printf("\n");
-    }
-  } else {
-    printf("\n");
-  }
-  return(0);
-}
-
-#endif
Index: phyr.c
===================================================================
--- zephyr.c	(revision 5547211b2a49e2fe6b405d8b72af6474b2a7b1a6)
+++ 	(revision )
@@ -1,1240 +1,0 @@
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <string.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-#ifdef HAVE_LIBZEPHYR
-Code_t ZResetAuthentication();
-#endif
-
-int owl_zephyr_initialize()
-{
-#ifdef HAVE_LIBZEPHYR
-  int ret;
-  ZNotice_t notice;
-
-  /* Stat the zhm manually, with a shorter timeout */
-  if ((ret = ZOpenPort(NULL)) != ZERR_NONE)
-    return(ret);
-
-  if ((ret = owl_zhm_stat(&notice)) != ZERR_NONE)
-    return(ret);
-
-  ZClosePort();
-
-  if ((ret = ZInitialize()) != ZERR_NONE) {
-    com_err("owl",ret,"while initializing");
-    return(1);
-  }
-  if ((ret = ZOpenPort(NULL)) != ZERR_NONE) {
-    com_err("owl",ret,"while opening port");
-    return(1);
-  }
-#endif
-  return(0);
-}
-
-#ifdef HAVE_LIBZEPHYR
-#define HM_SVC_FALLBACK		htons((unsigned short) 2104)
-
-/*
- * Code modified from libzephyr's ZhmStat.c
- *
- * Modified to only wait one second to time out if there is no
- * hostmanager present, rather than a rather excessive 10 seconds.
- */
-Code_t owl_zhm_stat(ZNotice_t *notice) {
-  struct servent *sp;
-  struct sockaddr_in sin;
-  ZNotice_t req;
-  Code_t code;
-  struct timeval tv;
-  fd_set readers;
-
-  (void) memset((char *)&sin, 0, sizeof(struct sockaddr_in));
-
-  sp = getservbyname(HM_SVCNAME, "udp");
-
-  sin.sin_port = (sp) ? sp->s_port : HM_SVC_FALLBACK;
-  sin.sin_family = AF_INET;
-
-  sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
-  (void) memset((char *)&req, 0, sizeof(req));
-  req.z_kind = STAT;
-  req.z_port = 0;
-  req.z_class = HM_STAT_CLASS;
-  req.z_class_inst = HM_STAT_CLIENT;
-  req.z_opcode = HM_GIMMESTATS;
-  req.z_sender = "";
-  req.z_recipient = "";
-  req.z_default_format = "";
-  req.z_message_len = 0;
-	
-  if ((code = ZSetDestAddr(&sin)) != ZERR_NONE)
-    return(code);
-
-  if ((code = ZSendNotice(&req, ZNOAUTH)) != ZERR_NONE)
-    return(code);
-
-  /* Wait up to 1 second for a response. */
-  FD_ZERO(&readers);
-  FD_SET(ZGetFD(), &readers);
-  tv.tv_sec = 1;
-  tv.tv_usec = 0;
-  code = select(ZGetFD() + 1, &readers, NULL, NULL, &tv);
-  if (code < 0 && errno != EINTR)
-    return(errno);
-  if (code == 0 || (code < 0 && errno == EINTR) || ZPending() == 0)
-    return(ZERR_HMDEAD);
-
-  return(ZReceiveNotice(notice, (struct sockaddr_in *) 0));
-}
-
-#endif
-
-int owl_zephyr_shutdown()
-{
-#ifdef HAVE_LIBZEPHYR
-  if(owl_global_is_havezephyr(&g)) {
-    unsuball();
-    ZClosePort();
-  }
-#endif
-  return(0);
-}
-
-int owl_zephyr_zpending()
-{
-#ifdef HAVE_LIBZEPHYR
-  if(owl_global_is_havezephyr(&g))
-    return(ZPending());
-  else
-    return 0;
-#else
-  return(0);
-#endif
-}
-
-char *owl_zephyr_get_realm()
-{
-#ifdef HAVE_LIBZEPHYR
-  return(ZGetRealm());
-#else
-  return("");
-#endif
-}
-
-char *owl_zephyr_get_sender()
-{
-#ifdef HAVE_LIBZEPHYR
-  return(ZGetSender());
-#else
-  return("");
-#endif
-}
-
-#ifdef HAVE_LIBZEPHYR
-int owl_zephyr_loadsubs_helper(ZSubscription_t subs[], int count)
-{
-  int i, ret = 0;
-  /* sub without defaults */
-  if (ZSubscribeToSansDefaults(subs,count,0) != ZERR_NONE) {
-    owl_function_error("Error subscribing to zephyr notifications.");
-    ret=-2;
-  }
-
-  /* free stuff */
-  for (i=0; i<count; i++) {
-    owl_free(subs[i].zsub_class);
-    owl_free(subs[i].zsub_classinst);
-    owl_free(subs[i].zsub_recipient);
-  }
-
-  return ret;
-}
-#endif
-
-/* Load zephyr subscriptions form 'filename'.  If 'filename' is NULL,
- * the default file $HOME/.zephyr.subs will be used.
- *
- * Returns 0 on success.  If the file does not exist, return -1 if
- * 'error_on_nofile' is 1, otherwise return 0.  Return -1 if the file
- * exists but can not be read.  Return -2 if there is a failure from
- * zephyr to load the subscriptions.
- */
-int owl_zephyr_loadsubs(char *filename, int error_on_nofile)
-{
-#ifdef HAVE_LIBZEPHYR
-  FILE *file;
-  char *tmp, *start;
-  char buffer[1024], subsfile[1024];
-  ZSubscription_t *subs;
-  int subSize = 1024;
-  int count, ret;
-  struct stat statbuff;
-
-  subs = owl_malloc(sizeof(ZSubscription_t) * subSize);
-  if (filename==NULL) {
-    sprintf(subsfile, "%s/%s", owl_global_get_homedir(&g), ".zephyr.subs");
-  } else {
-    strcpy(subsfile, filename);
-  }
-
-  ret=stat(subsfile, &statbuff);
-  if (ret) {
-    if (error_on_nofile==1) return(-1);
-    return(0);
-  }
-
-  ZResetAuthentication();
-  count=0;
-  file=fopen(subsfile, "r");
-  if (!file) return(-1);
-  while ( fgets(buffer, 1024, file)!=NULL ) {
-    if (buffer[0]=='#' || buffer[0]=='\n' || buffer[0]=='\n') continue;
-    
-    if (buffer[0]=='-') {
-      start=buffer+1;
-    } else {
-      start=buffer;
-    }
-    
-    if (count >= subSize) {
-      ZSubscription_t* newsubs;
-      newsubs = owl_realloc(subs, sizeof(ZSubscription_t) * subSize * 2);
-      if (NULL == newsubs) {
-	/* If realloc fails, load what we've got, clear, and continue */
-	ret = owl_zephyr_loadsubs_helper(subs, count);
-	if (ret != 0) {
-	  fclose(file);
-	  return(ret);
-	}
-	count=0;
-      }
-      else {
-	subs = newsubs;
-	subSize *= 2;
-      }
-    }
-    
-    /* add it to the list of subs */
-    if ((tmp=(char *) strtok(start, ",\n\r"))==NULL) continue;
-    subs[count].zsub_class=owl_strdup(tmp);
-    if ((tmp=(char *) strtok(NULL, ",\n\r"))==NULL) continue;
-    subs[count].zsub_classinst=owl_strdup(tmp);
-    if ((tmp=(char *) strtok(NULL, " \t\n\r"))==NULL) continue;
-    subs[count].zsub_recipient=owl_strdup(tmp);
-    
-    /* if it started with '-' then add it to the global punt list, and
-     * remove it from the list of subs. */
-    if (buffer[0]=='-') {
-      owl_function_zpunt(subs[count].zsub_class, subs[count].zsub_classinst, subs[count].zsub_recipient, 0);
-      owl_free(subs[count].zsub_class);
-      owl_free(subs[count].zsub_classinst);
-      owl_free(subs[count].zsub_recipient);
-    }
-    else {
-      count++;
-    }
-  }
-  fclose(file);
-
-  ret=owl_zephyr_loadsubs_helper(subs, count);
-  owl_free(subs);
-  return(ret);
-#else
-  return(0);
-#endif
-}
-
-int owl_zephyr_loaddefaultsubs()
-{
-#ifdef HAVE_LIBZEPHYR
-  ZSubscription_t subs[10];
-    
-  if (ZSubscribeTo(subs,0,0) != ZERR_NONE) {
-    owl_function_error("Error subscribing to default zephyr notifications.");
-    return(-1);
-  }
-  return(0);
-#else
-  return(0);
-#endif
-}
-
-int owl_zephyr_loadloginsubs(char *filename)
-{
-#ifdef HAVE_LIBZEPHYR
-  FILE *file;
-  ZSubscription_t subs[3001];
-  char subsfile[1024], buffer[1024];
-  int count, ret, i;
-  struct stat statbuff;
-
-  if (filename==NULL) {
-    sprintf(subsfile, "%s/%s", owl_global_get_homedir(&g), ".anyone");
-  } else {
-    strcpy(subsfile, filename);
-  }
-  
-  ret=stat(subsfile, &statbuff);
-  if (ret) return(0);
-
-  ret=0;
-
-  ZResetAuthentication();
-  /* need to redo this to do chunks, not just bag out after 3000 */
-  count=0;
-  file=fopen(subsfile, "r");
-  if (file) {
-    while ( fgets(buffer, 1024, file)!=NULL ) {
-      if (buffer[0]=='#' || buffer[0]=='\n' || buffer[0]=='\n') continue;
-      
-      if (count >= 3000) break; /* also tell the user */
-
-      buffer[strlen(buffer)-1]='\0';
-      subs[count].zsub_class="login";
-      subs[count].zsub_recipient="*";
-      if (strchr(buffer, '@')) {
-	subs[count].zsub_classinst=owl_strdup(buffer);
-      } else {
-	subs[count].zsub_classinst=owl_sprintf("%s@%s", buffer, ZGetRealm());
-      }
-
-      count++;
-    }
-    fclose(file);
-  } else {
-    count=0;
-    ret=-1;
-  }
-
-  /* sub with defaults */
-  if (ZSubscribeToSansDefaults(subs,count,0) != ZERR_NONE) {
-    owl_function_error("Error subscribing to zephyr notifications.");
-    ret=-2;
-  }
-
-  /* free stuff */
-  for (i=0; i<count; i++) {
-    owl_free(subs[i].zsub_classinst);
-  }
-
-  return(ret);
-#else
-  return(0);
-#endif
-}
-
-void unsuball()
-{
-#if HAVE_LIBZEPHYR
-  int ret;
-
-  ZResetAuthentication();
-  ret=ZCancelSubscriptions(0);
-  if (ret != ZERR_NONE) {
-    com_err("owl",ret,"while unsubscribing");
-  }
-#endif
-}
-
-int owl_zephyr_sub(char *class, char *inst, char *recip)
-{
-#ifdef HAVE_LIBZEPHYR
-  ZSubscription_t subs[5];
-
-  subs[0].zsub_class=class;
-  subs[0].zsub_classinst=inst;
-  subs[0].zsub_recipient=recip;
-
-  ZResetAuthentication();
-  if (ZSubscribeTo(subs,1,0) != ZERR_NONE) {
-    owl_function_error("Error subbing to <%s,%s,%s>", class, inst, recip);
-    return(-2);
-  }
-  return(0);
-#else
-  return(0);
-#endif
-}
-
-
-int owl_zephyr_unsub(char *class, char *inst, char *recip)
-{
-#ifdef HAVE_LIBZEPHYR
-  ZSubscription_t subs[5];
-
-  subs[0].zsub_class=class;
-  subs[0].zsub_classinst=inst;
-  subs[0].zsub_recipient=recip;
-
-  ZResetAuthentication();
-  if (ZUnsubscribeTo(subs,1,0) != ZERR_NONE) {
-    owl_function_error("Error unsubbing from <%s,%s,%s>", class, inst, recip);
-    return(-2);
-  }
-  return(0);
-#else
-  return(0);
-#endif
-}
-
-/* return a pointer to the data in the Jth field, (NULL terminated by
- * definition).  Caller must free the return.
- */
-#ifdef HAVE_LIBZEPHYR
-char *owl_zephyr_get_field(ZNotice_t *n, int j)
-{
-  int i, count, save;
-  char *out;
-
-  /* If there's no message here, just run along now */
-  if (n->z_message_len == 0)
-    return(owl_strdup(""));
-
-  count=save=0;
-  for (i=0; i<n->z_message_len; i++) {
-    if (n->z_message[i]=='\0') {
-      count++;
-      if (count==j) {
-	/* just found the end of the field we're looking for */
-	return(owl_strdup(n->z_message+save));
-      } else {
-	save=i+1;
-      }
-    }
-  }
-  /* catch the last field, which might not be null terminated */
-  if (count==j-1) {
-    out=owl_malloc(n->z_message_len-save+5);
-    memcpy(out, n->z_message+save, n->z_message_len-save);
-    out[n->z_message_len-save]='\0';
-    return(out);
-  }
-
-  return(owl_strdup(""));
-}
-
-char *owl_zephyr_get_field_as_utf8(ZNotice_t *n, int j)
-{
-  int i, count, save;
-
-  /* If there's no message here, just run along now */
-  if (n->z_message_len == 0)
-    return(owl_strdup(""));
-
-  count=save=0;
-  for (i = 0; i < n->z_message_len; i++) {
-    if (n->z_message[i]=='\0') {
-      count++;
-      if (count == j) {
-	/* just found the end of the field we're looking for */
-	return(owl_validate_or_convert(n->z_message + save));
-      } else {
-	save = i + 1;
-      }
-    }
-  }
-  /* catch the last field, which might not be null terminated */
-  if (count == j - 1) {
-    char *tmp, *out;
-    tmp = owl_malloc(n->z_message_len-save+5);
-    memcpy(tmp, n->z_message+save, n->z_message_len-save);
-    tmp[n->z_message_len-save]='\0';
-    out = owl_validate_or_convert(tmp);
-    owl_free(tmp);
-    return out;
-  }
-
-  return(owl_strdup(""));
-}
-#else
-char *owl_zephyr_get_field(void *n, int j)
-{
-  return(owl_strdup(""));
-}
-char *owl_zephyr_get_field_as_utf8(void *n, int j)
-{
-  return owl_zephyr_get_field(n, j);
-}
-#endif
-
-
-#ifdef HAVE_LIBZEPHYR
-int owl_zephyr_get_num_fields(ZNotice_t *n)
-{
-  int i, fields;
-
-  if(n->z_message_len == 0)
-    return 0;
-
-  fields=1;
-  for (i=0; i<n->z_message_len; i++) {
-    if (n->z_message[i]=='\0') fields++;
-  }
-  
-  return(fields);
-}
-#else
-int owl_zephyr_get_num_fields(void *n)
-{
-  return(0);
-}
-#endif
-
-#ifdef HAVE_LIBZEPHYR
-/* return a pointer to the message, place the message length in k
- * caller must free the return
- */
-char *owl_zephyr_get_message(ZNotice_t *n, owl_message *m)
-{
-  /* don't let ping messages have a body */
-  if (!strcasecmp(n->z_opcode, "ping")) {
-    return(owl_strdup(""));
-  }
-
-  /* deal with MIT NOC messages */
-  if (!strcasecmp(n->z_default_format, "@center(@bold(NOC Message))\n\n@bold(Sender:) $1 <$sender>\n@bold(Time:  ) $time\n\n@italic($opcode service on $instance $3.) $4\n")) {
-    char *msg, *field3, *field4;
-
-    field3 = owl_zephyr_get_field(n, 3);
-    field4 = owl_zephyr_get_field(n, 4);
-
-    msg = owl_sprintf("%s service on %s %s\n%s", n->z_opcode, n->z_class_inst, field3, field4);
-    owl_free(field3);
-    owl_free(field4);
-    if (msg) {
-      return msg;
-    }
-  }
-  /* deal with MIT Discuss messages */
-  else if (!strcasecmp(n->z_default_format, "New transaction [$1] entered in $2\nFrom: $3 ($5)\nSubject: $4")) {
-    char *msg, *field1, *field2, *field3, *field4, *field5;
-    
-    field1 = owl_zephyr_get_field(n, 1);
-    field2 = owl_zephyr_get_field(n, 2);
-    field3 = owl_zephyr_get_field(n, 3);
-    field4 = owl_zephyr_get_field(n, 4);
-    field5 = owl_zephyr_get_field(n, 5);
-    
-    msg = owl_sprintf("New transaction [%s] entered in %s\nFrom: %s (%s)\nSubject: %s", field1, field2, field3, field5, field4);
-    owl_free(field1);
-    owl_free(field2);
-    owl_free(field3);
-    owl_free(field4);
-    owl_free(field5);
-    if (msg) {
-      return msg;
-    }
-  }
-  /* deal with MIT Moira messages */
-  else if (!strcasecmp(n->z_default_format, "MOIRA $instance on $fromhost:\n $message\n")) {
-    char *msg, *field1;
-    
-    field1 = owl_zephyr_get_field(n, 1);
-    
-    msg = owl_sprintf("MOIRA %s on %s: %s", n->z_class_inst, owl_message_get_hostname(m), field1);
-    owl_free(field1);
-    if (msg) {
-      return msg;
-    }
-  }
-
-  if (owl_zephyr_get_num_fields(n) == 1) {
-    return(owl_zephyr_get_field(n, 1));
-  }
-  else {
-    return(owl_zephyr_get_field(n, 2));
-  }
-}
-#endif
-
-#ifdef HAVE_LIBZEPHYR
-char *owl_zephyr_get_zsig(ZNotice_t *n, int *k)
-{
-  /* return a pointer to the zsig if there is one */
-
-  /* message length 0? No zsig */
-  if (n->z_message_len==0) {
-    *k=0;
-    return("");
-  }
-
-  /* If there's only one field, no zsig */
-  if (owl_zephyr_get_num_fields(n) == 1) {
-    *k=0;
-    return("");
-  }
-
-  /* Everything else is field 1 */
-  *k=strlen(n->z_message);
-  return(n->z_message);
-}
-#else
-char *owl_zephyr_get_zsig(void *n, int *k)
-{
-  return("");
-}
-#endif
-
-int send_zephyr(char *opcode, char *zsig, char *class, char *instance, char *recipient, char *message)
-{
-#ifdef HAVE_LIBZEPHYR
-  int ret;
-  ZNotice_t notice;
-    
-  memset(&notice, 0, sizeof(notice));
-
-  ZResetAuthentication();
-
-  if (!zsig) zsig="";
-  
-  notice.z_kind=ACKED;
-  notice.z_port=0;
-  notice.z_class=class;
-  notice.z_class_inst=instance;
-  if (!strcmp(recipient, "*") || !strcmp(recipient, "@")) {
-    notice.z_recipient="";
-  } else {
-    notice.z_recipient=recipient;
-  }
-  notice.z_default_format="Class $class, Instance $instance:\nTo: @bold($recipient) at $time $date\nFrom: @bold{$1 <$sender>}\n\n$2";
-  if (*owl_global_get_zsender(&g))
-      notice.z_sender=owl_global_get_zsender(&g);
-  else
-      notice.z_sender=NULL;
-  if (opcode) notice.z_opcode=opcode;
-
-  notice.z_message_len=strlen(zsig)+1+strlen(message);
-  notice.z_message=owl_malloc(notice.z_message_len+10);
-  strcpy(notice.z_message, zsig);
-  memcpy(notice.z_message+strlen(zsig)+1, message, strlen(message));
-
-  /* ret=ZSendNotice(&notice, ZAUTH); */
-  ret=ZSrvSendNotice(&notice, ZAUTH, send_zephyr_helper);
-  
-  /* free then check the return */
-  owl_free(notice.z_message);
-  ZFreeNotice(&notice);
-  if (ret!=ZERR_NONE) {
-    owl_function_error("Error sending zephyr");
-    return(ret);
-  }
-  return(0);
-#else
-  return(0);
-#endif
-}
-
-#ifdef HAVE_LIBZEPHYR
-Code_t send_zephyr_helper(ZNotice_t *notice, char *buf, int len, int wait)
-{
-  return(ZSendPacket(buf, len, 0));
-}
-#endif
-
-void send_ping(char *to)
-{
-#ifdef HAVE_LIBZEPHYR
-  send_zephyr("PING", "", "MESSAGE", "PERSONAL", to, "");
-#endif
-}
-
-#ifdef HAVE_LIBZEPHYR
-void owl_zephyr_handle_ack(ZNotice_t *retnotice)
-{
-  char *tmp;
-  
-  /* if it's an HMACK ignore it */
-  if (retnotice->z_kind == HMACK) return;
-
-  if (retnotice->z_kind == SERVNAK) {
-    owl_function_error("Authorization failure sending zephyr");
-  } else if ((retnotice->z_kind != SERVACK) || !retnotice->z_message_len) {
-    owl_function_error("Detected server failure while receiving acknowledgement");
-  } else if (!strcmp(retnotice->z_message, ZSRVACK_SENT)) {
-    if (!strcasecmp(retnotice->z_opcode, "ping")) {
-      return;
-    } else if (!strcasecmp(retnotice->z_class, "message") &&
-	       !strcasecmp(retnotice->z_class_inst, "personal")) {
-      tmp=short_zuser(retnotice->z_recipient);
-      owl_function_makemsg("Message sent to %s.", tmp);
-      free(tmp);
-    } else {
-      owl_function_makemsg("Message sent to -c %s -i %s\n", retnotice->z_class, retnotice->z_class_inst);
-    }
-  } else if (!strcmp(retnotice->z_message, ZSRVACK_NOTSENT)) {
-    #define BUFFLEN 1024
-    if (retnotice->z_recipient == NULL
-        || *retnotice->z_recipient == 0
-        || *retnotice->z_recipient == '@') {
-      char buff[BUFFLEN];
-      owl_function_error("No one subscribed to class %s", retnotice->z_class);
-      snprintf(buff, BUFFLEN, "Could not send message to class %s: no one subscribed.\n", retnotice->z_class);
-      owl_function_adminmsg("", buff);
-    } else {
-      char buff[BUFFLEN];
-      tmp = short_zuser(retnotice->z_recipient);
-      owl_function_error("%s: Not logged in or subscribing.", tmp);
-      if(strcmp(retnotice->z_class, "message")) {
-        snprintf(buff, BUFFLEN,
-                 "Could not send message to %s: "
-                 "not logged in or subscribing to class %s, instance %s.\n", 
-                 tmp,
-                 retnotice->z_class,
-                 retnotice->z_class_inst);
-      } else {
-        snprintf(buff, BUFFLEN,
-                 "Could not send message to %s: "
-                 "not logged in or subscribing to messages.\n",
-                 tmp);
-      }
-      owl_function_adminmsg("", buff);
-      owl_log_outgoing_zephyr_error(tmp, buff);
-      owl_free(tmp);
-    }
-  } else {
-    owl_function_error("Internal error on ack (%s)", retnotice->z_message);
-  }
-}
-#else
-void owl_zephyr_handle_ack(void *retnotice)
-{
-}
-#endif
-
-#ifdef HAVE_LIBZEPHYR
-int owl_zephyr_notice_is_ack(ZNotice_t *n)
-{
-  if (n->z_kind == SERVNAK || n->z_kind == SERVACK || n->z_kind == HMACK) {
-    if (!strcasecmp(n->z_class, LOGIN_CLASS)) return(0);
-    return(1);
-  }
-  return(0);
-}
-#else
-int owl_zephyr_notice_is_ack(void *n)
-{
-  return(0);
-}
-#endif
-  
-void owl_zephyr_zaway(owl_message *m)
-{
-#ifdef HAVE_LIBZEPHYR
-  char *tmpbuff, *myuser, *to;
-  owl_message *mout;
-  
-  /* bail if it doesn't look like a message we should reply to.  Some
-   * of this defined by the way zaway(1) works
-   */
-  if (strcasecmp(owl_message_get_class(m), "message")) return;
-  if (strcasecmp(owl_message_get_recipient(m), ZGetSender())) return;
-  if (!strcasecmp(owl_message_get_sender(m), "")) return;
-  if (!strcasecmp(owl_message_get_opcode(m), "ping")) return;
-  if (!strcasecmp(owl_message_get_opcode(m), "auto")) return;
-  if (!strcasecmp(owl_message_get_zsig(m), "Automated reply:")) return;
-  if (!strcasecmp(owl_message_get_sender(m), ZGetSender())) return;
-  if (owl_message_get_attribute_value(m, "isauto")) return;
-
-  if (owl_global_is_smartstrip(&g)) {
-    to=owl_zephyr_smartstripped_user(owl_message_get_sender(m));
-  } else {
-    to=owl_strdup(owl_message_get_sender(m));
-  }
-
-  send_zephyr("",
-	      "Automated reply:",
-	      owl_message_get_class(m),
-	      owl_message_get_instance(m),
-	      to,
-	      owl_global_get_zaway_msg(&g));
-
-  myuser=short_zuser(to);
-  if (!strcasecmp(owl_message_get_instance(m), "personal")) {
-    tmpbuff = owl_sprintf("zwrite %s", myuser);
-  } else {
-    tmpbuff = owl_sprintf("zwrite -i %s %s", owl_message_get_instance(m), myuser);
-  }
-  owl_free(myuser);
-  owl_free(to);
-
-  /* display the message as an admin message in the receive window */
-  mout=owl_function_make_outgoing_zephyr(owl_global_get_zaway_msg(&g), tmpbuff, "Automated reply:");
-  owl_global_messagequeue_addmsg(&g, mout);
-  owl_free(tmpbuff);
-#endif
-}
-
-#ifdef HAVE_LIBZEPHYR
-void owl_zephyr_hackaway_cr(ZNotice_t *n)
-{
-  /* replace \r's with ' '.  Gross-ish */
-  int i;
-
-  for (i=0; i<n->z_message_len; i++) {
-    if (n->z_message[i]=='\r') {
-      n->z_message[i]=' ';
-    }
-  }
-}
-#endif
-
-void owl_zephyr_zlocate(char *user, char *out, int auth)
-{
-#ifdef HAVE_LIBZEPHYR
-  int ret, numlocs;
-  int one = 1;
-  ZLocations_t locations;
-  char *myuser;
-  
-  strcpy(out, "");
-  ZResetAuthentication();
-  ret=ZLocateUser(user,&numlocs,auth?ZAUTH:ZNOAUTH);
-  if (ret != ZERR_NONE) {
-    sprintf(out, "Error locating user %s\n", user);
-    return;
-  }
-
-  if (numlocs==0) {
-    myuser=short_zuser(user);
-    sprintf(out, "%s: Hidden or not logged in\n", myuser);
-    owl_free(myuser);
-    return;
-  }
-    
-  for (;numlocs;numlocs--) {
-    ZGetLocations(&locations,&one);
-    myuser=short_zuser(user);
-    sprintf(out + strlen(out), "%s: %s\t%s\t%s\n", myuser,
-	    locations.host ? locations.host : "?",
-	    locations.tty ? locations.tty : "?",
-	    locations.time ? locations.time : "?");
-    owl_free(myuser);
-  }
-#endif
-}
-
-void owl_zephyr_addsub(char *filename, char *class, char *inst, char *recip)
-{
-#ifdef HAVE_LIBZEPHYR
-  char *line, subsfile[LINE], buff[LINE];
-  FILE *file;
-
-  line=owl_zephyr_makesubline(class, inst, recip);
-
-  if (filename==NULL) {
-    sprintf(subsfile, "%s/%s", owl_global_get_homedir(&g), ".zephyr.subs");
-  } else {
-    strcpy(subsfile, filename);
-  }
-
-  /* if the file already exists, check to see if the sub is already there */
-  file=fopen(subsfile, "r");
-  if (file) {
-    while (fgets(buff, LINE, file)!=NULL) {
-      if (!strcasecmp(buff, line)) {
-	owl_function_error("Subscription already present in %s", subsfile);
-	owl_free(line);
-	fclose(file);
-	return;
-      }
-    }
-    fclose(file);
-  }
-
-  /* if we get here then we didn't find it */
-  file=fopen(subsfile, "a");
-  if (!file) {
-    owl_function_error("Error opening file %s for writing", subsfile);
-    owl_free(line);
-    return;
-  }
-  fputs(line, file);
-  fclose(file);
-  owl_function_makemsg("Subscription added");
-  
-  owl_free(line);
-#endif
-}
-
-void owl_zephyr_delsub(char *filename, char *class, char *inst, char *recip)
-{
-#ifdef HAVE_LIBZEPHYR
-  char *line, *subsfile;
-  
-  line=owl_zephyr_makesubline(class, inst, recip);
-  line[strlen(line)-1]='\0';
-
-  if (!filename) {
-    subsfile=owl_sprintf("%s/.zephyr.subs", owl_global_get_homedir(&g));
-  } else {
-    subsfile=owl_strdup(filename);
-  }
-  
-  owl_util_file_deleteline(subsfile, line, 1);
-  owl_free(subsfile);
-  owl_free(line);
-  owl_function_makemsg("Subscription removed");
-#endif
-}
-
-/* caller must free the return */
-char *owl_zephyr_makesubline(char *class, char *inst, char *recip)
-{
-  char *out;
-
-  out=owl_malloc(strlen(class)+strlen(inst)+strlen(recip)+30);
-  sprintf(out, "%s,%s,%s\n", class, inst, !strcmp(recip, "") ? "*" : recip);
-  return(out);
-}
-
-
-void owl_zephyr_zlog_in(void)
-{
-#ifdef HAVE_LIBZEPHYR
-  char *exposure, *eset;
-  int ret;
-
-  ZResetAuthentication();
-    
-  eset=EXPOSE_REALMVIS;
-  exposure=ZGetVariable("exposure");
-  if (exposure==NULL) {
-    eset=EXPOSE_REALMVIS;
-  } else if (!strcasecmp(exposure,EXPOSE_NONE)) {
-    eset = EXPOSE_NONE;
-  } else if (!strcasecmp(exposure,EXPOSE_OPSTAFF)) {
-    eset = EXPOSE_OPSTAFF;
-  } else if (!strcasecmp(exposure,EXPOSE_REALMVIS)) {
-    eset = EXPOSE_REALMVIS;
-  } else if (!strcasecmp(exposure,EXPOSE_REALMANN)) {
-    eset = EXPOSE_REALMANN;
-  } else if (!strcasecmp(exposure,EXPOSE_NETVIS)) {
-    eset = EXPOSE_NETVIS;
-  } else if (!strcasecmp(exposure,EXPOSE_NETANN)) {
-    eset = EXPOSE_NETANN;
-  }
-   
-  ret=ZSetLocation(eset);
-  if (ret != ZERR_NONE) {
-    /*
-      char buff[LINE];
-      sprintf(buff, "Error setting location: %s", error_message(ret));
-      owl_function_makemsg(buff);
-    */
-  }
-#endif
-}
-
-void owl_zephyr_zlog_out(void)
-{
-#ifdef HAVE_LIBZEPHYR
-  int ret;
-
-  ZResetAuthentication();
-  ret=ZUnsetLocation();
-  if (ret != ZERR_NONE) {
-    /*
-      char buff[LINE];
-      sprintf(buff, "Error unsetting location: %s", error_message(ret));
-      owl_function_makemsg(buff);
-    */
-  }
-#endif
-}
-
-void owl_zephyr_addbuddy(char *name)
-{
-  char *filename;
-  FILE *file;
-  
-  filename=owl_sprintf("%s/.anyone", owl_global_get_homedir(&g));
-  file=fopen(filename, "a");
-  owl_free(filename);
-  if (!file) {
-    owl_function_error("Error opening zephyr buddy file for append");
-    return;
-  }
-  fprintf(file, "%s\n", name);
-  fclose(file);
-}
-
-void owl_zephyr_delbuddy(char *name)
-{
-  char *filename;
-
-  filename=owl_sprintf("%s/.anyone", owl_global_get_homedir(&g));
-  owl_util_file_deleteline(filename, name, 0);
-  owl_free(filename);
-}
-
-/* return auth string */
-#ifdef HAVE_LIBZEPHYR
-char *owl_zephyr_get_authstr(ZNotice_t *n)
-{
-
-  if (!n) return("UNKNOWN");
-
-  if (n->z_auth == ZAUTH_FAILED) {
-    return ("FAILED");
-  } else if (n->z_auth == ZAUTH_NO) {
-    return ("NO");
-  } else if (n->z_auth == ZAUTH_YES) {
-    return ("YES");
-  } else {
-    return ("UNKNOWN");
-  }           
-}
-#else
-char *owl_zephyr_get_authstr(void *n)
-{
-  return("");
-}
-#endif
-
-/* Returns a buffer of subscriptions or an error message.  Caller must
- * free the return.
- */
-char *owl_zephyr_getsubs()
-{
-#ifdef HAVE_LIBZEPHYR
-  int ret, num, i, one;
-  int buffsize;
-  ZSubscription_t sub;
-  char *out;
-  one=1;
-
-  ret=ZRetrieveSubscriptions(0, &num);
-  if (ret==ZERR_TOOMANYSUBS) {
-    return(owl_strdup("Zephyr: too many subscriptions\n"));
-  } else if (ret || (num <= 0)) {
-    return(owl_strdup("Zephyr: error retriving subscriptions\n"));
-  }
-
-  buffsize = (num + 1) * 50;
-  out=owl_malloc(buffsize);
-  strcpy(out, "");
-  for (i=0; i<num; i++) {
-    if ((ret = ZGetSubscriptions(&sub, &one)) != ZERR_NONE) {
-      owl_free(out);
-      ZFlushSubscriptions();
-      out=owl_strdup("Error while getting subscriptions\n");
-      return(out);
-    } else {
-      int tmpbufflen;
-      char *tmpbuff;
-      tmpbuff = owl_sprintf("<%s,%s,%s>\n%s", sub.zsub_class, sub.zsub_classinst, sub.zsub_recipient, out);
-      tmpbufflen = strlen(tmpbuff) + 1;
-      if (tmpbufflen > buffsize) {
-        char *out2;
-        buffsize = tmpbufflen * 2;
-        out2 = owl_realloc(out, buffsize);
-        if (out2 == NULL) {
-          owl_free(out);
-          owl_free(tmpbuff);
-          ZFlushSubscriptions();
-          out=owl_strdup("Realloc error while getting subscriptions\n");
-          return(out);    
-        }
-        out = out2;
-      }
-      strcpy(out, tmpbuff);
-      owl_free(tmpbuff);
-    }
-  }
-
-  ZFlushSubscriptions();
-  return(out);
-#else
-  return(owl_strdup("Zephyr not available"));
-#endif
-}
-
-char *owl_zephyr_get_variable(char *var)
-{
-#ifdef HAVE_LIBZEPHYR
-  return(ZGetVariable(var));
-#else
-  return("");
-#endif
-}
-
-void owl_zephyr_set_locationinfo(char *host, char *val)
-{
-#ifdef HAVE_LIBZEPHYR
-  ZInitLocationInfo(host, val);
-#endif
-}
-  
-/* Strip a local realm fron the zephyr user name.
- * The caller must free the return
- */
-char *short_zuser(char *in)
-{
-  char *out, *ptr;
-
-  out=owl_strdup(in);
-  ptr=strchr(out, '@');
-  if (ptr) {
-    if (!strcasecmp(ptr+1, owl_zephyr_get_realm())) {
-      *ptr='\0';
-    }
-  }
-  return(out);
-}
-
-/* Append a local realm to the zephyr user name if necessary.
- * The caller must free the return.
- */
-char *long_zuser(char *in)
-{
-  if (strchr(in, '@')) {
-    return(owl_strdup(in));
-  }
-  return(owl_sprintf("%s@%s", in, owl_zephyr_get_realm()));
-}
-
-/* strip out the instance from a zsender's principal.  Preserves the
- * realm if present.  daemon.webzephyr is a special case.  The
- * caller must free the return
- */
-char *owl_zephyr_smartstripped_user(char *in)
-{
-  char *ptr, *realm, *out;
-
-  out=owl_strdup(in);
-
-  /* bail immeaditly if we don't have to do any work */
-  ptr=strchr(in, '.');
-  if (!strchr(in, '/') && !ptr) {
-    /* no '/' and no '.' */
-    return(out);
-  }
-  if (ptr && strchr(in, '@') && (ptr > strchr(in, '@'))) {
-    /* There's a '.' but it's in the realm */
-    return(out);
-  }
-  if (!strncasecmp(in, OWL_WEBZEPHYR_PRINCIPAL, strlen(OWL_WEBZEPHYR_PRINCIPAL))) {
-    return(out);
-  }
-
-  /* remove the realm from ptr, but hold on to it */
-  realm=strchr(out, '@');
-  if (realm) realm[0]='\0';
-
-  /* strip */
-  ptr=strchr(out, '.');
-  if (!ptr) ptr=strchr(out, '/');
-  ptr[0]='\0';
-
-  /* reattach the realm if we had one */
-  if (realm) {
-    strcat(out, "@");
-    strcat(out, realm+1);
-  }
-
-  return(out);
-}
-
-/* read the list of users in 'filename' as a .anyone file, and put the
- * names of the zephyr users in the list 'in'.  If 'filename' is NULL,
- * use the default .anyone file in the users home directory.  Returns
- * -1 on failure, 0 on success.
- */
-int owl_zephyr_get_anyone_list(owl_list *in, char *filename)
-{
-#ifdef HAVE_LIBZEPHYR
-  char *ourfile, *tmp, buff[LINE];
-  FILE *f;
-
-  if (filename==NULL) {
-    tmp=owl_global_get_homedir(&g);
-    ourfile=owl_sprintf("%s/.anyone", owl_global_get_homedir(&g));
-  } else {
-    ourfile=owl_strdup(filename);
-  }
-  
-  f=fopen(ourfile, "r");
-  if (!f) {
-    owl_function_error("Error opening file %s: %s", ourfile, strerror(errno) ? strerror(errno) : "");
-    owl_free(ourfile);
-    return(-1);
-  }
-
-  while (fgets(buff, LINE, f)!=NULL) {
-    /* ignore comments, blank lines etc. */
-    if (buff[0]=='#') continue;
-    if (buff[0]=='\n') continue;
-    if (buff[0]=='\0') continue;
-    
-    /* strip the \n */
-    buff[strlen(buff)-1]='\0';
-    
-    /* ingore from # on */
-    tmp=strchr(buff, '#');
-    if (tmp) tmp[0]='\0';
-    
-    /* ingore from SPC */
-    tmp=strchr(buff, ' ');
-    if (tmp) tmp[0]='\0';
-    
-    /* stick on the local realm. */
-    if (!strchr(buff, '@')) {
-      strcat(buff, "@");
-      strcat(buff, ZGetRealm());
-    }
-    owl_list_append_element(in, owl_strdup(buff));
-  }
-  fclose(f);
-  owl_free(ourfile);
-  return(0);
-#else
-  return(-1);
-#endif
-}
-
-#ifdef HAVE_LIBZEPHYR
-void owl_zephyr_process_events() {
-  int zpendcount=0;
-  ZNotice_t notice;
-  struct sockaddr_in from;
-  owl_message *m=NULL;
-
-  while(owl_zephyr_zpending() && zpendcount < 20) {
-    if (owl_zephyr_zpending()) {
-      ZReceiveNotice(&notice, &from);
-      zpendcount++;
-
-      /* is this an ack from a zephyr we sent? */
-      if (owl_zephyr_notice_is_ack(&notice)) {
-        owl_zephyr_handle_ack(&notice);
-        continue;
-      }
-
-      /* if it's a ping and we're not viewing pings then skip it */
-      if (!owl_global_is_rxping(&g) && !strcasecmp(notice.z_opcode, "ping")) {
-        continue;
-      }
-
-      /* create the new message */
-      m=owl_malloc(sizeof(owl_message));
-      owl_message_create_from_znotice(m, &notice);
-
-      owl_global_messagequeue_addmsg(&g, m);
-    }
-  }
-}
-
-#else
-void owl_zephyr_process_events() {
-  
-}
-#endif
Index: rite.c
===================================================================
--- zwrite.c	(revision 5547211b2a49e2fe6b405d8b72af6474b2a7b1a6)
+++ 	(revision )
@@ -1,375 +1,0 @@
-#include <string.h>
-#include <pwd.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include "owl.h"
-
-static const char fileIdent[] = "$Id$";
-
-int owl_zwrite_create_from_line(owl_zwrite *z, char *line)
-{
-  int argc, badargs, myargc;
-  char **argv, **myargv;
-
-  badargs=0;
-  
-  /* start with null entires */
-  z->realm=NULL;
-  z->class=NULL;
-  z->inst=NULL;
-  z->opcode=NULL;
-  z->zsig=NULL;
-  z->message=NULL;
-  z->cc=0;
-  z->noping=0;
-  owl_list_create(&(z->recips));
-
-  /* parse the command line for options */
-  argv=myargv=owl_parseline(line, &argc);
-  if (argc<0) {
-    owl_function_error("Unbalanced quotes in zwrite");
-    return(-1);
-  }
-  myargc=argc;
-  if (myargc && *(myargv[0])!='-') {
-    myargc--;
-    myargv++;
-  }
-  while (myargc) {
-    if (!strcmp(myargv[0], "-c")) {
-      if (myargc<2) {
-	badargs=1;
-	break;
-      }
-      z->class=owl_get_iso_8859_1_if_possible(myargv[1]);
-      myargv+=2;
-      myargc-=2;
-    } else if (!strcmp(myargv[0], "-i")) {
-      if (myargc<2) {
-	badargs=1;
-	break;
-      }
-      z->inst=owl_get_iso_8859_1_if_possible(myargv[1]);
-      myargv+=2;
-      myargc-=2;
-    } else if (!strcmp(myargv[0], "-r")) {
-      if (myargc<2) {
-	badargs=1;
-	break;
-      }
-      z->realm=owl_get_iso_8859_1_if_possible(myargv[1]);
-      myargv+=2;
-      myargc-=2;
-    } else if (!strcmp(myargv[0], "-s")) {
-      if (myargc<2) {
-	badargs=1;
-	break;
-      }
-      z->zsig=owl_get_iso_8859_1_if_possible(myargv[1]);
-      myargv+=2;
-      myargc-=2;
-    } else if (!strcmp(myargv[0], "-O")) {
-      if (myargc<2) {
-	badargs=1;
-	break;
-      }
-      z->opcode=owl_get_iso_8859_1_if_possible(myargv[1]);
-      myargv+=2;
-      myargc-=2;
-    } else if (!strcmp(myargv[0], "-m")) {
-      if (myargc<2) {
-	badargs=1;
-	break;
-      }
-      /* we must already have users or a class or an instance*/
-      if (owl_list_get_size(&(z->recips))<1 && (!z->class) && (!z->inst)) {
-	badargs=1;
-	break;
-      }
-
-      /* Once we have -m, gobble up everything else on the line */
-      myargv++;
-      myargc--;
-      z->message=owl_get_iso_8859_1_if_possible("");
-      while (myargc) {
-	z->message=owl_realloc(z->message, strlen(z->message)+strlen(myargv[0])+5);
-	strcat(z->message, myargv[0]);
-	strcat(z->message, " ");
-	myargc--;
-	myargv++;
-      }
-      z->message[strlen(z->message)-1]='\0'; /* remove last space */
-      break;
-    } else if (!strcmp(myargv[0], "-C")) {
-      z->cc=1;
-      myargv++;
-      myargc--;
-    } else if (!strcmp(myargv[0], "-n")) {
-      z->noping=1;
-      myargv++;
-      myargc--;
-    } else {
-      /* anything unattached is a recipient */
-      owl_list_append_element(&(z->recips), owl_get_iso_8859_1_if_possible(myargv[0]));
-      myargv++;
-      myargc--;
-    }
-  }
-
-  owl_parsefree(argv, argc);
-
-  if (badargs) {
-    return(-1);
-  }
-
-  if (z->class == NULL &&
-      z->inst == NULL &&
-      owl_list_get_size(&(z->recips))==0) {
-    owl_function_error("You must specify a recipient for zwrite");
-    return(-1);
-  }
-
-  /* now deal with defaults */
-  if (z->class==NULL) z->class=owl_strdup("message");
-  if (z->inst==NULL) z->inst=owl_strdup("personal");
-  if (z->realm==NULL) z->realm=owl_strdup("");
-  if (z->opcode==NULL) z->opcode=owl_strdup("");
-  /* z->message is allowed to stay NULL */
-  
-  return(0);
-}
-
-void owl_zwrite_populate_zsig(owl_zwrite *z)
-{
-  char *zsigproc, *zsigowlvar, *zsigzvar, *ptr;
-  struct passwd *pw;
-
-  /* get a zsig, if not given */
-  if (z->zsig==NULL) {
-    zsigproc = owl_global_get_zsigproc(&g);
-    zsigowlvar = owl_global_get_zsig(&g);
-    zsigzvar = owl_zephyr_get_variable("zwrite-signature");
-
-    if (zsigowlvar && *zsigowlvar) {
-      z->zsig=owl_get_iso_8859_1_if_possible(zsigowlvar);
-    } else if (zsigproc && *zsigproc) {
-      FILE *file;
-      char buff[LINE], *openline;
-      
-      /* simple hack for now to nuke stderr */
-      openline=owl_malloc(strlen(zsigproc)+40);
-      strcpy(openline, zsigproc);
-#if !(OWL_STDERR_REDIR)
-      strcat(openline, " 2> /dev/null");
-#endif
-      file=popen(openline, "r");
-      owl_free(openline);
-      if (!file) {
-	if (zsigzvar && *zsigzvar) {
-	  z->zsig=owl_get_iso_8859_1_if_possible(zsigzvar);
-	}
-      } else {
-	z->zsig=owl_malloc(LINE*5);
-	strcpy(z->zsig, "");
-	while (fgets(buff, LINE, file)) { /* wrong sizing */
-	  strcat(z->zsig, buff);
-	}
-	pclose(file);
-	if (z->zsig[strlen(z->zsig)-1]=='\n') {
-	  z->zsig[strlen(z->zsig)-1]='\0';
-	}
-      }
-    } else if (zsigzvar) {
-      z->zsig=owl_get_iso_8859_1_if_possible(zsigzvar);
-    } else if (((pw=getpwuid(getuid()))!=NULL) && (pw->pw_gecos)) {
-      z->zsig=owl_get_iso_8859_1_if_possible(pw->pw_gecos);
-      ptr=strchr(z->zsig, ',');
-      if (ptr) {
-	ptr[0]='\0';
-      }
-    }
-  }
-}
-
-void owl_zwrite_send_ping(owl_zwrite *z)
-{
-  int i, j;
-  char to[LINE];
-
-  if (z->noping) return;
-  
-  if (strcasecmp(z->class, "message") ||
-      strcasecmp(z->inst, "personal")) {
-    return;
-  }
-
-  /* if there are no recipients we won't send a ping, which
-     is what we want */
-  j=owl_list_get_size(&(z->recips));
-  for (i=0; i<j; i++) {
-    if (strcmp(z->realm, "")) {
-      sprintf(to, "%s@%s", (char *) owl_list_get_element(&(z->recips), i), z->realm);
-    } else {
-      strcpy(to, owl_list_get_element(&(z->recips), i));
-    }
-    send_ping(to);
-  }
-
-}
-
-void owl_zwrite_set_message(owl_zwrite *z, char *msg)
-{
-  int i, j;
-  char toline[LINE];
-  char *tmp = NULL;
-
-  if (z->message) owl_free(z->message);
-
-  j=owl_list_get_size(&(z->recips));
-  if (j>0 && z->cc) {
-    strcpy(toline, "CC: ");
-    for (i=0; i<j; i++) {
-      if (strcmp(z->realm, "")) {
-	sprintf(toline + strlen(toline), "%s@%s ", (char *) owl_list_get_element(&(z->recips), i), z->realm);
-      } else {
-	sprintf(toline + strlen(toline), "%s ", (char *) owl_list_get_element(&(z->recips), i));
-      }
-    }
-    tmp = owl_get_iso_8859_1_if_possible(msg);
-    z->message=owl_sprintf("%s\n%s", toline, tmp);
-  } else {
-    z->message=owl_get_iso_8859_1_if_possible(msg);
-  }
-  if (tmp) owl_free(tmp);
-}
-
-char *owl_zwrite_get_message(owl_zwrite *z)
-{
-  if (z->message) return(z->message);
-  return("");
-}
-
-int owl_zwrite_is_message_set(owl_zwrite *z)
-{
-  if (z->message) return(1);
-  return(0);
-}
-
-int owl_zwrite_send_message(owl_zwrite *z)
-{
-  int i, j;
-  char to[LINE];
-
-  if (z->message==NULL) return(-1);
-
-  j=owl_list_get_size(&(z->recips));
-  if (j>0) {
-    for (i=0; i<j; i++) {
-      if (strcmp(z->realm, "")) {
-	sprintf(to, "%s@%s", (char *) owl_list_get_element(&(z->recips), i), z->realm);
-      } else {
-	strcpy(to, owl_list_get_element(&(z->recips), i));
-      }
-      send_zephyr(z->opcode, z->zsig, z->class, z->inst, to, z->message);
-    }
-  } else {
-    sprintf(to, "@%s", z->realm);
-    send_zephyr(z->opcode, z->zsig, z->class, z->inst, to, z->message);
-  }
-  return(0);
-}
-
-int owl_zwrite_create_and_send_from_line(char *cmd, char *msg)
-{
-  owl_zwrite z;
-  int rv;
-  rv=owl_zwrite_create_from_line(&z, cmd);
-  if (rv) return(rv);
-  if (!owl_zwrite_is_message_set(&z)) {
-    owl_zwrite_set_message(&z, msg);
-  }
-  owl_zwrite_populate_zsig(&z);
-  owl_zwrite_send_message(&z);
-  owl_zwrite_free(&z);
-  return(0);
-}
-
-char *owl_zwrite_get_class(owl_zwrite *z)
-{
-  return(z->class);
-}
-
-char *owl_zwrite_get_instance(owl_zwrite *z)
-{
-  return(z->inst);
-}
-
-char *owl_zwrite_get_opcode(owl_zwrite *z)
-{
-  return(z->opcode);
-}
-
-void owl_zwrite_set_opcode(owl_zwrite *z, char *opcode)
-{
-  if (z->opcode) owl_free(z->opcode);
-  z->opcode=owl_get_iso_8859_1_if_possible(opcode);
-}
-
-char *owl_zwrite_get_realm(owl_zwrite *z)
-{
-  return(z->realm);
-}
-
-char *owl_zwrite_get_zsig(owl_zwrite *z)
-{
-  if (z->zsig) return(z->zsig);
-  return("");
-}
-
-void owl_zwrite_get_recipstr(owl_zwrite *z, char *buff)
-{
-  int i, j;
-
-  strcpy(buff, "");
-  j=owl_list_get_size(&(z->recips));
-  for (i=0; i<j; i++) {
-    strcat(buff, owl_list_get_element(&(z->recips), i));
-    strcat(buff, " ");
-  }
-  buff[strlen(buff)-1]='\0';
-}
-
-int owl_zwrite_get_numrecips(owl_zwrite *z)
-{
-  return(owl_list_get_size(&(z->recips)));
-}
-
-char *owl_zwrite_get_recip_n(owl_zwrite *z, int n)
-{
-  return(owl_list_get_element(&(z->recips), n));
-}
-
-int owl_zwrite_is_personal(owl_zwrite *z)
-{
-  /* return true if at least one of the recipients is personal */
-  int i, j;
-  char *foo;
-
-  j=owl_list_get_size(&(z->recips));
-  for (i=0; i<j; i++) {
-    foo=owl_list_get_element(&(z->recips), i);
-    if (foo[0]!='@') return(1);
-  }
-  return(0);
-}
-
-void owl_zwrite_free(owl_zwrite *z)
-{
-  owl_list_free_all(&(z->recips), &owl_free);
-  if (z->class) owl_free(z->class);
-  if (z->inst) owl_free(z->inst);
-  if (z->opcode) owl_free(z->opcode);
-  if (z->realm) owl_free(z->realm);
-  if (z->message) owl_free(z->message);
-  if (z->zsig) owl_free(z->zsig);
-}
