changeset 7014:67c4e9d39242

[gaim-migrate @ 7577] Here it is, the bulk of the new Jabber prpl. Left to do: - Implement registration - Implement password changing - Keep track of conversation threads (since I apparently have to) - Fix the bugs that always magically appear in code after I commit committer: Tailor Script <tailor@pidgin.im>
author Nathan Walp <nwalp@pidgin.im>
date Mon, 29 Sep 2003 15:23:19 +0000
parents 859cafb6433f
children dece74f05509
files ChangeLog src/html.c src/protocols/jabber/.cvsignore src/protocols/jabber/AUTHORS.libjabber src/protocols/jabber/AUTHORS.libxode src/protocols/jabber/COPYING.libjabber src/protocols/jabber/COPYING.libxode src/protocols/jabber/ChangeLog.libjabber src/protocols/jabber/ChangeLog.libxode src/protocols/jabber/INSTALL.libjabber src/protocols/jabber/INSTALL.libxode src/protocols/jabber/JEPS src/protocols/jabber/Makefile.am src/protocols/jabber/NEWS.libjabber src/protocols/jabber/NEWS.libxode src/protocols/jabber/README.libjabber src/protocols/jabber/README.libxode src/protocols/jabber/TODO.libjabber src/protocols/jabber/asciitab.h src/protocols/jabber/auth.c src/protocols/jabber/auth.h src/protocols/jabber/buddy.c src/protocols/jabber/buddy.h src/protocols/jabber/chat.c src/protocols/jabber/chat.h src/protocols/jabber/expat.c src/protocols/jabber/genhash.c src/protocols/jabber/hashtable.c src/protocols/jabber/hashtable.h src/protocols/jabber/iasciitab.h src/protocols/jabber/iq.c src/protocols/jabber/iq.h src/protocols/jabber/jabber.c src/protocols/jabber/jabber.h src/protocols/jabber/jconn.c src/protocols/jabber/jid.c src/protocols/jabber/jpacket.c src/protocols/jabber/jutil.c src/protocols/jabber/jutil.h src/protocols/jabber/karma.c src/protocols/jabber/latin1tab.h src/protocols/jabber/lib.h src/protocols/jabber/libxode.h src/protocols/jabber/log.c src/protocols/jabber/log.h src/protocols/jabber/message.c src/protocols/jabber/message.h src/protocols/jabber/nametab.h src/protocols/jabber/parser.c src/protocols/jabber/parser.h src/protocols/jabber/pool.c src/protocols/jabber/pproxy.c src/protocols/jabber/presence.c src/protocols/jabber/presence.h src/protocols/jabber/rate.c src/protocols/jabber/roster.c src/protocols/jabber/roster.h src/protocols/jabber/sha.c src/protocols/jabber/snprintf.c src/protocols/jabber/socket.c src/protocols/jabber/str.c src/protocols/jabber/utf8tab.h src/protocols/jabber/xhash.c src/protocols/jabber/xmldef.h src/protocols/jabber/xmlnode.c src/protocols/jabber/xmlnode.h src/protocols/jabber/xmlparse.c src/protocols/jabber/xmlparse.h src/protocols/jabber/xmlrole.c src/protocols/jabber/xmlrole.h src/protocols/jabber/xmltok.c src/protocols/jabber/xmltok.h src/protocols/jabber/xmltok_impl.c src/protocols/jabber/xmltok_impl.h src/protocols/jabber/xmltok_ns.c src/protocols/jabber/xstream.c
diffstat 74 files changed, 4370 insertions(+), 22463 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Mon Sep 29 13:00:55 2003 +0000
+++ b/ChangeLog	Mon Sep 29 15:23:19 2003 +0000
@@ -3,6 +3,7 @@
 version 0.71
 	* Display AIM away messages in the tooltip for buddies when 
 	  they are away.
+	* Re-write of Jabber protocol plugin
 
 version 0.70 (09/28/2003):
 	* Implemented Yahoo's new authentication method (Cerulean Studios)
--- a/src/html.c	Mon Sep 29 13:00:55 2003 +0000
+++ b/src/html.c	Mon Sep 29 15:23:19 2003 +0000
@@ -468,7 +468,9 @@
 				ALLOW_TAG("h4");
 				ALLOW_TAG("h5");
 				ALLOW_TAG("h6");
-				ALLOW_TAG("html");
+				/* we only allow html to start the message */
+				if(c == html)
+					ALLOW_TAG("html");
 				ALLOW_TAG_ALT("i", "em");
 				ALLOW_TAG_ALT("italic", "em");
 				ALLOW_TAG("li");
--- a/src/protocols/jabber/.cvsignore	Mon Sep 29 13:00:55 2003 +0000
+++ b/src/protocols/jabber/.cvsignore	Mon Sep 29 15:23:19 2003 +0000
@@ -2,30 +2,11 @@
 Makefile
 .deps
 .libs
-expat.lo
-genhash.lo
-hashtable.lo
-jabber.lo
-jconn.lo
-jid.lo
-jpacket.lo
-jutil.lo
-karma.lo
-libjabber.la
-log.lo
-pool.lo
-pproxy.lo
-rate.lo
-sha.lo
-snprintf.lo
-socket.lo
-str.lo
-xhash.lo
-xmlnode.lo
-xmlparse.lo
-xmlrole.lo
-xmltok.lo
-xstream.lo
+*.lo
+*.la
+*.dll
 *.def
 *.lib
-*.dll
+.*.swp
+.*.swo
+.todo.*
--- a/src/protocols/jabber/AUTHORS.libjabber	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
--- AUTHORS for libjabber  - A library for the Jabber server.
-
-Authors:
-	Scott Robinson <quad@jabber.org>
-	Gurer Ozen <palpa@jabber.org>
-	Jeremie Miller <jer@jeremie.com>
--- a/src/protocols/jabber/AUTHORS.libxode	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
--- AUTHORS for libxode  - A library of XML and string helper functions.
-
-Authors:
-        Jeremie Miller <jer@jabber.org>
-        Thomas Muldowney <temas@box5.net>
-        Dave Smith <dave@jabber.org>
--- a/src/protocols/jabber/COPYING.libjabber	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,340 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, 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 software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, 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 redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-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 give any other recipients of the Program a copy of this License
-along with the Program.
-
-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 Program or any portion
-of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-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 Program, 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 Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) 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; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, 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 executable.  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.
-
-If distribution of executable or 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 counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program 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.
-
-  5. 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 Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program 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.
-
-  7. 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 Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program 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 Program.
-
-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.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program 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.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the 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 Program
-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 Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, 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
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), 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 Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  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 program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    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
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year  name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
--- a/src/protocols/jabber/COPYING.libxode	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,340 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, 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 software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, 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 redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-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 give any other recipients of the Program a copy of this License
-along with the Program.
-
-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 Program or any portion
-of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-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 Program, 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 Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) 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; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, 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 executable.  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.
-
-If distribution of executable or 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 counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program 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.
-
-  5. 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 Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program 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.
-
-  7. 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 Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program 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 Program.
-
-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.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program 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.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the 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 Program
-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 Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, 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
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), 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 Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  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 program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    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
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year  name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
--- a/src/protocols/jabber/ChangeLog.libjabber	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,621 +0,0 @@
-2000-10-30  temas <temas@box5.net> (temas@jabber.org)
-    
-    * src/Makefile.am:  new libtool version info
-
-    * configure.in:  1.2 final version
-
-2000-10-20  jer <jer@jabber.org>
-
-    * jpacket.c: fixed it so that we actually check the full packet name (we shouldn't have been cheating) and flagged when bad addresses were used
-
-2000-10-08  jer <jer@jabber.org>
-
-    * rate.c: renamed to jlimit_*
-
-2000-10-06  madcat <palpa@jabber.org>
-
-    * jconn.c: jab_auth is not automated anymore.
-    * jconn.c: fixed seg fault bug in jab_start() (thanks Marco! :)
-
-2000-06-18  spectre <spectre@portent.net>
-
-    * jconn.c: automated jab_auth, shouldn't be called manually unless
-	       called after registering
-    * jconn.c: added JDEBUG #ifdefs to monitor incoming/outgoing xml stream
-    * jconn.c: added jab_reg, registering of users
-    * jutil.c: added jutil_msgnew, creating of message packets
-    * jabber.h: added message types to use with jutil_msgnew
-    * jabber.h: new state (JCONN_STATE_AUTH) for automated authorizing
-
-2000-06-15  madcat <palpa@jabber.org>
-
-    * jabberx removed from build system, it is now on jabber-x.sourceforge.net
-    * jabber.h: C++ friendlyness (conditionally compiled extern "C" {} stuff)
-
-2000-06-01  madcat <palpa@jabber.org>
-
-    * jconn.c: support for anonymous accounts, and new jab_getid() function
-
-2000-05-24  madcat <palpa@jabber.org>
-
-    * jabberx: new curses gui
-
-2000-05-21  madcat <palpa@jabber.org>
-
-    * jconn.c: new event handler system, they return jpackets now.
-               added comments to the functions
-
-    * jabberx: updated to new api
-
-2000-05-02  temas <temas@box5.net>
-
-    * configure.in:  fixes for the libxode checks
-
-2000-05-01  jer <jeremie@jabber.org>
-
-    * two bug fixes, type=normal and pproxy brokenedness
-
-    * -Wall
-
-    * astyle 4 space indent enforced
-
-2000-04-28  jer <jeremie@jabber.org>
-
-    * jpacket.c: message type=headline
-
-    * pproxy.c: update for pool heaps
-
-2000-04-25  jer <jeremie@jabber.org>
-
-    * jid.c: new jid_cmpx() function to compare by optional parts
-
-    * pproxy.c: dumb bug preventing the use of _primary() and user@host addresses
-
-    * util.c: the register utility was broke after 100 keys :)
-
-2000-04-22  jer <jeremie@jabber.org>
-
-    * by popular demand, the server now eats presence type=available (and normalizes it)
-
-2000-04-18  jer <jeremie@jabber.org>
-
-    * 1.0pre2
-
-2000-04-17  jer <jeremie@jabber.org>
-
-    * jid.c: username limit at 255
-
-    * log.c: zonestr now in libxode
-
-2000-04-12  temas <temas@box5.net>
-
-	* Build fixes for non standard prefixes
-
-2000-04-12  jer <jeremie@jabber.org>
-
-    * roll to 1.0pre1
-
-    * util.c: jutil_regkey to generate and validate registration keys
-
-2000-04-10  jer <jeremie@jabber.org>
-
-    * jid.c: jid_cmp was FUBAR under certian compares, ick, it's better now
-
-    * pproxy.c: I rewrote it all... why?  because it scared me
-
-    * util.c: lots of goodies transferred from jserver to share with all
-
-2000-03-28  temas <temas@box5.net>
-
-	* configure.in:  no more NONE
-
-2000-03-28  jer <jeremie@jabber.org>
-
-    * 0.9!
-
-2000-03-27	e-t	<eliot@landrum.cx>
-
-	* Updated README a bit. Not much changed.
-	* Commited some debian/ files that were missing...
-
-2000-03-27  jer <jeremie@jabber.org>
-
-    * jid.c: space character is illegal too :)
-
-2000-03-19  temas <temas@box5.net>
-
-	* RC
-
-2000-03-19  jer <jeremie@jabber.org>
-
-    * jpacket.c: a little more careful about jpackets now, strict
-
-2000-03-17  temas <temas@box5.net>
-
-	* configure.in:  libxode checks better
-
-	* bump to pre4
-
-2000-03-15  jer <jeremie@jabber.org>
-
-    * jid.c: now EXTRA cautious about the jid, validating the characters and length in the username/hostname
-
-2000-03-13  jer <jeremie@jabber.org>
-
-    * pproxy.c: presence priority is only negative for type=unavailable
-
-2000-03-12  jer <jeremie@jabber.org>
-
-    * jid.c: jid_nodescan() utility to get nodes with matchin jid's, behaving to jid matching rules
-
-    * jid.c: ignore type:, tolower server, better data validity checking, case insensitive username compares, 64 char limit on user/server
-
-2000-02-29  temas <temas@box5.net>
-
-	* Makefile.am:  get rid of common dir
-
-	* src/Makefile.am:  use the libxode stuff better
-
-	* configure.in:  libxode and common dir fixes
-
-	* ChangeLog:  double spaced e-t's entries cause I like it that way =)
-
-2000-02-29  e-t <eliot@jabber.org>
-
-    * README: general cleanup.
-	
-    * AUTHORS: general cleanup.
-	
-    * man/jabber-config.1: added, probably could use a bit more description,
-      but will do for now. (included Makefiles in man/)
-
-    * Makefile.am: added dir man/
-
-2000-02-27  jer <jeremie@jabber.org>
-
-    * jpacket.c: performance tweaks
-
-2000-02-24  jer <jeremie@jabber.org>
-
-    * common transformed to libxode, use that instead
-
-    * jpacket.c: now nulls out data upon a reset to be safer
-
-    * ppdb.c: bug, check data better!  grr
-
-    * jid.c: leaky leaky, handle memory better when appending jid's
-
-2000-02-20  e-t <eliot@jabber.org>
-
-	* README:  Kinda trashed the old one and copied/edited the Jabber standard README.
-
-2000-02-17  temas <temas@box5.net>
-
-	* Makefile.am:  don't have a macros dir anymore
-	* jabber-config.in:  cleanups
-
-	* configure.in:  pre2 roll
-
-2000-02-09  jer <jeremie@jabber.org>
-
-    * jpacket.c: added presence probe subtype
-
-2000-02-01  temas <temas@box5.net>
-
-	* jabber-config is needed for the macro stuff
-
-2000-01-31  jer <jeremie@jabber.org>
-
-    * xmlstream->jabstream: renamed all xmlstream to jabstream symbols, so they don't conflict with etherx's xmlstream
-
-2000-01-25  jer <jeremie@jabber.org>
-
-    * jpacket.c: jpacket_subtype() which breaks down the packet type further and stores it in p->subtype
-
-2000-01-06  jer <jeremie@jabber.org>
-
-    * jid.c: jid_xres() returns an xmlnode (same pool as the jid) representation of the resource and a standard query string,
-	for instance: /resource?name=value&foo=bar is an xmlnode for <resource name="value" foo="bar"/>
-
-    * fixed other header prototype misplacements
-
-2000-01-06  palpa <gozen@isbank.net.tr>
-
-    * bye libjnix, lala libjabber :)
-
-2000-01-04  palpa <gozen@isbank.net.tr>
-
-    * profile.c: from field added to jnixpf struct
-
-2000-01-03  palpa <gozen@isbank.net.tr>
-
-    * profile.c: handles jabber:iq:info queries
-
-2000-01-02  palpa <gozen@isbank.net.tr>
-
-    * jabberx fixed for new api
-
-    * auth.c: _jnix_reg() fixed
-
-    * funcs for updating roster items
-
-    * user field in the roster item struct is changed to (char*)
-      from (jid).
-
-2000-01-02  palpa <gozen@isbank.net.tr>
-
-    * jnixr_removeitem() added
-
-2000-01-01  palpa <gozen@isbank.net.tr>
-
-    * New JNIXC_ROSTER flag automatically requests roster from server.
-
-    * New roster api.
-
-    * Multiclient funcs removed & auth cb changed again.
-
-1999-12-30  scott <quad@jabber.org>
-
-    * continued adding features and breaking up jabberx. Soon, my pretty,
-        soon.
-
-    * well, y2k hath struck in some areas of the world. It's still 30 here,
-        so I'll note I've severely made jabberx awesome. Check it out o-kudasai!
-
-1999-12-30  palpa <gozen@isbank.net.tr>
-
-    * jnixprivate.h added and private defines/prototypes in
-      jnix.h are moved in it.
-
-    * com field in the roster item structure removed
-
-1999-12-29  palpa <gozen@isbank.net.tr>
-
-	* stresstest moved to test dir
-
-	* docs dir added
-
-	* some jabberx fixes
-
-	* user structure added & auth callback changed
-
-	* login(), logoff() funcs for multiclients
-
-1999-12-29  scott <quad@jabber.org>
-
-    * went to lower bandwidth node defaults
-
-    * continued improving jnixtest.
-
-    * Fixed a bit of roster parsing
-
-1999-12-28  scott <quad@jabber.org>
-
-    * Re-vamped connection
-
-    * Re-vamped rosters
-
-    * Added more management
-
-    * Fixed jnixtest to WORK
-
-    * Patched a bunch of miscellaneous bugs.
-
-    * patched a few more memory leaks
-
-1999-12-13  palpa <gozen@isbank.net.tr>
-
-	* new editNode() function
-
-	* id attribute support
-
-	* presence changed for 0.8
-
-1999-12-09  disq <disq@sanane.com>
-
-	* fixed auth/register <result> for 0.8
-
-1999-12-08  palpa <gozen@isbank.net.tr>
-
-	* test/api.html: added (not finished yet)
-
-	* node.c: msg/prs/iq things now use same set of functions
-	          old msg/prs/iq funcs removed
-
-	* jnix.c: now callbacks are global
-
-	* jnixtest.c: changed to new api
-
-1999-12-04  palpa <gozen@isbank.net.tr>
-
-	* xmlstream: removed unnecessary callback, fixed xmlstream_stop()
-
-	* jnix: disconnect() now frees jnixc structure
-
-	* auth: fixed/changed/optimized :)
-
-	* jnixtest: auth callback support
-
-1999-12-03  disq <disq@sanane.com>
-
-	* auth.c: added authorization & registration response callback
-
-	* iq.c: changed jnix_findIQitem, now it takes the jnixqitem as a parameter.
-					this way we can use this function to search attributes
-	* jnix.c: frees iq before we call j->cbRoster
-
-1999-11-25  palpa <gozen@isbank.net.tr>
-
-	* presence.c, iq.c: send functions changed for using spool
-
-1999-11-25  palpa <gozen@isbank.net.tr>
-
-	* message.c: sendMessage() now creates xml with spool functions
-	                           (faster and uses less memory)
-
-1999-11-24  palpa <gozen@isbank.net.tr>
-
-	* iq.c: newIQ() uses vararg arguments
-
-1999-11-24  palpa <gozen@isbank.net.tr>
-
-	* jnix.c: JNIXC_NEWUSER now sends auth request after registration
-
-	* jnixtext.c: new command line option, -n : registers new user
-
-1999-11-23  palpa <gozen@isbank.net.tr>
-
-	* roster.c: parseRoster now correctly gets comment information
-
-	* jnixtext.c: status command renamed to presence
-	              added probe command
-
-1999-11-22  palpa <gozen@isbank.net.tr>
-
-	* i did some api changes :}
-	  nspace field in the jnixq struct renamed to xmlns
-	  connect() now has a flags (int) field
-	  some #define's changed, look jnix.h for them
-	  old newXXX funcs removed, now all newXXX funcs takes vararg parameters
-
-	* if you call connect with JNIXC_NEWUSER flag, it registers
-	  that user (needs some work to send auth request after that :)
-
-	* new addIQitem() function supports query tags with attributes.
-
-	* roster.c and jnixtest.c patched for this changes.
-
-	* this changes are not fully tested, sorry :}
-
-1999-11-22  disq <disq@sanane.com>
-
-	* roster.c: added remaining roster routines, does not work mainly ;)
-	* jnixtest.c: updated
-
-1999-11-22  palpa <gozen@isbank.net.tr>
-
-	* iq.c: parseIQ() now parses attributes of tags too
-
-1999-11-22  palpa <gozen@isbank.net.tr>
-
-	* auth.c: jnix_register() added
-	  (jnix_auth() moved to this file too)
-
-1999-11-22  disq <disq@sanane.com>
-
-	* roster.c: added, parseRoster is there, untested
-
-1999-11-21  palpa <gozen@isbank.net.tr>
-
-	* presence.c: changes for jnixp from field
-
-1999-11-21  palpa <gozen@isbank.net.tr>
-
-	* jnix_auth(jnixc j, char *user, char* pass) added to api
-	  This is for multiclients, jnix_connect() automatically
-	  calls it for first user of that connection.
-
-	* message.c: now fully supports jnixm from field.
-
-	* jnix.c: sends auth request after receiving stream tag.
-
-1999-11-20  tcharron >tcharron@ductape.net
-
-        * More changes to StressTest.
-        * message.c: _jnix_parsenode() Changed so to field is populated
-          by the jnixc user field if not specificaly stated in the message
-
-1999-11-20  palpa <gozen@isbank.net.tr>
-
-	* presence.c: createPresence(int type, ...) added
-
-1999-11-19  temas <temas@box5.net>
-
-	* added the header to files
-
-1999-11-17  palpa <gozen@isbank.net.tr>
-
-	* createMessage() fixes/improvements
-
-1999-11-17  palpa <gozen@isbank.net.tr>
-
-	* createMessage(char *to, ...) added to message api
-
-1999-11-16  TCharron <tcharron@ductape.net>
-
-        * StressTest will now use full threading, and take
-          command line option.
-
-1999-11-15  TCharron <tcharron@ductape.net>
-
-        * Added StressTest directory.  This is going to be a program
-          to put the servers under incredible load.  I'm currently using
-          it to simply login over 900 simo users.  In the future, they'll
-          message eachother, go on and off line, and change status
-          messages.  More to come..
-
-          (PPsst..  No comments..  Shoot me..)
-
-1999-11-15  palpa <gozen@isbank.net.tr>
-
-	* sendIQ completed
-
-1999-11-13  palpa <gozen@isbank.net.tr>
-
-	* parseIQ stuff
-
-1999-11-13  palpa <gozen@isbank.net.tr>
-
-	* jnixm/p/q structures now have 'from' and 'to' fields instead of 'user'
-	  (necessary for multi client support)
-
-1999-11-12  palpa <gozen@isbank.net.tr>
-
-	* id field added to jnixm, jnixp, jnixq structures
-
-	* iq callback partially working
-
-	* sendPresence now sends priority
-
-1999-11-12  palpa <gozen@isbank.net.tr>
-
-	* fixes for new jdebug() stuff
-
-1999-11-09  palpa <gozen@isbank.net.tr>
-
-	* jnix_isOnline() function added
-
-	* jnix now parses priority data in incoming message and presence nodes
-
-1999-11-09  palpa <gozen@isbank.net.tr>
-
-	* establish-close callbacks renamed to online-offline
-
-	* offline callback returns the reason of disconnection
-
-	* jnix prefix added to callback typedefs
-
-	* test client fixed for this changes
-
-1999-11-09  spectre <spectre@winterland.net>
-
-	* added presence stuff, shortcuts and reply cmd to test client
-	
-	* and also some visual improvements
-
-1999-11-09  disq <disq@sanane.com>
-
-	* fixed some /* bug/typo in jnix.h
-
-	* debug(), insane(), _log() now defined even if DEBUG is not defined, but
-		they're empty functions
-
-1999-11-07  palpa <gozen@isbank.net.tr>
-
-	* name of the test client changed to jnixtest
-
-	* presence.c: jnix_sendMessage() added
-
-1999-11-07  disq <disq@sanane.com>
-
-	* fixed typo in presence.c, now compiles
-
-1999-11-07  palpa <gozen@isbank.net.tr>
-
-	* jnix.c: jnix_disconnect() added
-
-	* presence.c: now it parses incoming presence nodes
-
-	* message.c: some fixes
-
-1999-11-07  palpa <gozen@isbank.net.tr>
-
-	* presence.c added for putting presence handling functions in
-
-	* jnix_freeMessage() added
-
-	* jnix.c and xmlstream.c now fully uses memory pools
-
-1999-11-06  palpa <gozen@isbank.net.tr>
-
-	* jnix_newMessage and jnix_chatMessage added
-
-1999-11-06  spectre <spectre@winterland.net>
-
-	* onMessage callback gets jnixm structure now
-	
-	* new ncurses based quick'n'dirty testclient
-
-1999-11-05  temas <temas@box5.net>
-	
-	* test/Makefile.am:  testclient should build..
-
-	* configure.in:  Fixed up some of the checks
-
-	* acconfig.h:  Make this file so we get a config.h
-
-1999-11-05  palpa <gozen@isbank.net.tr>
-
-	* xmlstream api changed
-
-1999-11-04  palpa <gozen@isbank.net.tr>
-
-	* xmlstream.c now uses string pools
-
-1999-11-04  palpa <gozen@isbank.net.tr>
-
-	* parseMessage() is working
-
-1999-11-03  palpa <gozen@isbank.net.tr>
-
-	* simple test client added
-
-	* log stuff fixed
-
-	* TODO file added
-
-1999-11-03  palpa <gozen@isbank.net.tr>
-
-	* connect now takes a jid argument instead of server and user
-
-	* 0.6 stuff removed
-
-1999-11-03  palpa <gozen@isbank.net.tr>
-
-	* jnix_sendMessage (v0.7 protocol)
-
-	* new jnix_auth for v0.7
-
-1999-11-03  palpa <gozen@isbank.net.tr>
-
-	* added message.c for putting message handling functions in
-
-	* connection close/establish and message callbacks are working
-
-1999-11-02  palpa <gozen@isbank.net.tr>
-
-	* connect, poll, setcb and fd functions implemented
-
-	* pth and tstream stuff removed from xmlstream.c
-
-	* configure.in and makefile.am files in include dir fixed
-
-1999-10-31  Jer <jeremie@jabber.org>
-
-	* added xmlstream code from jlib for porting
-
-	* fixing includes for common/include
-
-	* jnix.h: rough API attempt
-
-1999-10-30  temas <temas@box5.net>
-	
-	* now use the common dir
-
-1999-10-29  temas <temas@box5.net>
-
-	* autogen.sh:  this is libjnix not jlib
-
-1999-10-29  Jer <jeremie@jabber.org>
-
-	* birth!  stole most of this from jlib
--- a/src/protocols/jabber/ChangeLog.libxode	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,206 +0,0 @@
-2000-10-30  temas   <temas@box5.net> (temas@jabber.org)
-    
-    * include/libxode.h:  Solaris compiler warnings
-
-    * src/Makefile.am:  updated libtool version
-
-    * configure.in:  1.2 version
-
-2000-10-25  jeremie <jer@jabber.org>
-
-    * pool.c: debug stuff is working again and cool now :)
-
-2000-10-23  temas <temas@box5.net> (temas@jabber.org)
-
-    * sha.c:  replaced with a version from Mozilla, works again for real
-
-2000-10-20  temas <temas@box5.net> (temas@jabber.org)
-
-    * sha.c:  no more memory overrun... exploring other possible bugs
-
-2000-10-06  jeremie <jer@jabber.org>
-
-    * xstream.c: bug in XSTREAM_ERR event, was passing an overloaded xmlnode (DUH!), it's now a normal <error>error message</error> node that has to be free'd like any other
-
-2000-09-26  jeremie <jer@jabber.org>
-
-    * xstream.c: bug in put_vattrib() fixed
-
-2000-08-05  jeremie <jer@jabber.org>
-
-    * xstream.c: moved primatives for xmlstream from libetherx to libxode, much cleaner and nicer now and usable in more places independent of IO
-
-2000-06-15  madcat <palpa@jabber.org>
-
-    * xmlnode.c: static keyword added to local functions
-    * libxode.h: C++ friendlyness (conditionally compiled extern "C" {} stuff)
-
-2000-05-22  madcat <palpa@jabber.org>
-
-    * sha.c: endianness fix
-
-2000-05-20  madcat <palpa@jabber.org>
-
-    * xmlnode.c xmlnode2str() : indentation fixed, root node with no child problem fixed
-
-2000-05-13  madcat <palpa@jabber.org>
-
-    * xmlnode.c: added comments to some functions
-    * xmlnode.c: xode_node2str() morphed into xmlnode2str()
-    * README: pth dependency statement removed
-
-2000-05-06  madcat <palpa@jabber.org>
-
-    * new function: xode_node2str()
-    it's the non-recursive version of xmlnode2str()
-
-2000-05-03  jer <jeremie@jabber.org>
-
-    * pool.c: last minute fixes, important part is the byte boundary fix for some platforms to prevent a Bus Error
-
-2000-05-01  jer <jeremie@jabber.org>
-
-    * astyle of 4 space indent applied to *.c
-
-2000-05-01  temas <temas@box5.net>
-
-    * sha.c:  moved to uint32
-    
-    * configure.in:  check some type sizes
-
-    * libxode.h:  define uint32 from size checks
-
-2000-04-29  madcat <palpa@jabber.org>
-
-    * str.c: evil strcat() in spool_print() replaced with j_strcat()
-
-2000-04-28  jer <jeremie@jabber.org>
-
-	* str.c: added spools() utility wrapper around spool_*
-
-	* pool.c: rewrite to use heaps, much more efficient and stuff, and modular cleanup is built into the pool now
-
-2000-04-26  temas <temas@box5.net>
-
-    * SHA1 is fixed, and no longer requires endian.h
-
-    * libxode-config is created
-
-2000-04-22  jer <jeremie@jabber.org>
-
-	* str.c: added simple base64 decode
-
-2000-04-20  jer <jeremie@jabber.org>
-
-	* str.c: added some more convenience wrappers
-
-2000-04-18  jer <jeremie@jabber.org>
-
-	* 1.0pre2
-
-2000-04-17  jer <jeremie@jabber.org>
-
-	* str.c: zonestr
-
-	* pool.c: labels and better debugging
-
-2000-04-14  jer <jeremie@jabber.org>
-
-	* xmlnode.c: made xmlnode_get_data() a little smarter, searching for it
-
-2000-04-12  jer <jeremie@jabber.org>
-
-	* 1.0pre1
-
-	* added str_hash_code function for the ghash utility
-
-2000-04-11  temas <temas@box5.net>
-
-	* hash generation routines moved into libxode
-
-	* sha support is now built in, supplies 4 functions to the users see sha.c
-	for more info
-
-2000-03-28  jer <jeremie@jabber.org>
-
-	* 0.9!
-
-2000-03-27	e-t	<eliot@landrum.cx>
-
-	* README: minor updates.
-
-2000-03-19  temas <temas@box5.net
-	
-	* RC
-
-2000-03-17  temas <temas@box5.net>
-
-	* quick bump to pre4
-
-2000-03-12  jer <jeremie@jabber.org>
- 
-	* xmlnode.c: xmlnode_insert_cdata() didn't make sure the parent existed, duh
-
-2000-03-02  temas <temas@box5.net>
-
-	* src/snprintf.c:  Use apaches snprintf replacement
-
-	* include/libxode.h:  patch up for snprintf
-
-2000-02-29  temas <temas@box5.net>
-
-	* configure.in:  pre3
-
-	* snprintf.c:  make this not build correctly if certain defines are set
-	
-	* ChangeLog:  cleaned up jer's mess
-
-2000-02-29  e-t <eliot@landrum.cx>
-
-        * Added a complete README.
-        * Added a complete AUTHORS.
-
-2000-02-27  jer <jeremie@jabber.org>
-
-	* pool.c: now has a debug version that tracks all stats
-
-2000-02-23  temas <temas@box5.net>
-	
-	* moved the common dir into what is now known as libxode
-
-2000-02-21  jer <jeremie@jabber.org>
- 
-	* xmlnode.c: xmlnode_get_tag() had a bug under certian queries
-
-2000-01-30  jer <jeremie@jabber.org>
- 
-	* xmlnode.c: few places in the core functions that weren't too 
-	tolerant of bad data :)
-
-2000-01-28  jer <jeremie@jabber.org>
- 
-	* xmlnode.c: fixed bug in xmlnode_get_data with parsing NTYPE_ATTRIB nodes
-
-	* xmlnode.c: fixed bug in xmlnode_get_tag, a check failed and ?queries 
-	would fail
-
-	* xmlnode.c: created xmlnode_insert_tag_node() for convenience
-
-2000-01-22  jer <jeremie@jabber.org>
- 
-	* xmlnode.c: added xmlnode_new_tag_pool() and xmlnode_dup_pool() 
-	convenience functions to force the pool to use
-
-2000-01-19  jer <jeremie@jabber.org>
- 
-	* xmlnode.c: changed xmlnode_get_data() to automatically do 
-	xmlnode_get_firstchild if you pass it a tag
-
-	* xmlnode.c: upgraded xmlnode_get_tag() to support queries, and 
-	convenience xmlnode_get_tag_data()
-
-2000-01-19  jer <jeremie@jabber.org>
- 
-	* pool.c: added pool_size(p) to return the bytes used in the pool
-
-	* added ChangeLog for common
--- a/src/protocols/jabber/INSTALL.libjabber	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-Basic Installation
-==================
-
-   These are generic installation instructions.
-
-   The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation.  It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions.  Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, a file
-`config.cache' that saves the results of its tests to speed up
-reconfiguring, and a file `config.log' containing compiler output
-(useful mainly for debugging `configure').
-
-   If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release.  If at some point `config.cache'
-contains results you don't want to keep, you may remove or edit it.
-
-   The file `configure.in' is used to create `configure' by a program
-called `autoconf'.  You only need `configure.in' if you want to change
-it or regenerate `configure' using a newer version of `autoconf'.
-
-The simplest way to compile this package is:
-
-  1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.  If you're
-     using `csh' on an old version of System V, you might need to type
-     `sh ./configure' instead to prevent `csh' from trying to execute
-     `configure' itself.
-
-     Running `configure' takes awhile.  While running, it prints some
-     messages telling which features it is checking for.
-
-  2. Type `make' to compile the package.
-
-  3. Optionally, type `make check' to run any self-tests that come with
-     the package.
-
-  4. Type `make install' to install the programs and any data files and
-     documentation.
-
-  5. You can remove the program binaries and object files from the
-     source code directory by typing `make clean'.  To also remove the
-     files that `configure' created (so you can compile the package for
-     a different kind of computer), type `make distclean'.  There is
-     also a `make maintainer-clean' target, but that is intended mainly
-     for the package's developers.  If you use it, you may have to get
-     all sorts of other programs in order to regenerate files that came
-     with the distribution.
-
-Compilers and Options
-=====================
-
-   Some systems require unusual options for compilation or linking that
-the `configure' script does not know about.  You can give `configure'
-initial values for variables by setting them in the environment.  Using
-a Bourne-compatible shell, you can do that on the command line like
-this:
-     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
-
-Or on systems that have the `env' program, you can do it like this:
-     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
-
-Compiling For Multiple Architectures
-====================================
-
-   You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory.  To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'.  `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script.  `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
-   If you have to use a `make' that does not supports the `VPATH'
-variable, you have to compile the package for one architecture at a time
-in the source code directory.  After you have installed the package for
-one architecture, use `make distclean' before reconfiguring for another
-architecture.
-
-Installation Names
-==================
-
-   By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc.  You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
-
-   You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files.  If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
-
-   In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
-kinds of files.  Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
-   If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
-   Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System).  The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
-   For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
-   There may be some features `configure' can not figure out
-automatically, but needs to determine by the type of host the package
-will run on.  Usually `configure' can figure that out, but if it prints
-a message saying it can not guess the host type, give it the
-`--host=TYPE' option.  TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name with three fields:
-     CPU-COMPANY-SYSTEM
-
-See the file `config.sub' for the possible values of each field.  If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the host type.
-
-   If you are building compiler tools for cross-compiling, you can also
-use the `--target=TYPE' option to select the type of system they will
-produce code for and the `--build=TYPE' option to select the type of
-system on which you are compiling the package.
-
-Sharing Defaults
-================
-
-   If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists.  Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Operation Controls
-==================
-
-   `configure' recognizes the following options to control how it
-operates.
-
-`--cache-file=FILE'
-     Use and save the results of the tests in FILE instead of
-     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
-     debugging `configure'.
-
-`--help'
-     Print a summary of the options to `configure', and exit.
-
-`--quiet'
-`--silent'
-`-q'
-     Do not print messages saying which checks are being made.  To
-     suppress all normal output, redirect it to `/dev/null' (any error
-     messages will still be shown).
-
-`--srcdir=DIR'
-     Look for the package's source code in directory DIR.  Usually
-     `configure' can determine that directory automatically.
-
-`--version'
-     Print the version of Autoconf used to generate the `configure'
-     script, and exit.
-
-`configure' also accepts some other, not widely useful, options.
--- a/src/protocols/jabber/INSTALL.libxode	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +0,0 @@
-Basic Installation
-==================
-
-   These are generic installation instructions.
-
-   The `configure' shell script attempts to guess correct values for
-various system-dependent variables used during compilation.  It uses
-those values to create a `Makefile' in each directory of the package.
-It may also create one or more `.h' files containing system-dependent
-definitions.  Finally, it creates a shell script `config.status' that
-you can run in the future to recreate the current configuration, a file
-`config.cache' that saves the results of its tests to speed up
-reconfiguring, and a file `config.log' containing compiler output
-(useful mainly for debugging `configure').
-
-   If you need to do unusual things to compile the package, please try
-to figure out how `configure' could check whether to do them, and mail
-diffs or instructions to the address given in the `README' so they can
-be considered for the next release.  If at some point `config.cache'
-contains results you don't want to keep, you may remove or edit it.
-
-   The file `configure.in' is used to create `configure' by a program
-called `autoconf'.  You only need `configure.in' if you want to change
-it or regenerate `configure' using a newer version of `autoconf'.
-
-The simplest way to compile this package is:
-
-  1. `cd' to the directory containing the package's source code and type
-     `./configure' to configure the package for your system.  If you're
-     using `csh' on an old version of System V, you might need to type
-     `sh ./configure' instead to prevent `csh' from trying to execute
-     `configure' itself.
-
-     Running `configure' takes awhile.  While running, it prints some
-     messages telling which features it is checking for.
-
-  2. Type `make' to compile the package.
-
-  3. Optionally, type `make check' to run any self-tests that come with
-     the package.
-
-  4. Type `make install' to install the programs and any data files and
-     documentation.
-
-  5. You can remove the program binaries and object files from the
-     source code directory by typing `make clean'.  To also remove the
-     files that `configure' created (so you can compile the package for
-     a different kind of computer), type `make distclean'.  There is
-     also a `make maintainer-clean' target, but that is intended mainly
-     for the package's developers.  If you use it, you may have to get
-     all sorts of other programs in order to regenerate files that came
-     with the distribution.
-
-Compilers and Options
-=====================
-
-   Some systems require unusual options for compilation or linking that
-the `configure' script does not know about.  You can give `configure'
-initial values for variables by setting them in the environment.  Using
-a Bourne-compatible shell, you can do that on the command line like
-this:
-     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
-
-Or on systems that have the `env' program, you can do it like this:
-     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
-
-Compiling For Multiple Architectures
-====================================
-
-   You can compile the package for more than one kind of computer at the
-same time, by placing the object files for each architecture in their
-own directory.  To do this, you must use a version of `make' that
-supports the `VPATH' variable, such as GNU `make'.  `cd' to the
-directory where you want the object files and executables to go and run
-the `configure' script.  `configure' automatically checks for the
-source code in the directory that `configure' is in and in `..'.
-
-   If you have to use a `make' that does not supports the `VPATH'
-variable, you have to compile the package for one architecture at a time
-in the source code directory.  After you have installed the package for
-one architecture, use `make distclean' before reconfiguring for another
-architecture.
-
-Installation Names
-==================
-
-   By default, `make install' will install the package's files in
-`/usr/local/bin', `/usr/local/man', etc.  You can specify an
-installation prefix other than `/usr/local' by giving `configure' the
-option `--prefix=PATH'.
-
-   You can specify separate installation prefixes for
-architecture-specific files and architecture-independent files.  If you
-give `configure' the option `--exec-prefix=PATH', the package will use
-PATH as the prefix for installing programs and libraries.
-Documentation and other data files will still use the regular prefix.
-
-   In addition, if you use an unusual directory layout you can give
-options like `--bindir=PATH' to specify different values for particular
-kinds of files.  Run `configure --help' for a list of the directories
-you can set and what kinds of files go in them.
-
-   If the package supports it, you can cause programs to be installed
-with an extra prefix or suffix on their names by giving `configure' the
-option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-
-Optional Features
-=================
-
-   Some packages pay attention to `--enable-FEATURE' options to
-`configure', where FEATURE indicates an optional part of the package.
-They may also pay attention to `--with-PACKAGE' options, where PACKAGE
-is something like `gnu-as' or `x' (for the X Window System).  The
-`README' should mention any `--enable-' and `--with-' options that the
-package recognizes.
-
-   For packages that use the X Window System, `configure' can usually
-find the X include and library files automatically, but if it doesn't,
-you can use the `configure' options `--x-includes=DIR' and
-`--x-libraries=DIR' to specify their locations.
-
-Specifying the System Type
-==========================
-
-   There may be some features `configure' can not figure out
-automatically, but needs to determine by the type of host the package
-will run on.  Usually `configure' can figure that out, but if it prints
-a message saying it can not guess the host type, give it the
-`--host=TYPE' option.  TYPE can either be a short name for the system
-type, such as `sun4', or a canonical name with three fields:
-     CPU-COMPANY-SYSTEM
-
-See the file `config.sub' for the possible values of each field.  If
-`config.sub' isn't included in this package, then this package doesn't
-need to know the host type.
-
-   If you are building compiler tools for cross-compiling, you can also
-use the `--target=TYPE' option to select the type of system they will
-produce code for and the `--build=TYPE' option to select the type of
-system on which you are compiling the package.
-
-Sharing Defaults
-================
-
-   If you want to set default values for `configure' scripts to share,
-you can create a site shell script called `config.site' that gives
-default values for variables like `CC', `cache_file', and `prefix'.
-`configure' looks for `PREFIX/share/config.site' if it exists, then
-`PREFIX/etc/config.site' if it exists.  Or, you can set the
-`CONFIG_SITE' environment variable to the location of the site script.
-A warning: not all `configure' scripts look for a site script.
-
-Operation Controls
-==================
-
-   `configure' recognizes the following options to control how it
-operates.
-
-`--cache-file=FILE'
-     Use and save the results of the tests in FILE instead of
-     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
-     debugging `configure'.
-
-`--help'
-     Print a summary of the options to `configure', and exit.
-
-`--quiet'
-`--silent'
-`-q'
-     Do not print messages saying which checks are being made.  To
-     suppress all normal output, redirect it to `/dev/null' (any error
-     messages will still be shown).
-
-`--srcdir=DIR'
-     Look for the package's source code in directory DIR.  Usually
-     `configure' can determine that directory automatically.
-
-`--version'
-     Print the version of Autoconf used to generate the `configure'
-     script, and exit.
-
-`configure' also accepts some other, not widely useful, options.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/JEPS	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,55 @@
+0004: NEED
+	Data Gathering and Reporting
+0011: NEED (or just do disco?)
+	Jabber Browsing
+0012: DONE
+	Last Activity
+0018: DONE (Is it?)
+	Presence (Invisible)
+0022: DONE (replace?)
+	Message Events
+0030: NEED
+	Service Discovery
+0045: DONE
+	Multi-User Chat
+0052: NEED
+	File Transfer
+0054: DONE (ugly)
+	vCard
+0060: NEED
+	Pub-Sub
+0071: DONE (needs spec confirmation)
+	XHTML-IM
+0073: NEED
+	Basic IM Protocol Suite
+0077: NEED 0.71
+	In-Band Registration
+0078: DONE
+	Non-SASL Authentication
+0080: NEED (Do we?)
+	Geographic Location Information
+0082: DONE
+	Jabber Date and Time Profiles
+0084: NEED
+	User Avatars in Jabber
+0085: NEED
+	Chat State Notifications
+0086: DONE
+	Legacy Errors
+0089: WATCH
+	Generic Alerts
+0090: DONE
+	Entity Time
+0091: DONE
+	Delayed Delivery
+0092: DONE
+	Software Version
+0093: NEED
+	Roster Item Exchange
+0100: NEED
+	Gateway Interaction (Transports)
+0115: WATCH
+	Client Capabilities
+0017: NEED
+	Advanced IM Protocol Suite
+
--- a/src/protocols/jabber/Makefile.am	Mon Sep 29 13:00:55 2003 +0000
+++ b/src/protocols/jabber/Makefile.am	Mon Sep 29 15:23:19 2003 +0000
@@ -1,53 +1,30 @@
-EXTRA_DIST = \
-		xmltok_impl.c \
-		xmltok_ns.c \
-		Makefile.mingw \
-		win32/posix.uname.c \
-		win32/utsname.h
+EXTRA_DIST = win32/posix.uname.c \
+			 win32/utsname.h
 
 pkgdir = $(libdir)/gaim
 
-JABBERSOURCES = \
-			asciitab.h \
-			expat.c \
-			genhash.c \
-			hashtable.c \
-			hashtable.h \
-			karma.c \
-			iasciitab.h \
-			latin1tab.h \
-			lib.h \
-			libxode.h \
-			nametab.h \
-			pool.c \
-			sha.c \
-			snprintf.c \
-			socket.c \
-			str.c \
-			utf8tab.h \
-			xhash.c \
-			xmldef.h \
-			xmlnode.c \
-			xmlparse.c \
-			xmlparse.h \
-			xmlrole.c \
-			xmlrole.h \
-			xmltok.c \
-			xmltok.h \
-			xmltok_impl.h \
-			xstream.c \
-			\
-			jabber.h \
-			jconn.c \
-			jid.c \
-			jpacket.c \
-			jutil.c \
-			log.c \
-			log.h \
-			pproxy.c \
-			rate.c \
-			\
-			jabber.c
+JABBERSOURCES = auth.c \
+			  auth.h \
+			  buddy.c \
+			  buddy.h \
+			  chat.c \
+			  chat.h \
+			  iq.c \
+			  iq.h \
+			  jabber.c \
+			  jabber.h \
+			  jutil.c \
+			  jutil.h \
+			  message.c \
+			  message.h \
+			  parser.c \
+			  parser.h \
+			  presence.c \
+			  presence.h \
+			  roster.c \
+			  roster.h \
+			  xmlnode.c \
+			  xmlnode.h 
 
 AM_CFLAGS = $(st)
 
@@ -57,14 +34,16 @@
 
 st = -DSTATIC
 noinst_LIBRARIES = libjabber.a
+pkg_LTLIBRARIES =
 
 libjabber_a_SOURCES = $(JABBERSOURCES)
-libjabber_a_CFLAGS = $(AM_CFLAGS)
+libjabber_a_CFLAGS  = $(AM_CFLAGS)
 
 else
 
 st =
 pkg_LTLIBRARIES = libjabber.la
+noinst_LIBRARIES =
 
 libjabber_la_SOURCES = $(JABBERSOURCES)
 
--- a/src/protocols/jabber/README.libjabber	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-  libjabber README
-  Jabber Documentation Team
-  March 27, 2000
-  ____________________________________________________________
-
-  Table of Contents
-
-
-  1. Introduction
-
-     1.1 General
-     1.2 What This Package Is
-
-  2. Getting Things Installed
-
-     2.1 Dependencies
-     2.2 Compilation and Installation
-     2.3 Problems/Bugs
-
-  3. Jabber Information
-
-     3.1 General Information
-     3.2 Developer Information
-  ______________________________________________________________________
-
-  1.  Introduction
-
-  1.1.  General
-
-  This document gives pointers for information on this package as well
-  as links to learn more about the Jabber project and about
-  participating in the project.
-
-  Copyright information can be found in each package directory in the
-  files "COPYRIGHT" and "COPYING."
-
-  1.2.  What This Package Is
-
-  Currently, libjabber provides Jabber server software with various
-  library functions.
-
-
-  2.  Getting Things Installed
-
-  2.1.  Dependencies
-
-  Apart from your standard UNIX fare, this package is dependent on the
-  following:
-
-  o  libxode, available from http://download.jabber.org/
-
-  2.2.  Compilation and Installation
-
-  To install as super user do the following in the libjabber root directory:
-
-  ______________________________________________________________________
-  ./configure
-  make
-  (become root)
-  make install
-  ldconfig
-  ______________________________________________________________________
-  
-  2.3.  Problems/Bugs
- 
-  Submit bug reports at http://bugs.jabber.org.
- 
-  For additional real-time support, many members of the development team
-  frequent jabber groupchat in jdev@conference.jabber.org and irc at
-  irc.openprojects.net in #jabber.
- 
-
-  3.  Jabber Information
-
-  3.1.  General Information
-
-  For general information about Jabber, including a quick introduction
-  to Jabber concepts, see the FAQ at http://docs.jabber.org/.
-
-  3.2.  Developer Information
-
-  There are many areas of Jabber that developers can contribute to.
-  Jabber encompasses many fields of expertise and anyone that is willing
-  to help can contribute.
-
-  You may want to delve into the internals of the Jabber project at
-  http://docs.jabber.org/ and http://protocol.jabber.org/.
-
-  Or maybe you would like to go ahead become a developer on the project.
-  Just go on over to http://jabber.org/ and register.  You may also
-  sign up for the main Jabber mailing list (JDEV).
--- a/src/protocols/jabber/README.libxode	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-  libxode README
-  Jabber Documentation Team
-  March 27, 2000
-  ____________________________________________________________
-
-  Table of Contents
-
-
-  1. Introduction
-
-     1.1 General
-     1.2 What This Package Is
-
-  2. Getting Things Installed
-
-     2.1 Dependencies
-     2.2 Compilation and Installation
-     2.3 Problems/Bugs
-
-  3. Jabber Information
-
-     3.1 General Information
-     3.2 Developer Information
-  ______________________________________________________________________
-
-  1.  Introduction
-
-  1.1.  General
-
-  This document gives pointers for information on this package as well
-  as links to learn more about the Jabber project and about
-  participating in the project.
-
-  Copyright information can be found in each package directory in the
-  files "COPYRIGHT" and "COPYING."
-
-  1.2.  What libxode is
-
-  libxode provides a library of XML, memory, and string helper functions.
-
-  Jabber server software uses libxode extensively.
-
-
-  2.  Getting it Installed
-
-  2.1.  Dependencies
-
-  Apart from the standard UNIX fare, this package isn't dependent on
-  anything.
-
-  2.2.  Compilation and Installation
-
-  To install as super user do the following in the libxode root directory:
-
-  ______________________________________________________________________
-  ./configure
-  make
-  (become root)
-  make install
-  ldconfig
-  ______________________________________________________________________
-
-  2.3.  Problems/Bugs
- 
-  Submit bug reports at http://bugs.jabber.org.
- 
-  For additional real-time support, many members of the development team
-  frequent jabber groupchat in jdev@conference.jabber.org and irc at
-  irc.openprojects.net in #jabber.
- 
-
-  3.  Jabber Information
-
-  3.1.  General Information
-
-  For general information about Jabber, including a quick introduction
-  to Jabber concepts, see the FAQ at http://docs.jabber.org/.
-
-  3.2.  Developer Information
-
-  There are many areas of Jabber that developers can contribute to.
-  Jabber encompasses many fields of expertise and anyone that is willing
-  to help can contribute.
-
-  You may want to delve into the internals of the Jabber project at
-  http://docs.jabber.org/ and http://protocol.jabber.org/.
-
-  Or maybe you would like to go ahead become a developer on the project.
-  Just go on over to http://jabber.org/ and register.  You may also
-  sign up for the main Jabber mailing list (JDEV).
--- a/src/protocols/jabber/TODO.libjabber	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-
-* update StressTest
-* documentation
-
-* any ideas? :)
--- a/src/protocols/jabber/asciitab.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
-/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
-/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
-/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
-/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
-/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
-/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
-/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
-/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
-/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
-/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/auth.c	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,378 @@
+/*
+ * gaim - Jabber Protocol Plugin
+ *
+ * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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 "jutil.h"
+#include "auth.h"
+#include "xmlnode.h"
+#include "jabber.h"
+#include "iq.h"
+#include "sha.h"
+
+#include "debug.h"
+#include "md5.h"
+#include "util.h"
+#include "sslconn.h"
+
+
+void
+jabber_auth_start(JabberStream *js, xmlnode *packet)
+{
+	xmlnode *mechs, *mechnode;
+	xmlnode *starttls;
+
+	gboolean digest_md5 = FALSE;
+
+	if(gaim_ssl_is_supported() &&
+			(starttls = xmlnode_get_child(packet, "starttls"))) {
+		jabber_send_raw(js,
+				"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>");
+		return;
+	}
+
+	mechs = xmlnode_get_child(packet, "mechanisms");
+
+	if(!mechs) {
+		gaim_connection_error(js->gc, _("Invalid response from server"));
+		return;
+	}
+
+	for(mechnode = mechs->child; mechnode; mechnode = mechnode->next)
+	{
+		if(mechnode->type == NODE_TYPE_TAG) {
+			char *mech_name = xmlnode_get_data(mechnode);
+			if(mech_name && !strcmp(mech_name, "DIGEST-MD5"))
+				digest_md5 = TRUE;
+			g_free(mech_name);
+		}
+	}
+
+	if(digest_md5) {
+		jabber_send_raw(js, "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl'"
+				" mechanism='DIGEST-MD5' />");
+	} else {
+		gaim_connection_error(js->gc,
+				_("Server does not use any supported authentication method"));
+	}
+}
+
+static void auth_old_result_cb(JabberStream *js, xmlnode *packet)
+{
+	const char *type = xmlnode_get_attrib(packet, "type");
+
+	if(type && !strcmp(type, "error")) {
+		xmlnode *error = xmlnode_get_child(packet, "error");
+		const char *err_code;
+		char *err_text;
+		char *buf;
+
+		err_code = xmlnode_get_attrib(error, "code");
+		err_text = xmlnode_get_data(error);
+
+		if(!err_code)
+			err_code = "";
+		if(!err_text)
+			err_text = g_strdup(_("Unknown"));
+
+		if(!strcmp(err_code, "401"))
+			js->gc->wants_to_die = TRUE;
+
+		buf = g_strdup_printf("Error %s: %s",
+				err_code, err_text);
+
+		gaim_connection_error(js->gc, buf);
+		g_free(err_text);
+		g_free(buf);
+	}
+	jabber_stream_set_state(js, JABBER_STREAM_CONNECTED);
+}
+
+static void auth_old_cb(JabberStream *js, xmlnode *packet)
+{
+	JabberIq *iq;
+	xmlnode *query, *x;
+	gboolean digest = FALSE;
+	const char *pw = gaim_account_get_password(js->gc->account);
+
+	query = xmlnode_get_child(packet, "query");
+	if(js->stream_id && xmlnode_get_child(query, "digest")) {
+		digest = TRUE;
+	} else if(!xmlnode_get_child(query, "password")) {
+		gaim_connection_error(js->gc,
+				_("Server does not use any supported authentication method"));
+		return;
+	}
+
+	iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:auth");
+	query = xmlnode_get_child(iq->node, "query");
+	x = xmlnode_new_child(query, "username");
+	xmlnode_insert_data(x, js->user->node, -1);
+	x = xmlnode_new_child(query, "resource");
+	xmlnode_insert_data(x, js->user->resource, -1);
+
+	if(digest) {
+		unsigned char hashval[20];
+		char *s, h[41], *p;
+		int i;
+
+		x = xmlnode_new_child(query, "digest");
+		s = g_strdup_printf("%s%s", js->stream_id, pw);
+		shaBlock((unsigned char *)s, strlen(s), hashval);
+		p = h;
+		for(i=0; i<20; i++, p+=2)
+			snprintf(p, 3, "%02x", hashval[i]);
+		xmlnode_insert_data(x, h, -1);
+		g_free(s);
+	} else {
+		x = xmlnode_new_child(query, "password");
+		xmlnode_insert_data(x, pw, -1);
+	}
+
+	jabber_iq_set_callback(iq, auth_old_result_cb);
+
+	jabber_iq_send(iq);
+}
+
+void jabber_auth_start_old(JabberStream *js)
+{
+	JabberIq *iq;
+	xmlnode *query, *username;
+
+	iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:auth");
+
+	query = xmlnode_get_child(iq->node, "query");
+	username = xmlnode_new_child(query, "username");
+	xmlnode_insert_data(username, js->user->node, -1);
+
+	jabber_iq_set_callback(iq, auth_old_cb);
+
+	jabber_iq_send(iq);
+}
+
+static GHashTable* parse_challenge(const char *challenge)
+{
+	GHashTable *ret = g_hash_table_new_full(g_str_hash, g_str_equal,
+			g_free, g_free);
+	char **pairs;
+	int i;
+
+	pairs = g_strsplit(challenge, ",", -1);
+
+	for(i=0; pairs[i]; i++) {
+		char **keyval = g_strsplit(pairs[i], "=", 2);
+		if(keyval[0] && keyval[1]) {
+			if(keyval[1][0] == '"' && keyval[1][strlen(keyval[1])-1] == '"')
+				g_hash_table_replace(ret, g_strdup(keyval[0]), g_strndup(keyval[1]+1, strlen(keyval[1])-2));
+			else
+				g_hash_table_replace(ret, g_strdup(keyval[0]), g_strdup(keyval[1]));
+		}
+		g_strfreev(keyval);
+	}
+
+	g_strfreev(pairs);
+
+	return ret;
+}
+
+static unsigned char*
+generate_response_value(JabberID *jid, const char *passwd, const char *nonce,
+		const char *cnonce, const char *a2)
+{
+	md5_state_t ctx;
+	md5_byte_t result[16];
+
+	char *x, *y, *a1, *ha1, *ha2, *kd, *z;
+
+	x = g_strdup_printf("%s:%s:%s", jid->node, jid->domain, passwd);
+	md5_init(&ctx);
+	md5_append(&ctx, x, strlen(x));
+	md5_finish(&ctx, result);
+
+	y = g_strndup(result, 16);
+
+	a1 = g_strdup_printf("%s:%s:%s:%s@%s/%s", y, nonce, cnonce, jid->node,
+			jid->domain, jid->resource);
+
+	md5_init(&ctx);
+	md5_append(&ctx, a1, strlen(a1));
+	md5_finish(&ctx, result);
+
+	ha1 = tobase16(result, 16);
+
+	md5_init(&ctx);
+	md5_append(&ctx, a2, strlen(a2));
+	md5_finish(&ctx, result);
+
+	ha2 = tobase16(result, 16);
+
+	kd = g_strdup_printf("%s:%s:00000001:%s:auth:%s", ha1, nonce, cnonce, ha2);
+
+	md5_init(&ctx);
+	md5_append(&ctx, kd, strlen(kd));
+	md5_finish(&ctx, result);
+
+	z = tobase16(result, 16);
+
+	g_free(x);
+	g_free(y);
+	g_free(a1);
+	g_free(ha1);
+	g_free(ha2);
+	g_free(kd);
+
+	return z;
+}
+
+void
+jabber_auth_handle_challenge(JabberStream *js, xmlnode *packet)
+{
+	char *enc_in = xmlnode_get_data(packet);
+	char *dec_in;
+	char *enc_out;
+	GHashTable *parts;
+
+	frombase64(enc_in, &dec_in, NULL);
+
+	parts = parse_challenge(dec_in);
+
+	/* we're actually supposed to prompt the user for a realm if
+	 * the server doesn't send one, but that really complicates things,
+	 * so i'm not gonna worry about it until is poses a problem to someone,
+	 * or I get really bored */
+
+	if(g_hash_table_lookup(parts, "realm")) {
+		/* assemble a response, and send it */
+		/* see RFC 2831 */
+		GString *response = g_string_new("");
+		char *a2;
+		char *auth_resp;
+		char *buf;
+		char *cnonce;
+		char *realm;
+		char *nonce;
+
+		cnonce = g_strdup_printf("%p%u%p", js, (int)time(NULL), packet);
+		nonce = g_hash_table_lookup(parts, "nonce");
+		realm = g_hash_table_lookup(parts, "realm");
+
+		a2 = g_strdup_printf("AUTHENTICATE:xmpp/%s", realm);
+		auth_resp = generate_response_value(js->user,
+				gaim_account_get_password(js->gc->account), nonce, cnonce, a2);
+		g_free(a2);
+
+		a2 = g_strdup_printf(":xmpp/%s", realm);
+		js->expected_rspauth = generate_response_value(js->user,
+				gaim_account_get_password(js->gc->account), nonce, cnonce, a2);
+		g_free(a2);
+
+
+		g_string_append_printf(response, "username=\"%s\"", js->user->node);
+		g_string_append_printf(response, ",realm=\"%s\"", realm);
+		g_string_append_printf(response, ",nonce=\"%s\"", nonce);
+		g_string_append_printf(response, ",cnonce=\"%s\"", cnonce);
+		g_string_append_printf(response, ",nc=00000001");
+		g_string_append_printf(response, ",qop=auth");
+		g_string_append_printf(response, ",digest-uri=\"xmpp/%s\"", realm);
+		g_string_append_printf(response, ",response=%s", auth_resp);
+		g_string_append_printf(response, ",charset=utf-8");
+		g_string_append_printf(response, ",authzid=\"%s\"",
+				gaim_account_get_username(js->gc->account));
+
+		g_free(auth_resp);
+		g_free(cnonce);
+
+		enc_out = tobase64(response->str, response->len);
+
+		gaim_debug(GAIM_DEBUG_MISC, "jabber", "decoded response (%d): %s\n", response->len, response->str);
+
+		buf = g_strdup_printf("<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>%s</response>", enc_out);
+
+		jabber_send_raw(js, buf);
+
+		g_free(buf);
+
+		g_free(enc_out);
+
+		g_string_free(response, TRUE);
+	} else if (g_hash_table_lookup(parts, "rspauth")) {
+		char *rspauth = g_hash_table_lookup(parts, "rspauth");
+
+
+		if(rspauth && !strcmp(rspauth, js->expected_rspauth)) {
+			jabber_send_raw(js,
+					"<response xmlns='urn:ietf:params:xml:ns:xmpp-sasl' />");
+		} else {
+			gaim_connection_error(js->gc, _("Invalid challenge from server"));
+		}
+		g_free(js->expected_rspauth);
+	}
+
+	g_free(enc_in);
+	g_free(dec_in);
+	g_hash_table_destroy(parts);
+}
+
+void jabber_auth_handle_success(JabberStream *js, xmlnode *packet)
+{
+	const char *ns = xmlnode_get_attrib(packet, "xmlns");
+
+	if(!ns || strcmp(ns, "urn:ietf:params:xml:ns:xmpp-sasl")) {
+		gaim_connection_error(js->gc, _("Invalid response from server"));
+		return;
+	}
+
+	jabber_stream_set_state(js, JABBER_STREAM_REINITIALIZING);
+}
+
+void jabber_auth_handle_failure(JabberStream *js, xmlnode *packet)
+{
+	const char *ns = xmlnode_get_attrib(packet, "xmlns");
+
+	if(!ns)
+		gaim_connection_error(js->gc, _("Invalid response from server"));
+	else if(!strcmp(ns, "urn:ietf:params:xml:ns:xmpp-sasl")) {
+		if(xmlnode_get_child(packet, "bad-protocol")) {
+			gaim_connection_error(js->gc, _("Bad Protocol"));
+		} else if(xmlnode_get_child(packet, "encryption-required")) {
+			js->gc->wants_to_die = TRUE;
+			gaim_connection_error(js->gc, _("Encryption Required"));
+		} else if(xmlnode_get_child(packet, "invalid-authzid")) {
+			js->gc->wants_to_die = TRUE;
+			gaim_connection_error(js->gc, _("Invalid authzid"));
+		} else if(xmlnode_get_child(packet, "invalid-mechanism")) {
+			js->gc->wants_to_die = TRUE;
+			gaim_connection_error(js->gc, _("Invalid Mechanism"));
+		} else if(xmlnode_get_child(packet, "invalid-realm")) {
+			gaim_connection_error(js->gc, _("Invalid Realm"));
+		} else if(xmlnode_get_child(packet, "mechanism-too-weak")) {
+			js->gc->wants_to_die = TRUE;
+			gaim_connection_error(js->gc, _("Mechanism Too Weak"));
+		} else if(xmlnode_get_child(packet, "not-authorized")) {
+			js->gc->wants_to_die = TRUE;
+			gaim_connection_error(js->gc, _("Not Authorized"));
+		} else if(xmlnode_get_child(packet, "temporary-auth-failure")) {
+			gaim_connection_error(js->gc,
+					_("Temporary Authentication Failure"));
+		} else {
+			gaim_connection_error(js->gc, _("Authentication Failure"));
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/auth.h	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,34 @@
+/**
+ * @file auth.h Authentication routines
+ *
+ * gaim
+ *
+ * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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
+ */
+#ifndef _GAIM_JABBER_AUTH_H_
+#define _GAIM_JABBER_AUTH_H_
+
+#include "jabber.h"
+#include "xmlnode.h"
+
+void jabber_auth_start(JabberStream *js, xmlnode *packet);
+void jabber_auth_start_old(JabberStream *js);
+void jabber_auth_handle_challenge(JabberStream *js, xmlnode *packet);
+void jabber_auth_handle_success(JabberStream *js, xmlnode *packet);
+void jabber_auth_handle_failure(JabberStream *js, xmlnode *packet);
+
+#endif /* _GAIM_JABBER_AUTH_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/buddy.c	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,845 @@
+/*
+ * gaim - Jabber Protocol Plugin
+ *
+ * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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 "debug.h"
+#include "multi.h"
+#include "notify.h"
+#include "request.h"
+#include "util.h"
+
+#include "buddy.h"
+#include "chat.h"
+#include "jabber.h"
+#include "iq.h"
+#include "presence.h"
+#include "xmlnode.h"
+
+
+JabberBuddy *jabber_buddy_find(JabberStream *js, const char *name,
+		gboolean create)
+{
+	JabberBuddy *jb;
+	JabberID *jid = jabber_id_new(name);
+	char *realname;
+
+	if(!jid)
+		return NULL;
+
+	if(jid->node)
+		realname = g_strdup_printf("%s@%s", jid->node, jid->domain);
+	else
+		realname = g_strdup(jid->domain);
+
+	jb = g_hash_table_lookup(js->buddies, realname);
+
+	if(!jb && create) {
+		jb = g_new0(JabberBuddy, 1);
+		g_hash_table_insert(js->buddies, g_strdup(realname), jb);
+	}
+	g_free(realname);
+
+	jabber_id_free(jid);
+
+	return jb;
+}
+
+
+JabberBuddyResource *jabber_buddy_find_resource(JabberBuddy *jb,
+		const char *resource)
+{
+	JabberBuddyResource *jbr = NULL;
+	GList *l;
+
+	if(!jb)
+		return NULL;
+
+	for(l = jb->resources; l; l = l->next)
+	{
+		if(!jbr && !resource) {
+			jbr = l->data;
+		} else if(!resource) {
+			if(((JabberBuddyResource *)l->data)->priority >= jbr->priority)
+				jbr = l->data;
+		} else if(((JabberBuddyResource *)l->data)->name) {
+			if(!strcmp(((JabberBuddyResource *)l->data)->name, resource)) {
+				jbr = l->data;
+				break;
+			}
+		}
+	}
+
+	return jbr;
+}
+
+void jabber_buddy_track_resource(JabberBuddy *jb, const char *resource,
+		int priority, int state, const char *status)
+{
+	JabberBuddyResource *jbr = jabber_buddy_find_resource(jb, resource);
+
+	if(!jbr) {
+		jbr = g_new0(JabberBuddyResource, 1);
+		jbr->name = g_strdup(resource);
+		jbr->capabilities = JABBER_CAP_XHTML;
+		jb->resources = g_list_append(jb->resources, jbr);
+	}
+	jbr->priority = priority;
+	jbr->state = state;
+	if(jbr->status)
+		g_free(jbr->status);
+	jbr->status = g_strdup(status);
+}
+
+void jabber_buddy_remove_resource(JabberBuddy *jb, const char *resource)
+{
+	JabberBuddyResource *jbr = jabber_buddy_find_resource(jb, resource);
+
+	if(!jbr)
+		return;
+
+	jb->resources = g_list_remove(jb->resources, jbr);
+
+	g_free(jbr->name);
+	if(jbr->status)
+		g_free(jbr->status);
+	g_free(jbr);
+}
+
+const char *jabber_buddy_get_status_msg(JabberBuddy *jb)
+{
+	JabberBuddyResource *jbr;
+
+	if(!jb)
+		return NULL;
+
+	jbr = jabber_buddy_find_resource(jb, NULL);
+
+	if(!jbr)
+		return NULL;
+
+	return jbr->status;
+}
+
+/*******
+ * This is the old vCard stuff taken from the old prpl.  vCards, by definition
+ * are a temporary thing until jabber can get its act together and come up
+ * with a format for user information, hence the namespace of 'vcard-temp'
+ *
+ * Since I don't feel like putting that much work into something that's
+ * _supposed_ to go away, i'm going to just copy the kludgy old code here,
+ * and make it purdy when jabber comes up with a standards-track JEP to
+ * replace vcard-temp
+ *                                 --Nathan
+ *******/
+
+/*---------------------------------------*/
+/* Jabber "set info" (vCard) support     */
+/*---------------------------------------*/
+
+/*
+ * V-Card format:
+ *
+ *  <vCard prodid='' version='' xmlns=''>
+ *    <FN></FN>
+ *    <N>
+ *	<FAMILY/>
+ *	<GIVEN/>
+ *    </N>
+ *    <NICKNAME/>
+ *    <URL/>
+ *    <ADR>
+ *	<STREET/>
+ *	<EXTADD/>
+ *	<LOCALITY/>
+ *	<REGION/>
+ *	<PCODE/>
+ *	<COUNTRY/>
+ *    </ADR>
+ *    <TEL/>
+ *    <EMAIL/>
+ *    <ORG>
+ *	<ORGNAME/>
+ *	<ORGUNIT/>
+ *    </ORG>
+ *    <TITLE/>
+ *    <ROLE/>
+ *    <DESC/>
+ *    <BDAY/>
+ *  </vCard>
+ *
+ * See also:
+ *
+ *	http://docs.jabber.org/proto/html/vcard-temp.html
+ *	http://www.vcard-xml.org/dtd/vCard-XML-v2-20010520.dtd
+ */
+
+/*
+ * Cross-reference user-friendly V-Card entry labels to vCard XML tags
+ * and attributes.
+ *
+ * Order is (or should be) unimportant.  For example: we have no way of
+ * knowing in what order real data will arrive.
+ *
+ * Format: Label, Pre-set text, "visible" flag, "editable" flag, XML tag
+ *         name, XML tag's parent tag "path" (relative to vCard node).
+ *
+ *         List is terminated by a NULL label pointer.
+ *
+ *	   Entries with no label text, but with XML tag and parent tag
+ *	   entries, are used by V-Card XML construction routines to
+ *	   "automagically" construct the appropriate XML node tree.
+ *
+ * Thoughts on future direction/expansion
+ *
+ *	This is a "simple" vCard.
+ *
+ *	It is possible for nodes other than the "vCard" node to have
+ *      attributes.  Should that prove necessary/desirable, add an
+ *      "attributes" pointer to the vcard_template struct, create the
+ *      necessary tag_attr structs, and add 'em to the vcard_dflt_data
+ *      array.
+ *
+ *	The above changes will (obviously) require changes to the vCard
+ *      construction routines.
+ */
+
+struct vcard_template {
+	char *label;			/* label text pointer */
+	char *text;			/* entry text pointer */
+	int  visible;			/* should entry field be "visible?" */
+	int  editable;			/* should entry field be editable? */
+	char *tag;			/* tag text */
+	char *ptag;			/* parent tag "path" text */
+	char *url;			/* vCard display format if URL */
+} vcard_template_data[] = {
+	{N_("Full Name"),          NULL, TRUE, TRUE, "FN",        NULL,  NULL},
+	{N_("Family Name"),        NULL, TRUE, TRUE, "FAMILY",    "N",   NULL},
+	{N_("Given Name"),         NULL, TRUE, TRUE, "GIVEN",     "N",   NULL},
+	{N_("Nickname"),           NULL, TRUE, TRUE, "NICKNAME",  NULL,  NULL},
+	{N_("URL"),                NULL, TRUE, TRUE, "URL",       NULL,  "<A HREF=\"%s\">%s</A>"},
+	{N_("Street Address"),     NULL, TRUE, TRUE, "STREET",    "ADR", NULL},
+	{N_("Extended Address"),   NULL, TRUE, TRUE, "EXTADD",    "ADR", NULL},
+	{N_("Locality"),           NULL, TRUE, TRUE, "LOCALITY",  "ADR", NULL},
+	{N_("Region"),             NULL, TRUE, TRUE, "REGION",    "ADR", NULL},
+	{N_("Postal Code"),        NULL, TRUE, TRUE, "PCODE",     "ADR", NULL},
+	{N_("Country"),            NULL, TRUE, TRUE, "COUNTRY",   "ADR", NULL},
+	{N_("Telephone"),          NULL, TRUE, TRUE, "TELEPHONE", NULL,  NULL},
+	{N_("Email"),              NULL, TRUE, TRUE, "EMAIL",     NULL,  "<A HREF=\"mailto:%s\">%s</A>"},
+	{N_("Organization Name"),  NULL, TRUE, TRUE, "ORGNAME",   "ORG", NULL},
+	{N_("Organization Unit"),  NULL, TRUE, TRUE, "ORGUNIT",   "ORG", NULL},
+	{N_("Title"),              NULL, TRUE, TRUE, "TITLE",     NULL,  NULL},
+	{N_("Role"),               NULL, TRUE, TRUE, "ROLE",      NULL,  NULL},
+	{N_("Birthday"),           NULL, TRUE, TRUE, "BDAY",      NULL,  NULL},
+	{N_("Description"),        NULL, TRUE, TRUE, "DESC",      NULL,  NULL},
+	{"", NULL, TRUE, TRUE, "N",     NULL, NULL},
+	{"", NULL, TRUE, TRUE, "ADR",   NULL, NULL},
+	{"", NULL, TRUE, TRUE, "ORG",   NULL, NULL},
+	{NULL, NULL, 0, 0, NULL, NULL, NULL}
+};
+
+/*
+ * The "vCard" tag's attibute list...
+ */
+struct tag_attr {
+	char *attr;
+	char *value;
+} vcard_tag_attr_list[] = {
+	{"prodid",   "-//HandGen//NONSGML vGen v1.0//EN"},
+	{"version",  "2.0",                             },
+	{"xmlns",    "vcard-temp",                      },
+	{NULL, NULL},
+};
+
+
+/*
+ * Insert a tag node into an xmlnode tree, recursively inserting parent tag
+ * nodes as necessary
+ *
+ * Returns pointer to inserted node
+ *
+ * Note to hackers: this code is designed to be re-entrant (it's recursive--it
+ * calls itself), so don't put any "static"s in here!
+ */
+static xmlnode *insert_tag_to_parent_tag(xmlnode *start, const char *parent_tag, const char *new_tag)
+{
+	xmlnode *x = NULL;
+
+	/*
+	 * If the parent tag wasn't specified, see if we can get it
+	 * from the vCard template struct.
+	 */
+	if(parent_tag == NULL) {
+		struct vcard_template *vc_tp = vcard_template_data;
+
+		while(vc_tp->label != NULL) {
+			if(strcmp(vc_tp->tag, new_tag) == 0) {
+				parent_tag = vc_tp->ptag;
+				break;
+			}
+			++vc_tp;
+		}
+	}
+
+	/*
+	 * If we have a parent tag...
+	 */
+	if(parent_tag != NULL ) {
+		/*
+		 * Try to get the parent node for a tag
+		 */
+		if((x = xmlnode_get_child(start, parent_tag)) == NULL) {
+			/*
+			 * Descend?
+			 */
+			char *grand_parent = g_strdup(parent_tag);
+			char *parent;
+
+			if((parent = strrchr(grand_parent, '/')) != NULL) {
+				*(parent++) = '\0';
+				x = insert_tag_to_parent_tag(start, grand_parent, parent);
+			} else {
+				x = xmlnode_new_child(start, grand_parent);
+			}
+			g_free(grand_parent);
+		} else {
+			/*
+			 * We found *something* to be the parent node.
+			 * Note: may be the "root" node!
+			 */
+			xmlnode *y;
+			if((y = xmlnode_get_child(x, new_tag)) != NULL) {
+				return(y);
+			}
+		}
+	}
+
+	/*
+	 * insert the new tag into its parent node
+	 */
+	return(xmlnode_new_child((x == NULL? start : x), new_tag));
+}
+
+/*
+ * Send vCard info to Jabber server
+ */
+void jabber_set_info(GaimConnection *gc, const char *info)
+{
+	JabberIq *iq;
+	JabberStream *js = gc->proto_data;
+	xmlnode *vc_node;
+
+
+	/*
+	 * Send only if there's actually any *information* to send
+	 */
+	vc_node = xmlnode_from_str(info, -1);
+
+	if(vc_node) {
+		if (vc_node->name &&
+				!g_ascii_strncasecmp(vc_node->name, "vcard", 5)) {
+			iq = jabber_iq_new(js, JABBER_IQ_SET);
+			xmlnode_insert_child(iq->node, vc_node);
+			jabber_iq_send(iq);
+		} else {
+			xmlnode_free(vc_node);
+		}
+	}
+}
+
+/*
+ * This is the callback from the "ok clicked" for "set vCard"
+ *
+ * Formats GSList data into XML-encoded string and returns a pointer
+ * to said string.
+ *
+ * g_free()'ing the returned string space is the responsibility of
+ * the caller.
+ */
+static void
+jabber_format_info(GaimConnection *gc, GaimRequestFields *fields)
+{
+	GaimAccount *account;
+	xmlnode *vc_node;
+	GaimRequestField *field;
+	const char *text;
+	char *p;
+	const struct vcard_template *vc_tp;
+	struct tag_attr *tag_attr;
+
+	vc_node = xmlnode_new("vCard");
+
+	for(tag_attr = vcard_tag_attr_list; tag_attr->attr != NULL; ++tag_attr)
+		xmlnode_set_attrib(vc_node, tag_attr->attr, tag_attr->value);
+
+	for (vc_tp = vcard_template_data; vc_tp->label != NULL; vc_tp++) {
+		if (*vc_tp->label == '\0')
+			continue;
+
+		field = gaim_request_fields_get_field(fields, vc_tp->tag);
+		text  = gaim_request_field_string_get_value(field);
+
+		gaim_debug(GAIM_DEBUG_INFO, "jabber",
+				   "Setting %s to '%s'\n", vc_tp->tag, text);
+
+		if (text != NULL && *text != '\0') {
+			xmlnode *xp;
+
+			if ((xp = insert_tag_to_parent_tag(vc_node,
+											   NULL, vc_tp->tag)) != NULL) {
+
+				xmlnode_insert_data(xp, text, -1);
+			}
+		}
+	}
+
+	p = xmlnode_to_str(vc_node);
+	xmlnode_free(vc_node);
+
+	account = gaim_connection_get_account(gc);
+
+	if (account != NULL) {
+		gaim_account_set_user_info(account, p);
+
+		if (gc != NULL)
+			serv_set_info(gc, p);
+	}
+
+	g_free(p);
+}
+
+/*
+ * This gets executed by the proto action
+ *
+ * Creates a new GaimRequestFields struct, gets the XML-formatted user_info
+ * string (if any) into GSLists for the (multi-entry) edit dialog and
+ * calls the set_vcard dialog.
+ */
+void jabber_setup_set_info(GaimConnection *gc)
+{
+	GaimRequestFields *fields;
+	GaimRequestFieldGroup *group;
+	GaimRequestField *field;
+	const struct vcard_template *vc_tp;
+	char *user_info;
+	char *cdata;
+	xmlnode *x_vc_data = NULL;
+
+	fields = gaim_request_fields_new();
+	group = gaim_request_field_group_new(NULL);
+	gaim_request_fields_add_group(fields, group);
+
+	/*
+	 * Get existing, XML-formatted, user info
+	 */
+	if((user_info = g_strdup(gaim_account_get_user_info(gc->account))) != NULL)
+		x_vc_data = xmlnode_from_str(user_info, -1);
+	else
+		user_info = g_strdup("");
+
+	/*
+	 * Set up GSLists for edit with labels from "template," data from user info
+	 */
+	for(vc_tp = vcard_template_data; vc_tp->label != NULL; ++vc_tp) {
+		xmlnode *data_node;
+		if((vc_tp->label)[0] == '\0')
+			continue;
+		if(vc_tp->ptag == NULL) {
+			data_node = xmlnode_get_child(x_vc_data, vc_tp->tag);
+		} else {
+			gchar *tag = g_strdup_printf("%s/%s", vc_tp->ptag, vc_tp->tag);
+			data_node = xmlnode_get_child(x_vc_data, tag);
+			g_free(tag);
+		}
+		if(data_node)
+			cdata = xmlnode_get_data(data_node);
+		else
+			cdata = NULL;
+
+		if(strcmp(vc_tp->tag, "DESC") == 0) {
+			field = gaim_request_field_string_new(vc_tp->tag,
+												  _(vc_tp->label), cdata,
+												  TRUE);
+		} else {
+			field = gaim_request_field_string_new(vc_tp->tag,
+												  _(vc_tp->label), cdata,
+												  FALSE);
+		}
+
+		gaim_request_field_group_add_field(group, field);
+	}
+
+	if(x_vc_data != NULL)
+		xmlnode_free(x_vc_data);
+
+    g_free(user_info);
+
+	gaim_request_fields(gc, _("Edit Jabber vCard"),
+						_("Edit Jabber vCard"),
+						_("All items below are optional. Enter only the "
+						  "information with which you feel comfortable."),
+						fields,
+						_("Save"), G_CALLBACK(jabber_format_info),
+						_("Cancel"), NULL,
+						gc);
+}
+
+/*---------------------------------------*/
+/* End Jabber "set info" (vCard) support */
+/*---------------------------------------*/
+
+/******
+ * end of that ancient crap that needs to die
+ ******/
+
+
+static void jabber_vcard_parse(JabberStream *js, xmlnode *packet)
+{
+	GList *resources;
+	const char *from = xmlnode_get_attrib(packet, "from");
+	JabberBuddy *jb;
+	JabberBuddyResource *jbr;
+	GString *info_text;
+	const char *resource_name;
+	char *title;
+	xmlnode *vcard;
+
+	if(!from)
+		return;
+
+	resource_name = jabber_get_resource(from);
+
+	jb = jabber_buddy_find(js, from, TRUE);
+	info_text = g_string_new("");
+
+	g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n", _("Jabber ID"),
+			from);
+
+	if(resource_name) {
+		jbr = jabber_buddy_find_resource(jb, resource_name);
+		if(jbr) {
+			char *purdy = strdup_withhtml(jbr->status);
+			g_string_append_printf(info_text, "<b>%s:</b> %s%s%s<br/>\n",
+					_("Status"), jabber_get_state_string(jbr->state),
+					purdy ? ": " : "",
+					purdy ? purdy : "");
+			g_free(purdy);
+		} else {
+			g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n",
+					_("Status"), _("Unknown"));
+		}
+	} else {
+		for(resources = jb->resources; resources; resources = resources->next) {
+			char *purdy;
+			jbr = resources->data;
+			purdy = strdup_withhtml(jbr->status);
+			g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n",
+					_("Resource"), jbr->name);
+			g_string_append_printf(info_text, "<b>%s:</b> %s%s%s<br/><br/>\n",
+					_("Status"), jabber_get_state_string(jbr->state),
+					purdy ? ": " : "",
+					purdy ? purdy : "");
+			g_free(purdy);
+		}
+	}
+
+	if((vcard = xmlnode_get_child(packet, "vCard"))) {
+		xmlnode *child;
+		for(child = vcard->child; child; child = child->next)
+		{
+			xmlnode *child2;
+			char *text;
+
+			if(child->type != NODE_TYPE_TAG)
+				continue;
+
+			text = xmlnode_get_data(child);
+			if(text && !strcmp(child->name, "FN")) {
+				g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n",
+						_("Full Name"), text);
+			} else if(!strcmp(child->name, "N")) {
+				for(child2 = child->child; child2; child2 = child2->next)
+				{
+					char *text2;
+
+					if(child2->type != NODE_TYPE_TAG)
+						continue;
+
+					text2 = xmlnode_get_data(child2);
+					if(text2 && !strcmp(child2->name, "FAMILY")) {
+						g_string_append_printf(info_text,
+								"<b>%s:</b> %s<br/>\n",
+								_("Family Name"), text2);
+					} else if(text2 && !strcmp(child2->name, "GIVEN")) {
+						g_string_append_printf(info_text,
+								"<b>%s:</b> %s<br/>\n",
+								_("Given Name"), text2);
+					} else if(text2 && !strcmp(child2->name, "MIDDLE")) {
+						g_string_append_printf(info_text,
+								"<b>%s:</b> %s<br/>\n",
+								_("Middle Name"), text2);
+					}
+					g_free(text2);
+				}
+			} else if(text && !strcmp(child->name, "NICKNAME")) {
+				serv_got_alias(js->gc, from, text);
+				g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n",
+						_("Nickname"), text);
+			} else if(text && !strcmp(child->name, "BDAY")) {
+				g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n",
+						_("Birthday"), text);
+			} else if(!strcmp(child->name, "ADR")) {
+				/* show which address it is */
+				if(child->child)
+					g_string_append_printf(info_text, "<b>%s:</b><br/>\n",
+							_("Address"));
+				for(child2 = child->child; child2; child2 = child2->next)
+				{
+					char *text2;
+
+					if(child2->type != NODE_TYPE_TAG)
+						continue;
+
+					text2 = xmlnode_get_data(child2);
+					if(text2 && !strcmp(child2->name, "POBOX")) {
+						g_string_append_printf(info_text,
+								"&nbsp;<b>%s:</b> %s<br/>\n",
+								_("P.O. Box"), text2);
+					} else if(text2 && !strcmp(child2->name, "EXTADR")) {
+						g_string_append_printf(info_text,
+								"&nbsp;<b>%s:</b> %s<br/>\n",
+								_("Extended Address"), text2);
+					} else if(text2 && !strcmp(child2->name, "STREET")) {
+						g_string_append_printf(info_text,
+								"&nbsp;<b>%s:</b> %s<br/>\n",
+								_("Street Address"), text2);
+					} else if(text2 && !strcmp(child2->name, "LOCALITY")) {
+						g_string_append_printf(info_text,
+								"&nbsp;<b>%s:</b> %s<br/>\n",
+								_("Locality"), text2);
+					} else if(text2 && !strcmp(child2->name, "REGION")) {
+						g_string_append_printf(info_text,
+								"&nbsp;<b>%s:</b> %s<br/>\n",
+								_("Region"), text2);
+					} else if(text2 && !strcmp(child2->name, "PCODE")) {
+						g_string_append_printf(info_text,
+								"&nbsp;<b>%s:</b> %s<br/>\n",
+								_("Postal Code"), text2);
+					} else if(text2 && (!strcmp(child2->name, "CTRY")
+								|| !strcmp(child2->name, "COUNTRY"))) {
+						g_string_append_printf(info_text,
+								"&nbsp;<b>%s:</b> %s<br/>\n",
+								_("Country"), text2);
+					}
+					g_free(text2);
+				}
+			} else if(!strcmp(child->name, "TEL")) {
+				char *number;
+				if((child2 = xmlnode_get_child(child, "NUMBER"))) {
+					/* show what kind of number it is */
+					number = xmlnode_get_data(child2);
+					if(number) {
+						g_string_append_printf(info_text,
+								"<b>%s:</b> %s<br/>\n", _("Telephone"), number);
+						g_free(number);
+					}
+				} else if((number = xmlnode_get_data(child))) {
+					/* lots of clients (including gaim) do this, but it's
+					 * out of spec */
+					g_string_append_printf(info_text,
+							"<b>%s:</b> %s<br/>\n", _("Telephone"), number);
+					g_free(number);
+				}
+			} else if(!strcmp(child->name, "EMAIL")) {
+				char *userid;
+				if((child2 = xmlnode_get_child(child, "USERID"))) {
+					/* show what kind of email it is */
+					userid = xmlnode_get_data(child2);
+					if(userid) {
+						g_string_append_printf(info_text,
+								"<b>%s:</b> <a href='mailto:%s'>%s</a><br/>\n",
+								_("Email"), userid, userid);
+						g_free(userid);
+					}
+				} else if((userid = xmlnode_get_data(child))) {
+					/* lots of clients (including gaim) do this, but it's
+					 * out of spec */
+						g_string_append_printf(info_text,
+								"<b>%s:</b> <a href='mailto:%s'>%s</a><br/>\n",
+								_("Email"), userid, userid);
+					g_free(userid);
+				}
+			} else if(!strcmp(child->name, "ORG")) {
+				for(child2 = child->child; child2; child2 = child2->next)
+				{
+					char *text2;
+
+					if(child2->type != NODE_TYPE_TAG)
+						continue;
+
+					text2 = xmlnode_get_data(child2);
+					if(text2 && !strcmp(child2->name, "ORGNAME")) {
+						g_string_append_printf(info_text,
+								"<b>%s:</b> %s<br/>\n",
+								_("Organization Name"), text2);
+					} else if(text2 && !strcmp(child2->name, "ORGUNIT")) {
+						g_string_append_printf(info_text,
+								"<b>%s:</b> %s<br/>\n",
+								_("Organization Unit"), text2);
+					}
+					g_free(text2);
+				}
+			} else if(text && !strcmp(child->name, "TITLE")) {
+				g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n",
+						_("Title"), text);
+			} else if(text && !strcmp(child->name, "ROLE")) {
+				g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n",
+						_("Role"), text);
+			} else if(text && !strcmp(child->name, "DESC")) {
+				g_string_append_printf(info_text, "<b>%s:</b> %s<br/>\n",
+						_("Description"), text);
+			}
+			g_free(text);
+		}
+	}
+
+	title = g_strdup_printf("User info for %s", from);
+
+	gaim_notify_formatted(NULL, title, _("Jabber Profile"),
+			NULL, info_text->str, NULL, NULL);
+
+	g_free(title);
+	g_string_free(info_text, TRUE);
+}
+
+void jabber_buddy_get_info(GaimConnection *gc, const char *who)
+{
+	JabberStream *js = gc->proto_data;
+	JabberIq *iq;
+	xmlnode *vcard;
+
+	iq = jabber_iq_new(js, JABBER_IQ_GET);
+
+	xmlnode_set_attrib(iq->node, "to", who);
+	vcard = xmlnode_new_child(iq->node, "vCard");
+	xmlnode_set_attrib(vcard, "xmlns", "vcard-temp");
+
+	jabber_iq_set_callback(iq, jabber_vcard_parse);
+
+	jabber_iq_send(iq);
+}
+
+void jabber_buddy_get_info_chat(GaimConnection *gc, int id,
+		const char *resource)
+{
+	JabberStream *js = gc->proto_data;
+	JabberChat *chat = jabber_chat_find_by_id(js, id);
+	char *full_jid;
+
+	if(!chat)
+		return;
+
+	full_jid = g_strdup_printf("%s@%s/%s", chat->room, chat->server, resource);
+	jabber_buddy_get_info(gc, full_jid);
+	g_free(full_jid);
+}
+
+static void jabber_buddy_set_invisibility(JabberStream *js, const char *who,
+		gboolean invisible)
+{
+	JabberBuddy *jb = jabber_buddy_find(js, who, TRUE);
+	xmlnode *presence;
+
+	presence = jabber_presence_create(js->gc->away_state, js->gc->away);
+	xmlnode_set_attrib(presence, "to", who);
+	if(invisible) {
+		xmlnode_set_attrib(presence, "type", "invisible");
+		jb->invisible |= JABBER_INVIS_BUDDY;
+	} else {
+		jb->invisible &= ~JABBER_INVIS_BUDDY;
+	}
+
+	jabber_send(js, presence);
+	xmlnode_free(presence);
+}
+
+static void jabber_buddy_make_invisible(GaimConnection *gc, const char *name)
+{
+	JabberStream *js = gc->proto_data;
+	jabber_buddy_set_invisibility(js, name, TRUE);
+}
+
+static void jabber_buddy_make_visible(GaimConnection *gc, const char *name)
+{
+	JabberStream *js = gc->proto_data;
+	jabber_buddy_set_invisibility(js, name, FALSE);
+}
+
+static void jabber_buddy_cancel_presence_notification(GaimConnection *gc,
+		const char *name)
+{
+	JabberStream *js = gc->proto_data;
+
+	/* I wonder if we should prompt the user before doing this */
+	jabber_presence_subscription_set(js, name, "unsubscribed");
+}
+
+static void jabber_buddy_rerequest_auth(GaimConnection *gc, const char *name)
+{
+	JabberStream *js = gc->proto_data;
+
+	jabber_presence_subscription_set(js, name, "subscribe");
+}
+
+GList *jabber_buddy_menu(GaimConnection *gc, const char *name)
+{
+	GList *m = NULL;
+	struct proto_buddy_menu *pbm;
+	JabberStream *js = gc->proto_data;
+	JabberBuddy *jb = jabber_buddy_find(js, name, TRUE);
+
+	pbm = g_new0(struct proto_buddy_menu, 1);
+	if(jb->invisible & JABBER_INVIS_BUDDY) {
+		pbm->label = _("Un-hide From");
+		pbm->callback = jabber_buddy_make_visible;
+	} else {
+		pbm->label = _("Temporarily Hide From");
+		pbm->callback = jabber_buddy_make_invisible;
+	}
+	pbm->gc = gc;
+	m = g_list_append(m, pbm);
+
+	if(jb->subscription & JABBER_SUB_FROM) {
+		pbm = g_new0(struct proto_buddy_menu, 1);
+		pbm->label = _("Cancel Presence Notification");
+		pbm->callback = jabber_buddy_cancel_presence_notification;
+		pbm->gc = gc;
+		m = g_list_append(m, pbm);
+	}
+
+	if(!(jb->subscription & JABBER_SUB_TO)) {
+		pbm = g_new0(struct proto_buddy_menu, 1);
+		pbm->label = _("Re-request authorization");
+		pbm->callback = jabber_buddy_rerequest_auth;
+		pbm->gc = gc;
+		m = g_list_append(m, pbm);
+	}
+
+	return m;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/buddy.h	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,72 @@
+/**
+ * @file buddy.h Buddy handlers
+ *
+ * gaim
+ *
+ * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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
+ */
+#ifndef _GAIM_JABBER_BUDDY_H_
+#define _GAIM_JABBER_BUDDY_H_
+
+#include "jabber.h"
+
+typedef struct _JabberBuddyResource {
+	char *name;
+	int priority;
+	int state;
+	char *status;
+	enum {
+		JABBER_CAP_XHTML     = 1 << 1,
+		JABBER_CAP_COMPOSING = 1 << 2
+	} capabilities;
+} JabberBuddyResource;
+
+typedef struct _JabberBuddy {
+	GList *resources;
+	char *error_msg;
+	enum {
+		JABBER_INVISIBLE_NONE   = 0,
+		JABBER_INVISIBLE_SERVER = 1 << 1,
+		JABBER_INVIS_BUDDY      = 1 << 2
+	} invisible;
+	enum {
+		JABBER_SUB_NONE    = 0,
+		JABBER_SUB_PENDING = 1 << 1,
+		JABBER_SUB_TO      = 1 << 2,
+		JABBER_SUB_FROM    = 1 << 3,
+		JABBER_SUB_BOTH    = (JABBER_SUB_TO | JABBER_SUB_FROM)
+	} subscription;
+} JabberBuddy;
+
+JabberBuddy *jabber_buddy_find(JabberStream *js, const char *name,
+		gboolean create);
+JabberBuddyResource *jabber_buddy_find_resource(JabberBuddy *jb,
+		const char *resource);
+void jabber_buddy_track_resource(JabberBuddy *jb, const char *resource,
+		int priority, int state, const char *status);
+void jabber_buddy_remove_resource(JabberBuddy *jb, const char *resource);
+const char *jabber_buddy_get_status_msg(JabberBuddy *jb);
+void jabber_buddy_get_info(GaimConnection *gc, const char *who);
+void jabber_buddy_get_info_chat(GaimConnection *gc, int id,
+		const char *resource);
+
+GList *jabber_buddy_menu(GaimConnection *gc, const char *name);
+
+void jabber_set_info(GaimConnection *gc, const char *info);
+void jabber_setup_set_info(GaimConnection *gc);
+
+#endif /* _GAIM_JABBER_BUDDY_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/chat.c	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,249 @@
+/*
+ * gaim - Jabber Protocol Plugin
+ *
+ * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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 "debug.h"
+#include "multi.h" /* for proto_chat_entry */
+
+#include "chat.h"
+#include "message.h"
+
+GList *jabber_chat_info(GaimConnection *gc)
+{
+	GList *m = NULL;
+	struct proto_chat_entry *pce;
+	JabberStream *js = gc->proto_data;
+
+	pce = g_new0(struct proto_chat_entry, 1);
+	pce->label = _("Room:");
+	pce->identifier = "room";
+	m = g_list_append(m, pce);
+
+	/* we're gonna default to a conference server I know is true, until
+	 * I can figure out how to disco for a chat server */
+	pce = g_new0(struct proto_chat_entry, 1);
+	pce->label = _("Server:");
+	pce->identifier = "server";
+	pce->def = "conference.jabber.org";
+	m = g_list_append(m, pce);
+
+	pce = g_new0(struct proto_chat_entry, 1);
+	pce->label = _("Handle:");
+	pce->identifier = "handle";
+	pce->def = js->user->node;
+	m = g_list_append(m, pce);
+
+	pce = g_new0(struct proto_chat_entry, 1);
+	pce->label = _("Password:");
+	pce->identifier = "password";
+	pce->secret = TRUE;
+	m = g_list_append(m, pce);
+
+	return m;
+}
+
+JabberChat *jabber_chat_find(JabberStream *js, const char *room,
+		const char *server)
+{
+	JabberChat *chat;
+	char *room_jid;
+
+	room_jid = g_strdup_printf("%s@%s", room, server);
+
+	chat = g_hash_table_lookup(js->chats, room_jid);
+	g_free(room_jid);
+
+	return chat;
+}
+
+struct _find_by_id_data {
+	int id;
+	JabberChat *chat;
+};
+
+void find_by_id_foreach_cb(gpointer key, gpointer value, gpointer user_data)
+{
+	JabberChat *chat = value;
+	struct _find_by_id_data *fbid = user_data;
+
+	if(chat->id == fbid->id)
+		fbid->chat = chat;
+}
+
+JabberChat *jabber_chat_find_by_id(JabberStream *js, int id)
+{
+	JabberChat *chat;
+	struct _find_by_id_data *fbid = g_new0(struct _find_by_id_data, 1);
+	g_hash_table_foreach(js->chats, find_by_id_foreach_cb, fbid);
+	chat = fbid->chat;
+	g_free(fbid);
+	return chat;
+}
+
+void jabber_chat_invite(GaimConnection *gc, int id, const char *msg,
+		const char *name)
+{
+	JabberStream *js = gc->proto_data;
+	JabberChat *chat;
+	xmlnode *message, *body, *x, *invite;
+	char *room_jid;
+
+	chat = jabber_chat_find_by_id(js, id);
+	if(!chat)
+		return;
+
+	message = xmlnode_new("message");
+
+	room_jid = g_strdup_printf("%s@%s", chat->room, chat->server);
+
+	if(chat->muc) {
+		xmlnode_set_attrib(message, "to", room_jid);
+		x = xmlnode_new_child(message, "x");
+		xmlnode_set_attrib(x, "xmlns", "http://jabber.org/protocol/muc#user");
+		invite = xmlnode_new_child(x, "invite");
+		xmlnode_set_attrib(invite, "to", name);
+		body = xmlnode_new_child(invite, "reason");
+		xmlnode_insert_data(body, msg, -1);
+	} else {
+		xmlnode_set_attrib(message, "to", name);
+		body = xmlnode_new_child(message, "body");
+		xmlnode_insert_data(body, msg, -1);
+		x = xmlnode_new_child(message, "x");
+		xmlnode_set_attrib(x, "jid", room_jid);
+		xmlnode_set_attrib(x, "xmlns", "jabber:x:conference");
+	}
+
+	jabber_send(js, message);
+	xmlnode_free(message);
+	g_free(room_jid);
+}
+
+void jabber_chat_whisper(GaimConnection *gc, int id, const char *who,
+		const char *message)
+{
+	JabberStream *js = gc->proto_data;
+	JabberChat *chat;
+	char *full_jid;
+
+	chat = jabber_chat_find_by_id(js, id);
+
+	/* TODO: we get real Jabber IDs from MUC sometimes, we need to cache
+	 * them eventually */
+	full_jid = g_strdup_printf("%s@%s/%s", chat->room, chat->server, who);
+
+	jabber_message_send_im(gc, full_jid, message, 0);
+
+	g_free(full_jid);
+}
+
+void jabber_chat_join(GaimConnection *gc, GHashTable *data)
+{
+	JabberChat *chat;
+	char *room, *server, *handle, *passwd;
+	xmlnode *presence, *x;
+	char *room_jid, *full_jid;
+	JabberStream *js = gc->proto_data;
+
+	room = g_hash_table_lookup(data, "room");
+	server = g_hash_table_lookup(data, "server");
+	handle = g_hash_table_lookup(data, "handle");
+	passwd = g_hash_table_lookup(data, "password");
+
+	if(!room || !server || !handle)
+		return;
+
+	if(jabber_chat_find(js, room, server))
+		return;
+
+	room_jid = g_strdup_printf("%s@%s", room, server);
+
+	chat = g_new0(JabberChat, 1);
+	chat->js = gc->proto_data;
+
+	chat->room = g_strdup(room);
+	chat->server = g_strdup(server);
+	chat->nick = g_strdup(handle);
+
+	g_hash_table_insert(js->chats, room_jid, chat);
+
+	presence = xmlnode_new("presence");
+	full_jid = g_strdup_printf("%s/%s", room_jid, handle);
+	xmlnode_set_attrib(presence, "to", full_jid);
+	g_free(full_jid);
+
+	x = xmlnode_new_child(presence, "x");
+	xmlnode_set_attrib(x, "xmlns", "http://jabber.org/protocol/muc");
+
+	if(passwd && *passwd) {
+		xmlnode *password = xmlnode_new_child(x, "password");
+		xmlnode_insert_data(password, passwd, -1);
+	}
+
+	jabber_send(js, presence);
+	xmlnode_free(presence);
+}
+
+void jabber_chat_leave(GaimConnection *gc, int id)
+{
+	JabberStream *js = gc->proto_data;
+	JabberChat *chat = jabber_chat_find_by_id(js, id);
+	char *room_jid;
+	xmlnode *presence;
+
+	if(!chat)
+		return;
+
+	room_jid = g_strdup_printf("%s@%s", chat->room, chat->server);
+	gaim_debug(GAIM_DEBUG_INFO, "jabber", "%s is leaving chat %s\n",
+			chat->nick, room_jid);
+	presence = xmlnode_new("presence");
+	xmlnode_set_attrib(presence, "to", room_jid);
+	xmlnode_set_attrib(presence, "type", "unavailable");
+	jabber_send(js, presence);
+	xmlnode_free(presence);
+}
+
+void jabber_chat_destroy(JabberChat *chat)
+{
+	JabberStream *js = chat->js;
+	char *room_jid = g_strdup_printf("%s@%s", chat->room, chat->server);
+
+	g_hash_table_remove(js->chats, room_jid);
+	g_free(room_jid);
+
+	g_free(chat->room);
+	g_free(chat->server);
+	g_free(chat->nick);
+	g_free(chat);
+}
+
+gboolean jabber_chat_find_buddy(GaimConversation *conv, const char *name)
+{
+	GList *m = gaim_chat_get_users(GAIM_CHAT(conv));
+
+	while(m) {
+		if(!strcmp(m->data, name))
+			return TRUE;
+		m = m->next;
+	}
+
+	return FALSE;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/chat.h	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,55 @@
+/**
+ * @file chat.h Chat stuff
+ *
+ * gaim
+ *
+ * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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
+ */
+#ifndef _GAIM_JABBER_CHAT_H_
+#define _GAIM_JABBER_CHAT_H_
+
+#include "internal.h"
+#include "connection.h"
+#include "conversation.h"
+
+#include "jabber.h"
+
+
+typedef struct _JabberChat {
+	JabberStream *js;
+	char *room;
+	char *server;
+	char *nick;
+	int id;
+	GaimConversation *conv;
+	gboolean muc;
+} JabberChat;
+
+GList *jabber_chat_info(GaimConnection *gc);
+void jabber_chat_join(GaimConnection *gc, GHashTable *data);
+JabberChat *jabber_chat_find(JabberStream *js, const char *room,
+		const char *server);
+JabberChat *jabber_chat_find_by_id(JabberStream *js, int id);
+void jabber_chat_destroy(JabberChat *chat);
+gboolean jabber_chat_find_buddy(GaimConversation *conv, const char *name);
+void jabber_chat_whisper(GaimConnection *gc, int id, const char *who,
+		const char *message);
+void jabber_chat_invite(GaimConnection *gc, int id, const char *message,
+		const char *name);
+void jabber_chat_leave(GaimConnection *gc, int id);
+
+#endif /* _GAIM_JABBER_CHAT_H_ */
--- a/src/protocols/jabber/expat.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,223 +0,0 @@
-/* --------------------------------------------------------------------------
- *
- * License
- *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
- *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
- *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
-
-#include "lib.h"
-
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
-
-void expat_startElement(void* userdata, const char* name, const char** atts)
-{
-    /* get the xmlnode pointed to by the userdata */
-    xmlnode *x = userdata;
-    xmlnode current = *x;
-
-    if (current == NULL)
-    {
-        /* allocate a base node */
-        current = xmlnode_new_tag(name);
-        xmlnode_put_expat_attribs(current, atts);
-        *x = current;
-    }
-    else
-    {
-        *x = xmlnode_insert_tag(current, name);
-        xmlnode_put_expat_attribs(*x, atts);
-    }
-}
-
-void expat_endElement(void* userdata, const char* name)
-{
-    xmlnode *x = userdata;
-    xmlnode current = *x;
-
-    current->complete = 1;
-    current = xmlnode_get_parent(current);
-
-    /* if it's NULL we've hit the top folks, otherwise back up a level */
-    if(current != NULL)
-        *x = current;
-}
-
-void expat_charData(void* userdata, const char* s, int len)
-{
-    xmlnode *x = userdata;
-    xmlnode current = *x;
-
-    xmlnode_insert_cdata(current, s, len);
-}
-
-
-xmlnode xmlnode_str(char *str, int len)
-{
-    XML_Parser p;
-    xmlnode *x, node; /* pointer to an xmlnode */
-
-    if(NULL == str)
-        return NULL;
-
-    x = malloc(sizeof(void *));
-
-    *x = NULL; /* pointer to NULL */
-    p = XML_ParserCreate(NULL);
-    XML_SetUserData(p, x);
-    XML_SetElementHandler(p, expat_startElement, expat_endElement);
-    XML_SetCharacterDataHandler(p, expat_charData);
-    if(!XML_Parse(p, str, len, 1))
-    {
-        /*        jdebug(ZONE,"xmlnode_str_error: %s",(char *)XML_ErrorString(XML_GetErrorCode(p)));*/
-        xmlnode_free(*x);
-        *x = NULL;
-    }
-    node = *x;
-    free(x);
-    XML_ParserFree(p);
-    return node; /* return the xmlnode x points to */
-}
-
-xmlnode xmlnode_file(char *file)
-{
-    XML_Parser p;
-    xmlnode *x, node; /* pointer to an xmlnode */
-    char buf[BUFSIZ];
-    int done, fd, len;
-
-    if(NULL == file)
-        return NULL;
-
-    fd = open(file,O_RDONLY);
-    if(fd < 0)
-        return NULL;
-
-    x = malloc(sizeof(void *));
-
-    *x = NULL; /* pointer to NULL */
-    p = XML_ParserCreate(NULL);
-    XML_SetUserData(p, x);
-    XML_SetElementHandler(p, expat_startElement, expat_endElement);
-    XML_SetCharacterDataHandler(p, expat_charData);
-    do{
-        len = read(fd, buf, BUFSIZ);
-        done = len < BUFSIZ;
-        if(!XML_Parse(p, buf, len, done))
-        {
-            /*            jdebug(ZONE,"xmlnode_file_parseerror: %s",(char *)XML_ErrorString(XML_GetErrorCode(p)));*/
-            xmlnode_free(*x);
-            *x = NULL;
-            done = 1;
-        }
-    }while(!done);
-
-    node = *x;
-    XML_ParserFree(p);
-    free(x);
-    close(fd);
-    return node; /* return the xmlnode x points to */
-}
-
-char* xmlnode_file_borked(char *file)
-{
-    XML_Parser p;
-    char buf[BUFSIZ];
-    static char err[1024];
-    int fd, len, done;
-
-    if(NULL == file)
-        return "no file specified";
-
-    fd = open(file,O_RDONLY);
-    if(fd < 0)
-        return "unable to open file";
-
-    p = XML_ParserCreate(NULL);
-    while(1)
-    {
-        len = read(fd, buf, BUFSIZ);
-        done = len < BUFSIZ;
-        if(!XML_Parse(p, buf, len, done))
-        {
-            snprintf(err,1023,"%s at line %d and column %d",XML_ErrorString(XML_GetErrorCode(p)),XML_GetErrorLineNumber(p),XML_GetErrorColumnNumber(p));
-            XML_ParserFree(p);
-            close(fd);
-            return err;
-        }
-    }
-}
-
-int xmlnode2file(char *file, xmlnode node)
-{
-    char *doc, *ftmp;
-    int fd, i;
-
-    if(file == NULL || node == NULL)
-        return -1;
-
-    ftmp = spools(xmlnode_pool(node),file,".t.m.p",xmlnode_pool(node));
-    fd = open(ftmp, O_CREAT | O_WRONLY | O_TRUNC, 0600);
-    if(fd < 0)
-        return -1;
-
-    doc = xmlnode2str(node);
-    i = write(fd,doc,strlen(doc));
-    if(i < 0)
-        return -1;
-
-    close(fd);
-
-    if(rename(ftmp,file) < 0)
-    {
-        unlink(ftmp);
-        return -1;
-    }
-    return 1;
-}
-
-void xmlnode_put_expat_attribs(xmlnode owner, const char** atts)
-{
-    int i = 0;
-    if (atts == NULL) return;
-    while (atts[i] != '\0')
-    {
-        xmlnode_put_attrib(owner, atts[i], atts[i+1]);
-        i += 2;
-    }
-}
--- a/src/protocols/jabber/genhash.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/* --------------------------------------------------------------------------
- *
- * License
- *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
- *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
- *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
-
-#include "lib.h"
-
-/*** stubs that hook back to new xhash */
-
-HASHTABLE ghash_create(int buckets, KEYHASHFUNC hash, KEYCOMPAREFUNC cmp)
-{
-    return xhash_new(buckets);
-}
-
-HASHTABLE ghash_create_pool(pool p, int buckets, KEYHASHFUNC hash, KEYCOMPAREFUNC cmp)
-{
-    xht h = xhash_new(buckets);
-    pool_cleanup(p, (pool_cleaner)xhash_free, h);
-    return h;
-}
-
-void ghash_destroy(HASHTABLE tbl)
-{
-    xhash_free(tbl);
-}
-
-void *ghash_get(HASHTABLE tbl, const void *key)
-{
-    return xhash_get(tbl, key);
-}
-
-int ghash_put(HASHTABLE tbl, const void *key, void *value)
-{
-    xhash_put(tbl, key, value);
-    return 1;
-}
-
-int ghash_remove(HASHTABLE tbl, const void *key)
-{
-    xhash_zap(tbl, key);
-    return 1;
-}
-
-
-int ghash_walk(HASHTABLE tbl, TABLEWALKFUNC func, void *user_data)
-{
-    int i;
-    xhn n;
-    xht h = (xht)tbl;
-
-    for(i = 0; i < h->prime; i++)
-        for(n = &h->zen[i]; n != NULL; n = n->next)
-            if(n->key != NULL && n->val != NULL)
-                (*func)(user_data, n->key, n->val);
-
-    return 1;
-}
-
-
-int _xhasher(const char *key);
-int str_hash_code(const char *s)
-{
-    return _xhasher(s);
-}
-
--- a/src/protocols/jabber/hashtable.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-csompliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-*/
-
-#include "xmldef.h"
-
-#ifdef XML_UNICODE_WCHAR_T
-#ifndef XML_UNICODE
-#define XML_UNICODE
-#endif
-#endif
-
-#include "hashtable.h"
-
-#define INIT_SIZE 64
-
-static
-int keyeq(KEY s1, KEY s2)
-{
-    for (; *s1 == *s2; s1++, s2++)
-        if (*s1 == 0)
-            return 1;
-    return 0;
-}
-
-static
-unsigned long hash(KEY s)
-{
-    unsigned long h = 0;
-    while (*s)
-        h = (h << 5) + h + (unsigned char)*s++;
-    return h;
-}
-
-NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
-{
-    size_t i;
-    if (table->size == 0) {
-        if (!createSize)
-            return 0;
-        table->v = calloc(INIT_SIZE, sizeof(NAMED *));
-        if (!table->v)
-            return 0;
-        table->size = INIT_SIZE;
-        table->usedLim = INIT_SIZE / 2;
-        i = hash(name) & (table->size - 1);
-    }
-    else {
-        unsigned long h = hash(name);
-        for (i = h & (table->size - 1);
-                table->v[i];
-                i == 0 ? i = table->size - 1 : --i) {
-            if (keyeq(name, table->v[i]->name))
-                return table->v[i];
-        }
-        if (!createSize)
-            return 0;
-        if (table->used == table->usedLim) {
-            /* check for overflow */
-            size_t newSize = table->size * 2;
-            NAMED **newV = calloc(newSize, sizeof(NAMED *));
-            if (!newV)
-                return 0;
-            for (i = 0; i < table->size; i++)
-                if (table->v[i]) {
-                    size_t j;
-                    for (j = hash(table->v[i]->name) & (newSize - 1);
-                            newV[j];
-                            j == 0 ? j = newSize - 1 : --j)
-                        ;
-                    newV[j] = table->v[i];
-                }
-            free(table->v);
-            table->v = newV;
-            table->size = newSize;
-            table->usedLim = newSize/2;
-            for (i = h & (table->size - 1);
-                    table->v[i];
-                    i == 0 ? i = table->size - 1 : --i)
-                ;
-        }
-    }
-    table->v[i] = calloc(1, createSize);
-    if (!table->v[i])
-        return 0;
-    table->v[i]->name = name;
-    (table->used)++;
-    return table->v[i];
-}
-
-void hashTableDestroy(HASH_TABLE *table)
-{
-    size_t i;
-    for (i = 0; i < table->size; i++) {
-        NAMED *p = table->v[i];
-        if (p)
-            free(p);
-    }
-    free(table->v);
-}
-
-void hashTableInit(HASH_TABLE *p)
-{
-    p->size = 0;
-    p->usedLim = 0;
-    p->used = 0;
-    p->v = 0;
-}
-
-void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
-{
-    iter->p = table->v;
-    iter->end = iter->p + table->size;
-}
-
-NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
-{
-    while (iter->p != iter->end) {
-        NAMED *tem = *(iter->p)++;
-        if (tem)
-            return tem;
-    }
-    return 0;
-}
-
--- a/src/protocols/jabber/hashtable.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-
-#include <stddef.h>
-
-#ifdef XML_UNICODE
-
-#ifdef XML_UNICODE_WCHAR_T
-typedef const wchar_t *KEY;
-#else /* not XML_UNICODE_WCHAR_T */
-typedef const unsigned short *KEY;
-#endif /* not XML_UNICODE_WCHAR_T */
-
-#else /* not XML_UNICODE */
-
-typedef const char *KEY;
-
-#endif /* not XML_UNICODE */
-
-typedef struct {
-  KEY name;
-} NAMED;
-
-typedef struct {
-  NAMED **v;
-  size_t size;
-  size_t used;
-  size_t usedLim;
-} HASH_TABLE;
-
-NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
-void hashTableInit(HASH_TABLE *);
-void hashTableDestroy(HASH_TABLE *);
-
-typedef struct {
-  NAMED **p;
-  NAMED **end;
-} HASH_TABLE_ITER;
-
-void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
-NAMED *hashTableIterNext(HASH_TABLE_ITER *);
--- a/src/protocols/jabber/iasciitab.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
-/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
-/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
-/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
-/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
-/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
-/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
-/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
-/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
-/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
-/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
-/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
-/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
-/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
-/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/iq.c	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,231 @@
+/*
+ * gaim - Jabber Protocol Plugin
+ *
+ * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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 "debug.h"
+#include "prefs.h"
+
+#include "iq.h"
+#include "roster.h"
+
+
+JabberIq *jabber_iq_new(JabberStream *js, JabberIqType type)
+{
+	JabberIq *iq;
+
+	iq = g_new0(JabberIq, 1);
+
+	iq->type = type;
+
+	iq->node = xmlnode_new("iq");
+	switch(iq->type) {
+		case JABBER_IQ_SET:
+			xmlnode_set_attrib(iq->node, "type", "set");
+			break;
+		case JABBER_IQ_GET:
+			xmlnode_set_attrib(iq->node, "type", "get");
+			break;
+		case JABBER_IQ_ERROR:
+			xmlnode_set_attrib(iq->node, "type", "error");
+			break;
+		case JABBER_IQ_RESULT:
+			xmlnode_set_attrib(iq->node, "type", "result");
+			break;
+		case JABBER_IQ_NONE:
+			/* this shouldn't ever happen */
+			break;
+	}
+
+	iq->js = js;
+
+	if(type == JABBER_IQ_GET || type == JABBER_IQ_SET) {
+		iq->id = jabber_get_next_id(js);
+		xmlnode_set_attrib(iq->node, "id", iq->id);
+	}
+
+	return iq;
+}
+
+JabberIq *jabber_iq_new_query(JabberStream *js, JabberIqType type,
+		const char *xmlns)
+{
+	JabberIq *iq = jabber_iq_new(js, type);
+	xmlnode *query;
+
+	query = xmlnode_new_child(iq->node, "query");
+	xmlnode_set_attrib(query, "xmlns", xmlns);
+
+	return iq;
+}
+
+void jabber_iq_set_callback(JabberIq *iq, JabberCallback *callback)
+{
+	iq->callback = callback;
+}
+
+void jabber_iq_set_id(JabberIq *iq, const char *id)
+{
+	if(iq->id)
+		g_free(iq->id);
+
+	if(id) {
+		xmlnode_set_attrib(iq->node, "id", id);
+		iq->id = g_strdup(id);
+	} else {
+		xmlnode_remove_attrib(iq->node, "id");
+		iq->id = NULL;
+	}
+}
+
+void jabber_iq_send(JabberIq *iq)
+{
+	g_return_if_fail(iq != NULL);
+
+	jabber_send(iq->js, iq->node);
+
+	if(iq->id && iq->callback)
+		g_hash_table_insert(iq->js->callbacks, g_strdup(iq->id), iq->callback);
+
+	jabber_iq_free(iq);
+}
+
+void jabber_iq_free(JabberIq *iq)
+{
+	g_return_if_fail(iq != NULL);
+
+	g_free(iq->id);
+	xmlnode_free(iq->node);
+	g_free(iq);
+}
+
+static void jabber_iq_handle_last(JabberStream *js, xmlnode *packet)
+{
+	JabberIq *iq;
+	const char *from;
+	const char *id;
+	xmlnode *query;
+	char *idle_time;
+
+	from = xmlnode_get_attrib(packet, "from");
+	id = xmlnode_get_attrib(packet, "id");
+
+	iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:last");
+	jabber_iq_set_id(iq, id);
+	xmlnode_set_attrib(iq->node, "to", from);
+
+	query = xmlnode_get_child(iq->node, "query");
+
+	idle_time = g_strdup_printf("%ld", js->idle ? time(NULL) - js->idle : 0);
+	xmlnode_set_attrib(query, "seconds", idle_time);
+	g_free(idle_time);
+}
+
+static void jabber_iq_handle_time(JabberStream *js, xmlnode *packet)
+{
+	const char *from, *id;
+	JabberIq *iq;
+	char buf[1024];
+	xmlnode *query;
+	time_t now_t;
+	struct tm now;
+	time(&now_t);
+	localtime_r(&now_t, &now);
+
+	from = xmlnode_get_attrib(packet, "from");
+	id = xmlnode_get_attrib(packet, "id");
+
+	iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:time");
+	jabber_iq_set_id(iq, id);
+	xmlnode_set_attrib(iq->node, "to", from);
+
+	query = xmlnode_get_child(iq->node, "query");
+
+	strftime(buf, sizeof(buf), "%Y%m%dT%T", &now);
+	xmlnode_insert_data(xmlnode_new_child(query, "utc"), buf, -1);
+	strftime(buf, sizeof(buf), "%Z", &now);
+	xmlnode_insert_data(xmlnode_new_child(query, "tz"), buf, -1);
+	strftime(buf, sizeof(buf), "%d %b %Y %T", &now);
+	xmlnode_insert_data(xmlnode_new_child(query, "display"), buf, -1);
+
+	jabber_iq_send(iq);
+}
+
+static void jabber_iq_handle_version(JabberStream *js, xmlnode *packet)
+{
+	JabberIq *iq;
+	const char *from, *id;
+	xmlnode *query;
+	char *os = NULL;
+
+	if(!gaim_prefs_get_bool("/plugins/prpl/jabber/hide_os")) {
+		struct utsname osinfo;
+
+		uname(&osinfo);
+		os = g_strdup_printf("%s %s %s", osinfo.sysname, osinfo.release,
+				osinfo.machine);
+	}
+
+	from = xmlnode_get_attrib(packet, "from");
+	id = xmlnode_get_attrib(packet, "id");
+
+	iq = jabber_iq_new_query(js, JABBER_IQ_RESULT, "jabber:iq:version");
+	xmlnode_set_attrib(iq->node, "to", from);
+	jabber_iq_set_id(iq, id);
+
+	query = xmlnode_get_child(iq->node, "query");
+
+	xmlnode_insert_data(xmlnode_new_child(query, "name"), PACKAGE, -1);
+	xmlnode_insert_data(xmlnode_new_child(query, "version"), VERSION, -1);
+	if(os) {
+		xmlnode_insert_data(xmlnode_new_child(query, "os"), os, -1);
+		g_free(os);
+	}
+
+	jabber_iq_send(iq);
+}
+
+void jabber_iq_parse(JabberStream *js, xmlnode *packet)
+{
+	xmlnode *query;
+	const char *xmlns;
+
+	query = xmlnode_get_child(packet, "query");
+
+	if(!query)
+		return;
+
+	xmlns = xmlnode_get_attrib(query, "xmlns");
+
+	if(!xmlns)
+		return;
+
+	if(!strcmp(xmlns, "jabber:iq:roster")) {
+		jabber_roster_parse(js, packet);
+	} else if(!strcmp(xmlns, "jabber:iq:last")) {
+		jabber_iq_handle_last(js, packet);
+	} else if(!strcmp(xmlns, "jabber:iq:time")) {
+		jabber_iq_handle_time(js, packet);
+	} else if(!strcmp(xmlns, "jabber:iq:version")) {
+		jabber_iq_handle_version(js, packet);
+	} else {
+		gaim_debug(GAIM_DEBUG_WARNING, "jabber", "Unknown query: %s\n", xmlns);
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/iq.h	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,58 @@
+/**
+ * @file iq.h JabberID handlers
+ *
+ * gaim
+ *
+ * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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
+ */
+#ifndef _GAIM_JABBER_IQ_H_
+#define _GAIM_JABBER_IQ_H_
+
+#include "jabber.h"
+
+typedef struct _JabberIq JabberIq;
+
+typedef enum {
+	JABBER_IQ_SET,
+	JABBER_IQ_GET,
+	JABBER_IQ_RESULT,
+	JABBER_IQ_ERROR,
+	JABBER_IQ_NONE
+} JabberIqType;
+
+struct _JabberIq {
+	JabberIqType type;
+	char *id;
+	xmlnode *node;
+
+	JabberCallback *callback;
+
+	JabberStream *js;
+};
+
+JabberIq *jabber_iq_new(JabberStream *js, JabberIqType type);
+JabberIq *jabber_iq_new_query(JabberStream *js, JabberIqType type,
+		const char *xmlns);
+
+void jabber_iq_parse(JabberStream *js, xmlnode *packet);
+
+void jabber_iq_set_callback(JabberIq *iq, JabberCallback *cb);
+
+void jabber_iq_send(JabberIq *iq);
+void jabber_iq_free(JabberIq *iq);
+
+#endif /* _GAIM_JABBER_IQ_H_ */
--- a/src/protocols/jabber/jabber.c	Mon Sep 29 13:00:55 2003 +0000
+++ b/src/protocols/jabber/jabber.c	Mon Sep 29 15:23:19 2003 +0000
@@ -1,14 +1,13 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- * gaim
+ * gaim - Jabber Protocol Plugin
  *
- * Some code copyright (C) 1998-1999, Mark Spencer <markster@marko.net>
- * libfaim code copyright 1998, 1999 Adam Fritzler <afritz@auk.cx>
+ * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
  *
  * 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
@@ -21,2932 +20,430 @@
  */
 #include "internal.h"
 
-#ifdef _WIN32
-# include "utsname.h"
-#endif
-
-#include "account.h"
-#include "accountopt.h"
+/*
 #include "conversation.h"
-#include "debug.h"
 #include "ft.h"
 #include "multi.h"
 #include "notify.h"
-#include "prpl.h"
+#include "proxy.h"
 #include "request.h"
 #include "util.h"
-#include "html.h"
-#include "sslconn.h"
+
+*/
 
-/* XXX */
-#include "gaim.h"
+#include "account.h"
+#include "accountopt.h"
+#include "debug.h"
+#include "html.h"
+#include "message.h"
+#include "multi.h"
+#include "prpl.h"
+#include "server.h"
 
-#ifdef MAX
-# undef MAX
-#endif
-#ifdef MIN
-# undef MIN
-#endif
+#include "auth.h"
+#include "buddy.h"
+#include "chat.h"
+#include "iq.h"
+#include "jutil.h"
+#include "message.h"
+#include "parser.h"
+#include "presence.h"
+#include "jabber.h"
+#include "roster.h"
 
-#include "jabber.h"
-#include "proxy.h"
+#define JABBER_CONNECT_STEPS (js->gsc ? 8 : 5)
 
 static GaimPlugin *my_protocol = NULL;
 
-/* The priv member of gjconn's is a gaim_connection for now. */
-#define GJ_GC(x) ((GaimConnection *)(x)->priv)
-/* Confused? That makes three of us. -Robot101 */
-#define GC_GJ(x) ((gjconn)((struct jabber_data *)(x)->proto_data)->gjc)
-
-#define JABBER_CONNECT_STEPS 5
-
-#define IQID_AUTH "__AUTH__"
-
-#define IQ_NONE -1
-#define IQ_AUTH 0
-#define IQ_ROSTER 1
-
-#define UC_AWAY   (0x02 | UC_UNAVAILABLE)
-#define UC_CHAT    0x04
-#define UC_XA     (0x08 | UC_UNAVAILABLE)
-#define UC_DND    (0x10 | UC_UNAVAILABLE)
-#define UC_ERROR  (0x20 | UC_UNAVAILABLE)
-
-#define DEFAULT_SERVER "jabber.org"
-#define DEFAULT_GROUPCHAT "conference.jabber.org"
-#define DEFAULT_PORT 5222
-
-#define USEROPT_PORT 0
-#define USEROPT_CONN_SERVER 1
-
-#define JABBER_TYPING_NOTIFY_INT 15	/* Delay (in seconds) between sending typing notifications */
-
-#define JABBER_KEEPALIVE_STRING "  \t  "
-
-/*
- * Note: "was_connected" may seem redundant, but it was needed and I
- * didn't want to touch the Jabber state stuff not specific to Gaim.
- */
-typedef struct gjconn_struct {
-	/* Core structure */
-	pool p;			/* Memory allocation pool */
-	int state;		/* Connection state flag */
-	int was_connected;	/* We were once connected */
-	int fd;			/* Connection file descriptor */
-	jid user;		/* User info */
-	char *pass;		/* User passwd */
-
-	/* Stream stuff */
-	int id;			/* id counter for jab_getid() function */
-	char idbuf[9];		/* temporary storage for jab_getid() */
-	char *sid;		/* stream id from server, for digest auth */
-	XML_Parser parser;	/* Parser instance */
-	xmlnode current;	/* Current node in parsing instance.. */
-
-	/* Event callback ptrs */
-	void (*on_state)(struct gjconn_struct *gjc, int state);
-	void (*on_packet)(struct gjconn_struct *gjc, jpacket p);
-
-	GHashTable *queries;	/* query tracker */
-
-	void *priv;
-
-	GaimSslConnection *gsc;
-
-} *gjconn, gjconn_struct;
-
-typedef void (*gjconn_state_h)(gjconn gjc, int state);
-typedef void (*gjconn_packet_h)(gjconn gjc, jpacket p);
-
-static gjconn gjab_new(char *user, char *pass, void *priv);
-static void gjab_delete(gjconn gjc);
-static void gjab_state_handler(gjconn gjc, gjconn_state_h h);
-static void gjab_packet_handler(gjconn gjc, gjconn_packet_h h);
-static void gjab_start(gjconn gjc);
-static void gjab_stop(gjconn gjc);
-/*
-static int gjab_getfd(gjconn gjc);
-static jid gjab_getjid(gjconn gjc);
-static char *gjab_getsid(gjconn gjc);
-*/
-static char *gjab_getid(gjconn gjc);
-static void gjab_send(gjconn gjc, xmlnode x);
-static void gjab_send_raw(gjconn gjc, const char *str);
-static void gjab_recv(gjconn gjc);
-static void gjab_auth(gjconn gjc);
-
-/*
- * It is *this* to which we point the gaim_connection proto_data
- */
-struct jabber_data {
-	gjconn gjc;
-	gboolean did_import;
-	GSList *chats;
-	time_t idle;
-	GHashTable *buddies;
-	GSList *file_transfers;
-};
-
-/*
- * Used in jabber_buddy_data.invisible, below
- */
-#define JABBER_NOT_INVIS  0x00
-#define JABBER_SERV_INVIS 0x01	/* Invisible set on server */
-#define JABBER_BUD_INVIS  0x02	/* Invisible set on buddy */
+static void jabber_stream_init(JabberStream *js)
+{
+	char *open_stream;
 
-/*
- * Used in jabber_buddy_data.subscription, below
- */
-#define JABBER_SUB_NONE    0x0
-#define JABBER_SUB_PENDING 0x1
-#define JABBER_SUB_TO      0x2
-#define JABBER_SUB_FROM    0x4
-#define JABBER_SUB_BOTH    (JABBER_SUB_TO | JABBER_SUB_FROM)
-
-
-/*
- * It is *this* to which we point the buddy proto_data
- */
-struct jabber_buddy_data {
-	GSList *resources;
-	char *error_msg;
-	unsigned invisible;	/* We've set presence type invisible for this buddy */
-	unsigned subscription; /* subscription type for this buddy */
-};
-
-/*
- * per-resource info
- */
-typedef struct jabber_resource_info {
-	char *name;
-	int priority;
-	int state;
-	char *away_msg;
-	char *thread_id;
-	gboolean has_composing;
-	gboolean has_xhtml;
-} *jab_res_info;
+	open_stream = g_strdup_printf("<stream:stream to='%s' "
+				          "xmlns='jabber:client' "
+						  "xmlns:stream='http://etherx.jabber.org/streams' "
+						  "version='1.0'>", js->user->domain);
 
-/*
- * For our own jid handling
- *
- * We do our own so we can cleanly parse buddy names
- * (user@server/resource) and rid ourselves of the
- * struct when we're done with it.  The Jabber lib
- * structs last the life of the pool--we frequently
- * don't want that.
- *
- * We use the real jid structs so we can make use of
- * jid_safe(), jid_cmp() and some others.
- *
- *    BE CAREFUL using the Jabber lib routines.
- *    Many of them assume pool use and are not
- *    amenable to use with our own!
- *
- * We give them special names so we know, throughout
- * the code, that they're not alloc'd out of pool
- * memory and we can, and must, dispose of them when
- * we're done with 'em.
- */
-#define gaim_jid_struct jid_struct
-typedef struct gaim_jid_struct *gaim_jid;
-
-/*
- * Jabber "chat group" info.  Pointers to these go in jabber_data
- * pending and existing chats lists.
- */
-struct jabber_chat {
-	gaim_jid gjid;
-	GaimConnection *gc;
-	GaimConversation *b;
-	int id;
-	int state;
-};
+	jabber_send_raw(js, open_stream);
 
-/*
- * Jabber chat states...
- *
- * Note: due to a bug in one version of the Jabber server, subscriptions
- * to chat groups aren't (always?) properly removed at the server.  The
- * result is clients receive Jabber "presence" notifications for JIDs
- * they no longer care about.  The problem with such vestigial notifies is
- * that we really have no way of telling if it's vestigial or if it's a
- * valid "buddy" presence notification.  So we keep jabber_chat structs
- * around after leaving a chat group and simply mark them "closed."  That
- * way we can test for such errant presence notifications.  I.e.: if we
- * get a presence notfication from a JID that matches a chat group JID,
- * we disregard it.
- */
-#define JCS_PENDING 1	/* pending */
-#define JCS_ACTIVE  2	/* active */
-#define JCS_CLOSED  3	/* closed */
-
-
-#define STATE_EVT(arg) if(gjc->on_state) { (gjc->on_state)(gjc, (arg) ); }
-
-static void jabber_handlevcard(gjconn, xmlnode, char *);
-
-static char *jabber_normalize(const char *s);
-
-static char *create_valid_jid(const char *given, char *server, char *resource)
-{
-	char *valid;
-	char *tmp;
-
-	if (!(tmp = strchr(given, '@')))
-		valid = g_strdup_printf("%s@%s/%s", given, server, resource);
-	else if (!strchr(tmp, '/'))
-		valid = g_strdup_printf("%s/%s", given, resource);
-	else
-		valid = g_strdup(given);
-
-	return valid;
+	g_free(open_stream);
 }
 
-
-/*
- * Dispose of a gaim_jid_struct
- */
-static void gaim_jid_free(gaim_jid gjid)
+static void jabber_session_initialized_cb(JabberStream *js, xmlnode *packet)
 {
-	if(gjid) {
-		if(gjid->resource)
-			free(gjid->resource);
-		if(gjid->user)
-			free(gjid->user);
-		if(gjid->server)
-			free(gjid->server);
-		if(gjid->full)
-			free(gjid->full);
-		free(gjid);
+	const char *type = xmlnode_get_attrib(packet, "type");
+	if(type && !strcmp(type, "result")) {
+		jabber_stream_set_state(js, JABBER_STREAM_CONNECTED);
+	} else {
+		gaim_connection_error(js->gc, _("Error initializing session"));
 	}
 }
 
-/*
- * Create a new gjid struct
- *
- * Unlike jid_new(), also creates "full."
- *
- * Shamelessly copied, in part, from jid.c: jid_new()
- *
- * Caller is responsible for freeing the space allocated by this via
- * gaim_jid_free().
- *
- * JFIXME: Has a local declaration for jid.c:jid_safe().  I've put in a
- *         request to have that added to libjabber's lib.h file. (JSeymour)
- */
-static gaim_jid gaim_jid_new(char *name)
+static void jabber_session_init(JabberStream *js)
 {
-	extern jid jid_safe(jid);	/* *retch* */
-
-	gaim_jid gjid = NULL;
-
-	if(name && strlen(name)) {
-		char *server, *resource, *type, *str;
-		int full_len = 0;
-
-		/* user@server/resource */
-
-		str = strdup(name);	/* we mangle a copy */
-
-		gjid = calloc(1, sizeof(struct gaim_jid_struct));
-
-		if((resource = strstr(str, "/")) != NULL) {
-			*resource = '\0';
-			++resource;
-			if((full_len = strlen(resource)) > 0) {
-				gjid->resource = strdup(resource);
-				++full_len;	/* for later "/" addition */
-			}
-		} else {
-			resource = str + strlen(str); /* point to end */
-		}
-
-		type = strstr(str, ":");
-		if(type != NULL && type < resource) {
-			*type = '\0';
-			++type;
-			str = type; /* ignore the type: prefix */
-		}
+	JabberIq *iq = jabber_iq_new(js, JABBER_IQ_SET);
+	xmlnode *session;
 
-		server = strstr(str, "@");
-
-		/*
-		 * if there's no @, it's just the server address
-		 */
-		if(server == NULL || server > resource) {
-			gjid->server = strdup(str);
-			full_len += strlen(str);
-		} else {
-			*server = '\0';
-			++server;
-			gjid->server = strdup(server);
-			full_len += strlen(server) + 1;	/* account for later "@" */
-			if(strlen(str) > 0) {
-				gjid->user = strdup(str);
-				full_len += strlen(str);
-			}
-		}
-
-		free(str);
+	jabber_iq_set_callback(iq, jabber_session_initialized_cb);
 
-		if(!jid_safe(gjid)) {
-			gaim_jid_free(gjid);
-			gjid = NULL;
-		} else {
-			if(full_len) {
-				char *s = gjid->full = malloc(++full_len);
+	session = xmlnode_new_child(iq->node, "session");
+	xmlnode_set_attrib(session, "xmlns", "urn:ietf:params:xml:ns:xmpp-session");
 
-				if(gjid->user) {
-					strcpy(s, gjid->user);
-					s += strlen(gjid->user);
-				}
-				if(gjid->server) {
-					if(s > gjid->full)
-						*(s++) = '@';
-					strcpy(s, gjid->server);
-					s += strlen(gjid->server);
-				}
-				if(gjid->resource) {
-					*(s++) = '/';
-					strcpy(s, gjid->resource);
-				}
-			}
-		}
-	}
-
-	return gjid;
+	jabber_iq_send(iq);
 }
 
-/*
- * Get a "username@server" from unadorned "username"
- *
- * If there's no "@server" part and "who" doesn't match the
- * gjconn server (which would indicate that "who" *is* the
- * server in case of server messages), the gjconn server is
- * appended.
- *
- * If incl_resource is TRUE (non-0), the returned string
- * includes the "/resource" part (if it exists), otherwise not.
- *
- * Allocates space for returned string.  Caller is
- * responsible for freeing it with g_free().
- *
- * If "gjid" is non-null, sets that as well.  Caller is
- * reponsible for freeing that via gaim_jid_free() when done
- * with it.
- */
-static gchar *get_realwho(gjconn gjc, const char *who, int incl_resource, gaim_jid *gjid)
+static void jabber_stream_handle_error(JabberStream *js, xmlnode *packet)
 {
-	gaim_jid my_gjid;
-	gchar *my_who;
-	gchar *realwho = NULL;
-
-	if(!(who && who[0])) {
-	    return NULL;
-	}
+	xmlnode *textnode;
+	char *error_text = NULL;
+	const char *text;
+	char *buf;
 
-	/*
-	 * Bare username and "username" not the server itself?
-	 */
-	if(!strchr(who, '@') && strcasecmp(who, gjc->user->server)) {
-		my_who = g_strdup_printf("%s@%s", who, gjc->user->server);
+	if(xmlnode_get_child(packet, "bad-format")) {
+		text = _("Bad Format");
+	} else if(xmlnode_get_child(packet, "bad-namespace-prefix")) {
+		text = _("Bad Namespace Prefix");
+	} else if(xmlnode_get_child(packet, "conflict")) {
+		js->gc->wants_to_die = TRUE;
+		text = _("Resource Conflict");
+	} else if(xmlnode_get_child(packet, "connection-timeout")) {
+		text = _("Connection Timeout");
+	} else if(xmlnode_get_child(packet, "host-gone")) {
+		text = _("Host Gone");
+	} else if(xmlnode_get_child(packet, "host-unknown")) {
+		text = _("Host Unknown");
+	} else if(xmlnode_get_child(packet, "improper-addressing")) {
+		text = _("Improper Addressing");
+	} else if(xmlnode_get_child(packet, "internal-server-error")) {
+		text = _("Internal Server Error");
+	} else if(xmlnode_get_child(packet, "invalid-id")) {
+		text = _("Invalid ID");
+	} else if(xmlnode_get_child(packet, "invalid-namespace")) {
+		text = _("Invalid Namespace");
+	} else if(xmlnode_get_child(packet, "invalid-xml")) {
+		text = _("Invalid XML");
+	} else if(xmlnode_get_child(packet, "nonmatching-hosts")) {
+		text = _("Non-matching Hosts");
+	} else if(xmlnode_get_child(packet, "not-authorized")) {
+		text = _("Not Authorized");
+	} else if(xmlnode_get_child(packet, "policy-violation")) {
+		text = _("Policy Violation");
+	} else if(xmlnode_get_child(packet, "remote-connection-failed")) {
+		text = _("Remote Connection Failed");
+	} else if(xmlnode_get_child(packet, "resource-constraint")) {
+		text = _("Resource Constraint");
+	} else if(xmlnode_get_child(packet, "restricted-xml")) {
+		text = _("Restricted XML");
+	} else if(xmlnode_get_child(packet, "see-other-host")) {
+		text = _("See Other Host");
+	} else if(xmlnode_get_child(packet, "system-shutdown")) {
+		text = _("System Shutdown");
+	} else if(xmlnode_get_child(packet, "undefined-condition")) {
+		text = _("Undefined Condition");
+	} else if(xmlnode_get_child(packet, "unsupported-encoding")) {
+		text = _("Unsupported Condition");
+	} else if(xmlnode_get_child(packet, "unsupported-stanza-type")) {
+		text = _("Unsupported Stanza Type");
+	} else if(xmlnode_get_child(packet, "unsupported-version")) {
+		text = _("Unsupported Version");
+	} else if(xmlnode_get_child(packet, "xml-not-well-formed")) {
+		text = _("XML Not Well Formed");
 	} else {
-		my_who = g_strdup(who);
+		text = _("Stream Error");
 	}
 
-	if((my_gjid = gaim_jid_new(my_who)) != NULL) {
-		/*
-		 * If there's no "user" part, "who" was just the server or perhaps a transport (?)
-		 */
-		if(my_gjid->user) {
-			/*
-			 * Include "/resource" bit?
-			 */
-			if(incl_resource) {
-				realwho = g_strdup(my_gjid->full);
-			} else {
-				realwho = g_strdup_printf("%s@%s", my_gjid->user, my_gjid->server);
-			}
-		} else {
-			realwho = g_strdup(my_gjid->server);
-		}
-	}
-
-	g_free(my_who);
-
-	if(gjid) {
-		*gjid = my_gjid;
-	} else {
-		gaim_jid_free(my_gjid);
-	}
-
-	return realwho;
-}
-
-static gjconn gjab_new(char *user, char *pass, void *priv)
-{
-	pool p;
-	gjconn gjc;
+	if((textnode = xmlnode_get_child(packet, "text")))
+		error_text = xmlnode_get_data(textnode);
 
-	if (!user)
-		return (NULL);
-
-	p = pool_new();
-	if (!p)
-		return (NULL);
-	gjc = pmalloc_x(p, sizeof(gjconn_struct), 0);
-	if (!gjc) {
-		pool_free(p);	/* no need for this anymore! */
-		return (NULL);
-	}
-	gjc->p = p;
-
-	if((gjc->user = jid_new(p, user)) == NULL) {
-		pool_free(p);	/* no need for this anymore! */
-		return (NULL);
-	}
-
-	gjc->pass = strdup(pass);
-
-	gjc->state = JCONN_STATE_OFF;
-	gjc->was_connected = 0;
-	gjc->id = 1;
-	gjc->fd = -1;
-
-	gjc->priv = priv;
-
-	return gjc;
-}
-
-static void gjab_delete(gjconn gjc)
-{
-	if (!gjc)
-		return;
-
-	gjab_stop(gjc);
-	free(gjc->pass);
-	pool_free(gjc->p);
+	buf = g_strdup_printf("%s%s%s", text,
+			error_text ? ": " : "",
+			error_text ? error_text : "");
+	gaim_connection_error(js->gc, buf);
+	g_free(buf);
+	if(error_text)
+		g_free(error_text);
 }
 
-static void gjab_state_handler(gjconn gjc, gjconn_state_h h)
-{
-	if (!gjc)
-		return;
-
-	gjc->on_state = h;
-}
-
-static void gjab_packet_handler(gjconn gjc, gjconn_packet_h h)
-{
-	if (!gjc)
-		return;
-
-	gjc->on_packet = h;
-}
-
-static void gjab_stop(gjconn gjc)
-{
-	if (!gjc || gjc->state == JCONN_STATE_OFF)
-		return;
+static void tls_init(JabberStream *js);
 
-	gjab_send_raw(gjc, "</stream:stream>");
-	gjc->state = JCONN_STATE_OFF;
-	gjc->was_connected = 0;
-	if(gjc->gsc)
-		gaim_ssl_close(gjc->gsc);
-	else
-		close(gjc->fd);
-	gjc->fd = -1;
-	XML_ParserFree(gjc->parser);
-	gjc->parser = NULL;
-}
-
-/*
-static int gjab_getfd(gjconn gjc)
-{
-	if (gjc)
-		return gjc->fd;
-	else
-		return -1;
-}
-
-static jid gjab_getjid(gjconn gjc)
+void jabber_process_packet(JabberStream *js, xmlnode *packet)
 {
-	if (gjc)
-		return (gjc->user);
-	else
-		return NULL;
-}
-
-static char *gjab_getsid(gjconn gjc)
-{
-	if (gjc)
-		return (gjc->sid);
-	else
-		return NULL;
-}
-*/
-
-static char *gjab_getid(gjconn gjc)
-{
-	snprintf(gjc->idbuf, 8, "%d", gjc->id++);
-	return &gjc->idbuf[0];
-}
+	const char *id = xmlnode_get_attrib(packet, "id");
+	const char *type = xmlnode_get_attrib(packet, "type");
+	JabberCallback *callback;
 
-static void gjab_send(gjconn gjc, xmlnode x)
-{
-	if (gjc && gjc->state != JCONN_STATE_OFF) {
-		char *buf = xmlnode2str(x);
-		if (buf) {
-			if(gjc->gsc) {
-				if(gaim_ssl_write(gjc->gsc, buf, strlen(buf)) < 0) {
-					gaim_connection_error(GJ_GC(gjc), _("Write error"));
-				} else {
-					gaim_debug(GAIM_DEBUG_MISC, "jabber", "gjab_send (ssl): %s\n", buf);
-				}
-			} else {
-#ifndef _WIN32
-				if(write(gjc->fd, buf, strlen(buf)) < 0) {
-#else
-				if(send(gjc->fd, buf, strlen(buf), 0) < 0) {
-#endif
-					gaim_connection_error(GJ_GC(gjc), _("Write error"));
-				} else {
-					gaim_debug(GAIM_DEBUG_MISC, "jabber", "gjab_send: %s\n", buf);
-				}
-			}
+	if(!strcmp(packet->name, "iq")) {
+		if(type && (!strcmp(type, "result") || !strcmp(type, "error")) && id
+				&& *id && (callback = g_hash_table_lookup(js->callbacks, id)))
+			callback(js, packet);
+		else
+			jabber_iq_parse(js, packet);
+	} else if(!strcmp(packet->name, "presence")) {
+		jabber_presence_parse(js, packet);
+	} else if(!strcmp(packet->name, "message")) {
+		jabber_message_parse(js, packet);
+	} else if(!strcmp(packet->name, "stream:features")) {
+		if(js->state == JABBER_STREAM_AUTHENTICATING) {
+			jabber_auth_start(js, packet);
+		} else if(js->state == JABBER_STREAM_REINITIALIZING) {
+			jabber_session_init(js);
+		} else {
+			gaim_debug(GAIM_DEBUG_WARNING, "jabber",
+					"Unexpected stream:features packet, ignoring\n", js->state);
 		}
+	} else if(!strcmp(packet->name, "stream:error")) {
+		jabber_stream_handle_error(js, packet);
+	} else if(!strcmp(packet->name, "challenge")) {
+		if(js->state == JABBER_STREAM_AUTHENTICATING)
+			jabber_auth_handle_challenge(js, packet);
+	} else if(!strcmp(packet->name, "success")) {
+		if(js->state == JABBER_STREAM_AUTHENTICATING)
+			jabber_auth_handle_success(js, packet);
+	} else if(!strcmp(packet->name, "failure")) {
+		if(js->state == JABBER_STREAM_AUTHENTICATING)
+			jabber_auth_handle_failure(js, packet);
+	} else if(!strcmp(packet->name, "proceed")) {
+		if(js->state == JABBER_STREAM_AUTHENTICATING && !js->gsc)
+			tls_init(js);
+	} else {
+		gaim_debug(GAIM_DEBUG_WARNING, "jabber", "Unknown packet: %s\n",
+				packet->name);
 	}
 }
 
-static void gjab_send_raw(gjconn gjc, const char *str)
+void jabber_send_raw(JabberStream *js, const char *data)
 {
-	if (gjc && gjc->state != JCONN_STATE_OFF) {
-		/*
-		 * JFIXME: No error detection?!?!
-		 */
-		if(gjc->gsc) {
-			if(gaim_ssl_write(gjc->gsc, str, strlen(str)) < 0) {
-				gaim_connection_error(GJ_GC(gjc), _("Write error"));
-			} else {
-				gaim_debug(GAIM_DEBUG_MISC, "jabber", "gjab_send_raw (ssl): %s\n", str);
-			}
-		} else {
-#ifndef _WIN32
-			if(write(gjc->fd, str, strlen(str)) < 0) {
-#else
-			if(send(gjc->fd, str, strlen(str), 0) < 0) {
-#endif
-				gaim_connection_error(GJ_GC(gjc), _("Write error"));
-			}
-			/* printing keepalives to the debug window is really annoying */
-			if(strcmp(str, JABBER_KEEPALIVE_STRING))
-				gaim_debug(GAIM_DEBUG_MISC, "jabber", "gjab_send_raw: %s\n", str);
-		}
-	}
-}
+	int ret;
 
-static void gjab_reqroster(gjconn gjc)
-{
-	xmlnode x;
-
-	x = jutil_iqnew(JPACKET__GET, NS_ROSTER);
-	xmlnode_put_attrib(x, "id", gjab_getid(gjc));
-
-	gjab_send(gjc, x);
-	xmlnode_free(x);
-}
+	/* because printing a tab to debug every minute gets old */
+	if(strcmp(data, "\t"))
+		gaim_debug(GAIM_DEBUG_MISC, "jabber", "Sending%s: %s\n", 
+				js->gsc ? " (ssl)" : "", data);
 
-static void gjab_reqauth(gjconn gjc)
-{
-	xmlnode x, y, z;
-	char *user;
-
-	if (!gjc)
-		return;
-
-	x = jutil_iqnew(JPACKET__GET, NS_AUTH);
-	xmlnode_put_attrib(x, "id", IQID_AUTH);
-	y = xmlnode_get_tag(x, "query");
-
-	user = gjc->user->user;
-
-	if (user) {
-		z = xmlnode_insert_tag(y, "username");
-		xmlnode_insert_cdata(z, user, -1);
+	if(js->gsc) {
+		ret = gaim_ssl_write(js->gsc, data, strlen(data));
+	} else {
+		ret = write(js->fd, data, strlen(data));
 	}
 
-	gjab_send(gjc, x);
-	xmlnode_free(x);
+	if(ret < 0)
+		gaim_connection_error(js->gc, _("Write error"));
+
 }
 
-static void gjab_auth(gjconn gjc)
+void jabber_send(JabberStream *js, xmlnode *packet)
 {
-	xmlnode x, y, z;
-	char *hash, *user;
-
-	if (!gjc)
-		return;
-
-	x = jutil_iqnew(JPACKET__SET, NS_AUTH);
-	xmlnode_put_attrib(x, "id", IQID_AUTH);
-	y = xmlnode_get_tag(x, "query");
-
-	user = gjc->user->user;
-
-	if (user) {
-		z = xmlnode_insert_tag(y, "username");
-		xmlnode_insert_cdata(z, user, -1);
-	}
+	char *txt;
 
-	z = xmlnode_insert_tag(y, "resource");
-	xmlnode_insert_cdata(z, gjc->user->resource, -1);
-
-	if (gjc->sid) {
-		gaim_debug(GAIM_DEBUG_MISC, "jabber",
-				   "digest authentication (sid %s)\n", gjc->sid);
-		z = xmlnode_insert_tag(y, "digest");
-		hash = pmalloc(x->p, strlen(gjc->sid) + strlen(gjc->pass) + 1);
-		strcpy(hash, gjc->sid);
-		strcat(hash, gjc->pass);
-		hash = shahash(hash);
-		xmlnode_insert_cdata(z, hash, 40);
-	} else {
-		z = xmlnode_insert_tag(y, "password");
-		xmlnode_insert_cdata(z, gjc->pass, -1);
-	}
-
-	gjab_send(gjc, x);
-	xmlnode_free(x);
-
-	return;
+	txt = xmlnode_to_str(packet);
+	jabber_send_raw(js, txt);
+	g_free(txt);
 }
 
-static void gjab_recv(gjconn gjc)
+static void jabber_keepalive(GaimConnection *gc)
 {
-	static char buf[4096];
-	int len;
-
-	if (!gjc || gjc->state == JCONN_STATE_OFF)
-		return;
-#ifndef _WIN32
-	if ((len = read(gjc->fd, buf, sizeof(buf) - 1)) > 0) {
-#else
-	if ((len = recv(gjc->fd, buf, sizeof(buf) - 1, 0)) > 0) {
-#endif
-		buf[len] = '\0';
-		gaim_debug(GAIM_DEBUG_MISC, "jabber",
-				   "input (len %d): %s\n", len, buf);
-		XML_Parse(gjc->parser, buf, len, 0);
-	} else if (len < 0 || errno != EAGAIN) {
-		STATE_EVT(JCONN_STATE_OFF)
-	}
+	jabber_send_raw(gc->proto_data, "\t");
 }
 
-static void gjab_ssl_recv(gpointer data, GaimSslConnection *gsc,
+static void
+jabber_recv_cb_ssl(gpointer data, GaimSslConnection *gsc,
 		GaimInputCondition cond)
 {
-	static char buf[4096];
+	GaimConnection *gc = data;
+	JabberStream *js = gc->proto_data;
 	int len;
-	GaimConnection *gc = data;
-	struct jabber_data *jd;
-	gjconn gjc;
+	static char buf[4096];
 
-
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
+	if(!g_list_find(gaim_connections_get_all(), gc)) {
 		gaim_ssl_close(gsc);
 		return;
 	}
 
-	jd = gc->proto_data;
-	gjc= jd->gjc;
-
-	if (!gjc || gjc->state == JCONN_STATE_OFF)
-		return;
-
-	if((len = gaim_ssl_read(gsc, buf, sizeof(buf) -1)) > 0) {
+	if((len = gaim_ssl_read(gsc, buf, sizeof(buf) - 1)) > 0) {
 		buf[len] = '\0';
-		gaim_debug(GAIM_DEBUG_MISC, "jabber",
-				"input (ssl) (len %d): %s\n", len, buf);
-		XML_Parse(gjc->parser, buf, len, 0);
-	} else if(len < 0) {
-		STATE_EVT(JCONN_STATE_OFF)
-	}
-}
-
-static void startElement(void *userdata, const char *name, const char **attribs)
-{
-	xmlnode x;
-	gjconn gjc = (gjconn) userdata;
-
-	if (gjc->current) {
-		/* Append the node to the current one */
-		x = xmlnode_insert_tag(gjc->current, name);
-		xmlnode_put_expat_attribs(x, attribs);
-
-		gjc->current = x;
-	} else {
-		x = xmlnode_new_tag(name);
-		xmlnode_put_expat_attribs(x, attribs);
-		if (strcmp(name, "stream:stream") == 0) {
-			/* special case: name == stream:stream */
-			/* id attrib of stream is stored for digest auth */
-			gjc->sid = g_strdup(xmlnode_get_attrib(x, "id"));
-			gjc->state = JCONN_STATE_ON;
-			STATE_EVT(JCONN_STATE_ON);
-			xmlnode_free(x);
-		} else {
-			gjc->current = x;
-		}
+		gaim_debug(GAIM_DEBUG_INFO, "jabber", "Recv (ssl)(%d): %s\n", len, buf);
+		jabber_parser_process(js, buf, len);
 	}
 }
 
-static void endElement(void *userdata, const char *name)
-{
-	gjconn gjc = (gjconn) userdata;
-	xmlnode x;
-	jpacket p;
-
-	if (gjc->current == NULL) {
-		/* we got </stream:stream> */
-		STATE_EVT(JCONN_STATE_OFF)
-		    return;
-	}
-
-	x = xmlnode_get_parent(gjc->current);
-
-	if (!x) {
-		/* it is time to fire the event */
-		p = jpacket_new(gjc->current);
-
-		if (gjc->on_packet)
-			(gjc->on_packet) (gjc, p);
-		else
-			xmlnode_free(gjc->current);
-	}
-
-	gjc->current = x;
-}
-
-static void jabber_callback(gpointer data, gint source, GaimInputCondition condition)
+static void
+jabber_recv_cb(gpointer data, gint source, GaimInputCondition condition)
 {
 	GaimConnection *gc = data;
-	struct jabber_data *jd = (struct jabber_data *)gc->proto_data;
-
-	gjab_recv(jd->gjc);
-}
+	JabberStream *js = gc->proto_data;
+	int len;
+	static char buf[4096];
 
-static void charData(void *userdata, const char *s, int slen)
-{
-	gjconn gjc = (gjconn) userdata;
+	if(!g_list_find(gaim_connections_get_all(), gc))
+		return;
 
-	if (gjc->current)
-		xmlnode_insert_cdata(gjc->current, s, slen);
+	if((len = read(js->fd, buf, sizeof(buf) - 1)) > 0) {
+		buf[len] = '\0';
+		gaim_debug(GAIM_DEBUG_INFO, "jabber", "Recv (%d): %s\n", len, buf);
+		jabber_parser_process(js, buf, len);
+	}
 }
 
-
-static void gjab_start_stream(gjconn gjc)
-{
-	xmlnode x;
-	char *t, *t2;
-
-	gjc->state = JCONN_STATE_CONNECTED;
-	STATE_EVT(JCONN_STATE_CONNECTED)
-
-	/* start stream */
-	x = jutil_header(NS_CLIENT, gjc->user->server);
-	t = xmlnode2str(x);
-	/* this is ugly, we can create the string here instead of jutil_header */
-	/* what do you think about it? -madcat */
-	t2 = strstr(t, "/>");
-	*t2++ = '>';
-	*t2 = '\0';
-	gjab_send_raw(gjc, "<?xml version='1.0'?>");
-	gjab_send_raw(gjc, t);
-	xmlnode_free(x);
-}
-
-static void gjab_ssl_connected(gpointer data, GaimSslConnection *gsc,
+static void
+jabber_login_callback_ssl(gpointer data, GaimSslConnection *gsc,
 		GaimInputCondition cond)
 {
 	GaimConnection *gc = data;
-	struct jabber_data *jd;
-	gjconn gjc;
+	JabberStream *js = gc->proto_data;
 
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
+	if(!g_list_find(gaim_connections_get_all(), gc)) {
 		gaim_ssl_close(gsc);
 		return;
 	}
 
-	jd = gc->proto_data;
-	gjc = jd->gjc;
+	js->gsc = gsc;
 
-	gjab_start_stream(gjc);
+	if(js->state == JABBER_STREAM_CONNECTING)
+		jabber_send_raw(js, "<?xml version='1.0' ?>");
 
-	/* this seems wrong, but... */
-
-	gaim_ssl_input_add(gsc, gjab_ssl_recv, gc);
+	jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING);
+	gaim_ssl_input_add(gsc, jabber_recv_cb_ssl, gc);
 }
 
-static void gjab_connected(gpointer data, gint source, GaimInputCondition cond)
+
+static void
+jabber_login_callback(gpointer data, gint source, GaimInputCondition cond)
 {
 	GaimConnection *gc = data;
-	struct jabber_data *jd;
-	gjconn gjc;
+	JabberStream *js = gc->proto_data;
 
-	if (!g_list_find(gaim_connections_get_all(), gc)) {
+	if(!g_list_find(gaim_connections_get_all(), gc)) {
 		close(source);
 		return;
 	}
 
-	jd = gc->proto_data;
-	gjc = jd->gjc;
+	js->fd = source;
 
-	gjc->fd = source;
+	if(js->state == JABBER_STREAM_CONNECTING)
+		jabber_send_raw(js, "<?xml version='1.0' ?>");
 
-	if (source == -1) {
-		STATE_EVT(JCONN_STATE_OFF)
-		return;
-	}
+	jabber_stream_set_state(js, JABBER_STREAM_INITIALIZING);
+	gc->inpa = gaim_input_add(js->fd, GAIM_INPUT_READ, jabber_recv_cb, gc);
+}
 
-	gjab_start_stream(gjc);
-
-	gc->inpa = gaim_input_add(gjc->fd, GAIM_INPUT_READ, jabber_callback, gc);
+static void tls_init(JabberStream *js)
+{
+	gaim_input_remove(js->gc->inpa);
+	js->gc->inpa = 0;
+	js->gsc = gaim_ssl_connect_fd(js->gc->account, js->fd,
+			jabber_login_callback_ssl, js->gc);
 }
 
-static void gjab_start(gjconn gjc)
+static void
+jabber_login(GaimAccount *account)
 {
-	GaimAccount *account;
-	int port, rc;
-	const char *connect_server;
+	int rc;
+	GaimConnection *gc = gaim_account_get_connection(account);
+	const char *connect_server = gaim_account_get_string(account,
+			"connect_server", "");
 	const char *server;
-
-	if (!gjc || gjc->state != JCONN_STATE_OFF)
-		return;
+	JabberStream *js;
 
-	account = GJ_GC(gjc)->account;
-	port = gaim_account_get_int(account, "port", DEFAULT_PORT);
-	connect_server = gaim_account_get_string(account, "connect_server", "");
-	server = connect_server[0] ? connect_server : gjc->user->server;
+	gc->flags |= GAIM_CONNECTION_HTML;
+	js = gc->proto_data = g_new0(JabberStream, 1);
+	js->gc = gc;
+	js->callbacks = g_hash_table_new_full(g_str_hash, g_str_equal,
+			g_free, NULL);
+	js->buddies = g_hash_table_new_full(g_str_hash, g_str_equal,
+			g_free, NULL);
+	js->chats = g_hash_table_new_full(g_str_hash, g_str_equal,
+			g_free, NULL);
+	js->user = jabber_id_new(gaim_account_get_username(account));
 
+	server = connect_server[0] ? connect_server : js->user->domain;
 
-	gjc->parser = XML_ParserCreate(NULL);
-	XML_SetUserData(gjc->parser, (void *)gjc);
-	XML_SetElementHandler(gjc->parser, startElement, endElement);
-	XML_SetCharacterDataHandler(gjc->parser, charData);
+	jabber_stream_set_state(js, JABBER_STREAM_CONNECTING);
 
 	if(gaim_account_get_bool(account, "old_ssl", FALSE)
 			&& gaim_ssl_is_supported()) {
-		gjc->gsc = gaim_ssl_connect(account, server, port,
-				gjab_ssl_connected, GJ_GC(gjc));
-	}
-
-	if(!gjc->gsc) {
-		rc = gaim_proxy_connect(account, server, port, gjab_connected,
-				GJ_GC(gjc));
-		if (!account->gc || (rc != 0)) {
-			STATE_EVT(JCONN_STATE_OFF)
-				return;
-		}
-	}
-}
-
-/*
- * Find chat by chat group name
- */
-static GaimConversation *find_chat(GaimConnection *gc, char *name)
-{
-	GSList *bcs = gc->buddy_chats;
-	GaimConversation *b = NULL;
-	char *chat = g_strdup(normalize(name));
-
-	while (bcs) {
-		b = bcs->data;
-		if (!strcasecmp(normalize(b->name), chat))
-			break;
-		b = NULL;
-		bcs = bcs->next;
-	}
-
-	g_free(chat);
-	return b;
-}
-
-/*
- * Find chat by "chat id"
- *
- * Returns: 0 on success and jabber_chat pointer set
- * or -EINVAL on error and jabber_chat pointer is
- * undefined.
- *
- * TBD: Slogging through the buddy_chats list seems
- * redundant since the chat i.d. is mirrored in the
- * jabber_chat struct list.  But that's the way it
- * was, so that's the way I'm leaving it--for now.
- */
-static int jabber_find_chat_by_convo_id(GaimConnection *gc, int id, struct jabber_chat **jc)
-{
-	GSList *bcs = gc->buddy_chats;
-	GaimConversation *b = NULL;
-	struct jabber_data *jd = gc->proto_data;
-
-	*jc = NULL;
-
-	while(bcs != NULL) {
-		b = bcs->data;
-		if (id == gaim_chat_get_id(GAIM_CHAT(b)))
-			break;
-		bcs = bcs->next;
-	}
-
-	if (bcs != NULL) {
-		bcs = jd->chats;
-		while (bcs != NULL) {
-			*jc = bcs->data;
-			if ((*jc)->state == JCS_ACTIVE && (*jc)->b == b)
-				break;
-			bcs = bcs->next;
-		}
-	}
-
-	return(bcs == NULL? -EINVAL : 0);
-}
-
-/*
- * Find any chat
- */
-static struct jabber_chat *find_any_chat(GaimConnection *gc, jid chat)
-{
-	GSList *jcs = ((struct jabber_data *)gc->proto_data)->chats;
-	struct jabber_chat *jc = NULL;
-
-	while (jcs) {
-		jc = jcs->data;
-		if (!jid_cmpx(chat, jc->gjid, JID_USER | JID_SERVER))
-			break;
-		jc = NULL;
-		jcs = jcs->next;
-	}
-
-	return jc;
-}
-
-
-/*
- * Find existing/active Jabber chat
- */
-static struct jabber_chat *find_existing_chat(GaimConnection *gc, jid chat)
-{
-	GSList *jcs = ((struct jabber_data *)gc->proto_data)->chats;
-	struct jabber_chat *jc = NULL;
-
-	while (jcs) {
-		jc = jcs->data;
-		if (jc->state == JCS_ACTIVE && !jid_cmpx(chat, jc->gjid, JID_USER | JID_SERVER))
-			break;
-		jc = NULL;
-		jcs = jcs->next;
-	}
-
-	return jc;
-}
-
-/*
- * Find pending chat
- */
-static struct jabber_chat *find_pending_chat(GaimConnection *gc, jid chat)
-{
-	GSList *jcs = ((struct jabber_data *)gc->proto_data)->chats;
-	struct jabber_chat *jc = NULL;
-
-	while (jcs) {
-		jc = jcs->data;
-		if (jc->state == JCS_PENDING && !jid_cmpx(chat, jc->gjid, JID_USER | JID_SERVER))
-			break;
-		jc = NULL;
-		jcs = jcs->next;
-	}
-
-	return jc;
-}
-
-static gboolean find_chat_buddy(GaimConversation *b, char *name)
-{
-	GList *m = gaim_chat_get_users(GAIM_CHAT(b));
-
-	while (m) {
-		if (!strcmp(m->data, name))
-			return TRUE;
-		m = m->next;
-	}
-
-	return FALSE;
-}
-
-/*
- * Remove a buddy from the (gaim) buddylist (if he's on it)
- */
-static void jabber_remove_gaim_buddy(GaimConnection *gc, const char *buddyname)
-{
-	GaimBuddy *b;
-
-	if ((b = gaim_find_buddy(gc->account, buddyname)) != NULL) {
-		gaim_debug(GAIM_DEBUG_INFO, "jabber",
-				   "removing buddy [1]: %s\n", buddyname);
-		gaim_blist_remove_buddy(b);
-		gaim_blist_save();
-	}
-}
-
-static void jabber_change_passwd(GaimConnection *gc, const char *old, const char *new)
-{
-	gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-
-	if(strcmp(old, gjc->pass))
-	{
-		gaim_notify_error(gc, NULL,
-						  _("Unable to change password."),
-						  _("The current password you entered is incorrect.  "
-							"Your password has not been changed."));
-	}
-	else if(!strcmp(old, new))
-	{
-		gaim_notify_error(gc, NULL,
-						  _("Unable to change password."),
-						  _("The new password you entered is the same as "
-							"your current password.  "
-							"Your password remains the same."));
-	}
-	else
-	{
-		xmlnode x, y, z;
-		char *id;
-
-		x = jutil_iqnew(JPACKET__SET, NS_REGISTER);
-		xmlnode_put_attrib(x, "to", gjc->user->server);
-		y = xmlnode_get_tag(x, "query");
-		z = xmlnode_insert_tag(y, "username");
-		xmlnode_insert_cdata(z, gjc->user->user, -1);
-		z = xmlnode_insert_tag(y, "password");
-		xmlnode_insert_cdata(z, new, -1);
-
-		id = gjab_getid(gjc);
-		xmlnode_put_attrib(x, "id", id);
-
-		free(gjc->pass);
-		gjc->pass = strdup(new);
-
-		g_hash_table_insert(gjc->queries, g_strdup(id), g_strdup("change_password"));
-
-		gjab_send(gjc, x);
-		xmlnode_free(x);
-	}
-}
-
-/*
- * Return pointer to jabber_buddy_data if buddy found.  Create if necessary.
- */
-static struct jabber_buddy_data* jabber_find_buddy(GaimConnection *gc, const char *buddy, gboolean create)
-{
-	struct jabber_data *jd;
-	gpointer val;
-	char *realwho;
-
-	if (gc == NULL)
-		return NULL;
-
-	jd = gc->proto_data;
-	if((realwho = get_realwho(jd->gjc, buddy, FALSE, NULL)) == NULL)
-		return NULL;
-
-	val = g_hash_table_lookup(jd->buddies, realwho);
-	if(val) {
-		g_free(realwho);
-		return (struct jabber_buddy_data *)val;
-
-	} else if (create) {
-		struct jabber_buddy_data *jbd = g_new0(struct jabber_buddy_data, 1);
-		jbd->invisible = JABBER_NOT_INVIS;
-		g_hash_table_insert(jd->buddies, g_strdup(realwho), jbd);
-		g_free(realwho);
-		return jbd;
-	} else {
-		g_free(realwho);
-		return NULL;
-	}
-}
-
-/*
- * find a resource by name, or if no name given, return the "default" resource
- * default being the highest priority one.
- */
-
-static jab_res_info jabber_find_resource(GaimConnection *gc, const char *who)
-{
-	GSList *resources;
-	struct jabber_buddy_data *jbd = jabber_find_buddy(gc, who, FALSE);
-	jab_res_info jri = NULL;
-	char *res = strstr(who, "/");
-
-	if(res)
-		res++;
-
-	if(jbd)
-	{
-		resources = jbd->resources;
-		while(resources)
-		{
-			if(!jri && !res) {
-				jri = (jab_res_info) resources->data;
-			} else if(!res) { /* we're looking for the default priority, so... */
-				if(((jab_res_info) resources->data)->priority >= jri->priority)
-					jri = (jab_res_info) resources->data;
-			} else if(((jab_res_info)resources->data)->name) {
-				if(!strcasecmp(((jab_res_info) resources->data)->name, res)) {
-					jri = (jab_res_info) resources->data;
-					break;
-				}
-			}
-			resources = resources->next;
-		}
-	}
-
-	return jri;
-}
-
-#if 0
-static gboolean jabber_is_default_resource(GaimConnection *gc, const char *who)
-{
-	jab_res_info jri = jabber_find_resource(gc, who);
-	char *buddy = g_strdup(who);
-	char *resource = strrchr(buddy, '/');
-
-	if(!resource || !strcmp(resource+1, jri->name)) {
-		g_free(buddy);
-		return TRUE;
-	}
-
-	g_free(buddy);
-	return FALSE;
-}
-#endif
-
-/*
- * if the resource doesn't exist, create it.  otherwise, just update the priority
- */
-static void jabber_track_resource(GaimConnection *gc,
-				  char *buddy,
-				  char *res,
-				  int priority,
-				  int state)
-{
-	struct jabber_buddy_data *jbd = jabber_find_buddy(gc, buddy, TRUE);
-
-	if(jbd) {
-		char *who;
-		jab_res_info jri;
-		if(res)
-			who = g_strdup_printf("%s/%s", buddy, res);
-		else
-			who = g_strdup(buddy);
-		jri = jabber_find_resource(gc, who);
-		g_free(who);
-		if(!jri) {
-			jri = g_new0(struct jabber_resource_info, 1);
-			jri->name = g_strdup(res);
-			jri->away_msg = NULL;
-			jri->has_xhtml = TRUE;
-			jbd->resources = g_slist_append(jbd->resources, jri);
-		}
-		jri->priority = priority;
-		jri->state = state;
-	}
-}
-
-/*
- * remove the resource, if it exists
- */
-static void jabber_remove_resource(GaimConnection *gc, char *buddy, char *res)
-{
-	struct jabber_buddy_data *jbd = jabber_find_buddy(gc, buddy, FALSE);
-	if(jbd) {
-		char *who;
-		jab_res_info jri;
-		if(res)
-			who = g_strdup_printf("%s/%s", buddy, res);
-		else
-			who = g_strdup(buddy);
-		jri = jabber_find_resource(gc, who);
-		g_free(who);
-		if(jri) {
-			if(jri->name)
-				g_free(jri->name);
-			if(jri->away_msg)
-				g_free(jri->away_msg);
-			jbd->resources = g_slist_remove(jbd->resources, jri);
-			g_free(jri);
-		}
-	}
-}
-
-/*
- * grab the away message for the default resource
- */
-static char *jabber_lookup_away(gjconn gjc, char *name)
-{
-	jab_res_info jri = jabber_find_resource(GJ_GC(gjc), name);
-
-	if(!jri)
-		return _("Unknown");
-
-	return jri->away_msg;
-}
-static const char *jabber_get_state_string(int s) {
-	switch(s) {
-		case UC_AWAY:
-			return _("Away");
-		case UC_CHAT:
-			return _("Chatty");
-		case UC_XA:
-			return _("Extended Away");
-		case UC_DND:
-			return _("Do Not Disturb");
-		default:
-			return _("Available");
-	}
-}
-
-static void jabber_track_away(gjconn gjc, jpacket p, char *type)
-{
-	jab_res_info jri = NULL;
-
-	if(!p || !p->from || !p->from->user)
-		return;
-
-	jri = jabber_find_resource(GJ_GC(gjc), jid_full(p->from));
-
-	if(!jri)
-		return;
-
-	if(jri->away_msg)
-		g_free(jri->away_msg);
-
-	jri->away_msg = g_strdup(xmlnode_get_tag_data(p->x, "status"));
-}
-
-static void jabber_convo_closed(GaimConnection *gc, const char *name)
-{
-	jab_res_info jri = jabber_find_resource(gc, name);
-
-	if(jri) {
-		if(jri->thread_id)
-			g_free(jri->thread_id);
-
-		jri->thread_id = NULL;
-	}
-}
-
-static void jabber_track_convo_thread(gjconn gjc, char *name, char *thread_id)
-{
-	jab_res_info jri = jabber_find_resource(GJ_GC(gjc), name);
-
-	if(jri) {
-		if(jri->thread_id)
-			g_free(jri->thread_id);
-
-		jri->thread_id = g_strdup(thread_id);
-	}
-}
-
-static char *jabber_get_convo_thread(gjconn gjc, const char *name)
-{
-	char *ct = NULL;
-	jab_res_info jri = jabber_find_resource(GJ_GC(gjc), name);
-
-	if(jri) {
-		if(jri->thread_id)
-			ct = g_strdup(jri->thread_id);
-	}
-
-	return ct;
-}
-
-
-static time_t str_to_time(char *timestamp)
-{
-    struct tm t;
-    time_t retval = 0;
-	char buf[32];
-	char *c;
-	int tzoff = 0;
-
-	time(&retval);
-	localtime_r(&retval, &t);
-
-	snprintf(buf, sizeof(buf), "%s", timestamp);
-	c = buf;
-
-	/* 4 digit year */
-	if(!sscanf(c, "%04d", &t.tm_year)) return 0;
-	c+=4;
-	if(*c == '-')
-		c++;
-
-	t.tm_year -= 1900;
-
-	/* 2 digit month */
-	if(!sscanf(c, "%02d", &t.tm_mon)) return 0;
-	c+=2;
-	if(*c == '-')
-		c++;
-
-	t.tm_mon -= 1;
-
-	/* 2 digit day */
-	if(!sscanf(c, "%02d", &t.tm_mday)) return 0;
-	c+=2;
-
-	if(*c == 'T') { /* we have more than a date, keep going */
-		c++; /* skip the "T" */
-
-		/* 2 digit hour */
-		if(sscanf(c, "%02d:%02d:%02d", &t.tm_hour, &t.tm_min, &t.tm_sec)) {
-			int tzhrs, tzmins;
-			c+=8;
-			if(*c == '.') /* dealing with precision we don't care about */
-				c += 4;
-
-			if((*c == '+' || *c == '-') &&
-					sscanf(c+1, "%02d:%02d", &tzhrs, &tzmins)) {
-				tzoff = tzhrs*60*60 + tzmins*60;
-				if(*c == '+')
-					tzoff *= -1;
-			}
-
-#ifdef HAVE_TM_GMTOFF
-				tzoff += t.tm_gmtoff;
-#else
-#	ifdef HAVE_TIMEZONE
-				tzset();    /* making sure */
-				tzoff -= timezone;
-#	endif
-#endif
-		}
-	}
-	retval = mktime(&t);
-
-	retval += tzoff;
-
-    return retval;
-}
-
-static void jabber_handlemessage(gjconn gjc, jpacket p)
-{
-	xmlnode y, subj;
-	time_t time_sent = time(NULL);
-	gboolean typing = FALSE;
-	gboolean has_xhtml = TRUE;
-
-	char *from = NULL, *msg = NULL, *type = NULL, *topic = NULL;
-	char *thread_id = NULL;
-	char *conference_room = NULL;
-	char m[BUF_LONG * 2];
-
-	type = xmlnode_get_attrib(p->x, "type");
-
-	if ((y = xmlnode_get_tag(p->x, "thread")))
-		thread_id = xmlnode_get_data(y);
-
-	y = xmlnode_get_firstchild(p->x);
-
-	while(y) {
-		if(NSCHECK(y, NS_DELAY)) {
-			char *timestamp = xmlnode_get_attrib(y, "stamp");
-			if(timestamp)
-				time_sent = str_to_time(timestamp);
-		} else if(NSCHECK(y, "jabber:x:event")) {
-			if(xmlnode_get_tag(y, "composing"))
-				typing = TRUE;
-		} else if(NSCHECK(y, "jabber:x:conference")) {
-			conference_room = xmlnode_get_attrib(y, "jid");
-		}
-		y = xmlnode_get_nextsibling(y);
-	}
-
-	if (!type || !strcasecmp(type, "normal") || !strcasecmp(type, "chat")) {
-
-		from = jid_full(p->from);
-		/* a gross hack because i'm a nice guy */
-		if ((y = xmlnode_get_tag(p->x, "html")) && xmlnode_get_tag(y, "body")) {
-			msg = xmlnode2str(y);
-		} else if ((y = xmlnode_get_tag(p->x, "body"))) {
-			msg = xmlnode_get_data(y);
-			has_xhtml = FALSE;
-		}
-
-		if (!from)
-			return;
-
-		if (conference_room) {
-			GHashTable *components = g_hash_table_new_full(g_str_hash,
-					g_str_equal, g_free, g_free);
-			char **data;
-
-			data = g_strsplit(conference_room, "@", 2);
-			g_hash_table_replace(components, g_strdup("room"),
-					g_strdup(data[0]));
-			g_hash_table_replace(components, g_strdup("server"),
-					g_strdup(data[1]));
-			g_hash_table_replace(components, g_strdup("handle"),
-					g_strdup(gjc->user->user));
-			g_strfreev(data);
-
-			serv_got_chat_invite(GJ_GC(gjc), conference_room, from, msg, components);
-		} else if (msg) { /* whisper */
-			struct jabber_chat *jc;
-			g_snprintf(m, sizeof(m), "%s", msg);
-			if (((jc = find_existing_chat(GJ_GC(gjc), p->from)) != NULL) && jc->b)
-				serv_got_chat_in(GJ_GC(gjc),
-								 gaim_chat_get_id(GAIM_CHAT(jc->b)),
-								 p->from->resource, 1, m, time_sent);
-			else {
-				int flags = 0;
-				jab_res_info jri = jabber_find_resource(GJ_GC(gjc), from);
-				if(jri) {
-					if(typing)
-						jri->has_composing = TRUE;
-					jri->has_xhtml = has_xhtml;
-				}
-				jabber_track_convo_thread(gjc, from, thread_id);
-				if (gaim_find_conversation_with_account(from, GJ_GC(gjc)->account))
-					serv_got_im(GJ_GC(gjc), from, m, flags,
-						time_sent);
-				else {
-					if(p->from->user) {
-						from = g_strdup_printf("%s@%s", p->from->user,
-							p->from->server);
-					} else {
-						/* server message? */
-						from = g_strdup(p->from->server);
-					}
-					serv_got_im(GJ_GC(gjc), from, m, flags, time_sent);
-					g_free(from);
-				}
-			}
-		} else {
-			/* a non-message message! */
-			from = g_strdup_printf("%s@%s", p->from->user, p->from->server);
-			if(typing)
-				serv_got_typing(GJ_GC(gjc), from, 0, GAIM_TYPING);
-			else
-				serv_got_typing_stopped(GJ_GC(gjc), from);
-			g_free(from);
-		}
-
-	} else if (!strcasecmp(type, "error")) {
-		if ((y = xmlnode_get_tag(p->x, "error"))) {
-			type = xmlnode_get_attrib(y, "code");
-			msg = xmlnode_get_data(y);
-		}
-
-		if (msg) {
-			from = g_strdup_printf(_("Jabber Error %s"), type ? type : "");
-			gaim_notify_error(GJ_GC(gjc), NULL, from, msg);
-			g_free(from);
-		}
-	} else if (!strcasecmp(type, "groupchat")) {
-		struct jabber_chat *jc;
-		static int i = 0;
-
-		/* a gross hack because i'm a nice guy */
-		if ((y = xmlnode_get_tag(p->x, "html")) && xmlnode_get_tag(y, "body")) {
-			msg = xmlnode2str(y);
-		} else if ((y = xmlnode_get_tag(p->x, "body"))) {
-			msg = xmlnode_get_data(y);
-		}
-
-		if ((subj = xmlnode_get_tag(p->x, "subject"))) {
-			topic = xmlnode_get_data(subj);
-		}
-
-		jc = find_existing_chat(GJ_GC(gjc), p->from);
-		if (!jc) {
-			/* we're not in this chat. are we supposed to be? */
-			if ((jc = find_pending_chat(GJ_GC(gjc), p->from)) != NULL) {
-				/* yes, we're supposed to be. so now we are. */
-				jc->b = serv_got_joined_chat(GJ_GC(gjc), i++, p->from->user);
-				jc->id = gaim_chat_get_id(GAIM_CHAT(jc->b));
-				jc->state = JCS_ACTIVE;
-			} else {
-				/* no, we're not supposed to be. */
-				return;
-			}
-		}
-		if (p->from->resource) {
-			if (!y) {
-				if (!find_chat_buddy(jc->b, p->from->resource)) {
-					gaim_chat_add_user(GAIM_CHAT(jc->b),
-									   p->from->resource, NULL);
-				} else if ((y = xmlnode_get_tag(p->x, "status"))) {
-					jabber_track_away(gjc, p, NULL);
-				}
-			} else if (jc->b && msg) {
-				char buf[8192];
-
-				if (topic) {
-					char tbuf[8192];
-					g_snprintf(tbuf, sizeof(tbuf), "%s", topic);
-					gaim_chat_set_topic(GAIM_CHAT(jc->b),
-										p->from->resource, tbuf);
-				}
-
-				g_snprintf(buf, sizeof(buf), "%s", msg);
-				serv_got_chat_in(GJ_GC(gjc),
-								 gaim_chat_get_id(GAIM_CHAT(jc->b)),
-								 p->from->resource, 0, buf, time_sent);
-			}
-		} else { /* message from the server */
-			if(jc->b && topic) {
-				char tbuf[8192];
-				g_snprintf(tbuf, sizeof(tbuf), "%s", topic);
-				gaim_chat_set_topic(GAIM_CHAT(jc->b), "", tbuf);
-			}
-		}
-
-	} else {
-		gaim_debug(GAIM_DEBUG_WARNING, "jabber",
-				   "unhandled message %s\n", type);
-	}
-}
-
-static void jabber_handlepresence(gjconn gjc, jpacket p)
-{
-	char *from, *type;
-	GaimBuddy *b = NULL;
-	gaim_jid gjid;
-	char *buddy;
-	xmlnode y;
-	char *show;
-	int state = 0;
-	GaimConversation *cnv = NULL;
-	struct jabber_chat *jc = NULL;
-	int priority = 0;
-	struct jabber_buddy_data *jbd;
-
-	from = xmlnode_get_attrib(p->x, "from");
-	type = xmlnode_get_attrib(p->x, "type");
-
-	if((buddy = get_realwho(gjc, from, FALSE, &gjid)) == NULL)
-		return;
-
-	if (gjid->user == NULL) {
-		/* FIXME: transport */
-		g_free(buddy);
-		gaim_jid_free(gjid);
-		return;
-	}
-
-	jbd = jabber_find_buddy(GJ_GC(gjc), buddy, TRUE);
-
-	if(jbd->error_msg) {
-		g_free(jbd->error_msg);
-		jbd->error_msg = NULL;
-	}
-
-	if(type && !strcasecmp(type, "error")) {
-		state = UC_ERROR;
-		if((y = xmlnode_get_tag(p->x, "error")) != NULL) {
-			jbd->error_msg = g_strdup_printf(_("Error %s: %s"),
-				xmlnode_get_attrib(y, "code"), xmlnode_get_data(y));
-		} else {
-			jbd->error_msg = g_strdup(_("Unknown Error in presence"));
-		}
-	} else {
-		if ((y = xmlnode_get_tag(p->x, "show"))) {
-			show = xmlnode_get_data(y);
-			if (!show) {
-				state = 0;
-			} else if (!strcasecmp(show, "away")) {
-				state = UC_AWAY;
-			} else if (!strcasecmp(show, "chat")) {
-				state = UC_CHAT;
-			} else if (!strcasecmp(show, "xa")) {
-				state = UC_XA;
-			} else if (!strcasecmp(show, "dnd")) {
-				state = UC_DND;
-			}
-		} else {
-			state = 0;
-		}
-	}
-
-	if ((y = xmlnode_get_tag(p->x, "priority")))
-		priority = atoi(xmlnode_get_data(y));
-
-	/* um. we're going to check if it's a chat. if it isn't, and there are pending
-	 * chats, create the chat. if there aren't pending chats and we don't have the
-	 * buddy on our list, simply bail out. */
-	if ((cnv = find_chat(GJ_GC(gjc), gjid->user)) == NULL) {
-		static int i = 0x70;
-		if ((jc = find_pending_chat(GJ_GC(gjc), gjid)) != NULL) {
-			jc->b = cnv = serv_got_joined_chat(GJ_GC(gjc), i++, gjid->user);
-			jc->id = gaim_chat_get_id(GAIM_CHAT(jc->b));
-			jc->state = JCS_ACTIVE;
-		} else if ((b = gaim_find_buddy(GJ_GC(gjc)->account, buddy)) == NULL) {
-			g_free(buddy);
-			gaim_jid_free(gjid);
-			return;
-		}
-	}
-
-	if (state == UC_ERROR || (type && (strcasecmp(type, "unavailable") == 0)))
-		jabber_remove_resource(GJ_GC(gjc), buddy, gjid->resource);
-	else {
-		jabber_track_resource(GJ_GC(gjc), buddy, gjid->resource, priority, state);
-
-		/* keep track of away msg somewhat the same as the yahoo plugin */
-		jabber_track_away(gjc, p, type);
+		js->gsc = gaim_ssl_connect(account, server,
+				gaim_account_get_int(account, "port", 5222),
+				jabber_login_callback_ssl, gc);
 	}
 
-	if (!cnv) {
-		/* this is where we handle presence information for "regular" buddies */
-		jab_res_info jri = jabber_find_resource(GJ_GC(gjc), buddy);
-		if(jri) {
-			serv_got_update(GJ_GC(gjc), buddy, 1, 0, b->signon, b->idle, jri->state);
-		} else
-			serv_got_update(GJ_GC(gjc), buddy, 0, 0, 0, 0, 0);
-
-	} else {
-		if (gjid->resource) {
-			if (type && (!strcasecmp(type, "unavailable"))) {
-				struct jabber_data *jd;
-				if (!jc && !(jc = find_existing_chat(GJ_GC(gjc), gjid))) {
-					g_free(buddy);
-					gaim_jid_free(gjid);
-					return;
-				}
-				jd = jc->gc->proto_data;
-				/* if it's not ourselves...*/
-				if (strcmp(gjid->resource, jc->gjid->resource) && jc->b) {
-					gaim_chat_remove_user(GAIM_CHAT(jc->b), gjid->resource,
-										  NULL);
-					g_free(buddy);
-					gaim_jid_free(gjid);
-					return;
-				}
-
-				jc->state = JCS_CLOSED;
-				serv_got_chat_left(GJ_GC(gjc), jc->id);
-				/*
-				 * TBD: put back some day?
-				jd->chats = g_slist_remove(jd->chats, jc);
-				g_free(jc);
-				 */
-			} else {
-				if ((!jc && !(jc = find_existing_chat(GJ_GC(gjc), gjid))) || !jc->b) {
-					g_free(buddy);
-					gaim_jid_free(gjid);
-					return;
-				}
-				if (!find_chat_buddy(jc->b, gjid->resource)) {
-					gaim_chat_add_user(GAIM_CHAT(jc->b), gjid->resource, NULL);
-				}
-			}
-		}
-	}
-
-	g_free(buddy);
-	gaim_jid_free(gjid);
-
-	return;
-}
-
-/*
- * Used only by Jabber accept/deny add stuff just below
- */
-struct jabber_add_permit {
-	GaimConnection *gc;
-	gchar *user;
-};
-
-/*
- * Common part for Jabber accept/deny adds
- *
- * "type" says whether we'll permit/deny the subscribe request
- */
-static void jabber_accept_deny_add(struct jabber_add_permit *jap, const char *type)
-{
-	xmlnode g = xmlnode_new_tag("presence");
-
-	xmlnode_put_attrib(g, "to", jap->user);
-	xmlnode_put_attrib(g, "type", type);
-	gjab_send(GC_GJ(jap->gc), g);
-
-	xmlnode_free(g);
-}
-
-/*
- * Callback from "accept" in gaim_request_action() invoked
- * by jabber_handles10n()
- */
-static void jabber_accept_add(struct jabber_add_permit *jap)
-{
-	if(g_list_find(gaim_connections_get_all(), jap->gc)) {
-		jabber_accept_deny_add(jap, "subscribed");
-		/*
-		 * If we don't already have the buddy on *our* buddylist,
-		 * ask if we want him or her added.
-		 */
-		if(gaim_find_buddy(jap->gc->account, jap->user) == NULL) {
-			show_got_added(jap->gc, NULL, jap->user, NULL, NULL);
-		}
-	}
-
-	g_free(jap->user);
-	g_free(jap);
-}
-
-/*
- * Callback from "deny/cancel" in gaim_request_action() invoked
- * by jabber_handles10n()
- */
-static void jabber_deny_add(struct jabber_add_permit *jap)
-{
-	if(g_list_find(gaim_connections_get_all(), jap->gc)) {
-		jabber_accept_deny_add(jap, "unsubscribed");
-	}
-
-	g_free(jap->user);
-	g_free(jap);
-}
-
-/*
- * Handle subscription requests
- */
-static void jabber_handles10n(gjconn gjc, jpacket p)
-{
-	xmlnode g;
-	char *Jid = xmlnode_get_attrib(p->x, "from");
-	char *type = xmlnode_get_attrib(p->x, "type");
-
-	g = xmlnode_new_tag("presence");
-	xmlnode_put_attrib(g, "to", Jid);
-
-	if (!strcmp(type, "subscribe")) {
-		/*
-		 * A "subscribe to us" request was received - put up the approval dialog
-		 */
-		struct jabber_add_permit *jap = g_new0(struct jabber_add_permit, 1);
-		gchar *msg = g_strdup_printf(_("The user %s wants to add you to their buddy list."),
-				Jid);
-
-		jap->gc = GJ_GC(gjc);
-		jap->user = g_strdup(Jid);
-
-		gaim_request_action(jap->gc, NULL, msg, NULL, 0, jap, 2,
-							_("Authorize"), G_CALLBACK(jabber_accept_add),
-							_("Deny"), G_CALLBACK(jabber_deny_add));
-
-		g_free(msg);
-		xmlnode_free(g);	/* Never needed it here anyway */
-		return;
-
-	} else if (!strcmp(type, "unsubscribe")) {
-		/*
-		 * An "unsubscribe to us" was received - simply "approve" it
-		 */
-		xmlnode_put_attrib(g, "type", "unsubscribed");
-	} else {
-		/*
-		 * Did we attempt to subscribe to somebody and they do not exist?
-		 */
-		if (!strcmp(type, "unsubscribed")) {
-			xmlnode y;
-			char *status;
-			if((y = xmlnode_get_tag(p->x, "status")) && (status = xmlnode_get_data(y)) &&
-					!strcmp(status, "Not Found")) {
-				char *msg = g_strdup_printf(_("The Jabber user %s does not exist and was therefore "
-							      "not added to your roster."), 
-							    xmlnode_get_attrib(p->x, "from"));
-				gaim_notify_error(GJ_GC(gjc), NULL, _("No such user."), msg);
-				g_free(msg);
-			}
-		}
-
-		xmlnode_free(g);
-		return;
-	}
-
-	gjab_send(gjc, g);
-	xmlnode_free(g);
-}
-
-/*
- * Pending subscription to a buddy?
- */
-#define BUD_SUB_TO_PEND(sub, ask) ((!strcasecmp((sub), "none") || !strcasecmp((sub), "from")) && \
-					(ask) != NULL && !strcasecmp((ask), "subscribe"))
-
-/*
- * Subscribed to a buddy?
- */
-#define BUD_SUBD_TO(sub, ask) ((!strcasecmp((sub), "to") || !strcasecmp((sub), "both")) && \
-					((ask) == NULL || !strcasecmp((ask), "subscribe")))
-
-/*
- * Pending unsubscription to a buddy?
- */
-#define BUD_USUB_TO_PEND(sub, ask) ((!strcasecmp((sub), "to") || !strcasecmp((sub), "both")) && \
-					(ask) != NULL && !strcasecmp((ask), "unsubscribe")) 
-
-/*
- * Unsubscribed to a buddy?
- */
-#define BUD_USUBD_TO(sub, ask) ((!strcasecmp((sub), "none") || !strcasecmp((sub), "from")) && \
-					((ask) == NULL || !strcasecmp((ask), "unsubscribe")))
-
-/*
- * If a buddy is added or removed from the roster on another resource
- * jabber_handlebuddy is called
- *
- * Called with roster item node.
- */
-static void jabber_handlebuddy(gjconn gjc, xmlnode x)
-{
-	xmlnode g;
-	char *who, *name, *sub, *ask;
-	gaim_jid gjid;
-	GaimBuddy *b = NULL;
-	struct jabber_buddy_data *jbd = NULL;
-	char *buddyname, *groupname = NULL;
-
-	who = xmlnode_get_attrib(x, "jid");
-	name = xmlnode_get_attrib(x, "name");
-	sub = xmlnode_get_attrib(x, "subscription");
-	ask = xmlnode_get_attrib(x, "ask");
-
-	if((buddyname = get_realwho(gjc, who, FALSE, &gjid)) == NULL)
-		return;
-
-
-	/* JFIXME: jabber_handleroster() had a "FIXME: transport" at this
-	 * equivilent point.  So...
-	 *
-	 * We haven't done anything interesting to this point, so we'll
-	 * violate Good Coding Structure here by simply bailing out.
-	 */
-	if(!gjid->user) {
-		g_free(buddyname);
-		gaim_jid_free(gjid);
-		return;
-	}
-	gaim_jid_free(gjid);
-
-	if((g = xmlnode_get_tag(x, "group")) != NULL) {
-		groupname = xmlnode_get_data(g);
-	}
-
-	/*
-	 * Add or remove a buddy?  Change buddy's alias or group?
-	 */
-	if (BUD_SUB_TO_PEND(sub, ask) || BUD_SUBD_TO(sub, ask)) {
-		if ((b = gaim_find_buddy(GJ_GC(gjc)->account, buddyname)) == NULL) {
-			GaimGroup *g;
-			b = gaim_buddy_new(GJ_GC(gjc)->account, buddyname, name);
-
-			if(!groupname)
-				groupname = _("Buddies");
-
-			if (!(g = gaim_find_group(groupname))) {
-				g = gaim_group_new(groupname);
-				gaim_blist_add_group(g, NULL);
-			}
-
-			gaim_debug(GAIM_DEBUG_INFO, "jabber",
-					   "adding buddy [4]: %s\n", buddyname);
-			gaim_blist_add_buddy(b, NULL, g, NULL);
-			gaim_blist_save();
-		} else {
-			gboolean save = FALSE;
-			GaimGroup *c_grp = gaim_find_buddys_group(b);
-
-			/*
-			 * If the buddy's in a new group or his/her alias is changed...
-			 */
-			if(groupname && c_grp && strcmp(c_grp->name, groupname)) {
-				GaimGroup *g = gaim_find_group(groupname);
-				if(!g) {
-					g = gaim_group_new(groupname);
-					gaim_blist_add_group(g, NULL);
-				}
-
-				gaim_blist_add_buddy(b, NULL, g, NULL);
-				save = TRUE;
-			}
-
-			if(name && (!b->alias || strcmp(b->alias, name))) {
-				gaim_blist_alias_buddy(b, name);
-				save = TRUE;
-			}
-
-			if(save)
-				gaim_blist_save();
-		}
-	}  else if (BUD_USUB_TO_PEND(sub, ask) || BUD_USUBD_TO(sub, ask) || !strcasecmp(sub, "remove")) {
-		jabber_remove_gaim_buddy(GJ_GC(gjc), buddyname);
-	}
-	if(b && (jbd = jabber_find_buddy(b->account->gc, buddyname, TRUE)) != NULL) {
-		jbd->subscription = JABBER_SUB_NONE;
-		if(!strcasecmp(sub, "to"))
-			jbd->subscription |= JABBER_SUB_TO;
-		else if(!strcasecmp(sub, "from"))
-			jbd->subscription |= JABBER_SUB_FROM;
-		else if(!strcasecmp(sub, "both"))
-			jbd->subscription |= JABBER_SUB_BOTH;
-
-		if(ask && !strcasecmp(ask, "subscribe"))
-			jbd->subscription |= JABBER_SUB_PENDING;
-	}
-
-	g_free(buddyname);
-
-}
-
-static void jabber_handleroster(gjconn gjc, xmlnode querynode)
-{
-	xmlnode x;
-
-	x = xmlnode_get_firstchild(querynode);
-	while (x) {
-		jabber_handlebuddy(gjc, x);
-		x = xmlnode_get_nextsibling(x);
-	}
-
-	x = xmlnode_new_tag("presence");
-	gjab_send(gjc, x);
-	xmlnode_free(x);
-}
-
-static void jabber_handleauthresp(gjconn gjc, jpacket p)
-{
-	if (jpacket_subtype(p) == JPACKET__RESULT) {
-		if (xmlnode_has_children(p->x)) {
-			xmlnode query = xmlnode_get_tag(p->x, "query");
-			gaim_connection_update_progress(GJ_GC(gjc), _("Authenticating"),
-					4, JABBER_CONNECT_STEPS);
-			if (!xmlnode_get_tag(query, "digest")) {
-				g_free(gjc->sid);
-				gjc->sid = NULL;
-			}
-			gjab_auth(gjc);
-		} else {
-			gaim_debug(GAIM_DEBUG_INFO, "jabber", "auth success\n");
-
-			gaim_connection_set_state(GJ_GC(gjc), GAIM_CONNECTED);
-			serv_finish_login(GJ_GC(gjc));
-
-			((struct jabber_data *)GJ_GC(gjc)->proto_data)->did_import = TRUE;
-
-			gjab_reqroster(gjc);
-		}
-	} else {
-		xmlnode xerr;
-		char *errmsg = NULL;
-		int errcode = 0;
-
-		gaim_debug(GAIM_DEBUG_ERROR, "jabber", "auth failed\n");
-		xerr = xmlnode_get_tag(p->x, "error");
-		if (xerr) {
-			char msg[BUF_LONG];
-			errmsg = xmlnode_get_data(xerr);
-			if (xmlnode_get_attrib(xerr, "code")) {
-				errcode = atoi(xmlnode_get_attrib(xerr, "code"));
-				g_snprintf(msg, sizeof(msg), "Error %d: %s", errcode, errmsg);
-			} else
-				g_snprintf(msg, sizeof(msg), "%s", errmsg);
-			gaim_connection_error(GJ_GC(gjc), msg);
-		} else {
-			gaim_connection_error(GJ_GC(gjc), _("Unknown login error"));
-		}
-	}
-}
-
-static void jabber_handleversion(gjconn gjc, xmlnode iqnode) {
-	xmlnode querynode, x;
-	char *id, *from;
-	char os[1024];
-	struct utsname osinfo;
-
-	uname(&osinfo);
-	g_snprintf(os, sizeof os, "%s %s %s", osinfo.sysname, osinfo.release, osinfo.machine);
-
-	id = xmlnode_get_attrib(iqnode, "id");
-	from = xmlnode_get_attrib(iqnode, "from");
-
-	x = jutil_iqnew(JPACKET__RESULT, NS_VERSION);
-
-	xmlnode_put_attrib(x, "to", from);
-	xmlnode_put_attrib(x, "id", id);
-	querynode = xmlnode_get_tag(x, "query");
-	xmlnode_insert_cdata(xmlnode_insert_tag(querynode, "name"), PACKAGE, -1);
-	xmlnode_insert_cdata(xmlnode_insert_tag(querynode, "version"), VERSION, -1);
-	xmlnode_insert_cdata(xmlnode_insert_tag(querynode, "os"), os, -1);
-
-	gjab_send(gjc, x);
-
-	xmlnode_free(x);
-}
-
-static void jabber_handletime(gjconn gjc, xmlnode iqnode) {
-	xmlnode querynode, x;
-	char *id, *from;
-	time_t now_t;
-	struct tm *now;
-	char buf[1024];
-
-	time(&now_t);
-	now = localtime(&now_t);
-
-	id = xmlnode_get_attrib(iqnode, "id");
-	from = xmlnode_get_attrib(iqnode, "from");
-
-	x = jutil_iqnew(JPACKET__RESULT, NS_TIME);
-
-	xmlnode_put_attrib(x, "to", from);
-	xmlnode_put_attrib(x, "id", id);
-	querynode = xmlnode_get_tag(x, "query");
-
-	strftime(buf, 1024, "%Y%m%dT%T", now);
-	xmlnode_insert_cdata(xmlnode_insert_tag(querynode, "utc"), buf, -1);
-	strftime(buf, 1024, "%Z", now);
-	xmlnode_insert_cdata(xmlnode_insert_tag(querynode, "tz"), buf, -1);
-	strftime(buf, 1024, "%d %b %Y %T", now);
-	xmlnode_insert_cdata(xmlnode_insert_tag(querynode, "display"), buf, -1);
-
-	gjab_send(gjc, x);
+	if(!js->gsc) {
+		rc = gaim_proxy_connect(account, server,
+				gaim_account_get_int(account, "port", 5222),
+				jabber_login_callback, gc);
 
-	xmlnode_free(x);
-}
-
-struct jabber_xfer_data {
-	struct g_url *url;
-	GString *headers;
-	gboolean newline;
-
-	char *iq_id;
-
-	struct jabber_data *jd;
-};
-
-static void jabber_xfer_init(GaimXfer *xfer)
-{
-	struct jabber_xfer_data *data = xfer->data;
-	gaim_xfer_start(xfer, -1, data->url->address, data->url->port);
-}
-
-static void jabber_xfer_free(GaimXfer *xfer)
-{
-	struct jabber_xfer_data *data = xfer->data;
-	data->jd->file_transfers = g_slist_remove(data->jd->file_transfers, xfer);
-
-	g_string_free(data->headers, TRUE);
-	g_free(data->url);
-	g_free(data->iq_id);
-	g_free(data);
-
-	xfer->data = NULL;
-}
-
-static void jabber_xfer_end(GaimXfer *xfer)
-{
-	struct jabber_xfer_data *data = xfer->data;
-	xmlnode x;
-
-	x = xmlnode_new_tag("iq");
-	xmlnode_put_attrib(x, "type", "result");
-	xmlnode_put_attrib(x, "to", xfer->who);
-	xmlnode_put_attrib(x, "id", data->iq_id);
-
-	gjab_send(data->jd->gjc, x);
-
-	xmlnode_free(x);
-
-	jabber_xfer_free(xfer);
-}
-
-static void jabber_xfer_start(GaimXfer *xfer)
-{
-	struct jabber_xfer_data *data = xfer->data;
-	char *buf = g_strdup_printf("GET /%s HTTP/1.1\r\nHost: %s\r\n\r\n",
-			data->url->page, data->url->address);
-	write(xfer->fd, buf, strlen(buf));
-	g_free(buf);
-}
-
-static size_t jabber_xfer_read(char **buffer, GaimXfer *xfer) {
-	struct jabber_xfer_data *data = xfer->data;
-	char test;
-	int size;
-
-	if(read(xfer->fd, &test, sizeof(test)) > 0) {
-		data->headers = g_string_append_c(data->headers, test);
-		if(test == '\r')
-			return 0;
-		if(test == '\n') {
-			if(data->newline) {
-				gchar *lenstr = strstr(data->headers->str, "Content-Length: ");
-				if(lenstr) {
-					sscanf(lenstr, "Content-Length: %d", &size);
-					gaim_xfer_set_size(xfer, size);
-				}
-				gaim_xfer_set_read_fnc(xfer, NULL);
-				return 0;
-			} else
-				data->newline = TRUE;
-				return 0;
-			}
-		data->newline = FALSE;
-		return 0;
-	}
-	return 0;
-}
-
-static void jabber_xfer_cancel_send(GaimXfer *xfer) {
-}
-
-static void jabber_xfer_cancel_recv(GaimXfer *xfer) {
-	struct jabber_xfer_data *data = xfer->data;
-	xmlnode x,y;
-
-	x = xmlnode_new_tag("iq");
-	xmlnode_put_attrib(x, "type", "error");
-	xmlnode_put_attrib(x, "to", xfer->who);
-	xmlnode_put_attrib(x, "id", data->iq_id);
-	y = xmlnode_insert_tag(x, "error");
-	/* FIXME: need to handle other kinds of errors here */
-	xmlnode_put_attrib(y, "code", "406");
-	xmlnode_insert_cdata(y, "File Transfer Refused", -1);
-
-	gjab_send(data->jd->gjc, x);
-
-	xmlnode_free(x);
-
-	jabber_xfer_free(xfer);
-}
-
-static void jabber_handleoob(gjconn gjc, xmlnode iqnode) {
-	struct jabber_xfer_data *xfer_data;
-	struct jabber_data *jd = GJ_GC(gjc)->proto_data;
-	GaimXfer *xfer;
-	char *msg = NULL;
-	char *filename;
-	xmlnode querynode = xmlnode_get_tag(iqnode, "query");
-	xmlnode urlnode,descnode;
-
-	if(!querynode)
-		return;
-	urlnode = xmlnode_get_tag(querynode, "url");
-	if(!urlnode)
-		return;
-	descnode = xmlnode_get_tag(querynode, "desc");
-	if(descnode)
-		msg = xmlnode_get_data(descnode);
-
-	xfer_data = g_new0(struct jabber_xfer_data, 1);
-	xfer_data->url = parse_url(xmlnode_get_data(urlnode));
-	xfer_data->jd = jd;
-	xfer_data->headers = g_string_new("");
-	xfer_data->iq_id = g_strdup(xmlnode_get_attrib(iqnode, "id"));
-
-	xfer = gaim_xfer_new(GJ_GC(gjc)->account, GAIM_XFER_RECEIVE,
-			xmlnode_get_attrib(iqnode, "from"));
-	xfer->data = xfer_data;
-
-	filename = g_strdup(g_strrstr(xfer_data->url->page, "/"));
-	if(!filename)
-		filename = g_strdup(xfer_data->url->page);
-
-	gaim_xfer_set_filename(xfer, filename);
-
-	g_free(filename);
-
-	gaim_xfer_set_init_fnc(xfer,   jabber_xfer_init);
-	gaim_xfer_set_end_fnc(xfer,    jabber_xfer_end);
-	gaim_xfer_set_cancel_send_fnc(xfer, jabber_xfer_cancel_send);
-	gaim_xfer_set_cancel_recv_fnc(xfer, jabber_xfer_cancel_recv);
-	gaim_xfer_set_read_fnc(xfer,   jabber_xfer_read);
-	gaim_xfer_set_start_fnc(xfer,  jabber_xfer_start);
-
-	jd->file_transfers = g_slist_append(jd->file_transfers, xfer);
-
-	gaim_xfer_request(xfer);
-}
-
-static void jabber_handlelast(gjconn gjc, xmlnode iqnode) {
-	xmlnode x, querytag;
-	char *id, *from;
-	struct jabber_data *jd = GJ_GC(gjc)->proto_data;
-	char idle_time[32];
-
-	id = xmlnode_get_attrib(iqnode, "id");
-	from = xmlnode_get_attrib(iqnode, "from");
-
-	x = jutil_iqnew(JPACKET__RESULT, "jabber:iq:last");
-
-	xmlnode_put_attrib(x, "to", from);
-	xmlnode_put_attrib(x, "id", id);
-	querytag = xmlnode_get_tag(x, "query");
-	g_snprintf(idle_time, sizeof idle_time, "%ld", jd->idle ? time(NULL) - jd->idle : 0);
-	xmlnode_put_attrib(querytag, "seconds", idle_time);
-
-	gjab_send(gjc, x);
-	xmlnode_free(x);
-}
-
-/*
- * delete == TRUE: delete found entry
- *
- * returns pointer to (local) copy of value if found, NULL otherwise
- *
- * Note: non-reentrant!  Local static storage re-used on subsequent calls.
- * If you're going to need to keep the returned value, make a copy!
- */
-static gchar *jabber_track_queries(GHashTable *queries, gchar *key, gboolean delete)
-{
-	gpointer my_key, my_val;
-	static gchar *ret_val = NULL;
-
-	if(ret_val != NULL) {
-		g_free(ret_val);
-		ret_val = NULL;
-	}
-
-	/* self-protection */
-	if(queries != NULL && key != NULL) {
-		if(g_hash_table_lookup_extended(queries, key, &my_key, &my_val)) {
-			ret_val = g_strdup((gchar *) my_val);
-			if(delete) {
-				g_hash_table_remove(queries, key);
-				g_free(my_key);
-				g_free(my_val);
-			}
-		}
+		if (rc != 0)
+			gaim_connection_error(gc, _("Unable to create socket"));
 	}
-
-	return(ret_val);
-}
-
-static void jabber_handlepacket(gjconn gjc, jpacket p)
-{
-	char *id, *from, *to;
-	switch (p->type) {
-	case JPACKET_MESSAGE:
-		jabber_handlemessage(gjc, p);
-		break;
-	case JPACKET_PRESENCE:
-		jabber_handlepresence(gjc, p);
-		break;
-	case JPACKET_IQ:
-		gaim_debug(GAIM_DEBUG_MISC, "jabber",
-				   "jpacket_subtype: %d\n", jpacket_subtype(p));
-
-		id = xmlnode_get_attrib(p->x, "id");
-		if (id != NULL && !strcmp(id, IQID_AUTH)) {
-			jabber_handleauthresp(gjc, p);
-			break;
-		}
-
-		if (jpacket_subtype(p) == JPACKET__SET) {
-			xmlnode querynode;
-			querynode = xmlnode_get_tag(p->x, "query");
-			from = xmlnode_get_attrib(p->x, "from");
-			to = xmlnode_get_attrib(p->x, "to");
-			if (NSCHECK(querynode, "jabber:iq:roster") && (!from || !strcmp(from, to))) {
-				jabber_handlebuddy(gjc, xmlnode_get_firstchild(querynode));
-			} else if(NSCHECK(querynode, "jabber:iq:oob")) {
-				jabber_handleoob(gjc, p->x);
-			}
-		} else if (jpacket_subtype(p) == JPACKET__GET) {
-			xmlnode querynode;
-			querynode = xmlnode_get_tag(p->x, "query");
-			if (NSCHECK(querynode, NS_VERSION)) {
-				jabber_handleversion(gjc, p->x);
-			} else if (NSCHECK(querynode, NS_TIME)) {
-				jabber_handletime(gjc, p->x);
-			} else if (NSCHECK(querynode, "jabber:iq:last")) {
-				jabber_handlelast(gjc, p->x);
-			}
-		} else if (jpacket_subtype(p) == JPACKET__RESULT) {
-			xmlnode querynode, vcard;
-			char *xmlns, *from;
-
-			/*
-			 * TBD: ISTM maybe this part could use a serious re-work?
-			 */
-			from = xmlnode_get_attrib(p->x, "from");
-			querynode = xmlnode_get_tag(p->x, "query");
-			vcard = xmlnode_get_tag(p->x, "vCard");
-			if (!vcard)
-				vcard = xmlnode_get_tag(p->x, "VCARD");
-
-			if (NSCHECK(querynode, NS_ROSTER)) {
-				jabber_handleroster(gjc, querynode);
-			} else if (NSCHECK(querynode, NS_VCARD)) {
-				jabber_track_queries(gjc->queries, id, TRUE);	/* delete query track */
-				jabber_handlevcard(gjc, querynode, from);
-			} else if (vcard) {
-				jabber_track_queries(gjc->queries, id, TRUE);	/* delete query track */
-				jabber_handlevcard(gjc, vcard, from);
-			} else if((xmlns = xmlnode_get_attrib(querynode, "xmlns")) != NULL) {
-				gaim_debug(GAIM_DEBUG_MISC, "jabber",
-						   "jabber:iq:query: %s\n", xmlns);
-			} else {
-				char *val;
-
-				gaim_debug(GAIM_DEBUG_MISC, "jabber",
-						   "jabber:iq: %s\n", xmlnode2str(p->x));
-
-				/* handle "null" query results */
-				if((val = jabber_track_queries(gjc->queries, id, TRUE)) != NULL) {
-					if(strcmp((char *) val, "vCard") == 0) {
-						/*
-						 * No actual vCard, but there's other stuff.  This
-						 * way the user always gets some kind of response.
-						 */
-						jabber_handlevcard(gjc, NULL, from);
-					} else if(!strcmp((char *) val, "change_password")) {
-					   char buf[BUF_LONG];
-					   sprintf(buf, _("Password successfully changed."));
-
-					   gaim_notify_info(GJ_GC(gjc), NULL, buf, NULL);
-					}
-				}
-			}
-
-		} else if (jpacket_subtype(p) == JPACKET__ERROR) {
-			xmlnode xerr;
-			char *from, *errmsg = NULL;
-			int errcode = 0;
-
-			from = xmlnode_get_attrib(p->x, "from");
-			xerr = xmlnode_get_tag(p->x, "error");
-			if (xerr) {
-				errmsg = xmlnode_get_data(xerr);
-				if (xmlnode_get_attrib(xerr, "code"))
-					errcode = atoi(xmlnode_get_attrib(xerr, "code"));
-			}
-
-			from = g_strdup_printf("Jabber Error %d (%s)", errcode, from);
-			gaim_notify_error(GJ_GC(gjc), NULL, from, errmsg);
-			g_free(from);
-
-		}
-
-		break;
-	case JPACKET_S10N:
-		jabber_handles10n(gjc, p);
-		break;
-	default:
-		gaim_debug(GAIM_DEBUG_MISC, "jabber",
-				   "jabber: packet type %d (%s)\n", p->type, xmlnode2str(p->x));
-	}
-
-	xmlnode_free(p->x);
-
-	return;
-}
-
-static void jabber_handlestate(gjconn gjc, int state)
-{
-	switch (state) {
-	case JCONN_STATE_OFF:
-		if(gjc->was_connected) {
-			gaim_connection_error(GJ_GC(gjc), _("Connection lost"));
-		} else {
-			gaim_connection_error(GJ_GC(gjc), _("Unable to connect"));
-		}
-		break;
-	case JCONN_STATE_CONNECTED:
-		gjc->was_connected = 1;
-		gaim_connection_update_progress(GJ_GC(gjc), _("Connected"), 2, JABBER_CONNECT_STEPS);
-		break;
-	case JCONN_STATE_ON:
-		gaim_connection_update_progress(GJ_GC(gjc), _("Requesting Authentication Method"), 3, JABBER_CONNECT_STEPS);
-		gjab_reqauth(gjc);
-		break;
-	default:
-		gaim_debug(GAIM_DEBUG_MISC, "jabber", "state change: %d\n", state);
-	}
-	return;
-}
-
-static void jabber_login(GaimAccount *account)
-{
-	GaimConnection *gc = gaim_account_get_connection(account);
-	struct jabber_data *jd = gc->proto_data = g_new0(struct jabber_data, 1);
-	char *loginname = create_valid_jid(account->username, DEFAULT_SERVER, "Gaim");
-
-	gc->flags |= GAIM_CONNECTION_HTML;
-
-	jd->buddies = g_hash_table_new(g_str_hash, g_str_equal);
-	jd->chats = NULL;	/* we have no chats yet */
-
-	gaim_connection_update_progress(gc, _("Connecting"), 1, JABBER_CONNECT_STEPS);
-
-	if (!(jd->gjc = gjab_new(loginname, account->password, gc))) {
-		g_free(loginname);
-		gaim_debug(GAIM_DEBUG_ERROR, "jabber",
-				   "unable to connect (jab_new failed)\n");
-		gaim_connection_error(gc, _("Unable to connect"));
-		return;
-	}
-
-	g_free(loginname);
-	gjab_state_handler(jd->gjc, jabber_handlestate);
-	gjab_packet_handler(jd->gjc, jabber_handlepacket);
-	jd->gjc->queries = g_hash_table_new(g_str_hash, g_str_equal);
-	gjab_start(jd->gjc);
-}
-
-static gboolean jabber_destroy_hash(gpointer key, gpointer val, gpointer data) {
-	g_free(key);
-	g_free(val);
-	return TRUE;
-}
-
-static gboolean jabber_destroy_buddy_hash(gpointer key, gpointer val, gpointer data) {
-	struct jabber_buddy_data *jbd = val;
-	while (jbd->resources) {
-		g_free(((jab_res_info) ((GSList *)jbd->resources)->data)->name);
-		if(((jab_res_info) ((GSList *)jbd->resources)->data)->away_msg)
-			g_free(((jab_res_info) ((GSList *)jbd->resources)->data)->away_msg);
-		g_free(((GSList *)jbd->resources)->data);
-		jbd->resources = g_slist_remove(jbd->resources, ((GSList *)jbd->resources)->data);
-
-	}
-	if(jbd->error_msg)
-		g_free(jbd->error_msg);
-	g_free(key);
-	g_free(jbd);
-	return TRUE;
-}
-
-
-static gboolean jabber_free(gpointer data)
-{
-	struct jabber_data *jd = data;
-
-	if(jd->gjc != NULL) {
-		g_free(jd->gjc->sid);
-		gjab_delete(jd->gjc);
-		jd->gjc = NULL;
-	}
-	g_free(jd);
-
-	return FALSE;
 }
 
 static void jabber_close(GaimConnection *gc)
 {
-	struct jabber_data *jd = gc->proto_data;
-
-	if(jd) {
-		GSList *jcs = jd->chats;
-
-		/* Free-up the jabber_chat struct allocs and the list */
-		while (jcs) {
-			gaim_jid_free(((struct jabber_chat *)jcs->data)->gjid);
-			g_free(jcs->data);
-			jcs = jcs->next;
-		}
-		g_slist_free(jd->chats);
-
-		/* Free-up the buddy data hash */
-		if(jd->buddies != NULL)
-		{
-			g_hash_table_foreach_remove(jd->buddies, jabber_destroy_buddy_hash, NULL);
-			g_hash_table_destroy(jd->buddies);
-			jd->buddies = NULL;
-		}
+	JabberStream *js = gc->proto_data;
 
-		/* Free-up the pending queries memories and the list */
-		if(jd->gjc != NULL && jd->gjc->queries != NULL) {
-			g_hash_table_foreach_remove(jd->gjc->queries, jabber_destroy_hash, NULL);
-			g_hash_table_destroy(jd->gjc->queries);
-			jd->gjc->queries = NULL;
-		}
-	}
-	if (gc->inpa)
-		gaim_input_remove(gc->inpa);
-
-	if(jd) {
-		g_timeout_add(0, jabber_free, jd);
-		if(jd->gjc != NULL)
-			xmlnode_free(jd->gjc->current);
-	}
-	gc->proto_data = NULL;
-}
-
-static int jabber_send_typing(GaimConnection *gc, const char *who, int typing)
-{
-	xmlnode x, y;
-	char *realwho;
-	gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-	jab_res_info jri = jabber_find_resource(gc, who);
+	jabber_send_raw(js, "</stream:stream>");
 
-	if(!jri || !jri->has_composing)
-		return 0;
-
-	if((realwho = get_realwho(gjc, who, FALSE, NULL)) == NULL)
-		return 0;
-
-	x = xmlnode_new_tag("message");
-	xmlnode_put_attrib(x, "to", realwho);
-
-	y = xmlnode_insert_tag(x, "x");
-	xmlnode_put_attrib(y, "xmlns", "jabber:x:event");
-
-	if(typing == GAIM_TYPING)
-		xmlnode_insert_tag(y, "composing");
-
-	gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x);
-	xmlnode_free(x);
-	g_free(realwho);
-	return JABBER_TYPING_NOTIFY_INT;
-}
+	if(js->gsc) {
+		gaim_ssl_close(js->gsc);
+	} else {
+		close(js->fd);
+	}
 
-static void insert_message(xmlnode x, const char *message, gboolean use_xhtml) {
-	xmlnode y;
-	char *buf = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body>%s</body></html>", message);
-	char *xhtml, *plain;
-
-	html_to_xhtml(buf, &xhtml, &plain);
-	g_free(buf);
-
-	y = xmlnode_insert_tag(x, "body");
-	xmlnode_insert_cdata(y, plain, -1);
-	g_free(plain);
+	g_markup_parse_context_free(js->context);
 
-	if(use_xhtml) {
-		y = xmlnode_str(xhtml, strlen(xhtml));
-		if(y) {
-			xmlnode_insert_tag_node(x, y);
-			xmlnode_free(y);
-		} else {
-			gaim_debug(GAIM_DEBUG_ERROR, "jabber",
-					   "holy cow, html_to_xhtml didn't work right!\n");
-			gaim_debug(GAIM_DEBUG_ERROR, "jabber",
-					   "the invalid XML: %s\n", xhtml);
-		}
-	}
-	g_free(xhtml);
+	g_hash_table_destroy(js->callbacks);
+	g_hash_table_destroy(js->buddies);
+	if(js->stream_id)
+		g_free(js->stream_id);
+	jabber_id_free(js->user);
+	g_free(js);
 }
 
-static int jabber_send_im(GaimConnection *gc, const char *who, const char *message, GaimImFlags flags)
-{
-	xmlnode x, y;
-	char *thread_id = NULL;
-	gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-	jab_res_info jri = jabber_find_resource(gc, who);
-
-	if (!who || !message)
-		return 0;
-
-	x = xmlnode_new_tag("message");
-	xmlnode_put_attrib(x, "to", who);
-
-	thread_id = jabber_get_convo_thread(gjc, who);
-	if(thread_id)
-	{
-		if(strcmp(thread_id, "")) {
-			y = xmlnode_insert_tag(x, "thread");
-			xmlnode_insert_cdata(y, thread_id, -1);
-		}
-		g_free(thread_id);
-	}
-
-	xmlnode_put_attrib(x, "type", "chat");
-
-	/* let other clients know we support typing notification */
-	y = xmlnode_insert_tag(x, "x");
-	xmlnode_put_attrib(y, "xmlns", "jabber:x:event");
-	xmlnode_insert_tag(y, "composing");
-
-	if (message && strlen(message)) {
-		insert_message(x, message, jri ? jri->has_xhtml : TRUE);
-	}
-
-	gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x);
-	xmlnode_free(x);
-	return 1;
-}
-
-/*
- * Add/update buddy's roster entry on server
- *
- * If "alias" or "group" are NULL, gets them from Gaim's current buddylist values
- * for the buddy.
- */
-static void jabber_roster_update(GaimConnection *gc, const char *name, const char *alias, const char *group)
+void jabber_stream_set_state(JabberStream *js, JabberStreamState state)
 {
-	xmlnode x, y;
-	char *realwho;
-	gjconn gjc;
-	GaimBuddy *buddy = NULL;
-	GaimGroup *buddy_group = NULL;
-	const char *my_alias = NULL;
-	const char *my_group = NULL;
-
-	if(gc && gc->proto_data && ((struct jabber_data *)gc->proto_data)->gjc && name) {
-		gaim_jid gjid;
-		gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-
-		if((realwho = get_realwho(gjc, name, FALSE, &gjid)) == NULL)
-			return;
-
-		/* FIXME: transport */
-		if(gjid->user == NULL) {
-			g_free(realwho);
-			gaim_jid_free(gjid);
-			return;
-		}
-		gaim_jid_free(gjid);
-
-		x = jutil_iqnew(JPACKET__SET, NS_ROSTER);
-		y = xmlnode_insert_tag(xmlnode_get_tag(x, "query"), "item");
-		xmlnode_put_attrib(y, "jid", realwho);
-
-		buddy = gaim_find_buddy(gc->account, realwho);
-
-		/*
-		 * See if there's an explict (new?) alias for the buddy or we can pull
-		 * one out of current Gaim buddylist data for him.
-		 */
-		if(alias && alias[0] != '\0') {
-			my_alias = alias;
-		} else if(buddy && buddy->alias) {
-			my_alias = buddy->alias;
-		}
-
-		/* If there's an alias for the buddy, it's not 0-length
-		 * and it doesn't match his JID, add the "name" attribute.
-		 */
-		if(my_alias != NULL && my_alias[0] != '\0' && strcmp(realwho, my_alias))
-		{
-			xmlnode_put_attrib(y, "name", my_alias);
-		}
-
-		/*
-		 * See if there's an explict (new?) group for the buddy or pull
-		 * one out of current Gaim buddylist data for him.
-		 */
-		if(group && group[0] != '\0') {
-			my_group = group;
-		} else if((buddy_group = gaim_find_buddys_group(buddy)) != NULL) {
-			my_group = buddy_group->name;
-		}
-
-		/*
-		 * Send what group the buddy's in along with the roster item.
-		 */
-		if(my_group != NULL && my_group[0] != '\0') {
-			xmlnode z = xmlnode_insert_tag(y, "group");
-			xmlnode_insert_cdata(z, my_group, -1);
-		}
-
-		gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x);
-
-		xmlnode_free(x);
-		g_free(realwho);
+	js->state = state;
+	switch(state) {
+		case JABBER_STREAM_OFFLINE:
+			break;
+		case JABBER_STREAM_CONNECTING:
+			gaim_connection_update_progress(js->gc, _("Connecting"), 1,
+					JABBER_CONNECT_STEPS);
+			break;
+		case JABBER_STREAM_INITIALIZING:
+			gaim_connection_update_progress(js->gc, _("Initializing Stream"),
+					js->gsc ? 5 : 2, JABBER_CONNECT_STEPS);
+			jabber_stream_init(js);
+			jabber_parser_setup(js);
+			break;
+		case JABBER_STREAM_AUTHENTICATING:
+			gaim_connection_update_progress(js->gc, _("Authenticating"),
+					js->gsc ? 6 : 3, JABBER_CONNECT_STEPS);
+			if(js->protocol_version == JABBER_PROTO_0_9)
+				jabber_auth_start_old(js);
+			break;
+		case JABBER_STREAM_REINITIALIZING:
+			gaim_connection_update_progress(js->gc, _("Re-initializing Stream"),
+					6, JABBER_CONNECT_STEPS);
+			jabber_stream_init(js);
+			break;
+		case JABBER_STREAM_CONNECTED:
+			gaim_connection_set_state(js->gc, GAIM_CONNECTED);
+			jabber_roster_request(js);
+			jabber_presence_send(js->gc, js->gc->away_state, js->gc->away);
+			serv_finish_login(js->gc);
+			break;
 	}
 }
 
-/*
- * Add/update buddy's alias on server
- *
- * This is just a roster update using existing, local buddylist data
- */
-static void jabber_alias_buddy(GaimConnection *gc, const char *name, const char *alias)
-{
-	jabber_roster_update(gc, name, alias, NULL);
-}
-
-/*
- * Change buddy's group on server roster
- */
-static void jabber_group_change(GaimConnection *gc, const char *name, const char *old_group, const char *new_group)
-{
-	if(old_group && new_group && strcmp(old_group, new_group))
-		jabber_roster_update(gc, name, NULL, new_group);
-}
-
-/*
- * Group rename
- *
- * Jabber doesn't have "groups," per se.  "Group" is simply a JID attribute.
- * So we iterate through the list of buddies that are in the group and change
- * the group attribute for each of them.
- */
-static void jabber_rename_group(GaimConnection *gc,
-				const char *old_group,
-				const char *new_group,
-				GList *members)
-{
-	if(old_group && new_group && strcmp(old_group, new_group))
-		while(members) {
-			jabber_group_change(gc, (char *)(members->data), old_group, new_group);
-			members = members->next;
-		}
-}
-
-static void jabber_add_buddy(GaimConnection *gc, const char *name, GaimGroup *group)
+char *jabber_get_next_id(JabberStream *js)
 {
-	xmlnode x;
-	char *realwho;
-	gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-	gaim_jid gjid;
-	GaimAccount *account = gaim_connection_get_account(gc);
-
-	if (!((struct jabber_data *)gc->proto_data)->did_import)
-		return;
-
-	/*
-	 * If there's no name or the name is ourself
-	 */
-	if(!name || !strcmp(gaim_account_get_username(account), name))
-		return;
-
-	if((realwho = get_realwho(gjc, name, FALSE, &gjid)) == NULL) {
-		char *msg = g_strdup_printf(_("The user %s is an invalid Jabber I.D. and was "
-					      "therefore not added."),  name);
-		gaim_notify_error(gc, NULL, _("Unable to add buddy."),
-						  _("Jabber Error"));
-		g_free(msg);
-		jabber_remove_gaim_buddy(gc, name);
-		return;
-	}
-
-	/* FIXME: transport */
-	if(gjid->user == NULL) {
-		g_free(realwho);
-		gaim_jid_free(gjid);
-		return;
-	}
-	gaim_jid_free(gjid);
-
-	x = xmlnode_new_tag("presence");
-	xmlnode_put_attrib(x, "to", realwho);
-	xmlnode_put_attrib(x, "type", "subscribe");
-	gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x);
-	xmlnode_free(x);
-
-	jabber_roster_update(gc, realwho, NULL, NULL);
-
-	g_free(realwho);
-}
-
-static void jabber_remove_buddy(GaimConnection *gc, const char *name, const char *group)
-{
-	xmlnode x;
-	char *realwho;
-	gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-
-	if(!name || (realwho = get_realwho(gjc, name, FALSE, NULL)) == NULL)
-		return;
-
-	x = xmlnode_new_tag("presence");
-	xmlnode_put_attrib(x, "to", realwho);
-	xmlnode_put_attrib(x, "type", "unsubscribe");
-	gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x);
-	g_free(realwho);
-	xmlnode_free(x);
+	return g_strdup_printf("gaim%d", js->next_id++);
 }
 
-#if 0  /* Faceprint!  Look here! */
-/*
- * Remove a buddy item from the roster entirely
- */
-static void jabber_remove_buddy_roster_item(GaimConnection *gc, char *name)
-{
-	gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-	char *realwho;
-
-	if((realwho = get_realwho(gjc, name, FALSE, NULL)) != NULL) {
-		xmlnode x = jutil_iqnew(JPACKET__SET, NS_ROSTER);
-		xmlnode y = xmlnode_insert_tag(xmlnode_get_tag(x, "query"), "item");
-		xmlnode_put_attrib(y, "jid", realwho);
-		xmlnode_put_attrib(y, "subscription", "remove");
-		gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x);
-		g_free(realwho);
-		xmlnode_free(x);
-	}
-}
-#endif
-
-/*
- * Unsubscribe a buddy from our presence
- */
-static void jabber_unsubscribe_buddy_from_us(GaimConnection *gc, const char *name)
+void jabber_idle_set(GaimConnection *gc, int idle)
 {
-	gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-	char *realwho;
-
-	if((realwho = get_realwho(gjc, name, FALSE, NULL)) != NULL) {
-		xmlnode g = xmlnode_new_tag("presence");
-		xmlnode_put_attrib(g, "to", realwho);
-		xmlnode_put_attrib(g, "type", "unsubscribed");
-		gjab_send(gjc, g);
-		xmlnode_free(g);
-	}
-}
-
-/*
- * Common code for setting ourselves invisible/visible to buddy
- */
-static void jabber_invisible_to_buddy_common(GaimConnection *gc, const char *name, gboolean invisible)
-{
-	gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-	char *realwho;
-
-	if((realwho = get_realwho(gjc, name, FALSE, NULL)) != NULL) {
-		struct jabber_buddy_data *jbd = jabber_find_buddy(gc, realwho, TRUE);
-		xmlnode g = xmlnode_new_tag("presence");
-
-		xmlnode_put_attrib(g, "to", realwho);
-
-		if(invisible)
-			xmlnode_put_attrib(g, "type", "invisible");
-
-		gjab_send(gjc, g);
-
-		g_free(realwho);
-		xmlnode_free(g);
+	JabberStream *js = gc->proto_data;
 
-		if(jbd) {
-			if(invisible) {
-				jbd->invisible |= JABBER_BUD_INVIS;
-			} else {
-				jbd->invisible &= ~JABBER_BUD_INVIS;
-			}
-		}
-	}
-}
-
-/*
- * Make ourselves temporarily invisible to a buddy
- */
-static void jabber_invisible_to_buddy(GaimConnection *gc, const char *name)
-{
-	jabber_invisible_to_buddy_common(gc, name, TRUE);
-}
-
-/*
- * Make ourselves visible to a buddy
- */
-static void jabber_visible_to_buddy(GaimConnection *gc, const char *name)
-{
-	jabber_invisible_to_buddy_common(gc, name, FALSE);
-}
-
-/*
- * Function used by the g_hash_table_foreach() in invisible_to_all_buddies() to
- * actually set the status.
- *
- * key is unused
- * value is the pointer to the jabber_buddy_data struct
- * data is gboolean: TRUE (invisible) or FALSE (not invisible)
- */
-static void set_invisible_to_buddy_status(gpointer key, gpointer val, gpointer data) {
-	struct jabber_buddy_data *jbd = val;
-	gboolean invisible = GPOINTER_TO_INT(data);
-
-	if(jbd) {
-		if(invisible) {
-			jbd->invisible = JABBER_SERV_INVIS | JABBER_BUD_INVIS;
-		} else {
-			/*
-			 * If we've asserted server-level invisibility, cancelling
-			 * it removes explicit buddy invisibility settings too.
-			 */
-			if(jbd->invisible & JABBER_SERV_INVIS)
-				jbd->invisible = JABBER_NOT_INVIS;
-		}
-	}
-}
-
-/*
- * Show we've set ourselves invisible/visible to all buddies on the server
- *
- * Used when we set server-wide invisibility so that individual buddy menu
- * entries show the proper option.
- */
-static void invisible_to_all_buddies(GaimConnection *gc, gboolean invisible)
-{
-	struct jabber_data *jd = gc->proto_data;
-
-	if(jd->buddies != NULL)
-		g_hash_table_foreach(jd->buddies, set_invisible_to_buddy_status, GINT_TO_POINTER(invisible));
+	js->idle = idle ? time(NULL) - idle : idle;
 }
 
 static const char *jabber_list_icon(GaimAccount *a, GaimBuddy *b)
@@ -2954,578 +451,110 @@
 	return "jabber";
 }
 
-static void jabber_list_emblems(GaimBuddy *b, char **se, char **sw, char **nw, char **ne)
+static void jabber_list_emblems(GaimBuddy *b, char **se, char **sw,
+		char **nw, char **ne)
 {
-	struct jabber_buddy_data *jbd = jabber_find_buddy(b->account->gc, b->name, FALSE);
+	JabberStream *js;
+	JabberBuddy *jb;
+
+	if(!b->account->gc)
+		return;
+	js = b->account->gc->proto_data;
+	jb = jabber_buddy_find(js, b->name, FALSE);
 
 	if(!GAIM_BUDDY_IS_ONLINE(b)) {
-		if (jbd && jbd->error_msg)
+		if(jb && jb->error_msg)
 			*nw = "error";
 
-		if(jbd && (jbd->subscription & JABBER_SUB_PENDING ||
-				!(jbd->subscription & JABBER_SUB_TO)))
+		if(jb && (jb->subscription & JABBER_SUB_PENDING ||
+					!(jb->subscription & JABBER_SUB_TO)))
 			*se = "notauthorized";
 		else
 			*se = "offline";
-
 	} else {
 		switch (b->uc) {
-		case UC_AWAY:
-			*se = "away";
-			break;
-		case UC_CHAT:
-			*se = "chat";
-			break;
-		case UC_XA:
-			*se = "extendedaway";
-			break;
-		case UC_DND:
-			*se = "dnd";
-			break;
-		case UC_ERROR:
-			*se = "error";
-			break;
+			case JABBER_STATE_AWAY:
+				*se = "away";
+				break;
+			case JABBER_STATE_CHAT:
+				*se = "chat";
+				break;
+			case JABBER_STATE_XA:
+				*se = "extendedaway";
+				break;
+			case JABBER_STATE_DND:
+				*se = "extendedaway";
+				break;
+			case JABBER_STATE_ERROR:
+				*se = "error";
+				break;
 		}
 	}
 }
 
-static GList *jabber_chat_info(GaimConnection *gc)
+static char *jabber_status_text(GaimBuddy *b)
 {
-	gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-
-	static char *confserv = NULL;	/* this pointer must be persistent */
-	gchar *server;
-
-	GList *m = NULL;
-	struct proto_chat_entry *pce;
-
-	/* This is a scientific wild-ass guess...
-	 *
-	 * If there are more than two "components" to the current server name,
-	 * lop-off the left-most component and replace with "conference."
-	 */
-	if(confserv != NULL) {
-		g_free(confserv);	/* dispose of the old value */
-	}
-
-	if((server = g_strdup(gjc->user->server)) == NULL) {
-		confserv = g_strdup(DEFAULT_GROUPCHAT);
-	} else {
-		gchar **splits, **index;
-		gchar *tmp;
-		int cnt = 0;
-
-
-		index = splits = g_strsplit(server, ".", -1);	/* split the connected server */
-
-		while(*(index++))	/* index to the end--counting the parts */
-			++cnt;
-
-		/*
-		 * If we've more than two parts, point to the second part.  Else point
-		 * to the start.
-		 */
-		if(cnt > 2) {
-			index -= cnt;
-		} else {
-			index = splits;
-		}
-
-		/* Put it together */
-		confserv = g_strjoin(".", "conference", (tmp = g_strjoinv(".", index)), NULL);
-
-		g_free(server);		/* we don't need this stuff no more */
-		g_free(tmp);
-		g_strfreev(splits);
-	}
-
-	pce = g_new0(struct proto_chat_entry, 1);
-	pce->label = _("Room:");
-	pce->identifier = "room";
-	m = g_list_append(m, pce);
-
-	pce = g_new0(struct proto_chat_entry, 1);
-	pce->label = _("Server:");
-	pce->identifier = "server";
-	pce->def = confserv;
-	m = g_list_append(m, pce);
-
-	pce = g_new0(struct proto_chat_entry, 1);
-	pce->label = _("Handle:");
-	pce->identifier = "handle";
-	pce->def = gjc->user->user;
-	m = g_list_append(m, pce);
-
-	return m;
-}
-
-static void jabber_join_chat(GaimConnection *gc, GHashTable *data)
-{
-	xmlnode x;
-	char *room, *server, *handle;
-	char *realwho;
-	gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-	GSList *jcs = ((struct jabber_data *)gc->proto_data)->chats;
-	struct jabber_chat *jc;
-	gaim_jid gjid;
-
-	room = g_hash_table_lookup(data, "room");
-	server = g_hash_table_lookup(data, "server");
-	handle = g_hash_table_lookup(data, "handle");
+	JabberBuddy *jb = jabber_buddy_find(b->account->gc->proto_data, b->name,
+			FALSE);
+	char *ret = NULL;
 
-	if (!room || !server || !handle)
-		return;
-
-	realwho = create_valid_jid(room, server, handle);
-	gaim_debug(GAIM_DEBUG_INFO, "jabber", "%s\n", realwho);
-
-	if((gjid = gaim_jid_new(realwho)) == NULL) {
-		char *msg = g_strdup_printf("The Jabber I.D. %s is invalid.", realwho);
-		gaim_notify_error(gc, NULL, _("Unable to join chat"), msg);
-		g_free(msg);
-		g_free(realwho);
-		return;
-	}
-
-	if((jc = find_any_chat(gc, gjid)) != NULL) {
-		switch(jc->state) {
-			case JCS_PENDING:
-				gaim_debug(GAIM_DEBUG_INFO, "jabber",
-						   "attempt to re-join already pending Jabber chat! (ignoring)\n");
-				g_free(realwho);	/* yuck! */
-				gaim_jid_free(gjid);
-				return;
-			case JCS_ACTIVE:
-				gaim_debug(GAIM_DEBUG_INFO, "jabber",
-						   "attempt to re-join already active Jabber chat! (ignoring)\n");
-				g_free(realwho);	/* yuck! */
-				gaim_jid_free(gjid);
-				return;
-			case JCS_CLOSED:
-				gaim_debug(GAIM_DEBUG_INFO, "jabber",
-						   "rejoining previously closed Jabber chat\n");
-				break;
-			default:
-				gaim_debug(GAIM_DEBUG_INFO, "jabber",
-						   "found Jabber chat in unknown state! (ignoring)\n");
-				g_free(realwho);	/* yuck! */
-				gaim_jid_free(gjid);
-				return;
-		}
+	if(jb && !GAIM_BUDDY_IS_ONLINE(b) && (jb->subscription & JABBER_SUB_PENDING || !(jb->subscription & JABBER_SUB_TO))) {
+		ret = g_strdup(_("Not Authorized"));
+	} else if(jb && !GAIM_BUDDY_IS_ONLINE(b) && jb->error_msg) {
+		ret = g_strdup(jb->error_msg);
 	} else {
-		gaim_debug(GAIM_DEBUG_INFO, "jabber",
-				   "joining completely new Jabber chat\n");
-		jc = g_new0(struct jabber_chat, 1);
-		jc->gjid = gjid;
-		jc->gc = gc;
-		((struct jabber_data *)gc->proto_data)->chats = g_slist_append(jcs, jc);
-		//	add_buddy(gc->account, _("Chats"), realwho, realwho);
-	}
+		char *stripped = strip_html(jabber_buddy_get_status_msg(jb));
 
-	jc->state = JCS_PENDING;
-
-	x = jutil_presnew(0, realwho, NULL);
-	gjab_send(gjc, x);
-	xmlnode_free(x);
-	g_free(realwho);
-}
+		if(!stripped && b->uc & UC_UNAVAILABLE)
+			stripped = g_strdup(jabber_get_state_string(b->uc));
 
-static void jabber_chat_invite(GaimConnection *gc, int id, const char *message, const char *name)
-{
-	xmlnode x, y;
-	struct jabber_data *jd = gc->proto_data;
-	gjconn gjc = jd->gjc;
-	struct jabber_chat *jc = NULL;
-	char *realwho, *subject;
-
-	if(!name || (realwho = get_realwho(gjc, name, FALSE, NULL)) == NULL)
-		return;
-
-	/* find which chat we're inviting to */
-	if(jabber_find_chat_by_convo_id(gc, id, &jc) != 0)
-		return;
-
-	x = xmlnode_new_tag("message");
-	xmlnode_put_attrib(x, "to", realwho);
-
-	g_free(realwho);
-
-	y = xmlnode_insert_tag(x, "x");
-	xmlnode_put_attrib(y, "xmlns", "jabber:x:conference");
-	subject = g_strdup_printf("%s@%s", jc->gjid->user, jc->gjid->server);
-	xmlnode_put_attrib(y, "jid", subject);
-	g_free(subject);
-
-	if (message && strlen(message)) {
-		insert_message(x, message, FALSE);
+		if(stripped) {
+			ret = g_markup_escape_text(stripped, -1);
+			g_free(stripped);
+		}
 	}
 
-	gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x);
-	xmlnode_free(x);
-}
-
-static void jabber_chat_leave(GaimConnection *gc, int id)
-{
-	struct jabber_data *jd = gc->proto_data;
-	gjconn gjc = jd->gjc;
-	struct jabber_chat *jc = NULL;
-	char *chatname;
-	xmlnode x;
-
-	/* Find out which chat we're leaving */
-	if(jabber_find_chat_by_convo_id(gc, id, &jc) != 0)
-		return;
-
-	chatname = g_strdup_printf("%s@%s", jc->gjid->user, jc->gjid->server);
-	x = jutil_presnew(0, chatname, NULL);
-	g_free(chatname);
-	xmlnode_put_attrib(x, "type", "unavailable");
-	gjab_send(gjc, x);
-	xmlnode_free(x);
-	jc->b = NULL;
-}
-
-static int jabber_chat_send(GaimConnection *gc, int id, const char *message)
-{
-	xmlnode x, y;
-	struct jabber_chat *jc = NULL;
-	char *chatname;
-	int retval = 0;
-
-	/* Find out which chat we're sending to */
-	if((retval = jabber_find_chat_by_convo_id(gc, id, &jc)) != 0)
-		return(retval);
-
-	x = xmlnode_new_tag("message");
-	xmlnode_put_attrib(x, "from", jc->gjid->full);
-	chatname = g_strdup_printf("%s@%s", jc->gjid->user, jc->gjid->server);
-	xmlnode_put_attrib(x, "to", chatname);
-	g_free(chatname);
-	xmlnode_put_attrib(x, "type", "groupchat");
-
-	if (message && strlen(message) > strlen("/topic ") &&
-			!g_ascii_strncasecmp(message, "/topic ", strlen("/topic "))) {
-		char buf[8192];
-		y = xmlnode_insert_tag(x, "subject");
-		xmlnode_insert_cdata(y, message + strlen("/topic "), -1);
-		y = xmlnode_insert_tag(x, "body");
-		g_snprintf(buf, sizeof(buf), "/me has changed the subject to: %s", message + strlen("/topic"));
-		xmlnode_insert_cdata(y, buf, -1);
-	} else if (message && strlen(message)) {
-		insert_message(x, message, FALSE);
-	}
-
-	gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x);
-	xmlnode_free(x);
-	return 0;
-}
-
-static void jabber_chat_whisper(GaimConnection *gc, int id, const char *who, const char *message)
-{
-	xmlnode x;
-	struct jabber_chat *jc = NULL;
-	char *chatname;
-
-	/* Find out which chat we're whispering to */
-	if(jabber_find_chat_by_convo_id(gc, id, &jc) != 0)
-		return;
-
-	x = xmlnode_new_tag("message");
-	xmlnode_put_attrib(x, "from", jc->gjid->full);
-	chatname = g_strdup_printf("%s@%s/%s", jc->gjid->user, jc->gjid->server, who);
-	xmlnode_put_attrib(x, "to", chatname);
-	g_free(chatname);
-	xmlnode_put_attrib(x, "type", "normal");
-
-	if (message && strlen(message)) {
-		insert_message(x, message, FALSE);
-	}
-
-	gjab_send(((struct jabber_data *)gc->proto_data)->gjc, x);
-	xmlnode_free(x);
-}
-
-static char *jabber_normalize(const char *s)
-{
-	static char buf[BUF_LEN];
-	char *t, *u;
-	int x = 0;
-
-	g_return_val_if_fail((s != NULL), NULL);
-
-	/* Somebody called us with s == NULL once... */
-	if(s == NULL) {
-		return(NULL);
-	} else {
-		u = t = g_utf8_strdown(s, -1);
-
-		while (*t && (x < BUF_LEN - 1)) {
-			if (*t != ' ')
-				buf[x++] = *t;
-			t++;
-		}
-		buf[x] = '\0';
-		g_free(u);
-
-		if (!strchr(buf, '@')) {
-			strcat(buf, "@" DEFAULT_SERVER); /* this isn't always right, but eh */
-		} else if ((u = strchr(strchr(buf, '@'), '/')) != NULL) {
-			*u = '\0';
-		}
-
-		return buf;
-	}
-}
-
-static void jabber_get_info(GaimConnection *gc, const char *who) {
-	xmlnode x;
-	char *id;
-	char *realwho;
-	struct jabber_data *jd = gc->proto_data;
-	gjconn gjc = jd->gjc;
-
-	if((realwho = get_realwho(gjc, who, TRUE, NULL)) == NULL)
-		return;
-
-	x = jutil_iqnew(JPACKET__GET, NS_VCARD);
-	xmlnode_put_attrib(x, "to", realwho);
-
-	g_free(realwho);
-
-	id = gjab_getid(gjc);
-	xmlnode_put_attrib(x, "id", id);
-
-	g_hash_table_insert(jd->gjc->queries, g_strdup(id), g_strdup("vCard"));
-
-	gjab_send(gjc, x);
-
-	xmlnode_free(x);
-}
-
-static void jabber_get_error_msg(GaimConnection *gc, const char *who) {
-	struct jabber_data *jd = gc->proto_data;
-	gjconn gjc = jd->gjc;
-	gchar **str_arr = (gchar **) g_new(gpointer, 3);
-	gchar **ap = str_arr;
-	gchar *realwho, *final;
-	struct jabber_buddy_data *jbd;
-
-	if((realwho = get_realwho(gjc, who, FALSE, NULL)) == NULL) {
-		g_strfreev(str_arr);
-		return;
-	}
-
-	jbd = jabber_find_buddy(gc, realwho, TRUE);
-
-	*ap++ = g_strdup_printf("<B>%s:</B> %s<BR>\n", _("Jabber ID"), realwho);
-	*ap++ = g_strdup_printf("<B>%s:</B> %s<BR>\n", _("Error"), jbd->error_msg);
-	*ap = NULL;
-
-	final= g_strjoinv(NULL, str_arr);
-
-	g_strfreev(str_arr);
-
-	g_show_info_text(gc, realwho, 2, final, NULL);
-	g_free(realwho);
-	g_free(final);
-}
-
-static void jabber_get_away_msg(GaimConnection *gc, const char *who) {
-	struct jabber_data *jd = gc->proto_data;
-	gjconn gjc = jd->gjc;
-	int num_resources;
-	gaim_jid gjid;
-	char *buddy = get_realwho(gjc, who, FALSE, &gjid);
-	struct jabber_buddy_data *jbd = jabber_find_buddy(gc, buddy, TRUE);
-	gchar **str_arr;
-	gchar **ap;
-	gchar *realwho, *final;
-	GSList *resources;
-	int i;
-
-	if(!buddy)
-		return;
-
-	if(!gjid->resource) {
-		num_resources = g_slist_length(jbd->resources);
-		resources = jbd->resources;
-	} else {
-		num_resources = 1;
-		resources = jbd->resources;
-		while(strcasecmp(((jab_res_info)resources->data)->name, gjid->resource))
-			resources = resources->next;
-	}
-
-	gaim_jid_free(gjid);
-
-	/* space for all elements: Jabber I.D. + "status" + NULL (list terminator) */
-	str_arr = (gchar **) g_new(gpointer, num_resources*2 + 1);
-	ap = str_arr;
-
-	for(i=0; i<num_resources; i++)
-	{
-		jab_res_info jri = resources->data;
-		char *status;
-		realwho = g_strdup_printf("%s/%s", buddy, jri->name);
-		status = strdup_withhtml(jabber_lookup_away(gjc, realwho));
-		*ap++ = g_strdup_printf("<B>%s:</B> %s<BR>\n", _("Jabber ID"), realwho);
-		*ap++ = g_strdup_printf("<B>%s:</B> %s%s%s<BR>\n", _("Status"), jabber_get_state_string(jri->state), status ? ": " : "", status ? status : "");
-		g_free(status);
-		g_free(realwho);
-		resources = resources->next;
-	}
-
-	*ap = NULL;
-
-	g_free(buddy);
-
-	final= g_strjoinv(NULL, str_arr);
-	g_strfreev(str_arr);
-
-	g_show_info_text(gc, who, 2, final, NULL);
-	g_free(final);
-
-}
-
-static void jabber_get_cb_info(GaimConnection *gc, int cid, const char *who) {
-	struct jabber_chat *jc = NULL;
-	char *realwho;
-
-	/* Find out which chat */
-	if(jabber_find_chat_by_convo_id(gc, cid, &jc) != 0)
-		return;
-
-	realwho = g_strdup_printf("%s@%s/%s", jc->gjid->user, jc->gjid->server, who);
-
-	jabber_get_info(gc, realwho);
-	g_free(realwho);
-}
-
-static void jabber_get_cb_away_msg(GaimConnection *gc, int cid, const char *who) {
-	struct jabber_chat *jc = NULL;
-	char *realwho;
-
-	/* Find out which chat */
-	if(jabber_find_chat_by_convo_id(gc, cid, &jc) != 0)
-		return;
-
-	realwho = g_strdup_printf("%s@%s/%s", jc->gjid->user, jc->gjid->server, who);
-
-	jabber_get_away_msg(gc, realwho);
-	g_free(realwho);
-
+	return ret;
 }
 
 static char *jabber_tooltip_text(GaimBuddy *b)
 {
-	struct jabber_buddy_data *jbd = jabber_find_buddy(b->account->gc, b->name, FALSE);
-	jab_res_info jri = jabber_find_resource(b->account->gc, b->name);
+	JabberBuddy *jb = jabber_buddy_find(b->account->gc->proto_data, b->name,
+			FALSE);
+	JabberBuddyResource *jbr = jabber_buddy_find_resource(jb, NULL);
 	char *ret = NULL;
-	if(jri) {
-		char *stripped = strip_html(jabber_lookup_away(GC_GJ(b->account->gc),
-					b->name));
+
+	if(jbr) {
 		char *text = NULL;
-		if(stripped)
-			text = g_markup_escape_text(stripped, strlen(stripped));
+		if(jbr->status) {
+			char *stripped;
+			stripped = strip_html(jbr->status);
+			text = g_markup_escape_text(stripped, -1);
+			g_free(stripped);
+		}
+
 		ret = g_strdup_printf("<b>%s:</b> %s%s%s",
 				_("Status"),
-				jabber_get_state_string(jri->state), text ? ": " : "",
+				jabber_get_state_string(jbr->state),
+				text ? ": " : "",
 				text ? text : "");
-
-		if(stripped) {
-			g_free(stripped);
+		if(text)
 			g_free(text);
-		}
-	} else if(jbd && !GAIM_BUDDY_IS_ONLINE(b) &&
-			(jbd->subscription & JABBER_SUB_PENDING ||
-				!(jbd->subscription & JABBER_SUB_TO))) {
-		ret = g_strdup_printf("<b>%s:</b> %s", _("Status"), _("Not Authorized"));
+	} else if(jb && !GAIM_BUDDY_IS_ONLINE(b) && jb->error_msg) {
+		ret = g_strdup_printf("<b>%s:</b> %s",
+				_("Error"), jb->error_msg);
+	} else if(jb && !GAIM_BUDDY_IS_ONLINE(b) &&
+			(jb->subscription & JABBER_SUB_PENDING ||
+			 !(jb->subscription & JABBER_SUB_TO))) {
+		ret = g_strdup_printf("<b>%s:</b> %s",
+				_("Status"), _("Not Authorized"));
 	}
-	return ret;
-}
 
-static char *jabber_status_text(GaimBuddy *b)
-{
-	struct jabber_buddy_data *jbd = jabber_find_buddy(b->account->gc, b->name, FALSE);
-	char *ret = NULL;
-	if (b->uc & UC_UNAVAILABLE) {
-		char *stripped = strip_html(jabber_lookup_away(GC_GJ(b->account->gc),
-					b->name));
-		if(!stripped) {
-			jab_res_info jri = jabber_find_resource(b->account->gc, b->name);
-			if(jri)
-				stripped = g_strdup(jabber_get_state_string(jri->state));
-		}
-		ret = g_markup_escape_text(stripped, strlen(stripped));
-		g_free(stripped);
-	} else if(jbd && !GAIM_BUDDY_IS_ONLINE(b) &&
-			(jbd->subscription & JABBER_SUB_PENDING ||
-				!(jbd->subscription & JABBER_SUB_TO))) {
-		ret = g_strdup(_("Not Authorized"));
-	}
 	return ret;
 }
 
-static void jabber_rereq_auth(GaimConnection *gc, const char *who) {
-	jabber_add_buddy(gc, who, NULL);
-}
-
-static GList *jabber_buddy_menu(GaimConnection *gc, const char *who) {
-	GList *m = NULL;
-	struct proto_buddy_menu *pbm;
-	GaimBuddy *b = gaim_find_buddy(gc->account, who);
-
-	if(b->uc == UC_ERROR)
-	{
-		pbm = g_new0(struct proto_buddy_menu, 1);
-		pbm->label = _("View Error Msg");
-		pbm->callback = jabber_get_error_msg;
-		pbm->gc = gc;
-		m = g_list_append(m, pbm);
-	} else {
-		gjconn gjc = ((struct jabber_data *)gc->proto_data)->gjc;
-		char *realwho = get_realwho(gjc, who, FALSE, NULL);
-		struct jabber_buddy_data *jbd = jabber_find_buddy(gc, realwho, FALSE);
-
-		g_free(realwho);
-
-		pbm = g_new0(struct proto_buddy_menu, 1);
-		pbm->label = _("Get Away Msg");
-		pbm->callback = jabber_get_away_msg;
-		pbm->gc = gc;
-		m = g_list_append(m, pbm);
-
-		pbm = g_new0(struct proto_buddy_menu, 1);
-		if(jbd && (jbd->invisible & JABBER_BUD_INVIS)) {
-			pbm->label = _("Un-hide From");
-			pbm->callback = jabber_visible_to_buddy;
-		} else {
-			pbm->label = _("Temporarily Hide From");
-			pbm->callback = jabber_invisible_to_buddy;
-		}
-
-		pbm->gc = gc;
-		m = g_list_append(m, pbm);
-		pbm = g_new0(struct proto_buddy_menu, 1);
-		pbm->label = _("Cancel Presence Notification");
-		pbm->callback = jabber_unsubscribe_buddy_from_us;
-		pbm->gc = gc;
-		m = g_list_append(m, pbm);
-
-		if(jbd && !GAIM_BUDDY_IS_ONLINE(b) &&
-				!(jbd->subscription & JABBER_SUB_TO)) {
-			pbm = g_new0(struct proto_buddy_menu, 1);
-			pbm->label = _("Re-request authorization");
-			pbm->callback = jabber_rereq_auth;
-			pbm->gc = gc;
-			m = g_list_append(m, pbm);
-		}
-	}
-
-	return m;
-}
-
-static GList *jabber_away_states(GaimConnection *gc) {
+static GList *jabber_away_states(GaimConnection *gc)
+{
 	GList *m = NULL;
 
 	m = g_list_append(m, _("Online"));
@@ -3539,864 +568,6 @@
 	return m;
 }
 
-static void jabber_set_away(GaimConnection *gc, const char *state, const char *message)
-{
-	xmlnode x, y;
-	struct jabber_data *jd = gc->proto_data;
-	gjconn gjc = jd->gjc;
-	GSList *jcs;
-	struct jabber_chat *jc;
-	char *chatname;
-	gboolean invisible = FALSE;
-
-	if (gc->away) {
-		g_free(gc->away);
-		gc->away = NULL;
-	}
-
-	x = xmlnode_new_tag("presence");
-
-	if (!strcmp(state, GAIM_AWAY_CUSTOM)) {
-		/* oh goody. Gaim is telling us what to do. */
-		if (message) {
-			/* Gaim wants us to be away */
-			char *stripped;
-
-			/* Jabber supports XHTML in IMs, but not in away messages. */
-			html_to_xhtml(message, NULL, &stripped);
-
-			y = xmlnode_insert_tag(x, "show");
-			xmlnode_insert_cdata(y, "away", -1);
-			y = xmlnode_insert_tag(x, "status");
-			xmlnode_insert_cdata(y, stripped, -1);
-
-			gc->away = g_strdup(stripped);
-			g_free(stripped);
-		} else {
-			/* Gaim wants us to not be away */
-			/* but for Jabber, we can just send presence with no other information. */
-		}
-	} else {
-		/* state is one of our own strings. it won't be NULL. */
-		if (!strcmp(state, _("Online"))) {
-			/* once again, we don't have to put anything here */
-		} else if (!strcmp(state, _("Chatty"))) {
-			y = xmlnode_insert_tag(x, "show");
-			xmlnode_insert_cdata(y, "chat", -1);
-			gc->away = g_strdup("");
-		} else if (!strcmp(state, _("Away"))) {
-			y = xmlnode_insert_tag(x, "show");
-			xmlnode_insert_cdata(y, "away", -1);
-			gc->away = g_strdup("");
-		} else if (!strcmp(state, _("Extended Away"))) {
-			y = xmlnode_insert_tag(x, "show");
-			xmlnode_insert_cdata(y, "xa", -1);
-			gc->away = g_strdup("");
-		} else if (!strcmp(state, _("Do Not Disturb"))) {
-			y = xmlnode_insert_tag(x, "show");
-			xmlnode_insert_cdata(y, "dnd", -1);
-			gc->away = g_strdup("");
-		} else if (!strcmp(state, _("Invisible"))) {
-			xmlnode_put_attrib(x, "type", "invisible");
-			gc->away = g_strdup("");
-			invisible = TRUE;
-		}
-	}
-
-	gjab_send(gjc, x);	/* Notify "individuals" */
-
-	/*
-	 * As of jabberd-1.4.2: simply sending presence to the server doesn't result in
-	 * it being propagated to conference rooms.  So we wade thru the list of chats,
-	 * sending our new presence status to each and every one.
-	 */
-	for(jcs = jd->chats; jcs; jcs = jcs->next) {
-		jc = jcs->data;
-		if(jc->state == JCS_ACTIVE) {
-			xmlnode_put_attrib(x, "from", jc->gjid->full);
-			chatname = g_strdup_printf("%s@%s", jc->gjid->user, jc->gjid->server);
-			xmlnode_put_attrib(x, "to", chatname);
-			gjab_send(gjc, x);
-			g_free(chatname);
-		}
-	}
-
-	xmlnode_free(x);
-
-	invisible_to_all_buddies(gc, invisible);
-}
-
-static void jabber_set_idle(GaimConnection *gc, int idle) {
-	struct jabber_data *jd = (struct jabber_data *)gc->proto_data;
-	gaim_debug(GAIM_DEBUG_INFO, "jabber",
-			   "jabber_set_idle: setting idle %i\n", idle);
-	jd->idle = idle ? time(NULL) - idle : idle;
-}
-
-static void jabber_keepalive(GaimConnection *gc) {
-	struct jabber_data *jd = (struct jabber_data *)gc->proto_data;
-	gjab_send_raw(jd->gjc, JABBER_KEEPALIVE_STRING);
-}
-
-/*---------------------------------------*/
-/* Jabber "set info" (vCard) support     */
-/*---------------------------------------*/
-
-/*
- * V-Card format:
- *
- *  <vCard prodid='' version='' xmlns=''>
- *    <FN></FN>
- *    <N>
- *	<FAMILY/>
- *	<GIVEN/>
- *    </N>
- *    <NICKNAME/>
- *    <URL/>
- *    <ADR>
- *	<STREET/>
- *	<EXTADD/>
- *	<LOCALITY/>
- *	<REGION/>
- *	<PCODE/>
- *	<COUNTRY/>
- *    </ADR>
- *    <TEL/>
- *    <EMAIL/>
- *    <ORG>
- *	<ORGNAME/>
- *	<ORGUNIT/>
- *    </ORG>
- *    <TITLE/>
- *    <ROLE/>
- *    <DESC/>
- *    <BDAY/>
- *  </vCard>
- *
- * See also:
- *
- *	http://docs.jabber.org/proto/html/vcard-temp.html
- *	http://www.vcard-xml.org/dtd/vCard-XML-v2-20010520.dtd
- */
-
-/*
- * Cross-reference user-friendly V-Card entry labels to vCard XML tags
- * and attributes.
- *
- * Order is (or should be) unimportant.  For example: we have no way of
- * knowing in what order real data will arrive.
- *
- * Format: Label, Pre-set text, "visible" flag, "editable" flag, XML tag
- *         name, XML tag's parent tag "path" (relative to vCard node).
- *
- *         List is terminated by a NULL label pointer.
- *
- *	   Entries with no label text, but with XML tag and parent tag
- *	   entries, are used by V-Card XML construction routines to
- *	   "automagically" construct the appropriate XML node tree.
- *
- * Thoughts on future direction/expansion
- *
- *	This is a "simple" vCard.
- *
- *	It is possible for nodes other than the "vCard" node to have
- *      attributes.  Should that prove necessary/desirable, add an
- *      "attributes" pointer to the vcard_template struct, create the
- *      necessary tag_attr structs, and add 'em to the vcard_dflt_data
- *      array.
- *
- *	The above changes will (obviously) require changes to the vCard
- *      construction routines.
- */
-
-struct vcard_template {
-	char *label;			/* label text pointer */
-	char *text;			/* entry text pointer */
-	int  visible;			/* should entry field be "visible?" */
-	int  editable;			/* should entry field be editable? */
-	char *tag;			/* tag text */
-	char *ptag;			/* parent tag "path" text */
-	char *url;			/* vCard display format if URL */
-} vcard_template_data[] = {
-	{N_("Full Name"),          NULL, TRUE, TRUE, "FN",        NULL,  NULL},
-	{N_("Family Name"),        NULL, TRUE, TRUE, "FAMILY",    "N",   NULL},
-	{N_("Given Name"),         NULL, TRUE, TRUE, "GIVEN",     "N",   NULL},
-	{N_("Nickname"),           NULL, TRUE, TRUE, "NICKNAME",  NULL,  NULL},
-	{N_("URL"),                NULL, TRUE, TRUE, "URL",       NULL,  "<A HREF=\"%s\">%s</A>"},
-	{N_("Street Address"),     NULL, TRUE, TRUE, "STREET",    "ADR", NULL},
-	{N_("Extended Address"),   NULL, TRUE, TRUE, "EXTADD",    "ADR", NULL},
-	{N_("Locality"),           NULL, TRUE, TRUE, "LOCALITY",  "ADR", NULL},
-	{N_("Region"),             NULL, TRUE, TRUE, "REGION",    "ADR", NULL},
-	{N_("Postal Code"),        NULL, TRUE, TRUE, "PCODE",     "ADR", NULL},
-	{N_("Country"),            NULL, TRUE, TRUE, "COUNTRY",   "ADR", NULL},
-	{N_("Telephone"),          NULL, TRUE, TRUE, "TELEPHONE", NULL,  NULL},
-	{N_("Email"),              NULL, TRUE, TRUE, "EMAIL",     NULL,  "<A HREF=\"mailto:%s\">%s</A>"},
-	{N_("Organization Name"),  NULL, TRUE, TRUE, "ORGNAME",   "ORG", NULL},
-	{N_("Organization Unit"),  NULL, TRUE, TRUE, "ORGUNIT",   "ORG", NULL},
-	{N_("Title"),              NULL, TRUE, TRUE, "TITLE",     NULL,  NULL},
-	{N_("Role"),               NULL, TRUE, TRUE, "ROLE",      NULL,  NULL},
-	{N_("Birthday"),           NULL, TRUE, TRUE, "BDAY",      NULL,  NULL},
-	{N_("Description"),        NULL, TRUE, TRUE, "DESC",      NULL,  NULL},
-	{"", NULL, TRUE, TRUE, "N",     NULL, NULL},
-	{"", NULL, TRUE, TRUE, "ADR",   NULL, NULL},
-	{"", NULL, TRUE, TRUE, "ORG",   NULL, NULL},
-	{NULL, NULL, 0, 0, NULL, NULL, NULL}
-};
-
-/*
- * The "vCard" tag's attibute list...
- */
-struct tag_attr {
-	char *attr;
-	char *value;
-} vcard_tag_attr_list[] = {
-	{"prodid",   "-//HandGen//NONSGML vGen v1.0//EN"},
-	{"version",  "2.0",                             },
-	{"xmlns",    "vcard-temp",                      },
-	{NULL, NULL},
-};
-
-
-/*
- * Used by routines to parse an XML-encoded string into an xmlnode tree
- */
-typedef struct {
-	XML_Parser parser;
-	xmlnode current;
-} *xmlstr2xmlnode_parser, xmlstr2xmlnode_parser_struct;
-
-
-/*
- * Display a Jabber vCard
- */
-static void jabber_handlevcard(gjconn gjc, xmlnode querynode, char *from)
-{
-	GaimConnection *gc = GJ_GC(gjc);
-	char *cdata, *status;
-	struct vcard_template *vc_tp = vcard_template_data;
-
-	/* space for all vCard elements + Jabber I.D. + "status" + NULL (list terminator) */
-	gchar **str_arr = (gchar **) g_new(gpointer,
-				(sizeof(vcard_template_data)/sizeof(struct vcard_template)) + 3);
-	gchar **ap = str_arr;
-	gchar *buddy, *final;
-
-	jab_res_info jri;
-
-	if((buddy = get_realwho(gjc, from, TRUE, NULL)) == NULL) {
-		g_strfreev(str_arr);
-		return;
-	}
-
-	jri = jabber_find_resource(GJ_GC(gjc), buddy);
-
-	*ap++ = g_strdup_printf("<B>%s:</B> %s<BR>\n", _("Jabber ID"), buddy);
-
-	for(vc_tp = vcard_template_data; vc_tp->label != NULL; ++vc_tp) {
-		if(strcmp(vc_tp->tag, "DESC") == 0)
-			continue;	/* special handling later */
-		if(vc_tp->ptag == NULL) {
-			cdata = xmlnode_get_tag_data(querynode, vc_tp->tag);
-		} else {
-			gchar *tag = g_strdup_printf("%s/%s", vc_tp->ptag, vc_tp->tag);
-			cdata = xmlnode_get_tag_data(querynode, tag);
-			g_free(tag);
-		}
-		if(cdata != NULL) {
-			if(vc_tp->url == NULL) {
-				*ap++ = g_strdup_printf("<B>%s:</B> %s<BR>\n", _(vc_tp->label), cdata);
-			} else {
-				gchar *fmt = g_strdup_printf("<B>%%s:</B> %s<BR>\n", vc_tp->url);
-				*ap++ = g_strdup_printf(fmt, _(vc_tp->label), cdata, cdata);
-				g_free(fmt);
-			}
-		}
-	}
-
-
-	status = strdup_withhtml(jabber_lookup_away(gjc, buddy));
-	*ap++ = g_strdup_printf("<B>%s:</B> %s%s%s<BR>\n",
-			_("Status"),
-			jri ? jabber_get_state_string(jri->state) : "",
-			jri && status ? ": " : "", status ? status : "");
-	g_free(status);
-
-	/*
-	 * "Description" handled as a special case: get a copy of the
-	 * string and HTML-ize.
-	 */
-	if((cdata = xmlnode_get_tag_data(querynode, "DESC")) != NULL) {
-		gchar *tmp = g_strdup_printf("<HR>%s<BR>", cdata);
-		*ap++ = strdup_withhtml(tmp);
-		g_free(tmp);
-	}
-
-	*ap = NULL;
-
-	final= g_strjoinv(NULL, str_arr);
-	g_strfreev(str_arr);
-
-	g_show_info_text(gc, buddy, 2, final, NULL);
-	g_free(buddy);
-	g_free(final);
-}
-
-/*
- * Used by XML_Parse on parsing CDATA
- */
-static void xmlstr2xmlnode_charData(void *userdata, const char *s, int slen)
-{
-	xmlstr2xmlnode_parser xmlp = (xmlstr2xmlnode_parser) userdata;
-
-	if (xmlp->current)
-		xmlnode_insert_cdata(xmlp->current, s, slen);
-}
-
-/*
- * Used by XML_Parse to start or append to an xmlnode
- */
-static void xmlstr2xmlnode_startElement(void *userdata, const char *name, const char **attribs)
-{
-	xmlnode x;
-	xmlstr2xmlnode_parser xmlp = (xmlstr2xmlnode_parser) userdata;
-
-	if (xmlp->current) {
-		/* Append the node to the current one */
-		x = xmlnode_insert_tag(xmlp->current, name);
-		xmlnode_put_expat_attribs(x, attribs);
-
-		xmlp->current = x;
-	} else {
-		x = xmlnode_new_tag(name);
-		xmlnode_put_expat_attribs(x, attribs);
-		xmlp->current = x;
-	}
-}
-
-/*
- * Used by XML_Parse to end an xmlnode
- */
-static void xmlstr2xmlnode_endElement(void *userdata, const char *name)
-{
-	xmlstr2xmlnode_parser xmlp = (xmlstr2xmlnode_parser) userdata;
-	xmlnode x;
-
-	if (xmlp->current != NULL && (x = xmlnode_get_parent(xmlp->current)) != NULL) {
-		xmlp->current = x;
-	}
-}
-
-/*
- * Parse an XML-encoded string into an xmlnode tree
- *
- * Caller is responsible for freeing the returned xmlnode
- */
-static xmlnode xmlstr2xmlnode(char *xmlstring)
-{
-	xmlstr2xmlnode_parser my_parser = g_new(xmlstr2xmlnode_parser_struct, 1);
-	xmlnode x = NULL;
-
-	my_parser->parser = XML_ParserCreate(NULL);
-	my_parser->current = NULL;
-
-	XML_SetUserData(my_parser->parser, (void *)my_parser);
-	XML_SetElementHandler(my_parser->parser, xmlstr2xmlnode_startElement, xmlstr2xmlnode_endElement);
-	XML_SetCharacterDataHandler(my_parser->parser, xmlstr2xmlnode_charData);
-	XML_Parse(my_parser->parser, xmlstring, strlen(xmlstring), 0);
-
-	x = my_parser->current;
-
-	XML_ParserFree(my_parser->parser);
-	g_free(my_parser);
-
-	return(x);
-}
-
-/*
- * Insert a tag node into an xmlnode tree, recursively inserting parent tag
- * nodes as necessary
- *
- * Returns pointer to inserted node
- *
- * Note to hackers: this code is designed to be re-entrant (it's recursive--it
- * calls itself), so don't put any "static"s in here!
- */
-static xmlnode insert_tag_to_parent_tag(xmlnode start, const char *parent_tag, const char *new_tag)
-{
-	xmlnode x = NULL;
-
-	/*
-	 * If the parent tag wasn't specified, see if we can get it
-	 * from the vCard template struct.
-	 */
-	if(parent_tag == NULL) {
-		struct vcard_template *vc_tp = vcard_template_data;
-
-		while(vc_tp->label != NULL) {
-			if(strcmp(vc_tp->tag, new_tag) == 0) {
-				parent_tag = vc_tp->ptag;
-				break;
-			}
-			++vc_tp;
-		}
-	}
-
-	/*
-	 * If we have a parent tag...
-	 */
-	if(parent_tag != NULL ) {
-		/*
-		 * Try to get the parent node for a tag
-		 */
-		if((x = xmlnode_get_tag(start, parent_tag)) == NULL) {
-			/*
-			 * Descend?
-			 */
-			char *grand_parent = strcpy(g_malloc(strlen(parent_tag) + 1), parent_tag);
-			char *parent;
-
-			if((parent = strrchr(grand_parent, '/')) != NULL) {
-				*(parent++) = '\0';
-				x = insert_tag_to_parent_tag(start, grand_parent, parent);
-			} else {
-				x = xmlnode_insert_tag(start, grand_parent);
-			}
-			g_free(grand_parent);
-		} else {
-			/*
-			 * We found *something* to be the parent node.
-			 * Note: may be the "root" node!
-			 */
-			xmlnode y;
-			if((y = xmlnode_get_tag(x, new_tag)) != NULL) {
-				return(y);
-			}
-		}
-	}
-
-	/*
-	 * insert the new tag into its parent node
-	 */
-	return(xmlnode_insert_tag((x == NULL? start : x), new_tag));
-}
-
-/*
- * Send vCard info to Jabber server
- */
-static void jabber_set_info(GaimConnection *gc, const char *info)
-{
-	xmlnode x, vc_node;
-	char *id;
-	struct jabber_data *jd = gc->proto_data;
-	gjconn gjc = jd->gjc;
-	gchar *info2;
-
-	x = xmlnode_new_tag("iq");
-	xmlnode_put_attrib(x, "type", "set");
-
-	id = gjab_getid(gjc);
-
-	xmlnode_put_attrib(x, "id", id);
-
-	/*
-	 * Send only if there's actually any *information* to send
-	 */
-	info2 = g_strdup(info);
-	vc_node = xmlstr2xmlnode(info2);
-
-	if(vc_node) {
-		if (xmlnode_get_name(vc_node) &&
-				!g_ascii_strncasecmp(xmlnode_get_name(vc_node), "vcard", 5)) {
-			xmlnode_insert_tag_node(x, vc_node);
-			gaim_debug(GAIM_DEBUG_MISC, "jabber",
-					   "jabber: vCard packet: %s\n", xmlnode2str(x));
-			gjab_send(gjc, x);
-		}
-		xmlnode_free(vc_node);
-	}
-
-	xmlnode_free(x);
-	g_free(info2);
-}
-
-/*
- * This is the callback from the "ok clicked" for "set vCard"
- *
- * Formats GSList data into XML-encoded string and returns a pointer
- * to said string.
- *
- * g_free()'ing the returned string space is the responsibility of
- * the caller.
- */
-static void
-jabber_format_info(GaimConnection *gc, GaimRequestFields *fields)
-{
-	GaimAccount *account;
-	xmlnode vc_node;
-	GaimRequestField *field;
-	const char *text;
-	char *p;
-	const struct vcard_template *vc_tp;
-	struct tag_attr *tag_attr;
-
-	vc_node = xmlnode_new_tag("vCard");
-
-	for(tag_attr = vcard_tag_attr_list; tag_attr->attr != NULL; ++tag_attr)
-		xmlnode_put_attrib(vc_node, tag_attr->attr, tag_attr->value);
-
-	for (vc_tp = vcard_template_data; vc_tp->label != NULL; vc_tp++) {
-		if (*vc_tp->label == '\0')
-			continue;
-
-		field = gaim_request_fields_get_field(fields, vc_tp->tag);
-		text  = gaim_request_field_string_get_value(field);
-
-		gaim_debug(GAIM_DEBUG_INFO, "jabber",
-				   "Setting %s to '%s'\n", vc_tp->tag, text);
-
-		if (text != NULL && *text != '\0') {
-			xmlnode xp;
-
-			if ((xp = insert_tag_to_parent_tag(vc_node,
-											   NULL, vc_tp->tag)) != NULL) {
-
-				xmlnode_insert_cdata(xp, text, -1);
-			}
-		}
-	}
-
-	p = g_strdup(xmlnode2str(vc_node));
-	xmlnode_free(vc_node);
-
-	account = gaim_connection_get_account(gc);
-
-	if (account != NULL) {
-		gaim_account_set_user_info(account, p);
-
-		if (gc != NULL)
-			serv_set_info(gc, p);
-	}
-
-	g_free(p);
-}
-
-/*
- * This gets executed by the proto action
- *
- * Creates a new GaimRequestFields struct, gets the XML-formatted user_info
- * string (if any) into GSLists for the (multi-entry) edit dialog and
- * calls the set_vcard dialog.
- */
-static void jabber_setup_set_info(GaimConnection *gc)
-{
-	GaimRequestFields *fields;
-	GaimRequestFieldGroup *group;
-	GaimRequestField *field;
-	const struct vcard_template *vc_tp;
-	char *user_info;
-	char *cdata;
-	xmlnode x_vc_data = NULL;
-
-	fields = gaim_request_fields_new();
-	group = gaim_request_field_group_new(NULL);
-	gaim_request_fields_add_group(fields, group);
-
-	/*
-	 * Get existing, XML-formatted, user info
-	 */
-	if((user_info = g_strdup(gaim_account_get_user_info(gc->account))) != NULL)
-		x_vc_data = xmlstr2xmlnode(user_info);
-	else
-		user_info = g_strdup("");
-
-	/*
-	 * Set up GSLists for edit with labels from "template," data from user info
-	 */
-	for(vc_tp = vcard_template_data; vc_tp->label != NULL; ++vc_tp) {
-		if((vc_tp->label)[0] == '\0')
-			continue;
-		if(vc_tp->ptag == NULL) {
-			cdata = xmlnode_get_tag_data(x_vc_data, vc_tp->tag);
-		} else {
-			gchar *tag = g_strdup_printf("%s/%s", vc_tp->ptag, vc_tp->tag);
-			cdata = xmlnode_get_tag_data(x_vc_data, tag);
-			g_free(tag);
-		}
-		if(strcmp(vc_tp->tag, "DESC") == 0) {
-			field = gaim_request_field_string_new(vc_tp->tag,
-												  _(vc_tp->label), cdata,
-												  TRUE);
-#if 0
-			multi_text_list_update(&(b->multi_text_items),
-				vc_tp->label, cdata, TRUE);
-#endif
-		} else {
-			field = gaim_request_field_string_new(vc_tp->tag,
-												  _(vc_tp->label), cdata,
-												  FALSE);
-#if 0
-			data = multi_entry_list_update(&(b->multi_entry_items),
-				vc_tp->label, cdata, TRUE);
-			data->visible = vc_tp->visible;
-			data->editable = vc_tp->editable;
-#endif
-		}
-
-		gaim_request_field_group_add_field(group, field);
-	}
-
-	if(x_vc_data != NULL) {
-		xmlnode_free(x_vc_data);
-	} else {
-		/*
-		 * I'm commenting this out for now. faceprint can look at it
-		 * later. The comment below says this is going away "real soon now,"
-		 * but it's probably been here a really long time. Getting this
-		 * to work with the multi-field stuff won't be pretty, since we're
-		 * manually going to have to search through all fields for the
-		 * label and update.
-		 *
-		 *     -- ChipX86
-		 */
-#if 0
-		/*
-		 * Early Beta versions had a different user_info storage format--let's
-		 * see if that works.
-		 *
-		 * This goes away RSN.
-		 */
-		const char *record_separator = "<BR>";
-		const char *field_separator = ": ";
-		gchar **str_list, **str_list_ptr, **str_list2;
-
-		if((str_list = g_strsplit(user_info, record_separator, 0)) != NULL) {
-			for(str_list_ptr = str_list; *str_list_ptr != NULL; ++str_list_ptr) {
-				str_list2 = g_strsplit(*str_list_ptr, field_separator, 2);
-				if(str_list2[0] != NULL && str_list2[1] != NULL) {
-					g_strstrip(str_list2[0]);
-					g_strstrip(str_list2[1]);
-					/* this is ugly--so far */
-					if(strcmp(str_list2[0], "Description") == 0) {
-						multi_text_list_update(&(b->multi_text_items),
-							str_list2[0], str_list2[1], FALSE);
-					} else {
-						multi_entry_list_update(&(b->multi_entry_items),
-							str_list2[0], str_list2[1], FALSE);
-					}
-				}
-				g_strfreev(str_list2);
-			}
-			g_strfreev(str_list);
-		}
-#endif
-	}
-
-    g_free(user_info);
-
-	gaim_request_fields(gc, _("Edit Jabber vCard"),
-						_("Edit Jabber vCard"),
-						_("All items below are optional. Enter only the "
-						  "information with which you feel comfortable."),
-						fields,
-						_("Save"), G_CALLBACK(jabber_format_info),
-						_("Cancel"), NULL,
-						gc);
-}
-
-/*---------------------------------------*/
-/* End Jabber "set info" (vCard) support */
-/*---------------------------------------*/
-
-/*----------------------------------------*/
-/* Jabber "user registration" support     */
-/*----------------------------------------*/
-
-/*
- * Three of the following four functions duplicate much of what
- * exists elsewhere:
- *
- *	jabber_handleregresp()
- *	gjab_reqreg()
- *	jabber_handle_registration_state()
- *
- * It may be that an additional flag could be added to one of
- * the "local" structs and the duplicated code modified to
- * account for it--thus eliminating the duplication.  Then again:
- * doing it the way it is may be much cleaner.
- *
- * TBD: Code to support requesting additional information server
- * wants at registration--incl. dialog.
- */
-
-/*
- * Like jabber_handlepacket(), only different
- */
-static void jabber_handleregresp(gjconn gjc, jpacket p)
-{
-	if (jpacket_subtype(p) == JPACKET__RESULT) {
-		xmlnode querynode;
-
-		if((querynode = xmlnode_get_tag(p->x, "query")) != NULL) {
-			char *xmlns;
-
-			/* we damn well *better* have this! */
-			if((xmlns = xmlnode_get_attrib(querynode, "xmlns")) != NULL &&
-				strcmp(xmlns, NS_REGISTER) == 0) {
-
-				char *tag;
-				xmlnode child = xmlnode_get_firstchild(querynode);
-
-				gaim_debug(GAIM_DEBUG_INFO, "jabber",
-						   "got registration requirments response!\n");
-
-				while(child != NULL) {
-					if((tag = xmlnode_get_name(child)) != NULL) {
-						char *data;
-
-						fprintf(stderr, "DBG: got node: \"%s\"\n", tag);
-						fflush(stderr);
-
-						if((data = xmlnode_get_data(child)) != NULL) {
-							fprintf(stderr, "DBG: got data: \"%s\"\n", data);
-							fflush(stderr);
-						}
-					}
-					child = xmlnode_get_nextsibling(child);
-				}
-			}
-		} else {
-			gaim_debug(GAIM_DEBUG_INFO, "jabber",
-					   "registration successful!\n");
-
-			gaim_connection_notice(GJ_GC(gjc), _("Server Registration successful!"));
-			gaim_connection_destroy(GJ_GC(gjc));
-		}
-
-	} else {
-		xmlnode xerr;
-		char *errmsg = NULL;
-		int errcode = 0;
-
-		gaim_debug(GAIM_DEBUG_ERROR, "jabber", "registration failed\n");
-		xerr = xmlnode_get_tag(p->x, "error");
-		if (xerr) {
-			char msg[BUF_LONG];
-			errmsg = xmlnode_get_data(xerr);
-			if (xmlnode_get_attrib(xerr, "code")) {
-				errcode = atoi(xmlnode_get_attrib(xerr, "code"));
-				g_snprintf(msg, sizeof(msg), _("Error %d: %s"), errcode, errmsg);
-			} else
-				g_snprintf(msg, sizeof(msg), "%s", errmsg);
-			gaim_connection_error(GJ_GC(gjc), msg);
-		} else {
-			gaim_connection_error(GJ_GC(gjc), _("Unknown registration error"));
-		}
-	}
-}
-
-/*
- * Like gjab_reqauth(), only different
- */
-static void gjab_reqreg(gjconn gjc)
-{
-	xmlnode x, y, z;
-	char *user;
-
-	if (!gjc)
-		return;
-
-	x = jutil_iqnew(JPACKET__SET, NS_REGISTER);
-	y = xmlnode_get_tag(x, "query");
-
-	user = gjc->user->user;
-
-	if (user) {
-		z = xmlnode_insert_tag(y, "username");
-		xmlnode_insert_cdata(z, user, -1);
-	}
-	z = xmlnode_insert_tag(y, "password");
-	xmlnode_insert_cdata(z, gjc->pass, -1);
-
-	gaim_debug(GAIM_DEBUG_MISC, "jabber",
-			   "jabber: registration packet: %s\n", xmlnode2str(x));
-	gjab_send(gjc, x);
-	xmlnode_free(x);
-}
-
-/*
- * Like jabber_handlestate(), only different
- */
-static void jabber_handle_registration_state(gjconn gjc, int state)
-{
-	switch (state) {
-	case JCONN_STATE_OFF:
-		if(gjc->was_connected) {
-			gaim_connection_error(GJ_GC(gjc), _("Connection lost"));
-		} else {
-			gaim_connection_error(GJ_GC(gjc), _("Unable to connect"));
-		}
-		break;
-	case JCONN_STATE_CONNECTED:
-		gjc->was_connected = 1;
-		/*
-		 * TBD?
-		gaim_connection_update_progress(GJ_GC(gjc), _("Connected"), 
-				2, JABBER_CONNECT_STEPS);
-		 */
-		break;
-	case JCONN_STATE_ON:
-		/*
-		 * TBD?
-		gaim_connection_update_progress(GJ_GC(gjc), _("Authenticating"),
-				_("Requesting Authentication Method"), 3, 
-				JABBER_CONNECT_STEPS);
-		 */
-		gjab_reqreg(gjc);
-		/*
-		 * TBD: A work-in-progress
-		gjab_reqregreqs(gjc);
-		 */
-		break;
-	default:
-		gaim_debug(GAIM_DEBUG_MISC, "jabber", "state change: %d\n", state);
-	}
-	return;
-}
-
-/*
- * Like jabber_login(), only different
- */
-void jabber_register_user(GaimAccount *account)
-{
-	GaimConnection *gc = gaim_account_get_connection(account);
-	struct jabber_data *jd = gc->proto_data = g_new0(struct jabber_data, 1);
-	char *loginname = create_valid_jid(account->username, DEFAULT_SERVER, "Gaim");
-
-	/*
-	 * These do nothing during registration
-	 */
-	jd->buddies = NULL;
-	jd->chats = NULL;
-
-	if ((jd->gjc = gjab_new(loginname, account->password, gc)) == NULL) {
-		g_free(loginname);
-		gaim_debug(GAIM_DEBUG_ERROR, "jabber",
-				   "unable to connect (jab_new failed)\n");
-		gaim_connection_error(gc, _("Unable to connect"));
-	} else {
-		gjab_state_handler(jd->gjc, jabber_handle_registration_state);
-		gjab_packet_handler(jd->gjc, jabber_handleregresp);
-		jd->gjc->queries = NULL;
-		gjab_start(jd->gjc);
-	}
-
-	g_free(loginname);
-}
-
-/*----------------------------------------*/
-/* End Jabber "user registration" support */
-/*----------------------------------------*/
-
 static GList *jabber_actions(GaimConnection *gc)
 {
 	GList *m = NULL;
@@ -4408,19 +579,7 @@
 	pam->gc = gc;
 	m = g_list_append(m, pam);
 
-	/*
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Set Dir Info");
-	pam->callback = show_set_dir;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
-	 */
-
-	pam = g_new0(struct proto_actions_menu, 1);
-	pam->label = _("Change Password");
-	pam->callback = show_change_passwd;
-	pam->gc = gc;
-	m = g_list_append(m, pam);
+	/* XXX: Change Password */
 
 	return m;
 }
@@ -4428,7 +587,7 @@
 static GaimPluginProtocolInfo prpl_info =
 {
 	GAIM_PROTO_JABBER,
-	OPT_PROTO_UNIQUE_CHATNAME | OPT_PROTO_CHAT_TOPIC,
+	OPT_PROTO_CHAT_TOPIC | OPT_PROTO_UNIQUE_CHATNAME,
 	NULL,
 	NULL,
 	jabber_list_icon,
@@ -4441,20 +600,20 @@
 	jabber_chat_info,
 	jabber_login,
 	jabber_close,
-	jabber_send_im,
+	jabber_message_send_im,
 	jabber_set_info,
 	jabber_send_typing,
-	jabber_get_info,
-	jabber_set_away,
+	jabber_buddy_get_info,
+	jabber_presence_send,
 	NULL,
 	NULL,
 	NULL,
 	NULL,
-	jabber_set_idle,
-	jabber_change_passwd,
-	jabber_add_buddy,
+	jabber_idle_set,
+	NULL, /* change_passwd */ /* XXX */
+	jabber_roster_add_buddy,
 	NULL,
-	jabber_remove_buddy,
+	jabber_roster_remove_buddy,
 	NULL,
 	NULL,
 	NULL,
@@ -4462,21 +621,21 @@
 	NULL,
 	NULL,
 	NULL,
-	jabber_join_chat,
+	jabber_chat_join,
 	jabber_chat_invite,
 	jabber_chat_leave,
 	jabber_chat_whisper,
-	jabber_chat_send,
+	jabber_message_send_chat,
 	jabber_keepalive,
-	jabber_register_user,
-	jabber_get_cb_info,
-	jabber_get_cb_away_msg,
-	jabber_alias_buddy,
-	jabber_group_change,
-	jabber_rename_group,
+	NULL, /* register_user */ /* XXX tell the user success/failure */
+	jabber_buddy_get_info_chat,
 	NULL,
-	jabber_convo_closed,
-	jabber_normalize
+	jabber_roster_alias_change,
+	jabber_roster_group_change,
+	jabber_roster_group_rename,
+	NULL,
+	NULL, /* convo_closed */ /* XXX: thread_ids */
+	NULL /* normalize */
 };
 
 static GaimPluginInfo info =
@@ -4512,31 +671,31 @@
 	GaimAccountUserSplit *split;
 	GaimAccountOption *option;
 
-	/* Splits */
 	split = gaim_account_user_split_new(_("Server"), "jabber.org", '@');
 	prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
 
 	split = gaim_account_user_split_new(_("Resource"), "Gaim", '/');
 	prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
 
-	/* Account Options */
-
 	if(gaim_ssl_is_supported()) {
-		option = gaim_account_option_bool_new(_("Use SSL"), "old_ssl", FALSE);
+		option = gaim_account_option_bool_new(_("Force Old SSL"), "old_ssl", FALSE);
 		prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
 				option);
 	}
 
-	option = gaim_account_option_int_new(_("Port"), "port", DEFAULT_PORT);
+	option = gaim_account_option_int_new(_("Port"), "port", 5222);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
-											   option);
+			option);
 
 	option = gaim_account_option_string_new(_("Connect server"),
-											"connect_server", NULL);
+			"connect_server", NULL);
 	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
-											   option);
+			option);
 
 	my_protocol = plugin;
+
+	gaim_prefs_add_none("/plugins/prpl/jabber");
+	gaim_prefs_add_bool("/plugins/prpl/jabber/hide_os", FALSE);
 }
 
 GAIM_INIT_PLUGIN(jabber, init_plugin, info);
--- a/src/protocols/jabber/jabber.h	Mon Sep 29 13:00:55 2003 +0000
+++ b/src/protocols/jabber/jabber.h	Mon Sep 29 15:23:19 2003 +0000
@@ -1,322 +1,83 @@
-/*
- *  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.
+/**
+ * @file jabber.h
+ *
+ * gaim
+ *
+ * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
  *
- *  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.
+ * 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.
  *
- *  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.
+ * 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.
  *
- *  Jabber
- *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
+ * 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 <sys/types.h>
-/*this must happen before sys/socket.h or freebsd won't compile*/
-
-#ifndef _WIN32
-#include <syslog.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <strings.h>
-#include <unistd.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdarg.h>
-#include <sys/time.h>
-#include <time.h>
-#include <ctype.h>
-
-#include "libxode.h"
-
-#ifndef INCL_JABBER_H
-#define INCL_JABBER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* JID structures & constants                                */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define JID_RESOURCE 1
-#define JID_USER     2
-#define JID_SERVER   4
+#ifndef _GAIM_JABBER_H_
+#define _GAIM_JABBER_H_
 
-typedef struct jid_struct
-{ 
-    pool               p;
-    char*              resource;
-    char*              user;
-    char*              server;
-    char*              full;
-    struct jid_struct *next; /* for lists of jids */
-} *jid;
-  
-jid     jid_new(pool p, char *idstr);	       /* Creates a jabber id from the idstr */
-void    jid_set(jid id, char *str, int item);  /* Individually sets jid components */
-char*   jid_full(jid id);		       /* Builds a string type=user/resource@server from the jid data */
-int     jid_cmp(jid a, jid b);		       /* Compares two jid's, returns 0 for perfect match */
-int     jid_cmpx(jid a, jid b, int parts);     /* Compares just the parts specified as JID_|JID_ */
-jid     jid_append(jid a, jid b);	       /* Appending b to a (list), no dups */
-xmlnode jid_xres(jid id);		       /* Returns xmlnode representation of the resource?query=string */
-xmlnode jid_nodescan(jid id, xmlnode x);       /* Scans the children of the node for a matching jid attribute */
-
+#include <glib.h>
+#include "connection.h"
+#include "sslconn.h"
 
-/* --------------------------------------------------------- */
-/*                                                           */
-/* JPacket structures & constants                            */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define JPACKET_UNKNOWN   0x00
-#define JPACKET_MESSAGE   0x01
-#define JPACKET_PRESENCE  0x02
-#define JPACKET_IQ        0x04
-#define JPACKET_S10N      0x08
-
-#define JPACKET__UNKNOWN      0
-#define JPACKET__NONE         1
-#define JPACKET__ERROR        2
-#define JPACKET__CHAT         3
-#define JPACKET__GROUPCHAT    4
-#define JPACKET__GET          5
-#define JPACKET__SET          6
-#define JPACKET__RESULT       7
-#define JPACKET__SUBSCRIBE    8
-#define JPACKET__SUBSCRIBED   9
-#define JPACKET__UNSUBSCRIBE  10
-#define JPACKET__UNSUBSCRIBED 11
-#define JPACKET__AVAILABLE    12
-#define JPACKET__UNAVAILABLE  13
-#define JPACKET__PROBE        14
-#define JPACKET__HEADLINE     15
+#include "jutil.h"
+#include "xmlnode.h"
 
-typedef struct jpacket_struct
-{
-    unsigned char type;
-    int           subtype;
-    int           flag;
-    void*         aux1;
-    xmlnode       x;
-    jid           to;
-    jid           from;
-    char*         iqns;
-    xmlnode       iq;
-    pool          p;
-} *jpacket, _jpacket;
- 
-jpacket jpacket_new(xmlnode x);	    /* Creates a jabber packet from the xmlnode */
-jpacket jpacket_reset(jpacket p);   /* Resets the jpacket values based on the xmlnode */
-int     jpacket_subtype(jpacket p); /* Returns the subtype value (looks at xmlnode for it) */
-
+typedef enum {
+	JABBER_STREAM_OFFLINE,
+	JABBER_STREAM_CONNECTING,
+	JABBER_STREAM_INITIALIZING,
+	JABBER_STREAM_AUTHENTICATING,
+	JABBER_STREAM_REINITIALIZING,
+	JABBER_STREAM_CONNECTED
+} JabberStreamState;
 
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Presence Proxy DB structures & constants                  */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef struct ppdb_struct
-{			      
-    jid     id;		       /* entry data */
-    int     pri;
-    xmlnode x;
-    struct ppdb_struct* user;  /* linked list for user@server */
-    pool                p;     /* db-level data */
-    struct ppdb_struct* next;
-} _ppdb, *ppdb;
-
-ppdb    ppdb_insert(ppdb db, jid id, xmlnode x); /* Inserts presence into the proxy */
-xmlnode ppdb_primary(ppdb db, jid id);		 /* Fetches the matching primary presence for the id */
-void    ppdb_free(ppdb db);			 /* Frees the db and all entries */
-xmlnode ppdb_get(ppdb db, jid id);		 /* Called successively to return each presence xmlnode */
-						 /*   for the id and children, returns NULL at the end */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Simple Jabber Rate limit functions                        */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef struct jlimit_struct
+typedef struct _JabberStream
 {
-    char *key;
-    int start;
-    int points;
-    int maxt, maxp;
-    pool p;
-} *jlimit, _jlimit;
- 
-jlimit jlimit_new(int maxt, int maxp);
-void jlimit_free(jlimit r);
-int jlimit_check(jlimit r, char *key, int points);
-
+	int fd;
 
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Error structures & constants                              */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef struct terror_struct
-{
-    int  code;
-    char msg[64];
-} terror;
-
-#define TERROR_BAD           (terror){400,"Bad Request"}
-#define TERROR_AUTH          (terror){401,"Unauthorized"}
-#define TERROR_PAY           (terror){402,"Payment Required"}
-#define TERROR_FORBIDDEN     (terror){403,"Forbidden"}
-#define TERROR_NOTFOUND      (terror){404,"Not Found"}
-#define TERROR_NOTALLOWED    (terror){405,"Not Allowed"}
-#define TERROR_NOTACCEPTABLE (terror){406,"Not Acceptable"}
-#define TERROR_REGISTER      (terror){407,"Registration Required"}
-#define TERROR_REQTIMEOUT    (terror){408,"Request Timeout"}
-#define TERROR_CONFLICT      (terror){409,"Conflict"}
+	GMarkupParseContext *context;
+	xmlnode *current;
 
-#define TERROR_INTERNAL   (terror){500,"Internal Server Error"}
-#define TERROR_NOTIMPL    (terror){501,"Not Implemented"}
-#define TERROR_EXTERNAL   (terror){502,"Remote Server Error"}
-#define TERROR_UNAVAIL    (terror){503,"Service Unavailable"}
-#define TERROR_EXTTIMEOUT (terror){504,"Remote Server Timeout"}
-#define TERROR_DISCONNECTED (terror){510,"Disconnected"}
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Namespace constants                                       */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define NSCHECK(x,n) (j_strcmp(xmlnode_get_attrib(x,"xmlns"),n) == 0)
+	enum {
+		JABBER_PROTO_0_9,
+		JABBER_PROTO_1_0
+	} protocol_version;
+	char *stream_id;
+	JabberStreamState state;
 
-#define NS_CLIENT    "jabber:client"
-#define NS_SERVER    "jabber:server"
-#define NS_AUTH      "jabber:iq:auth"
-#define NS_REGISTER  "jabber:iq:register"
-#define NS_ROSTER    "jabber:iq:roster"
-#define NS_OFFLINE   "jabber:x:offline"
-#define NS_AGENT     "jabber:iq:agent"
-#define NS_AGENTS    "jabber:iq:agents"
-#define NS_DELAY     "jabber:x:delay"
-#define NS_VERSION   "jabber:iq:version"
-#define NS_TIME      "jabber:iq:time"
-#define NS_VCARD     "vcard-temp"
-#define NS_PRIVATE   "jabber:iq:private"
-#define NS_SEARCH    "jabber:iq:search"
-#define NS_OOB       "jabber:iq:oob"
-#define NS_XOOB      "jabber:x:oob"
-#define NS_ADMIN     "jabber:iq:admin"
-#define NS_FILTER    "jabber:iq:filter"
-#define NS_AUTH_0K   "jabber:iq:auth:0k"
+	/* SASL authentication */
+	char *expected_rspauth;
 
+	GHashTable *buddies;
+	gboolean roster_parsed;
 
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Message Types                                             */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define TMSG_NORMAL	"normal"
-#define TMSG_ERROR	"error"
-#define TMSG_CHAT	"chat"
-#define TMSG_GROUPCHAT	"groupchat"
-#define TMSG_HEADLINE	"headline"
-
+	GHashTable *chats;
 
-/* --------------------------------------------------------- */
-/*                                                           */
-/* JUtil functions                                           */
-/*                                                           */
-/* --------------------------------------------------------- */
-xmlnode jutil_presnew(int type, char *to, char *status); /* Create a skeleton presence packet */
-xmlnode jutil_iqnew(int type, char *ns);		 /* Create a skeleton iq packet */
-xmlnode jutil_msgnew(char *type, char *to, char *subj, char *body);
-							 /* Create a skeleton message packet */
-xmlnode jutil_header(char* xmlns, char* server);	 /* Create a skeleton stream packet */
-int     jutil_priority(xmlnode x);			 /* Determine priority of this packet */
-void    jutil_tofrom(xmlnode x);			 /* Swaps to/from fields on a packet */
-xmlnode jutil_iqresult(xmlnode x);			 /* Generate a skeleton iq/result, given a iq/query */
-char*   jutil_timestamp(void);				 /* Get stringified timestamp */
-void    jutil_error(xmlnode x, terror E);		 /* Append an <error> node to x */
-void    jutil_delay(xmlnode msg, char *reason);		 /* Append a delay packet to msg */
-char*   jutil_regkey(char *key, char *seed);		 /* pass a seed to generate a key, pass the key again to validate (returns it) */
+	GHashTable *callbacks;
+	int next_id;
 
+	time_t idle;
 
-/* --------------------------------------------------------- */
-/*                                                           */
-/* JConn structures & functions                              */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define JCONN_STATE_OFF       0
-#define JCONN_STATE_CONNECTED 1
-#define JCONN_STATE_ON        2
-#define JCONN_STATE_AUTH      3
-
-typedef struct jconn_struct
-{
-    /* Core structure */
-    pool        p;	       /* Memory allocation pool */
-    int         state;	   /* Connection state flag */
-    int         fd;	       /* Connection file descriptor */
-    jid         user;      /* User info */
-    char        *pass;     /* User passwd */
+	JabberID *user;
+	GaimConnection *gc;
+	GaimSslConnection *gsc;
+} JabberStream;
 
-    /* Stream stuff */
-    int         id;        /* id counter for jab_getid() function */
-    char        idbuf[9];  /* temporary storage for jab_getid() */
-    char        *sid;      /* stream id from server, for digest auth */
-    XML_Parser  parser;    /* Parser instance */
-    xmlnode     current;   /* Current node in parsing instance.. */
+typedef void (JabberCallback)(JabberStream *js, xmlnode *packet);
 
-    /* Event callback ptrs */
-    void (*on_state)(struct jconn_struct *j, int state);
-    void (*on_packet)(struct jconn_struct *j, jpacket p);
-
-} *jconn, jconn_struct;
-
-typedef void (*jconn_state_h)(jconn j, int state);
-typedef void (*jconn_packet_h)(jconn j, jpacket p);
-
+void jabber_process_packet(JabberStream *js, xmlnode *packet);
+void jabber_send(JabberStream *js, xmlnode *data);
+void jabber_send_raw(JabberStream *js, const char *data);
 
-jconn jab_new(char *user, char *pass);
-void jab_delete(jconn j);
-void jab_state_handler(jconn j, jconn_state_h h);
-void jab_packet_handler(jconn j, jconn_packet_h h);
-void jab_start(jconn j);
-void jab_stop(jconn j);
-
-int jab_getfd(jconn j);
-jid jab_getjid(jconn j);
-char *jab_getsid(jconn j);
-char *jab_getid(jconn j);
+void jabber_stream_set_state(JabberStream *js, JabberStreamState state);
 
-void jab_send(jconn j, xmlnode x);
-void jab_send_raw(jconn j, const char *str);
-void jab_recv(jconn j);
-void jab_poll(jconn j, int timeout);
-
-char *jab_auth(jconn j);
-char *jab_reg(jconn j);
+char *jabber_get_next_id(JabberStream *js);
 
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif	/* INCL_JABBER_H */
+#endif /* _GAIM_JABBER_H_ */
--- a/src/protocols/jabber/jconn.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,489 +0,0 @@
-/*
- *  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.
- *
- *  Jabber
- *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
- */
-
-#include "jabber.h"
-
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
-
-/* local macros for launching event handlers */
-#define STATE_EVT(arg) if(j->on_state) { (j->on_state)(j, (arg) ); }
-
-/* prototypes of the local functions */
-static void startElement(void *userdata, const char *name, const char **attribs);
-static void endElement(void *userdata, const char *name);
-static void charData(void *userdata, const char *s, int slen);
-
-/*
- *  jab_new -- initialize a new jabber connection
- *
- *  parameters
- *      user -- jabber id of the user
- *      pass -- password of the user
- *
- *  results
- *      a pointer to the connection structure
- *      or NULL if allocations failed
- */
-jconn jab_new(char *user, char *pass)
-{
-    pool p;
-    jconn j;
-
-    if(!user) return(NULL);
-
-    p = pool_new();
-    if(!p) return(NULL);
-    j = pmalloc_x(p, sizeof(jconn_struct), 0);
-    if(!j) return(NULL);
-    j->p = p;
-
-    j->user = jid_new(p, user);
-    j->pass = pstrdup(p, pass);
-
-    j->state = JCONN_STATE_OFF;
-    j->id = 1;
-    j->fd = -1;
-
-    return j;
-}
-
-/*
- *  jab_delete -- free a jabber connection
- *
- *  parameters
- *      j -- connection
- *
- */
-void jab_delete(jconn j)
-{
-    if(!j) return;
-
-    jab_stop(j);
-    pool_free(j->p);
-}
-
-/*
- *  jab_state_handler -- set callback handler for state change
- *
- *  parameters
- *      j -- connection
- *      h -- name of the handler function
- */
-void jab_state_handler(jconn j, jconn_state_h h)
-{
-    if(!j) return;
-
-    j->on_state = h;
-}
-
-/*
- *  jab_packet_handler -- set callback handler for incoming packets
- *
- *  parameters
- *      j -- connection
- *      h -- name of the handler function
- */
-void jab_packet_handler(jconn j, jconn_packet_h h)
-{
-    if(!j) return;
-
-    j->on_packet = h;
-}
-
-
-/*
- *  jab_start -- start connection
- *
- *  parameters
- *      j -- connection
- *
- */
-void jab_start(jconn j)
-{
-    xmlnode x;
-    char *t,*t2;
-
-    if(!j || j->state != JCONN_STATE_OFF) return;
-
-    j->parser = XML_ParserCreate(NULL);
-    XML_SetUserData(j->parser, (void *)j);
-    XML_SetElementHandler(j->parser, startElement, endElement);
-    XML_SetCharacterDataHandler(j->parser, charData);
-
-    j->fd = make_netsocket(5222, j->user->server, NETSOCKET_CLIENT);
-    if(j->fd < 0) {
-        STATE_EVT(JCONN_STATE_OFF)
-        return;
-    }
-    j->state = JCONN_STATE_CONNECTED;
-    STATE_EVT(JCONN_STATE_CONNECTED)
-
-    /* start stream */
-    x = jutil_header(NS_CLIENT, j->user->server);
-    t = xmlnode2str(x);
-    /* this is ugly, we can create the string here instead of jutil_header */
-    /* what do you think about it? -madcat */
-    t2 = strstr(t,"/>");
-    *t2++ = '>';
-    *t2 = '\0';
-    jab_send_raw(j,"<?xml version='1.0'?>");
-    jab_send_raw(j,t);
-    xmlnode_free(x);
-
-    j->state = JCONN_STATE_ON;
-    STATE_EVT(JCONN_STATE_ON)
-
-}
-
-/*
- *  jab_stop -- stop connection
- *
- *  parameters
- *      j -- connection
- */
-void jab_stop(jconn j)
-{
-    if(!j || j->state == JCONN_STATE_OFF) return;
-
-    j->state = JCONN_STATE_OFF;
-    close(j->fd);
-    j->fd = -1;
-    XML_ParserFree(j->parser);
-}
-
-/*
- *  jab_getfd -- get file descriptor of connection socket
- *
- *  parameters
- *      j -- connection
- *
- *  returns
- *      fd of the socket or -1 if socket was not connected
- */
-int jab_getfd(jconn j)
-{
-    if(j)
-        return j->fd;
-    else
-        return -1;
-}
-
-/*
- *  jab_getjid -- get jid structure of user
- *
- *  parameters
- *      j -- connection
- */
-jid jab_getjid(jconn j)
-{
-    if(j)
-        return(j->user);
-    else
-        return NULL;
-}
-
-/*  jab_getsid -- get stream id
- *  This is the id of server's <stream:stream> tag and used for
- *  digest authorization.
- *
- *  parameters
- *      j -- connection
- */
-char *jab_getsid(jconn j)
-{
-    if(j)
-        return(j->sid);
-    else
-        return NULL;
-}
-
-/*
- *  jab_getid -- get a unique id
- *
- *  parameters
- *      j -- connection
- */
-char *jab_getid(jconn j)
-{
-    snprintf(j->idbuf, 8, "%d", j->id++);
-    return &j->idbuf[0];
-}
-
-/*
- *  jab_send -- send xml data
- *
- *  parameters
- *      j -- connection
- *      x -- xmlnode structure
- */
-void jab_send(jconn j, xmlnode x)
-{
-    if (j && j->state != JCONN_STATE_OFF)
-    {
-	    char *buf = xmlnode2str(x);
-	    if (buf) write(j->fd, buf, strlen(buf));
-#ifdef JDEBUG
-	    printf ("out: %s\n", buf);
-#endif
-    }
-}
-
-/*
- *  jab_send_raw -- send a string
- *
- *  parameters
- *      j -- connection
- *      str -- xml string
- */
-void jab_send_raw(jconn j, const char *str)
-{
-    if (j && j->state != JCONN_STATE_OFF)
-        write(j->fd, str, strlen(str));
-#ifdef JDEBUG
-    printf ("out: %s\n", str);
-#endif
-}
-
-/*
- *  jab_recv -- read and parse incoming data
- *
- *  parameters
- *      j -- connection
- */
-void jab_recv(jconn j)
-{
-    static char buf[4096];
-    int len;
-
-    if(!j || j->state == JCONN_STATE_OFF)
-        return;
-
-    len = read(j->fd, buf, sizeof(buf)-1);
-    if(len>0)
-    {
-        buf[len] = '\0';
-#ifdef JDEBUG
-        printf (" in: %s\n", buf);
-#endif
-        XML_Parse(j->parser, buf, len, 0);
-    }
-    else if(len<0)
-    {
-        STATE_EVT(JCONN_STATE_OFF);
-        jab_stop(j);
-    }
-}
-
-/*
- *  jab_poll -- check socket for incoming data
- *
- *  parameters
- *      j -- connection
- *      timeout -- poll timeout
- */
-void jab_poll(jconn j, int timeout)
-{
-    fd_set fds;
-    struct timeval tv;
-
-    if (!j || j->state == JCONN_STATE_OFF)
-        return;
-
-    FD_ZERO(&fds);
-    FD_SET(j->fd, &fds);
-
-    if (timeout < 0)
-    {
-        if (select(j->fd + 1, &fds, NULL, NULL, NULL) > 0)
-            jab_recv(j);
-    }
-    else
-    {
-	    tv.tv_sec  = 0;
-	    tv.tv_usec = timeout;
-	    if (select(j->fd + 1, &fds, NULL, NULL, &tv) > 0)
-	        jab_recv(j);
-    }
-}
-
-/*
- *  jab_auth -- authorize user
- *
- *  parameters
- *      j -- connection
- *
- *  returns
- *      id of the iq packet
- */
-char *jab_auth(jconn j)
-{
-    xmlnode x,y,z;
-    char *hash, *user, *id;
-
-    if(!j) return(NULL);
-
-    x = jutil_iqnew(JPACKET__SET, NS_AUTH);
-    id = jab_getid(j);
-    xmlnode_put_attrib(x, "id", id);
-    y = xmlnode_get_tag(x,"query");
-
-    user = j->user->user;
-
-    if (user)
-    {
-        z = xmlnode_insert_tag(y, "username");
-        xmlnode_insert_cdata(z, user, -1);
-    }
-
-    z = xmlnode_insert_tag(y, "resource");
-    xmlnode_insert_cdata(z, j->user->resource, -1);
-
-    if (j->sid)
-    {
-        z = xmlnode_insert_tag(y, "digest");
-        hash = pmalloc(x->p, strlen(j->sid)+strlen(j->pass)+1);
-        strcpy(hash, j->sid);
-        strcat(hash, j->pass);
-        hash = shahash(hash);
-        xmlnode_insert_cdata(z, hash, 40);
-    }
-    else
-    {
-	z = xmlnode_insert_tag(y, "password");
-	xmlnode_insert_cdata(z, j->pass, -1);
-    }
-
-    jab_send(j, x);
-    xmlnode_free(x);
-    return id;
-}
-
-/*
- *  jab_reg -- register user
- *
- *  parameters
- *      j -- connection
- *
- *  returns
- *      id of the iq packet
- */
-char *jab_reg(jconn j)
-{
-    xmlnode x,y,z;
-    char *user, *id;
-
-    if (!j) return(NULL);
-
-    x = jutil_iqnew(JPACKET__SET, NS_REGISTER);
-    id = jab_getid(j);
-    xmlnode_put_attrib(x, "id", id);
-    y = xmlnode_get_tag(x,"query");
-
-    user = j->user->user;
-
-    if (user)
-    {
-        z = xmlnode_insert_tag(y, "username");
-        xmlnode_insert_cdata(z, user, -1);
-    }
-
-    z = xmlnode_insert_tag(y, "resource");
-    xmlnode_insert_cdata(z, j->user->resource, -1);
-
-    if (j->pass)
-    {
-	z = xmlnode_insert_tag(y, "password");
-	xmlnode_insert_cdata(z, j->pass, -1);
-    }
-
-    jab_send(j, x);
-    xmlnode_free(x);
-    j->state = JCONN_STATE_ON;
-    STATE_EVT(JCONN_STATE_ON)
-    return id;
-}
-
-
-/* local functions */
-
-static void startElement(void *userdata, const char *name, const char **attribs)
-{
-    xmlnode x;
-    jconn j = (jconn)userdata;
-
-    if(j->current)
-    {
-        /* Append the node to the current one */
-        x = xmlnode_insert_tag(j->current, name);
-        xmlnode_put_expat_attribs(x, attribs);
-
-        j->current = x;
-    }
-    else
-    {
-        x = xmlnode_new_tag(name);
-        xmlnode_put_expat_attribs(x, attribs);
-        if(strcmp(name, "stream:stream") == 0) {
-            /* special case: name == stream:stream */
-            /* id attrib of stream is stored for digest auth */
-            j->sid = xmlnode_get_attrib(x, "id");
-            /* STATE_EVT(JCONN_STATE_AUTH) */
-        } else {
-            j->current = x;
-        }
-    }
-}
-
-static void endElement(void *userdata, const char *name)
-{
-    jconn j = (jconn)userdata;
-    xmlnode x;
-    jpacket p;
-
-    if(j->current == NULL) {
-        /* we got </stream:stream> */
-        STATE_EVT(JCONN_STATE_OFF)
-        return;
-    }
-
-    x = xmlnode_get_parent(j->current);
-
-    if(x == NULL)
-    {
-        /* it is time to fire the event */
-        p = jpacket_new(j->current);
-
-        if(j->on_packet)
-            (j->on_packet)(j, p);
-        else
-            xmlnode_free(j->current);
-    }
-
-    j->current = x;
-}
-
-static void charData(void *userdata, const char *s, int slen)
-{
-    jconn j = (jconn)userdata;
-
-    if (j->current)
-        xmlnode_insert_cdata(j->current, s, slen);
-}
--- a/src/protocols/jabber/jid.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,321 +0,0 @@
-/* --------------------------------------------------------------------------
- *
- * License
- *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
- *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
- *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
-
-#include "lib.h"
-
-jid jid_safe(jid id)
-{
-    unsigned char *str;
-
-    if(strlen(id->server) == 0 || strlen(id->server) > 255)
-        return NULL;
-
-    /* lowercase the hostname, make sure it's valid characters */
-    for(str = id->server; *str != '\0'; str++)
-    {
-        *str = tolower(*str);
-        if(!(isalnum(*str) || *str == '.' || *str == '-' || *str == '_')) return NULL;
-    }
-
-    /* cut off the user */
-    if(id->user != NULL && strlen(id->user) > 64)
-        id->user[64] = '\0';
-
-    /* check for low and invalid ascii characters in the username */
-    if(id->user != NULL)
-        for(str = id->user; *str != '\0'; str++)
-            if(*str <= 32 || *str == ':' || *str == '@' || *str == '<' || *str == '>' || *str == '\'' || *str == '"' || *str == '&') return NULL;
-
-    return id;
-}
-
-jid jid_new(pool p, char *idstr)
-{
-    char *server, *resource, *type, *str;
-    jid id;
-
-    if(p == NULL || idstr == NULL || strlen(idstr) == 0)
-        return NULL;
-
-    /* user@server/resource */
-
-    str = pstrdup(p, idstr);
-
-    id = pmalloco(p,sizeof(struct jid_struct));
-    id->p = p;
-
-    resource = strstr(str,"/");
-    if(resource != NULL)
-    {
-        *resource = '\0';
-        ++resource;
-        if(strlen(resource) > 0)
-            id->resource = resource;
-    }else{
-        resource = str + strlen(str); /* point to end */
-    }
-
-    type = strstr(str,":");
-    if(type != NULL && type < resource)
-    {
-        *type = '\0';
-        ++type;
-        str = type; /* ignore the type: prefix */
-    }
-
-    server = strstr(str,"@");
-    if(server == NULL || server > resource)
-    { /* if there's no @, it's just the server address */
-        id->server = str;
-    }else{
-        *server = '\0';
-        ++server;
-        id->server = server;
-        if(strlen(str) > 0)
-            id->user = str;
-    }
-
-    return jid_safe(id);
-}
-
-void jid_set(jid id, char *str, int item)
-{
-    char *old;
-
-    if(id == NULL)
-        return;
-
-    /* invalidate the cached copy */
-    id->full = NULL;
-
-    switch(item)
-    {
-    case JID_RESOURCE:
-        if(str != NULL && strlen(str) != 0)
-            id->resource = pstrdup(id->p, str);
-        else
-            id->resource = NULL;
-        break;
-    case JID_USER:
-        old = id->user;
-        if(str != NULL && strlen(str) != 0)
-            id->user = pstrdup(id->p, str);
-        else
-            id->user = NULL;
-        if(jid_safe(id) == NULL)
-            id->user = old; /* revert if invalid */
-        break;
-    case JID_SERVER:
-        old = id->server;
-        id->server = pstrdup(id->p, str);
-        if(jid_safe(id) == NULL)
-            id->server = old; /* revert if invalid */
-        break;
-    }
-
-}
-
-char *jid_full(jid id)
-{
-    spool s;
-
-    if(id == NULL)
-        return NULL;
-
-    /* use cached copy */
-    if(id->full != NULL)
-        return id->full;
-
-    s = spool_new(id->p);
-
-    if(id->user != NULL)
-        spooler(s, id->user,"@",s);
-
-    spool_add(s, id->server);
-
-    if(id->resource != NULL)
-        spooler(s, "/",id->resource,s);
-
-    id->full = spool_print(s);
-    return id->full;
-}
-
-/* parses a /resource?name=value&foo=bar into an xmlnode representing <resource name="value" foo="bar"/> */
-xmlnode jid_xres(jid id)
-{
-    char *cur, *qmark, *amp, *eq;
-    xmlnode x;
-
-    if(id == NULL || id->resource == NULL) return NULL;
-
-    cur = pstrdup(id->p, id->resource);
-    qmark = strstr(cur, "?");
-    if(qmark == NULL) return NULL;
-    *qmark = '\0';
-    qmark++;
-
-    x = _xmlnode_new(id->p, cur, NTYPE_TAG);
-
-    cur = qmark;
-    while(cur != '\0')
-    {
-        eq = strstr(cur, "=");
-        if(eq == NULL) break;
-        *eq = '\0';
-        eq++;
-
-        amp = strstr(eq, "&");
-        if(amp != NULL)
-        {
-            *amp = '\0';
-            amp++;
-        }
-
-        xmlnode_put_attrib(x,cur,eq);
-
-        if(amp != NULL)
-            cur = amp;
-        else
-            break;
-    }
-
-    return x;
-}
-
-/* local utils */
-int _jid_nullstrcmp(char *a, char *b)
-{
-    if(a == NULL && b == NULL) return 0;
-    if(a == NULL || b == NULL) return -1;
-    return strcmp(a,b);
-}
-int _jid_nullstrcasecmp(char *a, char *b)
-{
-    if(a == NULL && b == NULL) return 0;
-    if(a == NULL || b == NULL) return -1;
-    return strcasecmp(a,b);
-}
-
-int jid_cmp(jid a, jid b)
-{
-    if(a == NULL || b == NULL)
-        return -1;
-
-    if(_jid_nullstrcmp(a->resource, b->resource) != 0) return -1;
-    if(_jid_nullstrcasecmp(a->user, b->user) != 0) return -1;
-    if(_jid_nullstrcmp(a->server, b->server) != 0) return -1;
-
-    return 0;
-}
-
-/* suggested by Anders Qvist <quest@valdez.netg.se> */
-int jid_cmpx(jid a, jid b, int parts)
-{
-    if(a == NULL || b == NULL)
-        return -1;
-
-    if(parts & JID_RESOURCE && _jid_nullstrcmp(a->resource, b->resource) != 0) return -1;
-    if(parts & JID_USER && _jid_nullstrcasecmp(a->user, b->user) != 0) return -1;
-    if(parts & JID_SERVER && _jid_nullstrcmp(a->server, b->server) != 0) return -1;
-
-    return 0;
-}
-
-/* makes a copy of b in a's pool, requires a valid a first! */
-jid jid_append(jid a, jid b)
-{
-    jid next;
-
-    if(a == NULL)
-        return NULL;
-
-    if(b == NULL)
-        return a;
-
-    next = a;
-    while(next != NULL)
-    {
-        /* check for dups */
-        if(jid_cmp(next,b) == 0)
-            break;
-        if(next->next == NULL)
-            next->next = jid_new(a->p,jid_full(b));
-        next = next->next;
-    }
-    return a;
-}
-
-xmlnode jid_nodescan(jid id, xmlnode x)
-{
-    xmlnode cur;
-    pool p;
-    jid tmp;
-
-    if(id == NULL || xmlnode_get_firstchild(x) == NULL) return NULL;
-
-    p = pool_new();
-    for(cur = xmlnode_get_firstchild(x); cur != NULL; cur = xmlnode_get_nextsibling(cur))
-    {
-        if(xmlnode_get_type(cur) != NTYPE_TAG) continue;
-
-        tmp = jid_new(p,xmlnode_get_attrib(cur,"jid"));
-        if(tmp == NULL) continue;
-
-        if(jid_cmp(tmp,id) == 0) break;
-    }
-    pool_free(p);
-
-    return cur;
-}
-
-jid jid_user(jid a)
-{
-    jid ret;
-
-    if(a == NULL || a->resource == NULL) return a;
-
-    ret = pmalloco(a->p,sizeof(struct jid_struct));
-    ret->p = a->p;
-    ret->user = a->user;
-    ret->server = a->server;
-
-    return ret;
-}
--- a/src/protocols/jabber/jpacket.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-/* --------------------------------------------------------------------------
- *
- * License
- *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
- *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
- *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
-
-#include "lib.h"
-
-jpacket jpacket_new(xmlnode x)
-{
-    jpacket p;
-
-    if(x == NULL)
-        return NULL;
-
-    p = pmalloc(xmlnode_pool(x),sizeof(_jpacket));
-    p->x = x;
-
-    return jpacket_reset(p);
-}
-
-jpacket jpacket_reset(jpacket p)
-{
-    char *val;
-    xmlnode x;
-
-    x = p->x;
-    memset(p,0,sizeof(_jpacket));
-    p->x = x;
-    p->p = xmlnode_pool(x);
-
-    if(strncmp(xmlnode_get_name(x),"message",7) == 0)
-    {
-        p->type = JPACKET_MESSAGE;
-    }else if(strncmp(xmlnode_get_name(x),"presence",8) == 0)
-    {
-        p->type = JPACKET_PRESENCE;
-        val = xmlnode_get_attrib(x, "type");
-        if(val == NULL)
-            p->subtype = JPACKET__AVAILABLE;
-        else if(strcmp(val,"unavailable") == 0)
-            p->subtype = JPACKET__UNAVAILABLE;
-        else if(strcmp(val,"probe") == 0)
-            p->subtype = JPACKET__PROBE;
-        else if(strcmp(val,"error") == 0)
-            p->subtype = JPACKET__ERROR;
-        else if(strcmp(val,"invisible") == 0)
-            p->subtype = JPACKET__INVISIBLE;
-        else if(*val == 's' || *val == 'u')
-            p->type = JPACKET_S10N;
-        else if(strcmp(val,"available") == 0)
-        { /* someone is using type='available' which is frowned upon */
-            xmlnode_hide_attrib(x,"type");
-            p->subtype = JPACKET__AVAILABLE;
-        }else
-            p->type = JPACKET_UNKNOWN;
-    }else if(strncmp(xmlnode_get_name(x),"iq",2) == 0)
-    {
-        p->type = JPACKET_IQ;
-        p->iq = xmlnode_get_tag(x,"?xmlns");
-        p->iqns = xmlnode_get_attrib(p->iq,"xmlns");
-    }
-
-    /* set up the jids if any, flag packet as unknown if they are unparseable */
-    val = xmlnode_get_attrib(x,"to");
-    if(val != NULL)
-        if((p->to = jid_new(p->p, val)) == NULL)
-            p->type = JPACKET_UNKNOWN;
-    val = xmlnode_get_attrib(x,"from");
-    if(val != NULL)
-        if((p->from = jid_new(p->p, val)) == NULL)
-            p->type = JPACKET_UNKNOWN;
-
-    return p;
-}
-
-
-int jpacket_subtype(jpacket p)
-{
-    char *type;
-    int ret = p->subtype;
-
-    if(ret != JPACKET__UNKNOWN)
-        return ret;
-
-    ret = JPACKET__NONE; /* default, when no type attrib is specified */
-    type = xmlnode_get_attrib(p->x, "type");
-    if(j_strcmp(type,"error") == 0)
-        ret = JPACKET__ERROR;
-    else
-        switch(p->type)
-        {
-        case JPACKET_MESSAGE:
-            if(j_strcmp(type,"chat") == 0)
-                ret = JPACKET__CHAT;
-            else if(j_strcmp(type,"groupchat") == 0)
-                ret = JPACKET__GROUPCHAT;
-            else if(j_strcmp(type,"headline") == 0)
-                ret = JPACKET__HEADLINE;
-            break;
-        case JPACKET_S10N:
-            if(j_strcmp(type,"subscribe") == 0)
-                ret = JPACKET__SUBSCRIBE;
-            else if(j_strcmp(type,"subscribed") == 0)
-                ret = JPACKET__SUBSCRIBED;
-            else if(j_strcmp(type,"unsubscribe") == 0)
-                ret = JPACKET__UNSUBSCRIBE;
-            else if(j_strcmp(type,"unsubscribed") == 0)
-                ret = JPACKET__UNSUBSCRIBED;
-            break;
-        case JPACKET_IQ:
-            if(j_strcmp(type,"get") == 0)
-                ret = JPACKET__GET;
-            else if(j_strcmp(type,"set") == 0)
-                ret = JPACKET__SET;
-            else if(j_strcmp(type,"result") == 0)
-                ret = JPACKET__RESULT;
-            break;
-        }
-
-    p->subtype = ret;
-    return ret;
-}
--- a/src/protocols/jabber/jutil.c	Mon Sep 29 13:00:55 2003 +0000
+++ b/src/protocols/jabber/jutil.c	Mon Sep 29 15:23:19 2003 +0000
@@ -1,295 +1,185 @@
-/* --------------------------------------------------------------------------
- *
- * License
+/*
+ * gaim - Jabber Protocol Plugin
  *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
+ * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
  *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
+ * 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.
  *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
+ * 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
  *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
+ */
+#include "internal.h"
+#include "server.h"
+
+#include "presence.h"
+#include "jutil.h"
 
-#include "lib.h"
+time_t str_to_time(const char *timestamp)
+{
+	struct tm t;
+	time_t retval = 0;
+	char buf[32]; 
+	char *c;
+	int tzoff = 0;
 
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
+	time(&retval);
+	localtime_r(&retval, &t);
+
+	snprintf(buf, sizeof(buf), "%s", timestamp);
+	c = buf;
 
-/* util for making presence packets */
-xmlnode jutil_presnew(int type, char *to, char *status)
-{
-    xmlnode pres;
+	/* 4 digit year */
+	if(!sscanf(c, "%04d", &t.tm_year)) return 0;
+	c+=4;
+	if(*c == '-')
+        c++;
 
-    pres = xmlnode_new_tag("presence");
-    switch(type)
-    {
-    case JPACKET__SUBSCRIBE:
-        xmlnode_put_attrib(pres,"type","subscribe");
-        break;
-    case JPACKET__UNSUBSCRIBE:
-        xmlnode_put_attrib(pres,"type","unsubscribe");
-        break;
-    case JPACKET__SUBSCRIBED:
-        xmlnode_put_attrib(pres,"type","subscribed");
-        break;
-    case JPACKET__UNSUBSCRIBED:
-        xmlnode_put_attrib(pres,"type","unsubscribed");
-        break;
-    case JPACKET__PROBE:
-        xmlnode_put_attrib(pres,"type","probe");
-        break;
-    case JPACKET__UNAVAILABLE:
-        xmlnode_put_attrib(pres,"type","unavailable");
-        break;
-    case JPACKET__INVISIBLE:
-        xmlnode_put_attrib(pres,"type","invisible");
-        break;
-    }
-    if(to != NULL)
-        xmlnode_put_attrib(pres,"to",to);
-    if(status != NULL)
-        xmlnode_insert_cdata(xmlnode_insert_tag(pres,"status"),status,strlen(status));
+    t.tm_year -= 1900;
+
+    /* 2 digit month */
+    if(!sscanf(c, "%02d", &t.tm_mon)) return 0;
+    c+=2;
+    if(*c == '-')
+        c++;
+
+    t.tm_mon -= 1;
 
-    return pres;
-}
+    /* 2 digit day */
+    if(!sscanf(c, "%02d", &t.tm_mday)) return 0;
+    c+=2;
+    if(*c == 'T') { /* we have more than a date, keep going */
+        c++; /* skip the "T" */
 
-/* util for making IQ packets */
-xmlnode jutil_iqnew(int type, char *ns)
-{
-    xmlnode iq;
+        /* 2 digit hour */
+        if(sscanf(c, "%02d:%02d:%02d", &t.tm_hour, &t.tm_min, &t.tm_sec)) {
+            int tzhrs, tzmins;
+            c+=8;
+            if(*c == '.') /* dealing with precision we don't care about */
+                c += 4;
 
-    iq = xmlnode_new_tag("iq");
-    switch(type)
-    {
-    case JPACKET__GET:
-        xmlnode_put_attrib(iq,"type","get");
-        break;
-    case JPACKET__SET:
-        xmlnode_put_attrib(iq,"type","set");
-        break;
-    case JPACKET__RESULT:
-        xmlnode_put_attrib(iq,"type","result");
-        break;
-    case JPACKET__ERROR:
-        xmlnode_put_attrib(iq,"type","error");
-        break;
-    }
-    xmlnode_put_attrib(xmlnode_insert_tag(iq,"query"),"xmlns",ns);
-
-    return iq;
-}
-
-/* util for making message packets */
-xmlnode jutil_msgnew(char *type, char *to, char *subj, char *body)
-{
-    xmlnode msg;
+            if((*c == '+' || *c == '-') &&
+                    sscanf(c+1, "%02d:%02d", &tzhrs, &tzmins)) {
+                tzoff = tzhrs*60*60 + tzmins*60;
+                if(*c == '+')
+                    tzoff *= -1;
+            }
 
-    msg = xmlnode_new_tag("message");
-    xmlnode_put_attrib (msg, "type", type);
-    xmlnode_put_attrib (msg, "to", to);
-
-    if (subj)
-    {
-	xmlnode_insert_cdata (xmlnode_insert_tag (msg, "subject"), subj, strlen (subj));
+#ifdef HAVE_TM_GMTOFF
+                tzoff += t.tm_gmtoff;
+#else
+#   ifdef HAVE_TIMEZONE
+                tzset();    /* making sure */
+                tzoff -= timezone;
+#   endif
+#endif
+        }
     }
-
-    xmlnode_insert_cdata (xmlnode_insert_tag (msg, "body"), body, strlen (body));
+    retval = mktime(&t);
 
-    return msg;
-}
+    retval += tzoff;
 
-/* util for making stream packets */
-xmlnode jutil_header(char* xmlns, char* server)
-{
-     xmlnode result;
-     if ((xmlns == NULL)||(server == NULL))
-	  return NULL;
-     result = xmlnode_new_tag("stream:stream");
-     xmlnode_put_attrib(result, "xmlns:stream", "http://etherx.jabber.org/streams");
-     xmlnode_put_attrib(result, "xmlns", xmlns);
-     xmlnode_put_attrib(result, "to", server);
-
-     return result;
+    return retval;
 }
 
-/* returns the priority on a presence packet */
-int jutil_priority(xmlnode x)
-{
-    char *str;
-    int p;
-
-    if(x == NULL)
-        return -1;
-
-    if(xmlnode_get_attrib(x,"type") != NULL)
-        return -1;
-
-    x = xmlnode_get_tag(x,"priority");
-    if(x == NULL)
-        return 0;
-
-    str = xmlnode_get_data((x));
-    if(str == NULL)
-        return 0;
-
-    p = atoi(str);
-    if(p >= 0)
-        return p;
-    else
-        return 0;
-}
-
-void jutil_tofrom(xmlnode x)
-{
-    char *to, *from;
-
-    to = xmlnode_get_attrib(x,"to");
-    from = xmlnode_get_attrib(x,"from");
-    xmlnode_put_attrib(x,"from",to);
-    xmlnode_put_attrib(x,"to",from);
-}
-
-xmlnode jutil_iqresult(xmlnode x)
-{
-    xmlnode cur;
-
-    jutil_tofrom(x);
-
-    xmlnode_put_attrib(x,"type","result");
-
-    /* hide all children of the iq, they go back empty */
-    for(cur = xmlnode_get_firstchild(x); cur != NULL; cur = xmlnode_get_nextsibling(cur))
-        xmlnode_hide(cur);
-
-    return x;
-}
-
-char *jutil_timestamp(void)
-{
-    time_t t;
-    struct tm *new_time;
-    static char timestamp[18];
-    int ret;
-
-    t = time(NULL);
-
-    if(t == (time_t)-1)
-        return NULL;
-    new_time = gmtime(&t);
-
-    ret = snprintf(timestamp, 18, "%d%02d%02dT%02d:%02d:%02d", 1900+new_time->tm_year,
-                   new_time->tm_mon+1, new_time->tm_mday, new_time->tm_hour,
-                   new_time->tm_min, new_time->tm_sec);
-
-    if(ret == -1)
-        return NULL;
-
-    return timestamp;
+const char *jabber_get_state_string(int s) {
+	switch(s) {
+		case JABBER_STATE_AWAY:
+			return _("Away");
+			break;
+		case JABBER_STATE_CHAT:
+			return _("Chatty");
+			break;
+		case JABBER_STATE_XA:
+			return _("Extended Away");
+			break;
+		case JABBER_STATE_DND:
+			return _("Do Not Disturb");
+			break;
+		default:
+			return _("Available");
+			break;
+	}
 }
 
-void jutil_error(xmlnode x, terror E)
+JabberID*
+jabber_id_new(const char *str)
 {
-    xmlnode err;
-    char code[4];
+	char *at;
+	char *slash;
+
+	JabberID *jid;
 
-    xmlnode_put_attrib(x,"type","error");
-    err = xmlnode_insert_tag(x,"error");
+	if(!str)
+		return NULL;
 
-    snprintf(code,4,"%d",E.code);
-    xmlnode_put_attrib(err,"code",code);
-    if(E.msg != NULL)
-        xmlnode_insert_cdata(err,E.msg,strlen(E.msg));
+	jid = g_new0(JabberID, 1);
+
+	at = strchr(str, '@');
+	slash = strchr(str, '/');
 
-    jutil_tofrom(x);
-}
-
-void jutil_delay(xmlnode msg, char *reason)
-{
-    xmlnode delay;
+	if(at) {
+		jid->node = g_strndup(str, at-str);
+		if(slash) {
+			jid->domain = g_strndup(at+1, slash-(at+1));
+			jid->resource = g_strdup(slash+1);
+		} else {
+			jid->domain = g_strdup(at+1);
+		}
+	} else {
+		if(slash) {
+			jid->domain = g_strndup(str, slash-str);
+			jid->resource = g_strdup(slash+1);
+		} else {
+			jid->domain = g_strdup(str);
+		}
+	}
 
-    delay = xmlnode_insert_tag(msg,"x");
-    xmlnode_put_attrib(delay,"xmlns",NS_DELAY);
-    xmlnode_put_attrib(delay,"from",xmlnode_get_attrib(msg,"to"));
-    xmlnode_put_attrib(delay,"stamp",jutil_timestamp());
-    if(reason != NULL)
-        xmlnode_insert_cdata(delay,reason,strlen(reason));
+	return jid;
 }
 
-#define KEYBUF 100
-
-char *jutil_regkey(char *key, char *seed)
+void
+jabber_id_free(JabberID *jid)
 {
-    static char keydb[KEYBUF][41];
-    static char seeddb[KEYBUF][41];
-    static int last = -1;
-    char *str, strint[32];
-    int i;
-
-    /* blanket the keydb first time */
-    if(last == -1)
-    {
-        last = 0;
-        memset(&keydb,0,KEYBUF*41);
-        memset(&seeddb,0,KEYBUF*41);
-        srand(time(NULL));
-    }
-
-    /* creation phase */
-    if(key == NULL && seed != NULL)
-    {
-        /* create a random key hash and store it */
-        sprintf(strint,"%d",rand());
-        strcpy(keydb[last],shahash(strint));
-
-        /* store a hash for the seed associated w/ this key */
-        strcpy(seeddb[last],shahash(seed));
-
-        /* return it all */
-        str = keydb[last];
-        last++;
-        if(last == KEYBUF) last = 0;
-        return str;
-    }
-
-    /* validation phase */
-    str = shahash(seed);
-    for(i=0;i<KEYBUF;i++)
-        if(j_strcmp(keydb[i],key) == 0 && j_strcmp(seeddb[i],str) == 0)
-        {
-            seeddb[i][0] = '\0'; /* invalidate this key */
-            return keydb[i];
-        }
-
-    return NULL;
+	if(jid) {
+		if(jid->node)
+			g_free(jid->node);
+		if(jid->domain)
+			g_free(jid->domain);
+		if(jid->resource)
+			g_free(jid->resource);
+		g_free(jid);
+	}
 }
 
+
+const char *jabber_get_resource(const char *jid)
+{
+	char *slash;
+
+	slash = strrchr(jid, '/');
+	if(slash)
+		return slash+1;
+	else
+		return NULL;
+}
+
+char *jabber_get_bare_jid(const char *jid)
+{
+	char *slash;
+	slash = strrchr(jid, '/');
+
+	if(slash)
+		return g_strndup(jid, slash - jid);
+	else
+		return g_strdup(jid);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/jutil.h	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,41 @@
+/**
+ * @file jutil.h utility functions
+ *
+ * gaim
+ *
+ * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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
+ */
+#ifndef _GAIM_JABBER_JID_H_
+#define _GAIM_JABBER_JID_H_
+
+
+typedef struct _JabberID {
+	char *node;
+	char *domain;
+	char *resource;
+} JabberID;
+
+JabberID* jabber_id_new(const char *str);
+void jabber_id_free(JabberID *jid);
+
+const char *jabber_get_resource(const char *jid);
+char *jabber_get_bare_jid(const char *jid);
+
+time_t str_to_time(const char *timestamp);
+const char *jabber_get_state_string(int state);
+
+#endif /* _GAIM_JABBER_JID_H_ */
--- a/src/protocols/jabber/karma.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,144 +0,0 @@
-/* --------------------------------------------------------------------------
- *
- * License
- *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
- *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
- *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
-#include "lib.h"
-
-void karma_copy(struct karma *new, struct karma *old)
-{
-    new->init        = old->init;
-    new->val         = old->val;
-    new->bytes       = old->bytes;
-    new->max         = old->max;
-    new->inc         = old->inc;
-    new->dec         = old->dec;
-    new->penalty     = old->penalty;
-    new->restore     = old->restore;
-    new->last_update = old->last_update;
-    new->reset_meter = old->reset_meter;
-}
-
-struct karma *karma_new(pool p)
-{
-    struct karma *new;
-    if(p == NULL)
-        return NULL;
-
-    new          = pmalloco(p, sizeof(struct karma));
-    new->init    = 0;
-    new->bytes   = 0;
-    new->val     = KARMA_INIT;
-    new->max     = KARMA_MAX;
-    new->inc     = KARMA_INC;
-    new->dec     = KARMA_DEC;
-    new->penalty = KARMA_PENALTY;
-    new->restore = KARMA_RESTORE;
-    new->last_update = 0;
-    new->reset_meter = KARMA_RESETMETER;
-
-    return new;
-}
-
-void karma_increment(struct karma *k)
-{
-    /* set the current time, and check if we can increment */
-    time_t cur_time = time(NULL);
-    int punishment_over = 0;
-    
-    /* only increment every KARMA_HEARTBEAT seconds */
-    if( ( k->last_update + KARMA_HEARTBEAT > cur_time ) && k->last_update != 0)
-        return;
-
-    /* if incrementing will raise >= 0 */
-    if( ( k->val < 0 ) && ( k->val + k->inc >= 0 ) )
-        punishment_over = 1;
-
-    /* increment the karma value */
-    k->val += k->inc;
-    if( k->val > k->max ) k->val = k->max; /* can only be so good */
-
-    /* lower our byte count, if we have good karma */
-    if( k->val > 0 ) k->bytes -= ( KARMA_READ_MAX(k->val) );
-    if( k->bytes < 0 ) k->bytes = 0;
-
-    /* our karma has *raised* to 0 */
-    if( punishment_over )
-    /* Set Restore value and clear byte meter */
-    {
-        k->val = k->restore;
-        /* Total absolution for transgression */
-        if(k->reset_meter) k->bytes = 0;
-    }
-
-    /* reset out counter */
-    k->last_update = cur_time;
-}
-
-void karma_decrement(struct karma *k, long bytes_read)
-{
-
-    /* Increment the bytes read since last since last karma_increment */
-    k->bytes += bytes_read;
-
-    /* Check if our byte meter has exceeded the Max bytes our meter is allowed. */
-
-    if(k->bytes > KARMA_READ_MAX(k->val))
-    {
-        /* Our meter has exceeded it's allowable lower our karma */
-        k->val -= k->dec;
-
-        /* if below zero, set to penalty */
-        if(k->val <= 0) k->val = k->penalty;
-    }
-}
-
-/* returns 0 on okay check, 1 on bad check */
-int karma_check(struct karma *k,long bytes_read)
-{
-    /* Check the need to increase or decrease karma */
-    karma_increment(k);
-    karma_decrement(k, bytes_read);
-
-    /* check its karma */
-    if(k->val <= 0)
-        return 1; /* bad */
-
-    /* everything is okay */
-    return 0;
-}
--- a/src/protocols/jabber/latin1tab.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
-/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
-/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
-/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
-/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
-/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
-/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
--- a/src/protocols/jabber/lib.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,686 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-#include <sys/types.h>
-/*this must happen before sys/socket.h or freebsd won't compile*/
-
-#ifndef _WIN32
-#include <syslog.h>
-#include <strings.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <unistd.h>
-#else
-#include <winsock.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <time.h>
-
-#include "xmlparse.h"
-
-/*
-**  Arrange to use either varargs or stdargs
-*/
-
-#define MAXSHORTSTR	203		/* max short string length */
-#define QUAD_T	unsigned long long
-
-#ifdef __STDC__
-
-#include <stdarg.h>
-
-# define VA_LOCAL_DECL	va_list ap;
-# define VA_START(f)	va_start(ap, f)
-# define VA_END		va_end(ap)
-
-#else /* __STDC__ */
-
-# include <varargs.h>
-
-# define VA_LOCAL_DECL	va_list ap;
-# define VA_START(f)	va_start(ap)
-# define VA_END		va_end(ap)
-
-#endif /* __STDC__ */
-
-
-#ifndef INCL_LIB_H
-#define INCL_LIB_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifndef HAVE_SNPRINTF
-extern int ap_snprintf(char *, size_t, const char *, ...);
-#define snprintf ap_snprintf
-#endif
-
-#ifndef HAVE_VSNPRINTF
-extern int ap_vsnprintf(char *, size_t, const char *, va_list ap);
-#define vsnprintf ap_vsnprintf
-#endif
-
-#define ZONE zonestr(__FILE__,__LINE__)
-char *zonestr(char *file, int line);
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Pool-based memory management routines                     */
-/*                                                           */
-/* --------------------------------------------------------- */
-
-#undef POOL_DEBUG
-/*
- flip these, this should be a prime number for top # of pools debugging
-#define POOL_DEBUG 40009 
-*/
-
-/* pheap - singular allocation of memory */
-struct pheap
-{
-    void *block;
-    int size, used;
-};
-
-/* pool_cleaner - callback type which is associated
-   with a pool entry; invoked when the pool entry is 
-   free'd */
-typedef void (*pool_cleaner)(void *arg);
-
-/* pfree - a linked list node which stores an
-   allocation chunk, plus a callback */
-struct pfree
-{
-    pool_cleaner f;
-    void *arg;
-    struct pheap *heap;
-    struct pfree *next;
-};
-
-/* pool - base node for a pool. Maintains a linked list
-   of pool entries (pfree) */
-typedef struct pool_struct
-{
-    int size;
-    struct pfree *cleanup;
-    struct pheap *heap;
-#ifdef POOL_DEBUG
-    char name[8], zone[32];
-    int lsize;
-} _pool, *pool;
-#define pool_new() _pool_new(ZONE) 
-#define pool_heap(i) _pool_new_heap(i,ZONE) 
-#else
-} _pool, *pool;
-#define pool_heap(i) _pool_new_heap(i,NULL) 
-#define pool_new() _pool_new(NULL)
-#endif
-
-pool _pool_new(char *zone); /* new pool :) */
-pool _pool_new_heap(int size, char *zone); /* creates a new memory pool with an initial heap size */
-void *pmalloc(pool p, int size); /* wrapper around malloc, takes from the pool, cleaned up automatically */
-void *pmalloc_x(pool p, int size, char c); /* Wrapper around pmalloc which prefils buffer with c */
-void *pmalloco(pool p, int size); /* YAPW for zeroing the block */
-char *pstrdup(pool p, const char *src); /* wrapper around strdup, gains mem from pool */
-void pool_stat(int full); /* print to stderr the changed pools and reset */
-char *pstrdupx(pool p, const char *src); /* temp stub */
-void pool_cleanup(pool p, pool_cleaner f, void *arg); /* calls f(arg) before the pool is freed during cleanup */
-void pool_free(pool p); /* calls the cleanup functions, frees all the data on the pool, and deletes the pool itself */
-int pool_size(pool p); /* returns total bytes allocated in this pool */
-
-
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Socket helper stuff                                       */
-/*                                                           */
-/* --------------------------------------------------------- */
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-#define NETSOCKET_SERVER 0
-#define NETSOCKET_CLIENT 1
-#define NETSOCKET_UDP 2
-
-int make_netsocket(unsigned short port, char *host, int type);
-struct in_addr *make_addr(char *host);
-int set_fd_close_on_exec(int fd, int flag);
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* String management routines                                */
-/*                                                           */
-/* --------------------------------------------------------- */
-char *j_strdup(const char *str); /* provides NULL safe strdup wrapper */
-char *j_strcat(char *dest, char *txt); /* strcpy() clone */
-int j_strcmp(const char *a, const char *b); /* provides NULL safe strcmp wrapper */
-int j_strcasecmp(const char *a, const char *b); /* provides NULL safe strcasecmp wrapper */
-int j_strncmp(const char *a, const char *b, int i); /* provides NULL safe strncmp wrapper */
-int j_strncasecmp(const char *a, const char *b, int i); /* provides NULL safe strncasecmp wrapper */
-int j_strlen(const char *a); /* provides NULL safe strlen wrapper */
-int j_atoi(const char *a, int def); /* checks for NULL and uses default instead, convienence */
-void str_b64decode(char *str); /* what it says */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* SHA calculations                                          */
-/*                                                           */
-/* --------------------------------------------------------- */
-#if (SIZEOF_INT == 4)
-typedef unsigned int uint32;
-#elif (SIZEOF_SHORT == 4)
-typedef unsigned short uint32;
-#else
-typedef unsigned int uint32;
-#endif /* HAVEUINT32 */
-
-char *shahash(char *str);	/* NOT THREAD SAFE */
-void shahash_r(const char* str, char hashbuf[40]); /* USE ME */
-
-int strprintsha(char *dest, int *hashval);
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Hashtable functions                                       */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef struct xhn_struct
-{
-    struct xhn_struct *next;
-    const char *key;
-    void *val;
-} *xhn, _xhn;
-
-typedef struct xht_struct
-{
-    pool p;
-    int prime;
-    struct xhn_struct *zen;
-} *xht, _xht;
-
-xht xhash_new(int prime);
-void xhash_put(xht h, const char *key, void *val);
-void *xhash_get(xht h, const char *key);
-void xhash_zap(xht h, const char *key);
-void xhash_free(xht h);
-typedef void (*xhash_walker)(xht h, const char *key, void *val, void *arg);
-void xhash_walk(xht h, xhash_walker w, void *arg);
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* DEPRECIATED Hashtable functions                           */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef int (*KEYHASHFUNC)(const void *key);
-typedef int (*KEYCOMPAREFUNC)(const void *key1, const void *key2);
-typedef int (*TABLEWALKFUNC)(void *user_data, const void *key, void *data);
-
-typedef void *HASHTABLE;
-
-HASHTABLE ghash_create(int buckets, KEYHASHFUNC hash, KEYCOMPAREFUNC cmp);
-HASHTABLE ghash_create_pool(pool p, int buckets, KEYHASHFUNC hash, KEYCOMPAREFUNC cmp);
-void ghash_destroy(HASHTABLE tbl);
-void *ghash_get(HASHTABLE tbl, const void *key);
-int ghash_put(HASHTABLE tbl, const void *key, void *value);
-int ghash_remove(HASHTABLE tbl, const void *key);
-int ghash_walk(HASHTABLE tbl, TABLEWALKFUNC func, void *user_data);
-int str_hash_code(const char *s);
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* XML escaping utils                                        */
-/*                                                           */
-/* --------------------------------------------------------- */
-char *strescape(pool p, char *buf); /* Escape <>&'" chars */
-char *strunescape(pool p, char *buf);
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* String pools (spool) functions                            */
-/*                                                           */
-/* --------------------------------------------------------- */
-struct spool_node
-{
-    char *c;
-    struct spool_node *next;
-};
-
-typedef struct spool_struct
-{
-    pool p;
-    int len;
-    struct spool_node *last;
-    struct spool_node *first;
-} *spool;
-
-spool spool_new(pool p); /* create a string pool */
-void spooler(spool s, ...); /* append all the char * args to the pool, terminate args with s again */
-char *spool_print(spool s); /* return a big string */
-void spool_add(spool s, char *str); /* add a single char to the pool */
-char *spools(pool p, ...); /* wrap all the spooler stuff in one function, the happy fun ball! */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* xmlnodes - Document Object Model                          */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define NTYPE_TAG    0
-#define NTYPE_ATTRIB 1
-#define NTYPE_CDATA  2
-
-#define NTYPE_LAST   2
-#define NTYPE_UNDEF  -1
-
-/* -------------------------------------------------------------------------- 
-   Node structure. Do not use directly! Always use accessor macros 
-   and methods!
-   -------------------------------------------------------------------------- */
-typedef struct xmlnode_t
-{
-     char*               name;
-     unsigned short      type;
-     char*               data;
-     int                 data_sz;
-     int                 complete;
-     pool               p;
-     struct xmlnode_t*  parent;
-     struct xmlnode_t*  firstchild; 
-     struct xmlnode_t*  lastchild;
-     struct xmlnode_t*  prev; 
-     struct xmlnode_t*  next;
-     struct xmlnode_t*  firstattrib;
-     struct xmlnode_t*  lastattrib;
-} _xmlnode, *xmlnode;
-
-/* Node creation routines */
-xmlnode  xmlnode_wrap(xmlnode x,const char* wrapper);
-xmlnode  xmlnode_new_tag(const char* name);
-xmlnode  xmlnode_new_tag_pool(pool p, const char* name);
-xmlnode  xmlnode_insert_tag(xmlnode parent, const char* name); 
-xmlnode  xmlnode_insert_cdata(xmlnode parent, const char* CDATA, unsigned int size);
-xmlnode  xmlnode_insert_tag_node(xmlnode parent, xmlnode node);
-void     xmlnode_insert_node(xmlnode parent, xmlnode node);
-xmlnode  xmlnode_str(char *str, int len);
-xmlnode  xmlnode_file(char *file);
-char*    xmlnode_file_borked(char *file); /* same as _file but returns the parsing error */
-xmlnode  xmlnode_dup(xmlnode x); /* duplicate x */
-xmlnode  xmlnode_dup_pool(pool p, xmlnode x);
-
-/* Node Memory Pool */
-pool xmlnode_pool(xmlnode node);
-xmlnode _xmlnode_new(pool p, const char *name, unsigned int type);
-
-/* Node editing */
-void xmlnode_hide(xmlnode child);
-void xmlnode_hide_attrib(xmlnode parent, const char *name);
-
-/* Node deletion routine, also frees the node pool! */
-void xmlnode_free(xmlnode node);
-
-/* Locates a child tag by name and returns it */
-xmlnode  xmlnode_get_tag(xmlnode parent, const char* name);
-char* xmlnode_get_tag_data(xmlnode parent, const char* name);
-
-/* Attribute accessors */
-void     xmlnode_put_attrib(xmlnode owner, const char* name, const char* value);
-char*    xmlnode_get_attrib(xmlnode owner, const char* name);
-void     xmlnode_put_expat_attribs(xmlnode owner, const char** atts);
-
-/* Bastard am I, but these are fun for internal use ;-) */
-void     xmlnode_put_vattrib(xmlnode owner, const char* name, void *value);
-void*    xmlnode_get_vattrib(xmlnode owner, const char* name);
-
-/* Node traversal routines */
-xmlnode  xmlnode_get_firstattrib(xmlnode parent);
-xmlnode  xmlnode_get_firstchild(xmlnode parent);
-xmlnode  xmlnode_get_lastchild(xmlnode parent);
-xmlnode  xmlnode_get_nextsibling(xmlnode sibling);
-xmlnode  xmlnode_get_prevsibling(xmlnode sibling);
-xmlnode  xmlnode_get_parent(xmlnode node);
-
-/* Node information routines */
-char*    xmlnode_get_name(xmlnode node);
-char*    xmlnode_get_data(xmlnode node);
-int      xmlnode_get_datasz(xmlnode node);
-int      xmlnode_get_type(xmlnode node);
-
-int      xmlnode_has_children(xmlnode node);
-int      xmlnode_has_attribs(xmlnode node);
-
-/* Node-to-string translation */
-char*    xmlnode2str(xmlnode node);
-
-/* Node-to-terminated-string translation 
-   -- useful for interfacing w/ scripting langs */
-char*    xmlnode2tstr(xmlnode node);
-
-int      xmlnode_cmp(xmlnode a, xmlnode b); /* compares a and b for equality */
-
-int      xmlnode2file(char *file, xmlnode node); /* writes node to file */
-
-/* Expat callbacks */
-void expat_startElement(void* userdata, const char* name, const char** atts);
-void expat_endElement(void* userdata, const char* name);
-void expat_charData(void* userdata, const char* s, int len);
-
-/***********************
- * XSTREAM Section
- ***********************/
-
-#define XSTREAM_MAXNODE 1000000
-#define XSTREAM_MAXDEPTH 100
-
-#define XSTREAM_ROOT        0 /* root element */
-#define XSTREAM_NODE        1 /* normal node */
-#define XSTREAM_CLOSE       2 /* closed </stream:stream> */
-#define XSTREAM_ERR         4 /* parser error */
-
-typedef void (*xstream_onNode)(int type, xmlnode x, void *arg); /* xstream event handler */
-
-typedef struct xstream_struct
-{
-    XML_Parser parser;
-    xmlnode node;
-    char *cdata;
-    int cdata_len;
-    pool p;
-    xstream_onNode f;
-    void *arg;
-    int status;
-    int depth;
-} *xstream, _xstream;
-
-xstream xstream_new(pool p, xstream_onNode f, void *arg); /* create a new xstream */
-int xstream_eat(xstream xs, char *buff, int len); /* parse new data for this xstream, returns last XSTREAM_* status */
-
-/* convience functions */
-xmlnode xstream_header(char *namespace, char *to, char *from);
-char *xstream_header_char(xmlnode x);
-
-
-typedef struct {
-  unsigned long H[5];
-  unsigned long W[80];
-  int lenW;
-  unsigned long sizeHi,sizeLo;
-} j_SHA_CTX;
-
-
-void shaInit(j_SHA_CTX *ctx);
-void shaUpdate(j_SHA_CTX *ctx, unsigned char *dataIn, int len);
-void shaFinal(j_SHA_CTX *ctx, unsigned char hashout[20]);
-void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]);
-
-/********** END OLD libxode.h BEGIN OLD jabber.h *************/
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* JID structures & constants                                */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define JID_RESOURCE 1
-#define JID_USER     2
-#define JID_SERVER   4
-
-typedef struct jid_struct
-{ 
-    pool               p;
-    char*              resource;
-    char*              user;
-    char*              server;
-    char*              full;
-    struct jid_struct *next; /* for lists of jids */
-} *jid;
-  
-jid     jid_new(pool p, char *idstr);	       /* Creates a jabber id from the idstr */
-void    jid_set(jid id, char *str, int item);  /* Individually sets jid components */
-char*   jid_full(jid id);		       /* Builds a string type=user/resource@server from the jid data */
-int     jid_cmp(jid a, jid b);		       /* Compares two jid's, returns 0 for perfect match */
-int     jid_cmpx(jid a, jid b, int parts);     /* Compares just the parts specified as JID_|JID_ */
-jid     jid_append(jid a, jid b);	       /* Appending b to a (list), no dups */
-xmlnode jid_xres(jid id);		       /* Returns xmlnode representation of the resource?query=string */
-xmlnode jid_nodescan(jid id, xmlnode x);       /* Scans the children of the node for a matching jid attribute */
-jid     jid_user(jid a);                       /* returns the same jid but just of the user@host part */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* JPacket structures & constants                            */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define JPACKET_UNKNOWN   0x00
-#define JPACKET_MESSAGE   0x01
-#define JPACKET_PRESENCE  0x02
-#define JPACKET_IQ        0x04
-#define JPACKET_S10N      0x08
-
-#define JPACKET__UNKNOWN      0
-#define JPACKET__NONE         1
-#define JPACKET__ERROR        2
-#define JPACKET__CHAT         3
-#define JPACKET__GROUPCHAT    4
-#define JPACKET__GET          5
-#define JPACKET__SET          6
-#define JPACKET__RESULT       7
-#define JPACKET__SUBSCRIBE    8
-#define JPACKET__SUBSCRIBED   9
-#define JPACKET__UNSUBSCRIBE  10
-#define JPACKET__UNSUBSCRIBED 11
-#define JPACKET__AVAILABLE    12
-#define JPACKET__UNAVAILABLE  13
-#define JPACKET__PROBE        14
-#define JPACKET__HEADLINE     15
-#define JPACKET__INVISIBLE    16
-
-typedef struct jpacket_struct
-{
-    unsigned char type;
-    int           subtype;
-    int           flag;
-    void*         aux1;
-    xmlnode       x;
-    jid           to;
-    jid           from;
-    char*         iqns;
-    xmlnode       iq;
-    pool          p;
-} *jpacket, _jpacket;
- 
-jpacket jpacket_new(xmlnode x);	    /* Creates a jabber packet from the xmlnode */
-jpacket jpacket_reset(jpacket p);   /* Resets the jpacket values based on the xmlnode */
-int     jpacket_subtype(jpacket p); /* Returns the subtype value (looks at xmlnode for it) */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Presence Proxy DB structures & constants                  */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef struct ppdb_struct
-{			      
-    jid     id;		       /* entry data */
-    int     pri;
-    xmlnode x;
-    struct ppdb_struct* user;  /* linked list for user@server */
-    pool                p;     /* db-level data */
-    struct ppdb_struct* next;
-} _ppdb, *ppdb;
-
-ppdb    ppdb_insert(ppdb db, jid id, xmlnode x); /* Inserts presence into the proxy */
-xmlnode ppdb_primary(ppdb db, jid id);		 /* Fetches the matching primary presence for the id */
-void    ppdb_free(ppdb db);			 /* Frees the db and all entries */
-xmlnode ppdb_get(ppdb db, jid id);		 /* Called successively to return each presence xmlnode */
-						 /*   for the id and children, returns NULL at the end */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Simple Jabber Rate limit functions                        */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef struct jlimit_struct
-{
-    char *key;
-    int start;
-    int points;
-    int maxt, maxp;
-    pool p;
-} *jlimit, _jlimit;
- 
-jlimit jlimit_new(int maxt, int maxp);
-void jlimit_free(jlimit r);
-int jlimit_check(jlimit r, char *key, int points);
-
-
-/* #define KARMA_DEBUG */
-/* default to disable karma */
-#define KARMA_READ_MAX(k) (abs(k)*100) /* how much you are allowed to read off the sock */
-#define KARMA_INIT 5   /* internal "init" value */
-#define KARMA_HEARTBEAT 2 /* seconds to register for heartbeat */
-#define KARMA_MAX 10     /* total max karma you can have */
-#define KARMA_INC 1      /* how much to increment every KARMA_HEARTBEAT seconds */
-#define KARMA_DEC 0      /* how much to penalize for reading KARMA_READ_MAX in
-                            KARMA_HEARTBEAT seconds */
-#define KARMA_PENALTY -5 /* where you go when you hit 0 karma */
-#define KARMA_RESTORE 5  /* where you go when you payed your penelty or INIT */
-#define KARMA_RESETMETER 0 /* Reset byte meter on restore default is falst */
-
-struct karma
-{
-    int init; /* struct initialized */
-    int reset_meter; /* reset the byte meter on restore */
-    int val; /* current karma value */
-    long bytes; /* total bytes read (in that time period) */
-    int max;  /* max karma you can have */
-    int inc,dec; /* how much to increment/decrement */
-    int penalty,restore; /* what penalty (<0) or restore (>0) */
-    time_t last_update; /* time this was last incremented */
-};
-
-struct karma *karma_new(pool p); /* creates a new karma object, with default values */
-void karma_copy(struct karma *new, struct karma *old); /* makes a copy of old in new */
-void karma_increment(struct karma *k);          /* inteligently increments karma */
-void karma_decrement(struct karma *k, long bytes_read); /* inteligently decrements karma */
-int karma_check(struct karma *k,long bytes_read); /* checks to see if we have good karma */
-
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Error structures & constants                              */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef struct terror_struct
-{
-    int  code;
-    char msg[64];
-} terror;
-
-#define TERROR_BAD           (terror){400,"Bad Request"}
-#define TERROR_AUTH          (terror){401,"Unauthorized"}
-#define TERROR_PAY           (terror){402,"Payment Required"}
-#define TERROR_FORBIDDEN     (terror){403,"Forbidden"}
-#define TERROR_NOTFOUND      (terror){404,"Not Found"}
-#define TERROR_NOTALLOWED    (terror){405,"Not Allowed"}
-#define TERROR_NOTACCEPTABLE (terror){406,"Not Acceptable"}
-#define TERROR_REGISTER      (terror){407,"Registration Required"}
-#define TERROR_REQTIMEOUT    (terror){408,"Request Timeout"}
-#define TERROR_CONFLICT      (terror){409,"Conflict"}
-
-#define TERROR_INTERNAL   (terror){500,"Internal Server Error"}
-#define TERROR_NOTIMPL    (terror){501,"Not Implemented"}
-#define TERROR_EXTERNAL   (terror){502,"Remote Server Error"}
-#define TERROR_UNAVAIL    (terror){503,"Service Unavailable"}
-#define TERROR_EXTTIMEOUT (terror){504,"Remote Server Timeout"}
-#define TERROR_DISCONNECTED (terror){510,"Disconnected"}
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Namespace constants                                       */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define NSCHECK(x,n) (j_strcmp(xmlnode_get_attrib(x,"xmlns"),n) == 0)
-
-#define NS_CLIENT    "jabber:client"
-#define NS_SERVER    "jabber:server"
-#define NS_AUTH      "jabber:iq:auth"
-#define NS_REGISTER  "jabber:iq:register"
-#define NS_ROSTER    "jabber:iq:roster"
-#define NS_OFFLINE   "jabber:x:offline"
-#define NS_AGENT     "jabber:iq:agent"
-#define NS_AGENTS    "jabber:iq:agents"
-#define NS_DELAY     "jabber:x:delay"
-#define NS_VERSION   "jabber:iq:version"
-#define NS_TIME      "jabber:iq:time"
-#define NS_VCARD     "vcard-temp"
-#define NS_PRIVATE   "jabber:iq:private"
-#define NS_SEARCH    "jabber:iq:search"
-#define NS_OOB       "jabber:iq:oob"
-#define NS_XOOB      "jabber:x:oob"
-#define NS_ADMIN     "jabber:iq:admin"
-#define NS_FILTER    "jabber:iq:filter"
-#define NS_AUTH_0K   "jabber:iq:auth:0k"
-#define NS_BROWSE    "jabber:iq:browse"
-#define NS_EVENT     "jabber:x:event"
-#define NS_CONFERENCE "jabber:iq:conference"
-#define NS_SIGNED    "jabber:x:signed"
-#define NS_ENCRYPTED "jabber:x:encrypted"
-#define NS_GATEWAY   "jabber:iq:gateway"
-#define NS_LAST      "jabber:iq:last"
-#define NS_ENVELOPE  "jabber:x:envelope"
-#define NS_EXPIRE    "jabber:x:expire"
-#define NS_XHTML     "http://www.w3.org/1999/xhtml"
-
-#define NS_XDBGINSERT "jabber:xdb:ginsert"
-#define NS_XDBNSLIST  "jabber:xdb:nslist"
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* JUtil functions                                           */
-/*                                                           */
-/* --------------------------------------------------------- */
-xmlnode jutil_presnew(int type, char *to, char *status); /* Create a skeleton presence packet */
-xmlnode jutil_iqnew(int type, char *ns);		 /* Create a skeleton iq packet */
-xmlnode jutil_msgnew(char *type, char *to, char *subj, char *body);
-							 /* Create a skeleton message packet */
-xmlnode jutil_header(char* xmlns, char* server);	 /* Create a skeleton stream packet */
-int     jutil_priority(xmlnode x);			 /* Determine priority of this packet */
-void    jutil_tofrom(xmlnode x);			 /* Swaps to/from fields on a packet */
-xmlnode jutil_iqresult(xmlnode x);			 /* Generate a skeleton iq/result, given a iq/query */
-char*   jutil_timestamp(void);				 /* Get stringified timestamp */
-void    jutil_error(xmlnode x, terror E);		 /* Append an <error> node to x */
-void    jutil_delay(xmlnode msg, char *reason);		 /* Append a delay packet to msg */
-char*   jutil_regkey(char *key, char *seed);		 /* pass a seed to generate a key, pass the key again to validate (returns it) */
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif	/* INCL_LIB_H */
--- a/src/protocols/jabber/libxode.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,450 +0,0 @@
-#ifndef _WIN32
-#include <syslog.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <netdb.h>
-#include <arpa/inet.h>
-#include <strings.h>
-#include <arpa/nameser.h>
-#include <resolv.h>
-#include <unistd.h>
-#else
-#include <winsock.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/time.h>
-#include <time.h>
-
-#include "xmlparse.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif /* HAVE_CONFIG_H */
-
-/*
-**  Arrange to use either varargs or stdargs
-*/
-
-#define MAXSHORTSTR	203		/* max short string length */
-#define QUAD_T	unsigned long long
-
-#ifdef __STDC__
-
-#include <stdarg.h>
-
-# define VA_LOCAL_DECL	va_list ap;
-# define VA_START(f)	va_start(ap, f)
-# define VA_END		va_end(ap)
-
-#else /* __STDC__ */
-
-# include <varargs.h>
-
-# define VA_LOCAL_DECL	va_list ap;
-# define VA_START(f)	va_start(ap)
-# define VA_END		va_end(ap)
-
-#endif /* __STDC__ */
-
-
-#ifndef INCL_LIBXODE_H
-#define INCL_LIBXODE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifndef HAVE_SNPRINTF
-extern int ap_snprintf(char *, size_t, const char *, ...);
-#define snprintf ap_snprintf
-#endif
-
-#ifndef HAVE_VSNPRINTF
-extern int ap_vsnprintf(char *, size_t, const char *, va_list ap);
-#define vsnprintf ap_vsnprintf
-#endif
-
-#define ZONE zonestr(__FILE__,__LINE__)
-char *zonestr(char *file, int line);
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Pool-based memory management routines                     */
-/*                                                           */
-/* --------------------------------------------------------- */
-
-#undef POOL_DEBUG
-/*
- flip these, this should be a prime number for top # of pools debugging
-#define POOL_DEBUG 40009 
-*/
-
-/* pheap - singular allocation of memory */
-struct pheap
-{
-    void *block;
-    int size, used;
-};
-
-/* pool_cleaner - callback type which is associated
-   with a pool entry; invoked when the pool entry is 
-   free'd */
-typedef void (*pool_cleaner)(void *arg);
-
-/* pfree - a linked list node which stores an
-   allocation chunk, plus a callback */
-struct pfree
-{
-    pool_cleaner f;
-    void *arg;
-    struct pheap *heap;
-    struct pfree *next;
-};
-
-/* pool - base node for a pool. Maintains a linked list
-   of pool entries (pfree) */
-typedef struct pool_struct
-{
-    int size;
-    struct pfree *cleanup;
-    struct pheap *heap;
-#ifdef POOL_DEBUG
-    char name[8], zone[32];
-    int lsize;
-} _pool, *pool;
-#define pool_new() _pool_new(ZONE) 
-#define pool_heap(i) _pool_new_heap(i,ZONE) 
-#else
-} _pool, *pool;
-#define pool_heap(i) _pool_new_heap(i,NULL) 
-#define pool_new() _pool_new(NULL)
-#endif
-
-pool _pool_new(char *zone); /* new pool :) */
-pool _pool_new_heap(int size, char *zone); /* creates a new memory pool with an initial heap size */
-void *pmalloc(pool p, int size); /* wrapper around malloc, takes from the pool, cleaned up automatically */
-void *pmalloc_x(pool p, int size, char c); /* Wrapper around pmalloc which prefils buffer with c */
-void *pmalloco(pool p, int size); /* YAPW for zeroing the block */
-char *pstrdup(pool p, const char *src); /* wrapper around strdup, gains mem from pool */
-void pool_stat(int full); /* print to stderr the changed pools and reset */
-char *pstrdupx(pool p, const char *src); /* temp stub */
-void pool_cleanup(pool p, pool_cleaner f, void *arg); /* calls f(arg) before the pool is freed during cleanup */
-void pool_free(pool p); /* calls the cleanup functions, frees all the data on the pool, and deletes the pool itself */
-int pool_size(pool p); /* returns total bytes allocated in this pool */
-
-
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Socket helper stuff                                       */
-/*                                                           */
-/* --------------------------------------------------------- */
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-#define NETSOCKET_SERVER 0
-#define NETSOCKET_CLIENT 1
-#define NETSOCKET_UDP 2
-
-int make_netsocket(unsigned short port, char *host, int type);
-struct in_addr *make_addr(char *host);
-int set_fd_close_on_exec(int fd, int flag);
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* String management routines                                */
-/*                                                           */
-/* --------------------------------------------------------- */
-char *j_strdup(const char *str); /* provides NULL safe strdup wrapper */
-char *j_strcat(char *dest, char *txt); /* strcpy() clone */
-int j_strcmp(const char *a, const char *b); /* provides NULL safe strcmp wrapper */
-int j_strcasecmp(const char *a, const char *b); /* provides NULL safe strcasecmp wrapper */
-int j_strncmp(const char *a, const char *b, int i); /* provides NULL safe strncmp wrapper */
-int j_strncasecmp(const char *a, const char *b, int i); /* provides NULL safe strncasecmp wrapper */
-int j_strlen(const char *a); /* provides NULL safe strlen wrapper */
-int j_atoi(const char *a, int def); /* checks for NULL and uses default instead, convienence */
-void str_b64decode(char *str); /* what it says */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* SHA calculations                                          */
-/*                                                           */
-/* --------------------------------------------------------- */
-#if (SIZEOF_INT == 4)
-typedef unsigned int uint32;
-#elif (SIZEOF_SHORT == 4)
-typedef unsigned short uint32;
-#else
-typedef unsigned int uint32;
-#endif /* HAVEUINT32 */
-
-int sha_hash(int *data, int *hash);
-int sha_init(int *hash);
-char *shahash(char *str);	/* NOT THREAD SAFE */
-void shahash_r(const char* str, char hashbuf[41]); /* USE ME */
-
-int strprintsha(char *dest, int *hashval);
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* Hashtable functions                                       */
-/*                                                           */
-/* --------------------------------------------------------- */
-typedef int (*KEYHASHFUNC)(const void *key);
-typedef int (*KEYCOMPAREFUNC)(const void *key1, const void *key2);
-typedef int (*TABLEWALKFUNC)(void *user_data, const void *key, void *data);
-
-typedef void *HASHTABLE;
-
-HASHTABLE ghash_create(int buckets, KEYHASHFUNC hash, KEYCOMPAREFUNC cmp);
-void ghash_destroy(HASHTABLE tbl);
-void *ghash_get(HASHTABLE tbl, const void *key);
-int ghash_put(HASHTABLE tbl, const void *key, void *value);
-int ghash_remove(HASHTABLE tbl, const void *key);
-int ghash_walk(HASHTABLE tbl, TABLEWALKFUNC func, void *user_data);
-int str_hash_code(const char *s);
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* XML escaping utils                                        */
-/*                                                           */
-/* --------------------------------------------------------- */
-char *strescape(pool p, char *buf); /* Escape <>&'" chars */
-char *strunescape(pool p, char *buf);
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* String pools (spool) functions                            */
-/*                                                           */
-/* --------------------------------------------------------- */
-struct spool_node
-{
-    char *c;
-    struct spool_node *next;
-};
-
-typedef struct spool_struct
-{
-    pool p;
-    int len;
-    struct spool_node *last;
-    struct spool_node *first;
-} *spool;
-
-spool spool_new(pool p); /* create a string pool */
-void spooler(spool s, ...); /* append all the char * args to the pool, terminate args with s again */
-char *spool_print(spool s); /* return a big string */
-void spool_add(spool s, char *str); /* add a single char to the pool */
-char *spools(pool p, ...); /* wrap all the spooler stuff in one function, the happy fun ball! */
-
-
-/* --------------------------------------------------------- */
-/*                                                           */
-/* xmlnodes - Document Object Model                          */
-/*                                                           */
-/* --------------------------------------------------------- */
-#define NTYPE_TAG    0
-#define NTYPE_ATTRIB 1
-#define NTYPE_CDATA  2
-
-#define NTYPE_LAST   2
-#define NTYPE_UNDEF  -1
-
-/* -------------------------------------------------------------------------- 
-   Node structure. Do not use directly! Always use accessor macros 
-   and methods!
-   -------------------------------------------------------------------------- */
-typedef struct xmlnode_t
-{
-     char*               name;
-     unsigned short      type;
-     char*               data;
-     int                 data_sz;
-     int                 complete;
-     pool               p;
-     struct xmlnode_t*  parent;
-     struct xmlnode_t*  firstchild; 
-     struct xmlnode_t*  lastchild;
-     struct xmlnode_t*  prev; 
-     struct xmlnode_t*  next;
-     struct xmlnode_t*  firstattrib;
-     struct xmlnode_t*  lastattrib;
-} _xmlnode, *xmlnode;
-
-/* Node creation routines */
-xmlnode  xmlnode_wrap(xmlnode x,const char* wrapper);
-xmlnode  xmlnode_new_tag(const char* name);
-xmlnode  xmlnode_new_tag_pool(pool p, const char* name);
-xmlnode  xmlnode_insert_tag(xmlnode parent, const char* name); 
-xmlnode  xmlnode_insert_cdata(xmlnode parent, const char* CDATA, unsigned int size);
-xmlnode  xmlnode_insert_tag_node(xmlnode parent, xmlnode node);
-void     xmlnode_insert_node(xmlnode parent, xmlnode node);
-xmlnode  xmlnode_str(char *str, int len);
-xmlnode  xmlnode_file(char *file);
-xmlnode  xmlnode_dup(xmlnode x); /* duplicate x */
-xmlnode  xmlnode_dup_pool(pool p, xmlnode x);
-
-/* Node Memory Pool */
-pool xmlnode_pool(xmlnode node);
-xmlnode _xmlnode_new(pool p, const char *name, unsigned int type);
-
-/* Node editing */
-void xmlnode_hide(xmlnode child);
-void xmlnode_hide_attrib(xmlnode parent, const char *name);
-
-/* Node deletion routine, also frees the node pool! */
-void xmlnode_free(xmlnode node);
-
-/* Locates a child tag by name and returns it */
-xmlnode  xmlnode_get_tag(xmlnode parent, const char* name);
-char* xmlnode_get_tag_data(xmlnode parent, const char* name);
-
-/* Attribute accessors */
-void     xmlnode_put_attrib(xmlnode owner, const char* name, const char* value);
-char*    xmlnode_get_attrib(xmlnode owner, const char* name);
-void     xmlnode_put_expat_attribs(xmlnode owner, const char** atts);
-
-/* Bastard am I, but these are fun for internal use ;-) */
-void     xmlnode_put_vattrib(xmlnode owner, const char* name, void *value);
-void*    xmlnode_get_vattrib(xmlnode owner, const char* name);
-
-/* Node traversal routines */
-xmlnode  xmlnode_get_firstattrib(xmlnode parent);
-xmlnode  xmlnode_get_firstchild(xmlnode parent);
-xmlnode  xmlnode_get_lastchild(xmlnode parent);
-xmlnode  xmlnode_get_nextsibling(xmlnode sibling);
-xmlnode  xmlnode_get_prevsibling(xmlnode sibling);
-xmlnode  xmlnode_get_parent(xmlnode node);
-
-/* Node information routines */
-char*    xmlnode_get_name(xmlnode node);
-char*    xmlnode_get_data(xmlnode node);
-int      xmlnode_get_datasz(xmlnode node);
-int      xmlnode_get_type(xmlnode node);
-
-int      xmlnode_has_children(xmlnode node);
-int      xmlnode_has_attribs(xmlnode node);
-
-/* Node-to-string translation */
-char*    xmlnode2str(xmlnode node);
-
-/* Node-to-terminated-string translation 
-   -- useful for interfacing w/ scripting langs */
-char*    xmlnode2tstr(xmlnode node);
-
-int      xmlnode_cmp(xmlnode a, xmlnode b); /* compares a and b for equality */
-
-int      xmlnode2file(char *file, xmlnode node); /* writes node to file */
-
-/* Expat callbacks */
-void expat_startElement(void* userdata, const char* name, const char** atts);
-void expat_endElement(void* userdata, const char* name);
-void expat_charData(void* userdata, const char* s, int len);
-
-/***********************
- * XSTREAM Section
- ***********************/
-
-#define XSTREAM_MAXNODE 1000000
-#define XSTREAM_MAXDEPTH 100
-
-#define XSTREAM_ROOT        0 /* root element */
-#define XSTREAM_NODE        1 /* normal node */
-#define XSTREAM_CLOSE       2 /* closed </stream:stream> */
-#define XSTREAM_ERR         4 /* parser error */
-
-typedef void (*xstream_onNode)(int type, xmlnode x, void *arg); /* xstream event handler */
-
-typedef struct xstream_struct
-{
-    XML_Parser parser;
-    xmlnode node;
-    char *cdata;
-    int cdata_len;
-    pool p;
-    xstream_onNode f;
-    void *arg;
-    int status;
-    int depth;
-} *xstream, _xstream;
-
-xstream xstream_new(pool p, xstream_onNode f, void *arg); /* create a new xstream */
-int xstream_eat(xstream xs, char *buff, int len); /* parse new data for this xstream, returns last XSTREAM_* status */
-
-/* convience functions */
-xmlnode xstream_header(char *namespace, char *to, char *from);
-char *xstream_header_char(xmlnode x);
-
-/* SHA.H */
-/* 
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- * 
- * The Original Code is SHA 180-1 Header File
- * 
- * The Initial Developer of the Original Code is Paul Kocher of
- * Cryptography Research.  Portions created by Paul Kocher are 
- * Copyright (C) 1995-9 by Cryptography Research, Inc.  All
- * Rights Reserved.
- * 
- * Contributor(s):
- *
- *     Paul Kocher
- * 
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable 
- * instead of those above.  If you wish to allow use of your 
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL.  If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-
-typedef struct {
-  unsigned long H[5];
-  unsigned long W[80];
-  int lenW;
-  unsigned long sizeHi,sizeLo;
-} SHA_CTX;
-
-
-void shaInit(SHA_CTX *ctx);
-void shaUpdate(SHA_CTX *ctx, unsigned char *dataIn, int len);
-void shaFinal(SHA_CTX *ctx, unsigned char hashout[20]);
-void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]);
-
-
-/* END SHA.H */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* INCL_LIBXODE_H */
--- a/src/protocols/jabber/log.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- *  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.
- *
- *  Jabber
- *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
- */
-
-#include "jabber.h"
-#include "log.h"
-
-#ifdef DEBUG
-
-void jdebug(char *zone, const char *msgfmt, ...)
-{
-    va_list ap;
-    static char loghdr[LOGSIZE_HDR];
-    static char logmsg[LOGSIZE_TAIL];
-    static int size;
-
-    /* XXX: We may want to check the sizes eventually */
-    size = snprintf(loghdr, LOGSIZE_HDR, "debug/%s %s\n", zone, msgfmt);
-
-    va_start(ap, msgfmt);
-    size = vsnprintf(logmsg, LOGSIZE_TAIL, loghdr, ap);
-
-    fprintf(stderr,"%s",logmsg);
-
-    return;
-}
-
-
-#endif  /* DEBUG */
--- a/src/protocols/jabber/log.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- *  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.
- *
- *  Jabber
- *  Copyright (C) 1998-1999 The Jabber Team http://jabber.org/
- */
-
-#ifndef INCL_LOG_H
-#define INCL_LOG_H
-
-#define LOGSIZE_HDR 1024
-#define LOGSIZE_TAIL 2048
-
-
-#ifdef DEBUG
-	void jdebug(char *zone, const char *msgfmt, ...);
-#else
-	#define jdebug if(0) warn
-#endif
-
-
-
-#endif	/* INCL_LOG_H */
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/message.c	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,413 @@
+/*
+ * gaim - Jabber Protocol Plugin
+ *
+ * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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 "debug.h"
+#include "html.h"
+#include "notify.h"
+#include "server.h"
+
+#include "buddy.h"
+#include "chat.h"
+#include "message.h"
+#include "xmlnode.h"
+
+#define JABBER_TYPING_NOTIFY_INT 15
+
+void jabber_message_free(JabberMessage *jm)
+{
+	if(jm->from)
+		g_free(jm->from);
+	if(jm->to)
+		g_free(jm->to);
+	if(jm->subject)
+		g_free(jm->subject);
+	if(jm->body)
+		g_free(jm->body);
+	if(jm->xhtml)
+		g_free(jm->xhtml);
+	if(jm->password)
+		g_free(jm->password);
+
+	g_free(jm);
+}
+
+void handle_chat(JabberMessage *jm)
+{
+	JabberID *jid = jabber_id_new(jm->from);
+	char *from;
+
+	JabberBuddy *jb;
+	JabberBuddyResource *jbr;
+
+	jb = jabber_buddy_find(jm->js, jm->from, TRUE);
+	jbr = jabber_buddy_find_resource(jb, jabber_get_resource(jm->from));
+
+	if(gaim_find_conversation_with_account(jm->from, jm->js->gc->account))
+		from = g_strdup(jm->from);
+	else if(jid->node)
+		from = g_strdup_printf("%s@%s", jid->node, jid->domain);
+	else
+		from = g_strdup(jid->domain);
+
+	if(!jm->xhtml && !jm->body) {
+		if(jm->events & JABBER_MESSAGE_EVENT_COMPOSING)
+			serv_got_typing(jm->js->gc, from, 0, GAIM_TYPING);
+		else
+			serv_got_typing_stopped(jm->js->gc, from);
+	} else {
+		if(jbr && jm->events & JABBER_MESSAGE_EVENT_COMPOSING)
+			jbr->capabilities |= JABBER_CAP_COMPOSING;
+		serv_got_im(jm->js->gc, from, jm->xhtml ? jm->xhtml : jm->body, 0,
+				jm->sent);
+	}
+
+	g_free(from);
+	jabber_id_free(jid);
+}
+
+void handle_groupchat(JabberMessage *jm)
+{
+	JabberID *jid = jabber_id_new(jm->from);
+	JabberChat *chat = jabber_chat_find(jm->js, jid->node, jid->domain);
+
+	if(!chat)
+		return;
+
+	if(jm->subject)
+		gaim_chat_set_topic(GAIM_CHAT(chat->conv), jid->resource, jm->subject);
+
+	serv_got_chat_in(jm->js->gc, chat->id, jabber_get_resource(jm->from),
+			0, jm->xhtml ? jm->xhtml : jm->body, jm->sent);
+	jabber_id_free(jid);
+}
+
+void handle_groupchat_invite(JabberMessage *jm)
+{
+	GHashTable *components = g_hash_table_new_full(g_str_hash, g_str_equal,
+			g_free, g_free);
+	JabberID *jid = jabber_id_new(jm->to);
+
+	g_hash_table_replace(components, g_strdup("room"), jid->node);
+	g_hash_table_replace(components, g_strdup("server"), jid->node);
+	g_hash_table_replace(components, g_strdup("handle"), jm->js->user->node);
+	g_hash_table_replace(components, g_strdup("password"), jm->password);
+
+	jabber_id_free(jid);
+	serv_got_chat_invite(jm->js->gc, jm->to, jm->from, jm->body, components);
+}
+
+void handle_error(JabberMessage *jm)
+{
+	char *buf;
+
+	if(!jm->body)
+		return;
+
+	buf = g_strdup_printf(_("Message delivery to %s failed: %s"),
+			jm->from, jm->error);
+
+	gaim_notify_error(jm->js->gc, _("Jabber Message Error"), buf, jm->body);
+
+	g_free(buf);
+}
+
+void jabber_message_parse(JabberStream *js, xmlnode *packet)
+{
+	JabberMessage *jm;
+	const char *type;
+	xmlnode *child;
+
+	if(strcmp(packet->name, "message"))
+		return;
+
+	jm = g_new0(JabberMessage, 1);
+	jm->js = js;
+	jm->sent = time(NULL);
+
+	type = xmlnode_get_attrib(packet, "type");
+
+	if(type) {
+		if(!strcmp(type, "normal"))
+			jm->type = JABBER_MESSAGE_NORMAL;
+		else if(!strcmp(type, "chat"))
+			jm->type = JABBER_MESSAGE_CHAT;
+		else if(!strcmp(type, "groupchat"))
+			jm->type = JABBER_MESSAGE_GROUPCHAT;
+		else if(!strcmp(type, "headline"))
+			jm->type = JABBER_MESSAGE_HEADLINE;
+		else if(!strcmp(type, "error"))
+			jm->type = JABBER_MESSAGE_ERROR;
+		else
+			jm->type = JABBER_MESSAGE_OTHER;
+	} else {
+		jm->type = JABBER_MESSAGE_NORMAL;
+	}
+
+	jm->from = g_strdup(xmlnode_get_attrib(packet, "from"));
+	jm->to = g_strdup(xmlnode_get_attrib(packet, "to"));
+
+	for(child = packet->child; child; child = child->next) {
+		if(child->type != NODE_TYPE_TAG)
+			continue;
+
+		if(!strcmp(child->name, "subject")) {
+			if(!jm->subject)
+				jm->subject = xmlnode_get_data(child);
+		} else if(!strcmp(child->name, "body")) {
+			if(!jm->body)
+				jm->body = xmlnode_get_data(child);
+		} else if(!strcmp(child->name, "html") && child->child) {
+			/* check to see if the <html> actually contains anything,
+			 * otherwise we'll ignore it */
+			char *txt = xmlnode_get_data(child);
+			if(!jm->xhtml && txt)
+				jm->xhtml = xmlnode_to_str(child);
+			g_free(txt);
+		} else if(!strcmp(child->name, "error")) {
+			const char *code = xmlnode_get_attrib(child, "code");
+			char *code_txt = NULL;
+			char *text = xmlnode_get_data(child);
+
+			if(code)
+				code_txt = g_strdup_printf(_(" (Code %s)"), code);
+
+			if(!jm->error)
+				jm->error = g_strdup_printf("%s%s", text ? text : "",
+						code_txt ? code_txt : "");
+
+			g_free(code_txt);
+			g_free(text);
+		} else if(!strcmp(child->name, "x")) {
+			const char *xmlns = xmlnode_get_attrib(child, "xmlns");
+			if(xmlns && !strcmp(xmlns, "jabber:x:event")) {
+				if(xmlnode_get_child(child, "composing"))
+					jm->events |= JABBER_MESSAGE_EVENT_COMPOSING;
+			} else if(xmlns && !strcmp(xmlns, "jabber:x:delay")) {
+				const char *timestamp = xmlnode_get_attrib(child, "stamp");
+				if(timestamp)
+					jm->sent = str_to_time(timestamp);
+			} else if(xmlns && !strcmp(xmlns, "jabber:x:conference") &&
+					jm->type != JABBER_MESSAGE_GROUPCHAT_INVITE) {
+				const char *jid = xmlnode_get_attrib(child, "jid");
+				if(jid) {
+					jm->type = JABBER_MESSAGE_GROUPCHAT_INVITE;
+					g_free(jm->to);
+					jm->to = g_strdup(jid);
+				}
+			} else if(xmlns && !strcmp(xmlns,
+						"http://jabber.org/protocol/muc#user")) {
+				xmlnode *invite = xmlnode_get_child(child, "invite");
+				if(invite) {
+					xmlnode *reason, *password;
+					const char *jid = xmlnode_get_attrib(child, "from");
+					g_free(jm->to);
+					jm->to = jm->from;
+					jm->from = g_strdup(jid);
+					if((reason = xmlnode_get_child(invite, "reason"))) {
+						g_free(jm->body);
+						jm->body = xmlnode_get_data(reason);
+					}
+					if((password = xmlnode_get_child(invite, "password")))
+						jm->password = xmlnode_get_data(password);
+
+					jm->type = JABBER_MESSAGE_GROUPCHAT_INVITE;
+				}
+			}
+		}
+	}
+
+	switch(jm->type) {
+		case JABBER_MESSAGE_NORMAL:
+		case JABBER_MESSAGE_CHAT:
+		case JABBER_MESSAGE_HEADLINE:
+			handle_chat(jm);
+			break;
+		case JABBER_MESSAGE_GROUPCHAT:
+			handle_groupchat(jm);
+			break;
+		case JABBER_MESSAGE_GROUPCHAT_INVITE:
+			handle_groupchat_invite(jm);
+			break;
+		case JABBER_MESSAGE_ERROR:
+			handle_error(jm);
+			break;
+		case JABBER_MESSAGE_OTHER:
+			gaim_debug(GAIM_DEBUG_INFO, "jabber",
+					"Received message of unknown type: %s\n", type);
+			break;
+	}
+	jabber_message_free(jm);
+}
+
+void jabber_message_send(JabberMessage *jm)
+{
+	xmlnode *message, *child;
+	const char *type = NULL;
+
+	message = xmlnode_new("message");
+
+	switch(jm->type) {
+		case JABBER_MESSAGE_NORMAL:
+			type = "normal";
+			break;
+		case JABBER_MESSAGE_CHAT:
+		case JABBER_MESSAGE_GROUPCHAT_INVITE:
+			type = "chat";
+			break;
+		case JABBER_MESSAGE_HEADLINE:
+			type = "headline";
+			break;
+		case JABBER_MESSAGE_GROUPCHAT:
+			type = "groupchat";
+			break;
+		case JABBER_MESSAGE_ERROR:
+			type = "error";
+			break;
+		case JABBER_MESSAGE_OTHER:
+			type = NULL;
+			break;
+	}
+
+	if(type)
+		xmlnode_set_attrib(message, "type", type);
+
+	xmlnode_set_attrib(message, "to", jm->to);
+
+	if(jm->events || (!jm->body && !jm->xhtml)) {
+		child = xmlnode_new_child(message, "x");
+		xmlnode_set_attrib(child, "xmlns", "jabber:x:event");
+		if(jm->events & JABBER_MESSAGE_EVENT_COMPOSING)
+			xmlnode_new_child(child, "composing");
+	}
+
+	if(jm->subject) {
+		child = xmlnode_new_child(message, "subject");
+		xmlnode_insert_data(child, jm->subject, -1);
+	}
+
+	if(jm->body) {
+		child = xmlnode_new_child(message, "body");
+		xmlnode_insert_data(child, jm->body, -1);
+	}
+
+	if(jm->xhtml) {
+		child = xmlnode_from_str(jm->xhtml, -1);
+		if(child) {
+			xmlnode_insert_child(message, child);
+		} else {
+			gaim_debug(GAIM_DEBUG_ERROR, "jabber",
+					"XHTML translation/validation failed, returning: %s\n",
+					jm->xhtml);
+		}
+	}
+
+	jabber_send(jm->js, message);
+
+	xmlnode_free(message);
+}
+
+int jabber_message_send_im(GaimConnection *gc, const char *who, const char *msg,
+		GaimImFlags flags)
+{
+	JabberMessage *jm;
+	JabberBuddy *jb;
+	JabberBuddyResource *jbr;
+	char *buf;
+	char *xhtml, *plain;
+
+	if(!who || !msg)
+		return 0;
+
+	jb = jabber_buddy_find(gc->proto_data, who, TRUE);
+	jbr = jabber_buddy_find_resource(jb, jabber_get_resource(who));
+
+	jm = g_new0(JabberMessage, 1);
+	jm->js = gc->proto_data;
+	jm->type = JABBER_MESSAGE_CHAT;
+	jm->events = JABBER_MESSAGE_EVENT_COMPOSING;
+	jm->to = g_strdup(who);
+
+	buf = g_strdup_printf("<html xmlns='http://jabber.org/protocol/xhtml-im'><body>%s</body></html>", msg);
+
+	html_to_xhtml(buf, &xhtml, &plain);
+	g_free(buf);
+
+	jm->body = plain;
+	if(!jbr || jbr->capabilities & JABBER_CAP_XHTML)
+		jm->xhtml = xhtml;
+	else
+		g_free(xhtml);
+
+	jabber_message_send(jm);
+	jabber_message_free(jm);
+	return 1;
+}
+
+int jabber_message_send_chat(GaimConnection *gc, int id, const char *message)
+{
+	JabberChat *chat;
+	JabberMessage *jm;
+	JabberStream *js = gc->proto_data;
+
+	if(!message)
+		return 0;
+
+	chat = jabber_chat_find_by_id(js, id);
+
+	jm = g_new0(JabberMessage, 1);
+	jm->js = gc->proto_data;
+	jm->type = JABBER_MESSAGE_CHAT;
+	jm->to = g_strdup_printf("%s@%s", chat->room, chat->server);
+
+	html_to_xhtml(message, NULL, &jm->body);
+
+	jabber_message_send(jm);
+	jabber_message_free(jm);
+	return 1;
+}
+
+int jabber_send_typing(GaimConnection *gc, const char *who, int typing)
+{
+	JabberMessage *jm;
+	JabberBuddy *jb;
+	JabberBuddyResource *jbr;
+
+	jb = jabber_buddy_find(gc->proto_data, who, TRUE);
+	jbr = jabber_buddy_find_resource(jb, jabber_get_resource(who));
+
+	if(jbr && !(jbr->capabilities & JABBER_CAP_COMPOSING))
+		return 0;
+
+	jm = g_new0(JabberMessage, 1);
+	jm->js = gc->proto_data;
+	jm->type = JABBER_MESSAGE_CHAT;
+	jm->to = g_strdup(who);
+
+	if(typing == GAIM_TYPING)
+		jm->events = JABBER_MESSAGE_EVENT_COMPOSING;
+
+	jabber_message_send(jm);
+	jabber_message_free(jm);
+
+	return JABBER_TYPING_NOTIFY_INT;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/message.h	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,60 @@
+/**
+ * @file message.h Message handlers
+ *
+ * gaim
+ *
+ * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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
+ */
+#ifndef _GAIM_JABBER_MESSAGE_H_
+#define _GAIM_JABBER_MESSAGE_H_
+
+#include "jabber.h"
+#include "xmlnode.h"
+
+typedef struct _JabberMessage {
+	JabberStream *js;
+	enum {
+		JABBER_MESSAGE_NORMAL,
+		JABBER_MESSAGE_CHAT,
+		JABBER_MESSAGE_GROUPCHAT,
+		JABBER_MESSAGE_HEADLINE,
+		JABBER_MESSAGE_ERROR,
+		JABBER_MESSAGE_GROUPCHAT_INVITE,
+		JABBER_MESSAGE_OTHER
+	} type;
+	time_t sent;
+	char *from;
+	char *to;
+	char *subject;
+	char *body;
+	char *xhtml;
+	char *password;
+	char *error;
+	enum {
+		JABBER_MESSAGE_EVENT_COMPOSING = 1 << 1
+	} events;
+} JabberMessage;
+
+
+void jabber_message_parse(JabberStream *js, xmlnode *packet);
+int jabber_message_send_im(GaimConnection *gc, const char *who, const char *msg,
+		GaimImFlags flags);
+int jabber_message_send_chat(GaimConnection *gc, int id, const char *message);
+
+int jabber_send_typing(GaimConnection *gc, const char *who, int typing);
+
+#endif /* _GAIM_JABBER_MESSAGE_H_ */
--- a/src/protocols/jabber/nametab.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-static const unsigned namingBitmap[] = {
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
-0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
-0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
-0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
-0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
-0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
-0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
-0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
-0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
-0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
-0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
-0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
-0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
-0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
-0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
-0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
-0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
-0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
-0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
-0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
-0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
-0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
-0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
-0x40000000, 0xF580C900, 0x00000007, 0x02010800,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
-0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
-0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
-0x00000000, 0x00004C40, 0x00000000, 0x00000000,
-0x00000007, 0x00000000, 0x00000000, 0x00000000,
-0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
-0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
-0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
-0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
-0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
-0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
-0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
-0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
-0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
-0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
-0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
-0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
-0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
-0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
-0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
-0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
-0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
-0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
-0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
-0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
-0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
-0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
-0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
-0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
-0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
-0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
-0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
-0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x00000000, 0x00000000,
-0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
-0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
-0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
-};
-static const unsigned char nmstrtPages[] = {
-0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
-0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
-0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
-static const unsigned char namePages[] = {
-0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
-0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
-0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
-0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/parser.c	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,131 @@
+/*
+ * gaim - Jabber XML parser stuff
+ *
+ * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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 "connection.h"
+
+#include "jabber.h"
+#include "parser.h"
+#include "xmlnode.h"
+
+static void
+jabber_parser_element_start(GMarkupParseContext *context,
+		const char *element_name, const char **attrib_names,
+		const char **attrib_values, gpointer user_data, GError **error)
+{
+	JabberStream *js = user_data;
+	xmlnode *node;
+	int i;
+
+	if(!element_name) {
+		return;
+	} else if(!strcmp(element_name, "stream:stream")) {
+		js->protocol_version = JABBER_PROTO_0_9;
+		for(i=0; attrib_names[i]; i++) {
+			if(!strcmp(attrib_names[i], "version")
+					&& !strcmp(attrib_values[i], "1.0")) {
+				js->protocol_version = JABBER_PROTO_1_0;
+			} else if(!strcmp(attrib_names[i], "id")) {
+				if(js->stream_id)
+					g_free(js->stream_id);
+				js->stream_id = g_strdup(attrib_values[i]);
+			}
+		}
+
+		if(js->state == JABBER_STREAM_INITIALIZING)
+			jabber_stream_set_state(js, JABBER_STREAM_AUTHENTICATING);
+	} else {
+
+		if(js->current)
+			node = xmlnode_new_child(js->current, element_name);
+		else
+			node = xmlnode_new(element_name);
+
+		for(i=0; attrib_names[i]; i++) {
+			xmlnode_set_attrib(node, attrib_names[i], attrib_values[i]);
+		}
+
+		js->current = node;
+	}
+}
+
+static void
+jabber_parser_element_end(GMarkupParseContext *context,
+		const char *element_name, gpointer user_data, GError **error)
+{
+	JabberStream *js = user_data;
+
+	if(!js->current)
+		return;
+
+	if(js->current->parent) {
+		if(!strcmp(js->current->name, element_name))
+			js->current = js->current->parent;
+	} else {
+		jabber_process_packet(js, js->current);
+		xmlnode_free(js->current);
+		js->current = NULL;
+	}
+}
+
+static void
+jabber_parser_element_text(GMarkupParseContext *context, const char *text,
+		gsize text_len, gpointer user_data, GError **error)
+{
+	JabberStream *js = user_data;
+
+	if(!js->current)
+		return;
+
+	if(!text || !text_len)
+		return;
+
+	xmlnode_insert_data(js->current, text, text_len);
+}
+
+static GMarkupParser jabber_parser = {
+	jabber_parser_element_start,
+	jabber_parser_element_end,
+	jabber_parser_element_text,
+	NULL,
+	NULL
+};
+
+void
+jabber_parser_setup(JabberStream *js)
+{
+	if(!js->context)
+		js->context = g_markup_parse_context_new(&jabber_parser, 0, js, NULL);
+}
+
+
+void jabber_parser_process(JabberStream *js, const char *buf, int len)
+{
+
+	/* May need to check for other encodings and do the conversion here */
+
+	if(!g_markup_parse_context_parse(js->context, buf, len, NULL)) {
+		g_markup_parse_context_free(js->context);
+		js->context = NULL;
+		gaim_connection_error(js->gc, _("XML Parse error"));
+	}
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/parser.h	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,30 @@
+/**
+ * @file parser.h XML parser functions
+ *
+ * gaim
+ *
+ * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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
+ */
+#ifndef _GAIM_JABBER_PARSER_H_
+#define _GAIM_JABBER_PARSER_H_
+
+#include "jabber.h"
+
+void jabber_parser_setup(JabberStream *js);
+void jabber_parser_process(JabberStream *js, const char *buf, int len);
+
+#endif /* _GAIM_JABBER_PARSER_H_ */
--- a/src/protocols/jabber/pool.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,302 +0,0 @@
-/* --------------------------------------------------------------------------
- *
- * License
- *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
- *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
- *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
-
-#include "lib.h"
-
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
-
-#ifdef POOL_DEBUG
-int pool__total = 0;
-int pool__ltotal = 0;
-HASHTABLE pool__disturbed = NULL;
-void *_pool__malloc(size_t size)
-{
-    pool__total++;
-    return malloc(size);
-}
-void _pool__free(void *block)
-{
-    pool__total--;
-    free(block);
-}
-#else
-#define _pool__malloc malloc
-#define _pool__free free
-#endif
-
-
-/* make an empty pool */
-pool _pool_new(char *zone)
-{
-    pool p;
-    while((p = _pool__malloc(sizeof(_pool))) == NULL) sleep(1);
-    p->cleanup = NULL;
-    p->heap = NULL;
-    p->size = 0;
-
-#ifdef POOL_DEBUG
-    p->lsize = -1;
-    p->zone[0] = '\0';
-    strcat(p->zone,zone);
-    sprintf(p->name,"%X",p);
-
-    if(pool__disturbed == NULL)
-    {
-        pool__disturbed = 1; /* reentrancy flag! */
-        pool__disturbed = ghash_create(POOL_DEBUG,(KEYHASHFUNC)str_hash_code,(KEYCOMPAREFUNC)j_strcmp);
-    }
-    if(pool__disturbed != 1)
-        ghash_put(pool__disturbed,p->name,p);
-#endif
-
-    return p;
-}
-
-/* free a heap */
-void _pool_heap_free(void *arg)
-{
-    struct pheap *h = (struct pheap *)arg;
-
-    _pool__free(h->block);
-    _pool__free(h);
-}
-
-/* mem should always be freed last */
-void _pool_cleanup_append(pool p, struct pfree *pf)
-{
-    struct pfree *cur;
-
-    if(p->cleanup == NULL)
-    {
-        p->cleanup = pf;
-        return;
-    }
-
-    /* fast forward to end of list */
-    for(cur = p->cleanup; cur->next != NULL; cur = cur->next);
-
-    cur->next = pf;
-}
-
-/* create a cleanup tracker */
-struct pfree *_pool_free(pool p, pool_cleaner f, void *arg)
-{
-    struct pfree *ret;
-
-    /* make the storage for the tracker */
-    while((ret = _pool__malloc(sizeof(struct pfree))) == NULL) sleep(1);
-    ret->f = f;
-    ret->arg = arg;
-    ret->next = NULL;
-
-    return ret;
-}
-
-/* create a heap and make sure it get's cleaned up */
-struct pheap *_pool_heap(pool p, int size)
-{
-    struct pheap *ret;
-    struct pfree *clean;
-
-    /* make the return heap */
-    while((ret = _pool__malloc(sizeof(struct pheap))) == NULL) sleep(1);
-    while((ret->block = _pool__malloc(size)) == NULL) sleep(1);
-    ret->size = size;
-    p->size += size;
-    ret->used = 0;
-
-    /* append to the cleanup list */
-    clean = _pool_free(p, _pool_heap_free, (void *)ret);
-    clean->heap = ret; /* for future use in finding used mem for pstrdup */
-    _pool_cleanup_append(p, clean);
-
-    return ret;
-}
-
-pool _pool_new_heap(int size, char *zone)
-{
-    pool p;
-    p = _pool_new(zone);
-    p->heap = _pool_heap(p,size);
-    return p;
-}
-
-void *pmalloc(pool p, int size)
-{
-    void *block;
-
-    if(p == NULL)
-    {
-        fprintf(stderr,"Memory Leak! [pmalloc received NULL pool, unable to track allocation, exiting]\n");
-        abort();
-    }
-
-    /* if there is no heap for this pool or it's a big request, just raw, I like how we clean this :) */
-    if(p->heap == NULL || size > (p->heap->size / 2))
-    {
-        while((block = _pool__malloc(size)) == NULL) sleep(1);
-        p->size += size;
-        _pool_cleanup_append(p, _pool_free(p, _pool__free, block));
-        return block;
-    }
-
-    /* we have to preserve boundaries, long story :) */
-    if(size >= 4)
-        while(p->heap->used&7) p->heap->used++;
-
-    /* if we don't fit in the old heap, replace it */
-    if(size > (p->heap->size - p->heap->used))
-        p->heap = _pool_heap(p, p->heap->size);
-
-    /* the current heap has room */
-    block = (char *)p->heap->block + p->heap->used;
-    p->heap->used += size;
-    return block;
-}
-
-void *pmalloc_x(pool p, int size, char c)
-{
-   void* result = pmalloc(p, size);
-   if (result != NULL)
-           memset(result, c, size);
-   return result;
-}  
-
-/* easy safety utility (for creating blank mem for structs, etc) */
-void *pmalloco(pool p, int size)
-{
-    void *block = pmalloc(p, size);
-    memset(block, 0, size);
-    return block;
-}  
-
-/* XXX efficient: move this to const char * and then loop throug the existing heaps to see if src is within a block in this pool */
-char *pstrdup(pool p, const char *src)
-{
-    char *ret;
-
-    if(src == NULL)
-        return NULL;
-
-    ret = pmalloc(p,strlen(src) + 1);
-    strcpy(ret,src);
-
-    return ret;
-}
-
-/* when move above, this one would actually return a new block */
-char *pstrdupx(pool p, const char *src)
-{
-    return pstrdup(p, src);
-}
-
-int pool_size(pool p)
-{
-    if(p == NULL) return 0;
-
-    return p->size;
-}
-
-void pool_free(pool p)
-{
-    struct pfree *cur, *stub;
-
-    if(p == NULL) return;
-
-    cur = p->cleanup;
-    while(cur != NULL)
-    {
-        (*cur->f)(cur->arg);
-        stub = cur->next;
-        _pool__free(cur);
-        cur = stub;
-    }
-
-#ifdef POOL_DEBUG
-    ghash_remove(pool__disturbed,p->name);
-#endif
-
-    _pool__free(p);
-
-}
-
-/* public cleanup utils, insert in a way that they are run FIFO, before mem frees */
-void pool_cleanup(pool p, pool_cleaner f, void *arg)
-{
-    struct pfree *clean;
-
-    clean = _pool_free(p, f, arg);
-    clean->next = p->cleanup;
-    p->cleanup = clean;
-}
-
-#ifdef POOL_DEBUG
-void debug_log(char *zone, const char *msgfmt, ...);
-int _pool_stat(void *arg, const void *key, void *data)
-{
-    pool p = (pool)data;
-
-    if(p->lsize == -1)
-        debug_log("leak","%s: %X is a new pool",p->zone,p->name);
-    else if(p->size > p->lsize)
-        debug_log("leak","%s: %X grew %d",p->zone,p->name, p->size - p->lsize);
-    else if((int)arg)
-        debug_log("leak","%s: %X exists %d",p->zone,p->name, p->size);
-    p->lsize = p->size;
-    return 1;
-}
-
-void pool_stat(int full)
-{
-    ghash_walk(pool__disturbed,_pool_stat,(void *)full);
-    if(pool__total != pool__ltotal)
-        debug_log("leak","%d\ttotal missed mallocs",pool__total);
-    pool__ltotal = pool__total;
-    return;
-}
-#else
-void pool_stat(int full)
-{
-    return;
-}
-#endif
--- a/src/protocols/jabber/pproxy.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,211 +0,0 @@
-/* --------------------------------------------------------------------------
- *
- * License
- *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
- *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
- *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
-
-#include "lib.h"
-
-/* these aren't the most efficient things in the world, a hash optimized for tiny spaces would be far better */
-
-ppdb _ppdb_new(pool p, jid id)
-{
-    ppdb ret;
-    ret = pmalloc(p,sizeof(_ppdb));
-    ret->p = p;
-    ret->pri = -1;
-    ret->next = NULL;
-    ret->user = NULL;
-    ret->x = NULL;
-    ret->id = jid_new(p,jid_full(id));
-
-    return ret;
-}
-
-ppdb _ppdb_get(ppdb db, jid id)
-{
-    ppdb cur;
-
-    if(db == NULL || id == NULL) return NULL;
-
-    for(cur = db->next; cur != NULL; cur = cur->next)
-        if(jid_cmp(cur->id,id) == 0) return cur;
-
-    return NULL;
-}
-
-ppdb ppdb_insert(ppdb db, jid id, xmlnode x)
-{
-    ppdb cur, curu;
-    pool p;
-
-    if(id == NULL || id->server == NULL || x == NULL)
-        return db;
-
-    /* new ppdb list dummy holder */
-    if(db == NULL)
-    {
-        p = pool_heap(1024);
-        db = _ppdb_new(p,NULL);
-    }
-
-    cur = _ppdb_get(db,id);
-
-    /* just update it */
-    if(cur != NULL)
-    {
-        xmlnode_free(cur->x);
-        cur->x = xmlnode_dup(x);
-        cur->pri = jutil_priority(x);
-        return db;
-    }
-
-    /* make an entry for it */
-    cur = _ppdb_new(db->p,id);
-    cur->x = xmlnode_dup(x);
-    cur->pri = jutil_priority(x);
-    cur->next = db->next;
-    db->next = cur;
-
-    /* if this is a user's resource presence, get the the user entry */
-    if(id->user != NULL && (curu = _ppdb_get(db,jid_user(id))) != cur)
-    {
-        /* no user entry, make one */
-        if(curu == NULL)
-        {
-            curu = _ppdb_new(db->p,jid_user(id));
-            curu->next = db->next;
-            db->next = curu;
-        }
-
-        /* insert this resource into the user list */
-        cur->user = curu->user;
-        curu->user = cur;
-    }
-
-    return db;
-}
-
-xmlnode ppdb_primary(ppdb db, jid id)
-{
-    ppdb cur, top;
-
-    if(db == NULL || id == NULL) return NULL;
-
-    cur = _ppdb_get(db,id);
-
-    if(cur == NULL) return NULL;
-
-    /* not user@host check, just return */
-    if(id->user == NULL || id->resource != NULL) return cur->x;
-
-    top = cur;
-    for(cur = cur->user; cur != NULL; cur = cur->user)
-        if(cur->pri >= top->pri) top = cur;
-
-    if(top != NULL && top->pri >= 0) return top->x;
-
-    return NULL;
-}
-
-/* return the presence for the id, successive calls return all of the known resources for a user@host address */
-xmlnode ppdb_get(ppdb db, jid id)
-{
-    static ppdb last = NULL;
-    ppdb cur;
-
-    if(db == NULL || id == NULL) return NULL;
-
-    /* MODE: if this is NOT just user@host addy, return just the single entry */
-    if(id->user == NULL || id->resource != NULL)
-    {
-        /* we were just here, return now */
-        if(last != NULL)
-        {
-            last = NULL;
-            return NULL;
-        }
-
-        last = _ppdb_get(db,id);
-        if(last != NULL)
-            return last->x;
-        else
-            return NULL;
-    }
-
-    /* handle looping for user@host */
-
-    /* we're already in the loop */
-    if(last != NULL)
-    {
-        /* this is the last entry in the list */
-        if(last->user == NULL)
-        {
-            last = NULL;
-            return NULL;
-        }
-
-        last = last->user;
-        return last->x;
-    }
-
-    /* start a new loop */
-    cur = _ppdb_get(db,id);
-
-    if(cur == NULL) return NULL;
-
-    last = cur->user;
-    if(last != NULL)
-        return last->x;
-    else
-        return NULL;
-}
-
-
-void ppdb_free(ppdb db)
-{
-    ppdb cur;
-
-    if(db == NULL) return;
-
-    for(cur = db; cur != NULL; cur = cur->next)
-        xmlnode_free(cur->x);
-
-    pool_free(db->p);
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/presence.c	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,337 @@
+/*
+ * gaim - Jabber Protocol Plugin
+ *
+ * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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 "debug.h"
+#include "html.h"
+#include "notify.h"
+#include "request.h"
+#include "server.h"
+
+#include "buddy.h"
+#include "chat.h"
+#include "presence.h"
+#include "iq.h"
+#include "jutil.h"
+#include "xmlnode.h"
+
+
+static void chats_send_presence_foreach(gpointer key, gpointer val,
+		gpointer user_data)
+{
+	JabberChat *chat = val;
+	xmlnode *presence = user_data;
+	char *chat_jid = key;
+
+	xmlnode_set_attrib(presence, "to", chat_jid);
+	jabber_send(chat->js, presence);
+}
+
+
+void jabber_presence_send(GaimConnection *gc, const char *state,
+		const char *msg)
+{
+	JabberStream *js = gc->proto_data;
+	xmlnode *presence;
+	char *stripped = NULL;
+
+	if(msg) {
+		html_to_xhtml(msg, NULL, &stripped);
+	} else {
+		stripped = g_strdup("");
+	}
+
+	gc->away = stripped;
+
+	presence = jabber_presence_create(state, msg);
+	jabber_send(js, presence);
+	g_hash_table_foreach(js->chats, chats_send_presence_foreach, presence);
+	xmlnode_free(presence);
+}
+
+xmlnode *jabber_presence_create(const char *state, const char *msg)
+{
+	xmlnode *show, *status, *presence;
+
+
+	presence = xmlnode_new("presence");
+
+	if(state) {
+		const char *show_string = NULL;
+		if(!strcmp(state, _("Chatty")))
+			show_string = "chat";
+		else if(!strcmp(state, _("Away")) ||
+				(msg && !strcmp(state, GAIM_AWAY_CUSTOM)))
+			show_string = "away";
+		else if(!strcmp(state, _("Extended Away")))
+			show_string = "xa";
+		else if(!strcmp(state, _("Do Not Disturb")))
+			show_string = "dnd";
+		else if(!strcmp(state, _("Invisible"))) {
+			xmlnode_set_attrib(presence, "type", "invisible");
+		}
+
+		if(show_string) {
+			show = xmlnode_new_child(presence, "show");
+			xmlnode_insert_data(show, show_string, -1);
+		}
+	}
+
+	if(msg && *msg) {
+		status = xmlnode_new_child(presence, "status");
+		xmlnode_insert_data(status, msg, -1);
+	}
+
+	return presence;
+}
+
+struct _jabber_add_permit {
+	GaimConnection *gc;
+	char *who;
+};
+
+static void authorize_add_cb(struct _jabber_add_permit *jap)
+{
+	if(g_list_find(gaim_connections_get_all(), jap->gc)) {
+		jabber_presence_subscription_set(jap->gc->proto_data, jap->who,
+				"subscribed");
+
+		if(!gaim_find_buddy(jap->gc->account, jap->who))
+			show_got_added(jap->gc, NULL, jap->who, NULL, NULL);
+	}
+
+	g_free(jap->who);
+	g_free(jap);
+}
+
+static void deny_add_cb(struct _jabber_add_permit *jap)
+{
+	if(g_list_find(gaim_connections_get_all(), jap->gc)) {
+		jabber_presence_subscription_set(jap->gc->proto_data, jap->who,
+				"unsubscribed");
+
+		if(!gaim_find_buddy(jap->gc->account, jap->who))
+			show_got_added(jap->gc, NULL, jap->who, NULL, NULL);
+	}
+
+	g_free(jap->who);
+	g_free(jap);
+}
+
+void jabber_presence_parse(JabberStream *js, xmlnode *packet)
+{
+	const char *from = xmlnode_get_attrib(packet, "from");
+	const char *type = xmlnode_get_attrib(packet, "type");
+	char *status = NULL;
+	int priority = 0;
+	JabberID *jid;
+	JabberChat *chat;
+	JabberBuddy *jb;
+	JabberBuddyResource *jbr;
+	GaimBuddy *b;
+	char *buddy_name;
+	int state = 0;
+	xmlnode *y;
+	gboolean muc = FALSE;
+
+	jb = jabber_buddy_find(js, from, TRUE);
+
+	if(jb->error_msg) {
+		g_free(jb->error_msg);
+		jb->error_msg = NULL;
+	}
+
+	if(type && !strcasecmp(type, "error")) {
+		state = JABBER_STATE_ERROR;
+		if((y = xmlnode_get_child(packet, "error")) != NULL) {
+			char *txt = xmlnode_get_data(y);
+			jb->error_msg = g_strdup_printf(_("%s (Code %s)"),
+					txt, xmlnode_get_attrib(y, "code"));
+			g_free(txt);
+		} else {
+			jb->error_msg = g_strdup(_("Unknown Error in presence"));
+		}
+	} else if(type && !strcasecmp(type, "subscribe")) {
+		struct _jabber_add_permit *jap = g_new0(struct _jabber_add_permit, 1);
+		char *msg = g_strdup_printf(_("The user %s wants to add you to their buddy list."), from);
+		jap->gc = js->gc;
+		jap->who = g_strdup(from);
+
+		gaim_request_action(js->gc, NULL, msg, NULL, 0, jap, 2,
+				_("Authorize"), G_CALLBACK(authorize_add_cb),
+				_("Deny"), G_CALLBACK(deny_add_cb));
+		g_free(msg);
+	} else if(type && (!strcmp(type, "subscribed") ||
+				!strcmp(type, "unsubscribed"))) {
+		/* we've been allowed to see their presence, but we don't care */
+		return;
+	} else {
+		if((y = xmlnode_get_child(packet, "show"))) {
+			char *show = xmlnode_get_data(y);
+			if(!show) {
+				state = 0;
+			} else if(!strcasecmp(show, "away")) {
+				state = JABBER_STATE_AWAY;
+			} else if(!strcasecmp(show, "chat")) {
+				state = JABBER_STATE_CHAT;
+			} else if(!strcasecmp(show, "xa")) {
+				state = JABBER_STATE_XA;
+			} else if(!strcasecmp(show, "dnd")) {
+				state = JABBER_STATE_DND;
+			}
+			g_free(show);
+		} else {
+			state = 0;
+		}
+	}
+
+	for(y = packet->child; y; y = y->next) {
+		if(y->type != NODE_TYPE_TAG)
+			continue;
+
+		if(!strcmp(y->name, "status")) {
+			status = xmlnode_get_data(y);
+		} else if(!strcmp(y->name, "priority")) {
+			char *p = xmlnode_get_data(y);
+			if(p) {
+				priority = atoi(p);
+				g_free(p);
+			}
+		} else if(!strcmp(y->name, "x")) {
+			const char *xmlns = xmlnode_get_attrib(y, "xmlns");
+			if(xmlns && !strcmp(xmlns, "http://jabber.org/protocol/muc#user")) {
+				/* this is where we'd normally get the "op" status of the
+				 * user, but since we don't have a good way to show that yet
+				 * we'll ignore it */
+				muc = TRUE;
+			}
+		}
+	}
+
+	jid = jabber_id_new(from);
+
+	if((chat = jabber_chat_find(js, jid->node, jid->domain))) {
+		static int i = 0;
+		char *room_jid = g_strdup_printf("%s@%s", jid->node, jid->domain);
+
+		if(state == JABBER_STATE_ERROR) {
+			const char *code = NULL;
+			char *text = NULL;
+			char *buf;
+			xmlnode *error = xmlnode_get_child(packet, "error");
+			if(error) {
+				/* I should make my own messages so they can be
+				 * translated, but i'm tired */
+				code = xmlnode_get_attrib(error, "code");
+				text = xmlnode_get_data(error);
+			}
+
+			if(!code)
+				code = "";
+			if(!text)
+				text = g_strdup(_("Unable to join chat"));
+
+			buf = g_strdup_printf("Error %s joining chat %s: %s",
+					code, from, text);
+			gaim_notify_error(js->gc, _("Error"), _("Error"), buf);
+			g_free(text);
+			g_free(buf);
+
+			jabber_chat_destroy(chat);
+			return;
+		}
+
+
+		if(!chat->conv) {
+			chat->id = i++;
+			chat->muc = muc;
+			chat->conv = serv_got_joined_chat(js->gc, chat->id, room_jid);
+		}
+
+		if(type && !strcasecmp(type, "unavailable")) {
+			if(!strcmp(jid->resource, chat->nick)) {
+				serv_got_chat_left(js->gc, chat->id);
+				jabber_chat_destroy(chat);
+			} else {
+				gaim_chat_remove_user(GAIM_CHAT(chat->conv), jid->resource,
+						NULL);
+			}
+		} else {
+			if(!jabber_chat_find_buddy(chat->conv, jid->resource))
+				gaim_chat_add_user(GAIM_CHAT(chat->conv), jid->resource,
+						NULL);
+		}
+		g_free(room_jid);
+	} else {
+		if(!(jb->subscription & JABBER_SUB_TO)) {
+			gaim_debug(GAIM_DEBUG_INFO, "jabber",
+					"got unexpected presence from %s, ignoring\n", from);
+			jabber_id_free(jid);
+			return;
+		}
+
+		buddy_name = g_strdup_printf("%s@%s", jid->node, jid->domain);
+		if((b = gaim_find_buddy(js->gc->account, buddy_name)) == NULL) {
+			jabber_id_free(jid);
+			g_free(buddy_name);
+			return;
+		}
+
+		if(state == JABBER_STATE_ERROR ||
+				(type && !strcasecmp(type, "unavailable")))
+			jabber_buddy_remove_resource(jb, jid->resource);
+		else
+			jabber_buddy_track_resource(jb, jid->resource, priority, state,
+					status);
+
+		jbr = jabber_buddy_find_resource(jb, jid->resource);
+
+		if(jbr)
+			serv_got_update(js->gc, buddy_name, 1, 0, b->signon, b->idle,
+					jbr->state);
+		else
+			serv_got_update(js->gc, buddy_name, 0, 0, 0, 0, 0);
+#if 0
+		iq = jabber_iq_new_query(js, JABBER_IQ_GET,
+				"http://jabber.org/protocol/disco#items");
+		query = xmlnode_get_child(iq->node, "query");
+		xmlnode_set_attrib(query, "node",
+				"http://jabber.org/protocol/avatar");
+		xmlnode_set_attrib(iq->node, "to", buddy_name);
+		jabber_iq_send(iq);
+#endif
+
+		g_free(buddy_name);
+	}
+	g_free(status);
+	jabber_id_free(jid);
+}
+
+void jabber_presence_subscription_set(JabberStream *js, const char *who, const char *type)
+{
+	xmlnode *presence = xmlnode_new("presence");
+
+	xmlnode_set_attrib(presence, "to", who);
+	xmlnode_set_attrib(presence, "type", type);
+
+	jabber_send(js, presence);
+	xmlnode_free(presence);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/presence.h	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,41 @@
+/**
+ * @file presence.h Presence
+ *
+ * gaim
+ *
+ * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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
+ */
+#ifndef _GAIM_JABBER_PRESENCE_H_
+#define _GAIM_JABBER_PRESENCE_H_
+
+#include "jabber.h"
+#include "xmlnode.h"
+
+#define JABBER_STATE_AWAY  (0x02 | UC_UNAVAILABLE)
+#define JABBER_STATE_CHAT  (0x04)
+#define JABBER_STATE_XA    (0x08 | UC_UNAVAILABLE)
+#define JABBER_STATE_DND   (0x10 | UC_UNAVAILABLE)
+#define JABBER_STATE_ERROR (0x20 | UC_UNAVAILABLE)
+
+void jabber_presence_send(GaimConnection *gc, const char *state,
+		const char *msg);
+xmlnode *jabber_presence_create(const char *state, const char *msg);
+void jabber_presence_parse(JabberStream *js, xmlnode *packet);
+void jabber_presence_subscription_set(JabberStream *js, const char *who,
+		const char *type);
+
+#endif /* _GAIM_JABBER_PRESENCE_H_ */
--- a/src/protocols/jabber/rate.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/* --------------------------------------------------------------------------
- *
- * License
- *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
- *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
- *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
-
-#include "lib.h"
-
-jlimit jlimit_new(int maxt, int maxp)
-{
-    pool p;
-    jlimit r;
-
-    p = pool_new();
-    r = pmalloc(p,sizeof(_jlimit));
-    r->key = NULL;
-    r->start = r->points = 0;
-    r->maxt = maxt;
-    r->maxp = maxp;
-    r->p = p;
-
-    return r;
-}
-
-void jlimit_free(jlimit r)
-{
-    if(r != NULL)
-    {
-        if(r->key != NULL) free(r->key);
-        pool_free(r->p);
-    }
-}
-
-int jlimit_check(jlimit r, char *key, int points)
-{
-    int now = time(NULL);
-
-    if(r == NULL) return 0;
-
-    /* make sure we didn't go over the time frame or get a null/new key */
-    if((now - r->start) > r->maxt || key == NULL || j_strcmp(key,r->key) != 0)
-    { /* start a new key */
-        free(r->key);
-        if(key != NULL)
-	  /* We use strdup instead of pstrdup since r->key needs to be free'd before 
-	     and more often than the rest of the rlimit structure */
-            r->key = strdup(key); 
-        else
-            r->key = NULL;
-        r->start = now;
-        r->points = 0;
-    }
-
-    r->points += points;
-
-    /* if we're within the time frame and over the point limit */
-    if(r->points > r->maxp && (now - r->start) < r->maxt)
-    {
-        return 1; /* we don't reset the rate here, so that it remains rated until the time runs out */
-    }
-
-    return 0;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/roster.c	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,311 @@
+/*
+ * gaim - Jabber Protocol Plugin
+ *
+ * Copyright (C) 2003, Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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 "debug.h"
+#include "server.h"
+
+#include "buddy.h"
+#include "presence.h"
+#include "roster.h"
+#include "iq.h"
+
+#include <string.h>
+
+
+void jabber_roster_request(JabberStream *js)
+{
+	JabberIq *iq;
+
+	iq = jabber_iq_new_query(js, JABBER_IQ_GET, "jabber:iq:roster");
+
+	jabber_iq_send(iq);
+}
+
+static void remove_gaim_buddies(JabberStream *js, const char *jid)
+{
+	GSList *buddies, *l;
+
+	buddies = gaim_find_buddies(js->gc->account, jid);
+
+	for(l = buddies; l; l = l->next)
+		gaim_blist_remove_buddy(l->data);
+
+	g_slist_free(buddies);
+}
+
+static void add_gaim_buddies_in_groups(JabberStream *js, const char *jid,
+		const char *alias, GSList *groups)
+{
+	GSList *buddies, *g2, *l;
+	int present =0, idle=0, signon=0, state=0;
+
+	buddies = gaim_find_buddies(js->gc->account, jid);
+
+	g2 = groups;
+
+	if(!groups) {
+		if(!buddies)
+			g2 = g_slist_append(g2, g_strdup(_("Buddies")));
+		else
+			return;
+	}
+
+	if(buddies) {
+		present = ((GaimBuddy*)buddies->data)->present;
+		signon = ((GaimBuddy*)buddies->data)->signon;
+		idle = ((GaimBuddy*)buddies->data)->idle;
+		state = ((GaimBuddy*)buddies->data)->uc;
+	}
+
+	while(buddies) {
+		GaimBuddy *b = buddies->data;
+		GaimGroup *g = gaim_find_buddys_group(b);
+
+		buddies = g_slist_remove(buddies, b);
+
+		if((l = g_slist_find_custom(g2, g->name, (GCompareFunc)strcmp))) {
+			if(alias && (!b->alias || strcmp(b->alias, alias)))
+				gaim_blist_alias_buddy(b, alias);
+			g_free(l->data);
+			g2 = g_slist_delete_link(g2, l);
+		} else {
+			gaim_blist_remove_buddy(b);
+		}
+	}
+
+	while(g2) {
+		GaimBuddy *b = gaim_buddy_new(js->gc->account, jid, alias);
+		GaimGroup *g = gaim_find_group(g2->data);
+
+		if(!g) {
+			g = gaim_group_new(g2->data);
+			gaim_blist_add_group(g, NULL);
+		}
+
+		b->present = present;
+		b->signon = signon;
+		b->idle = idle;
+		b->uc = state;
+
+		gaim_blist_add_buddy(b, NULL, g, NULL);
+		g_free(g2->data);
+		g2 = g_slist_delete_link(g2, g2);
+	}
+
+	g_slist_free(buddies);
+}
+
+void jabber_roster_parse(JabberStream *js, xmlnode *packet)
+{
+	xmlnode *query, *item, *group;
+	const char *from = xmlnode_get_attrib(packet, "from");
+	if(from && strcmp(gaim_account_get_username(js->gc->account), from))
+		return;
+
+	query = xmlnode_get_child(packet, "query");
+	if(!query)
+		return;
+
+	js->roster_parsed = TRUE;
+
+	for(item = query->child; item; item = item->next)
+	{
+		const char *jid, *name, *subscription, *ask;
+		JabberBuddy *jb;
+
+		if(item->type != NODE_TYPE_TAG || strcmp(item->name, "item"))
+			continue;
+
+		subscription = xmlnode_get_attrib(item, "subscription");
+		jid = xmlnode_get_attrib(item, "jid");
+		name = xmlnode_get_attrib(item, "name");
+		ask = xmlnode_get_attrib(item, "ask");
+
+		jb = jabber_buddy_find(js, jid, TRUE);
+
+		if(!strcmp(subscription, "to"))
+			jb->subscription = JABBER_SUB_TO;
+		else if(!strcmp(subscription, "from"))
+			jb->subscription = JABBER_SUB_FROM;
+		else if(!strcmp(subscription, "both"))
+			jb->subscription = JABBER_SUB_BOTH;
+		else
+			jb->subscription = JABBER_SUB_NONE;
+
+		if(ask && !strcmp(ask, "subscribe"))
+			jb->subscription |= JABBER_SUB_PENDING;
+		else
+			jb->subscription &= ~JABBER_SUB_PENDING;
+
+		if(jb->subscription == JABBER_SUB_NONE) {
+			jb = jabber_buddy_find(js, jid, FALSE);
+			if(jb)
+				jb->subscription = JABBER_SUB_NONE;
+			remove_gaim_buddies(js, jid);
+		} else {
+			GSList *groups = NULL;
+
+			for(group = item->child; group; group = group->next) {
+				if(group->type != NODE_TYPE_TAG || strcmp(group->name, "group"))
+					continue;
+				groups = g_slist_append(groups,
+						xmlnode_get_data(group));
+			}
+			add_gaim_buddies_in_groups(js, jid, name, groups);
+		}
+	}
+
+	gaim_blist_save();
+}
+
+static void jabber_roster_update(JabberStream *js, const char *name,
+		GSList *grps)
+{
+	GaimBuddy *b;
+	GaimGroup *g;
+	GSList *groups = NULL, *l;
+	JabberIq *iq;
+	xmlnode *query, *item, *group;
+
+	if(grps) {
+		groups = grps;
+	} else {
+		GSList *buddies = gaim_find_buddies(js->gc->account, name);
+		if(!buddies)
+			return;
+		while(buddies) {
+			b = buddies->data;
+			g = gaim_find_buddys_group(b);
+			groups = g_slist_append(groups, g->name);
+			buddies = g_slist_remove(buddies, b);
+		}
+	}
+
+	b = gaim_find_buddy(js->gc->account, name);
+
+	iq = jabber_iq_new_query(js, JABBER_IQ_SET, "jabber:iq:roster");
+
+	query = xmlnode_get_child(iq->node, "query");
+	item = xmlnode_new_child(query, "item");
+
+	xmlnode_set_attrib(item, "jid", name);
+
+	if(b->alias)
+		xmlnode_set_attrib(item, "name", b->alias);
+
+	for(l = groups; l; l = l->next) {
+		group = xmlnode_new_child(item, "group");
+		xmlnode_insert_data(group, l->data, -1);
+	}
+
+	if(!grps)
+		g_slist_free(groups);
+
+	jabber_iq_send(iq);
+}
+
+void jabber_roster_add_buddy(GaimConnection *gc, const char *name,
+		GaimGroup *grp)
+{
+	JabberStream *js = gc->proto_data;
+	char *who;
+	GSList *buddies;
+	JabberBuddy *jb;
+
+	if(!js->roster_parsed)
+		return;
+
+	who = jabber_get_bare_jid(name);
+
+	buddies = gaim_find_buddies(gc->account, who);
+
+	jabber_roster_update(js, who, NULL);
+
+	jb = jabber_buddy_find(js, name, FALSE);
+	if(!jb || !(jb->subscription & JABBER_SUB_TO))
+		jabber_presence_subscription_set(js, who, "subscribe");
+	g_free(who);
+}
+
+void jabber_roster_alias_change(GaimConnection *gc, const char *name, const char *alias)
+{
+	jabber_roster_update(gc->proto_data, name, NULL);
+}
+
+void jabber_roster_group_change(GaimConnection *gc, const char *name,
+		const char *old_group, const char *new_group)
+{
+	GSList *buddies, *groups = NULL;
+	GaimBuddy *b;
+	GaimGroup *g;
+
+	if(!old_group || !new_group || !strcmp(old_group, new_group))
+		return;
+
+	buddies = gaim_find_buddies(gc->account, name);
+	while(buddies) {
+		b = buddies->data;
+		g = gaim_find_buddys_group(b);
+		if(!strcmp(g->name, old_group))
+			groups = g_slist_append(groups, (char*)new_group); /* ick */
+		else
+			groups = g_slist_append(groups, g->name);
+		buddies = g_slist_remove(buddies, b);
+	}
+	jabber_roster_update(gc->proto_data, name, groups);
+	g_slist_free(groups);
+}
+
+void jabber_roster_group_rename(GaimConnection *gc, const char *old_group,
+		const char *new_group, GList *members)
+{
+	GList *l;
+	if(old_group && new_group && strcmp(old_group, new_group)) {
+		for(l = members; l; l = l->next) {
+			jabber_roster_group_change(gc, l->data, old_group, new_group);
+		}
+	}
+}
+
+void jabber_roster_remove_buddy(GaimConnection *gc, const char *name, const char *group) {
+	GSList *buddies = gaim_find_buddies(gc->account, name);
+	GSList *groups = NULL;
+	GaimGroup *g = gaim_find_group(group);
+	GaimBuddy *b = gaim_find_buddy_in_group(gc->account, name, g);
+
+	buddies = g_slist_remove(buddies, b);
+	if(g_slist_length(buddies)) {
+		while(buddies) {
+			b = buddies->data;
+			g = gaim_find_buddys_group(b);
+			groups = g_slist_append(groups, g->name);
+			buddies = g_slist_remove(buddies, b);
+		}
+		jabber_roster_update(gc->proto_data, name, groups);
+	} else {
+		jabber_presence_subscription_set(gc->proto_data, name, "unsubscribe");
+	}
+
+	if(buddies)
+		g_slist_free(buddies);
+	if(groups)
+		g_slist_free(groups);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/roster.h	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,42 @@
+/**
+ * @file roster.h Roster manipulation
+ *
+ * gaim
+ *
+ * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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
+ */
+#ifndef _GAIM_JABBER_ROSTER_H_
+#define _GAIM_JABBER_ROSTER_H_
+
+#include "jabber.h"
+
+void jabber_roster_request(JabberStream *js);
+
+void jabber_roster_parse(JabberStream *js, xmlnode *packet);
+
+void jabber_roster_add_buddy(GaimConnection *gc, const char *name,
+		GaimGroup *grp);
+void jabber_roster_alias_change(GaimConnection *gc, const char *name,
+		const char *alias);
+void jabber_roster_group_change(GaimConnection *gc, const char *name,
+		const char *old_group, const char *new_group);
+void jabber_roster_group_rename(GaimConnection *gc, const char *old_group,
+		const char *new_group, GList *members);
+void jabber_roster_remove_buddy(GaimConnection *gc, const char *name,
+		const char *group);
+
+#endif /* _GAIM_JABBER_ROSTER_H_ */
--- a/src/protocols/jabber/sha.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/* 
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- * 
- * The Original Code is SHA 180-1 Reference Implementation (Compact version)
- * 
- * The Initial Developer of the Original Code is Paul Kocher of
- * Cryptography Research.  Portions created by Paul Kocher are 
- * Copyright (C) 1995-9 by Cryptography Research, Inc.  All
- * Rights Reserved.
- * 
- * Contributor(s):
- *
- */
-
-#include "lib.h"
-
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
-
-static void shaHashBlock(j_SHA_CTX *ctx);
-
-void shaInit(j_SHA_CTX *ctx) {
-  int i;
-
-  ctx->lenW = 0;
-  ctx->sizeHi = ctx->sizeLo = 0;
-
-  /* Initialize H with the magic constants (see FIPS180 for constants)
-   */
-  ctx->H[0] = 0x67452301L;
-  ctx->H[1] = 0xefcdab89L;
-  ctx->H[2] = 0x98badcfeL;
-  ctx->H[3] = 0x10325476L;
-  ctx->H[4] = 0xc3d2e1f0L;
-
-  for (i = 0; i < 80; i++)
-    ctx->W[i] = 0;
-}
-
-
-void shaUpdate(j_SHA_CTX *ctx, unsigned char *dataIn, int len) {
-  int i;
-
-  /* Read the data into W and process blocks as they get full
-   */
-  for (i = 0; i < len; i++) {
-    ctx->W[ctx->lenW / 4] <<= 8;
-    ctx->W[ctx->lenW / 4] |= (unsigned long)dataIn[i];
-    if ((++ctx->lenW) % 64 == 0) {
-      shaHashBlock(ctx);
-      ctx->lenW = 0;
-    }
-    ctx->sizeLo += 8;
-    ctx->sizeHi += (ctx->sizeLo < 8);
-  }
-}
-
-
-void shaFinal(j_SHA_CTX *ctx, unsigned char hashout[20]) {
-  unsigned char pad0x80 = 0x80;
-  unsigned char pad0x00 = 0x00;
-  unsigned char padlen[8];
-  int i;
-
-  /* Pad with a binary 1 (e.g. 0x80), then zeroes, then length
-   */
-  padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
-  padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
-  padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
-  padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
-  padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
-  padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
-  padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
-  padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
-  shaUpdate(ctx, &pad0x80, 1);
-  while (ctx->lenW != 56)
-    shaUpdate(ctx, &pad0x00, 1);
-  shaUpdate(ctx, padlen, 8);
-
-  /* Output hash
-   */
-  for (i = 0; i < 20; i++) {
-    hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
-    ctx->H[i / 4] <<= 8;
-  }
-
-  /*
-   *  Re-initialize the context (also zeroizes contents)
-   */
-  shaInit(ctx); 
-}
-
-
-void shaBlock(unsigned char *dataIn, int len, unsigned char hashout[20]) {
-  j_SHA_CTX ctx;
-
-  shaInit(&ctx);
-  shaUpdate(&ctx, dataIn, len);
-  shaFinal(&ctx, hashout);
-}
-
-
-#define SHA_ROTL(X,n) ((((X) << (n)) | ((X) >> (32-(n)))) & 0xffffffffL)
-
-static void shaHashBlock(j_SHA_CTX *ctx) {
-  int t;
-  unsigned long A,B,C,D,E,TEMP;
-
-  for (t = 16; t <= 79; t++)
-    ctx->W[t] =
-      SHA_ROTL(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
-
-  A = ctx->H[0];
-  B = ctx->H[1];
-  C = ctx->H[2];
-  D = ctx->H[3];
-  E = ctx->H[4];
-
-  for (t = 0; t <= 19; t++) {
-    TEMP = (SHA_ROTL(A,5) + (((C^D)&B)^D)     + E + ctx->W[t] + 0x5a827999L) & 0xffffffffL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-  for (t = 20; t <= 39; t++) {
-    TEMP = (SHA_ROTL(A,5) + (B^C^D)           + E + ctx->W[t] + 0x6ed9eba1L) & 0xffffffffL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-  for (t = 40; t <= 59; t++) {
-    TEMP = (SHA_ROTL(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdcL) & 0xffffffffL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-  for (t = 60; t <= 79; t++) {
-    TEMP = (SHA_ROTL(A,5) + (B^C^D)           + E + ctx->W[t] + 0xca62c1d6L) & 0xffffffffL;
-    E = D; D = C; C = SHA_ROTL(B, 30); B = A; A = TEMP;
-  }
-
-  ctx->H[0] += A;
-  ctx->H[1] += B;
-  ctx->H[2] += C;
-  ctx->H[3] += D;
-  ctx->H[4] += E;
-}
-
-/*----------------------------------------------------------------------------
- *
- * This code added by Thomas "temas" Muldowney for Jabber compatability
- *
- *---------------------------------------------------------------------------*/
-char *shahash(char *str)
-{
-    static char final[41];
-    char *pos;
-    unsigned char hashval[20];
-    int x;
-
-    if(!str || strlen(str) == 0)
-        return NULL;
-
-    shaBlock((unsigned char *)str, strlen(str), hashval);
-
-    pos = final;
-    for(x=0;x<20;x++)
-    {
-        snprintf(pos, 3, "%02x", hashval[x]);
-        pos += 2;
-    }
-    return (char *)final;
-}
-
-void shahash_r(const char* str, char hashbuf[41])
-{
-    int x;
-    char *pos;
-    unsigned char hashval[20];
-    
-    if(!str || strlen(str) == 0)
-        return;
-
-    shaBlock((unsigned char *)str, strlen(str), hashval);
-
-    pos = hashbuf;
-    for(x=0;x<20;x++)
-    {
-        snprintf(pos, 3, "%02x", hashval[x]);
-        pos += 2;
-    }
-
-    return;
-}
--- a/src/protocols/jabber/snprintf.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,932 +0,0 @@
-/* ====================================================================
- * Copyright (c) 1995-1998 The Apache Group.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer. 
- *
- * 2. 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.
- *
- * 3. All advertising materials mentioning features or use of this
- *    software must display the following acknowledgment:
- *    "This product includes software developed by the Apache Group
- *    for use in the Apache HTTP server project (http://www.apache.org/)."
- *
- * 4. The names "Apache Server" and "Apache Group" must not be used to
- *    endorse or promote products derived from this software without
- *    prior written permission.
- *
- * 5. Redistributions of any form whatsoever must retain the following
- *    acknowledgment:
- *    "This product includes software developed by the Apache Group
- *    for use in the Apache HTTP server project (http://www.apache.org/)."
- *
- * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
- * ITS CONTRIBUTORS 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Group and was originally based
- * on public domain software written at the National Center for
- * Supercomputing Applications, University of Illinois, Urbana-Champaign.
- * For more information on the Apache Group and the Apache HTTP server
- * project, please see <http://www.apache.org/>.
- *
- * This code is based on, and used with the permission of, the
- * SIO stdio-replacement strx_* functions by Panos Tsirigotis
- * <panos@alumni.cs.colorado.edu> for xinetd.
- */
-
-#include "lib.h"
-
-#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
-
-#include <stdio.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-#include <math.h>
-
-
-#ifdef HAVE_GCVT
-
-#define ap_ecvt ecvt
-#define ap_fcvt fcvt
-#define ap_gcvt gcvt
-
-#else
-
-/*
-* cvt.c - IEEE floating point formatting routines for FreeBSD
-* from GNU libc-4.6.27
-*/
-
-/*
-*    ap_ecvt converts to decimal
-*      the number of digits is specified by ndigit
-*      decpt is set to the position of the decimal point
-*      sign is set to 0 for positive, 1 for negative
-*/
-
-#define NDIG    80
-
-static char *
-ap_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag)
-{
-    register int r2;
-    double fi, fj;
-    register char *p, *p1;
-    static char buf[NDIG];
-
-    if (ndigits >= NDIG - 1)
-        ndigits = NDIG - 2;
-    r2 = 0;
-    *sign = 0;
-    p = &buf[0];
-    if (arg < 0) {
-        *sign = 1;
-        arg = -arg;
-    }
-    arg = modf(arg, &fi);
-    p1 = &buf[NDIG];
-    /*
-    * Do integer part
-    */
-    if (fi != 0) {
-        p1 = &buf[NDIG];
-        while (fi != 0) {
-            fj = modf(fi / 10, &fi);
-            *--p1 = (int) ((fj + .03) * 10) + '0';
-            r2++;
-        }
-        while (p1 < &buf[NDIG])
-            *p++ = *p1++;
-    } else if (arg > 0) {
-        while ((fj = arg * 10) < 1) {
-            arg = fj;
-            r2--;
-        }
-    }
-    p1 = &buf[ndigits];
-    if (eflag == 0)
-        p1 += r2;
-    *decpt = r2;
-    if (p1 < &buf[0]) {
-        buf[0] = '\0';
-        return (buf);
-    }
-    while (p <= p1 && p < &buf[NDIG]) {
-        arg *= 10;
-        arg = modf(arg, &fj);
-        *p++ = (int) fj + '0';
-    }
-    if (p1 >= &buf[NDIG]) {
-        buf[NDIG - 1] = '\0';
-        return (buf);
-    }
-    p = p1;
-    *p1 += 5;
-    while (*p1 > '9') {
-        *p1 = '0';
-        if (p1 > buf)
-            ++ * --p1;
-        else {
-            *p1 = '1';
-            (*decpt)++;
-            if (eflag == 0) {
-                if (p > buf)
-                    *p = '0';
-                p++;
-            }
-        }
-    }
-    *p = '\0';
-    return (buf);
-}
-
-static char *
-ap_ecvt(double arg, int ndigits, int *decpt, int *sign)
-{
-    return (ap_cvt(arg, ndigits, decpt, sign, 1));
-}
-
-static char *
-ap_fcvt(double arg, int ndigits, int *decpt, int *sign)
-{
-    return (ap_cvt(arg, ndigits, decpt, sign, 0));
-}
-
-/*
-* ap_gcvt  - Floating output conversion to
-* minimal length string
-*/
-
-static char *
-ap_gcvt(double number, int ndigit, char *buf)
-{
-    int sign, decpt;
-    register char *p1, *p2;
-    int i;
-
-    p1 = ap_ecvt(number, ndigit, &decpt, &sign);
-    p2 = buf;
-    if (sign)
-        *p2++ = '-';
-    for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--)
-        ndigit--;
-    if ((decpt >= 0 && decpt - ndigit > 4)
-            || (decpt < 0 && decpt < -3)) {     /* use E-style */
-        decpt--;
-        *p2++ = *p1++;
-        *p2++ = '.';
-        for (i = 1; i < ndigit; i++)
-            *p2++ = *p1++;
-        *p2++ = 'e';
-        if (decpt < 0) {
-            decpt = -decpt;
-            *p2++ = '-';
-        } else
-            *p2++ = '+';
-        if (decpt / 100 > 0)
-            *p2++ = decpt / 100 + '0';
-        if (decpt / 10 > 0)
-            *p2++ = (decpt % 100) / 10 + '0';
-        *p2++ = decpt % 10 + '0';
-    } else {
-        if (decpt <= 0) {
-            if (*p1 != '0')
-                *p2++ = '.';
-            while (decpt < 0) {
-                decpt++;
-                *p2++ = '0';
-            }
-        }
-        for (i = 1; i <= ndigit; i++) {
-            *p2++ = *p1++;
-            if (i == decpt)
-                *p2++ = '.';
-        }
-        if (ndigit < decpt) {
-            while (ndigit++ < decpt)
-                *p2++ = '0';
-            *p2++ = '.';
-        }
-    }
-    if (p2[-1] == '.')
-        p2--;
-    *p2 = '\0';
-    return (buf);
-}
-
-#endif                          /* HAVE_CVT */
-
-typedef enum {
-    NO = 0, YES = 1
-} boolean_e;
-
-#define FALSE           0
-#define TRUE            1
-#define NUL         '\0'
-#define INT_NULL        ((int *)0)
-#define WIDE_INT        long
-
-typedef WIDE_INT wide_int;
-typedef unsigned WIDE_INT u_wide_int;
-typedef int bool_int;
-
-#define S_NULL          "(null)"
-#define S_NULL_LEN      6
-
-#define FLOAT_DIGITS        6
-#define EXPONENT_LENGTH     10
-
-/*
- * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
- *
- * XXX: this is a magic number; do not decrease it
- */
-#define NUM_BUF_SIZE        512
-
-
-/*
- * Descriptor for buffer area
- */
-struct buf_area {
-    char *buf_end;
-    char *nextb;                /* pointer to next byte to read/write   */
-};
-
-typedef struct buf_area buffy;
-
-/*
- * The INS_CHAR macro inserts a character in the buffer and writes
- * the buffer back to disk if necessary
- * It uses the char pointers sp and bep:
- *      sp points to the next available character in the buffer
- *      bep points to the end-of-buffer+1
- * While using this macro, note that the nextb pointer is NOT updated.
- *
- * NOTE: Evaluation of the c argument should not have any side-effects
- */
-#define INS_CHAR( c, sp, bep, cc )  \
-        {               \
-        if ( sp < bep )     \
-        {           \
-            *sp++ = c ;     \
-            cc++ ;      \
-        }           \
-        }
-
-#define NUM( c )            ( c - '0' )
-
-#define STR_TO_DEC( str, num )      \
-    num = NUM( *str++ ) ;       \
-    while ( isdigit((int)*str ) )       \
-    {                   \
-    num *= 10 ;         \
-    num += NUM( *str++ ) ;      \
-    }
-
-/*
- * This macro does zero padding so that the precision
- * requirement is satisfied. The padding is done by
- * adding '0's to the left of the string that is going
- * to be printed.
- */
-#define FIX_PRECISION( adjust, precision, s, s_len )    \
-    if ( adjust )                   \
-    while ( s_len < precision )         \
-    {                       \
-        *--s = '0' ;                \
-        s_len++ ;                   \
-    }
-
-/*
- * Macro that does padding. The padding is done by printing
- * the character ch.
- */
-#define PAD( width, len, ch )   do      \
-    {                   \
-        INS_CHAR( ch, sp, bep, cc ) ;   \
-        width-- ;               \
-    }                   \
-    while ( width > len )
-
-/*
- * Prefix the character ch to the string str
- * Increase length
- * Set the has_prefix flag
- */
-#define PREFIX( str, length, ch )    *--str = ch ; length++ ; has_prefix = YES
-
-
-/*
- * Convert num to its decimal format.
- * Return value:
- *   - a pointer to a string containing the number (no sign)
- *   - len contains the length of the string
- *   - is_negative is set to TRUE or FALSE depending on the sign
- *     of the number (always set to FALSE if is_unsigned is TRUE)
- *
- * The caller provides a buffer for the string: that is the buf_end argument
- * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
- * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
- */
-static char *
-conv_10(register wide_int num, register bool_int is_unsigned,
-        register bool_int * is_negative, char *buf_end, register int *len)
-{
-    register char *p = buf_end;
-    register u_wide_int magnitude;
-
-    if (is_unsigned) {
-        magnitude = (u_wide_int) num;
-        *is_negative = FALSE;
-    } else {
-        *is_negative = (num < 0);
-
-        /*
-         * On a 2's complement machine, negating the most negative integer 
-         * results in a number that cannot be represented as a signed integer.
-         * Here is what we do to obtain the number's magnitude:
-         *      a. add 1 to the number
-         *      b. negate it (becomes positive)
-         *      c. convert it to unsigned
-         *      d. add 1
-         */
-        if (*is_negative) {
-            wide_int t = num + 1;
-
-            magnitude = ((u_wide_int) - t) + 1;
-        } else
-            magnitude = (u_wide_int) num;
-    }
-
-    /*
-     * We use a do-while loop so that we write at least 1 digit 
-     */
-    do {
-        register u_wide_int new_magnitude = magnitude / 10;
-
-        *--p = magnitude - new_magnitude * 10 + '0';
-        magnitude = new_magnitude;
-    }
-    while (magnitude);
-
-    *len = buf_end - p;
-    return (p);
-}
-
-
-
-/*
- * Convert a floating point number to a string formats 'f', 'e' or 'E'.
- * The result is placed in buf, and len denotes the length of the string
- * The sign is returned in the is_negative argument (and is not placed
- * in buf).
- */
-static char *
-conv_fp(register char format, register double num,
-        boolean_e add_dp, int precision, bool_int * is_negative, char *buf, int *len)
-{
-    register char *s = buf;
-    register char *p;
-    int decimal_point;
-
-    if (format == 'f')
-        p = ap_fcvt(num, precision, &decimal_point, is_negative);
-    else                        /* either e or E format */
-        p = ap_ecvt(num, precision + 1, &decimal_point, is_negative);
-
-    /*
-     * Check for Infinity and NaN
-     */
-    if (isalpha((int)*p)) {
-        *len = strlen(strcpy(buf, p));
-        *is_negative = FALSE;
-        return (buf);
-    }
-    if (format == 'f') {
-        if (decimal_point <= 0) {
-            *s++ = '0';
-            if (precision > 0) {
-                *s++ = '.';
-                while (decimal_point++ < 0)
-                    *s++ = '0';
-            } else if (add_dp) {
-                *s++ = '.';
-            }
-        } else {
-            while (decimal_point-- > 0) {
-                *s++ = *p++;
-            }
-            if (precision > 0 || add_dp) {
-                *s++ = '.';
-            }
-        }
-    } else {
-        *s++ = *p++;
-        if (precision > 0 || add_dp)
-            *s++ = '.';
-    }
-
-    /*
-     * copy the rest of p, the NUL is NOT copied
-     */
-    while (*p)
-        *s++ = *p++;
-
-    if (format != 'f') {
-        char temp[EXPONENT_LENGTH];     /* for exponent conversion */
-        int t_len;
-        bool_int exponent_is_negative;
-
-        *s++ = format;          /* either e or E */
-        decimal_point--;
-        if (decimal_point != 0) {
-            p = conv_10((wide_int) decimal_point, FALSE, &exponent_is_negative,
-                        &temp[EXPONENT_LENGTH], &t_len);
-            *s++ = exponent_is_negative ? '-' : '+';
-
-            /*
-             * Make sure the exponent has at least 2 digits
-             */
-            if (t_len == 1)
-                *s++ = '0';
-            while (t_len--)
-                *s++ = *p++;
-        } else {
-            *s++ = '+';
-            *s++ = '0';
-            *s++ = '0';
-        }
-    }
-    *len = s - buf;
-    return (buf);
-}
-
-
-/*
- * Convert num to a base X number where X is a power of 2. nbits determines X.
- * For example, if nbits is 3, we do base 8 conversion
- * Return value:
- *      a pointer to a string containing the number
- *
- * The caller provides a buffer for the string: that is the buf_end argument
- * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
- * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
- */
-static char *
-conv_p2(register u_wide_int num, register int nbits,
-        char format, char *buf_end, register int *len)
-{
-    register int mask = (1 << nbits) - 1;
-    register char *p = buf_end;
-    static char low_digits[] = "0123456789abcdef";
-    static char upper_digits[] = "0123456789ABCDEF";
-    register char *digits = (format == 'X') ? upper_digits : low_digits;
-
-    do {
-        *--p = digits[num & mask];
-        num >>= nbits;
-    }
-    while (num);
-
-    *len = buf_end - p;
-    return (p);
-}
-
-
-/*
- * Do format conversion placing the output in buffer
- */
-static int format_converter(register buffy * odp, const char *fmt,
-                            va_list ap)
-{
-    register char *sp;
-    register char *bep;
-    register int cc = 0;
-    register int i;
-
-    register char *s = NULL;
-    char *q;
-    int s_len;
-
-    register int min_width = 0;
-    int precision = 0;
-    enum {
-        LEFT, RIGHT
-    } adjust;
-    char pad_char;
-    char prefix_char;
-
-    double fp_num;
-    wide_int i_num = (wide_int) 0;
-    u_wide_int ui_num;
-
-    char num_buf[NUM_BUF_SIZE];
-    char char_buf[2];           /* for printing %% and %<unknown> */
-
-    /*
-     * Flag variables
-     */
-    boolean_e is_long;
-    boolean_e alternate_form;
-    boolean_e print_sign;
-    boolean_e print_blank;
-    boolean_e adjust_precision;
-    boolean_e adjust_width;
-    bool_int is_negative;
-
-    sp = odp->nextb;
-    bep = odp->buf_end;
-
-    while (*fmt) {
-        if (*fmt != '%') {
-            INS_CHAR(*fmt, sp, bep, cc);
-        } else {
-            /*
-             * Default variable settings
-             */
-            adjust = RIGHT;
-            alternate_form = print_sign = print_blank = NO;
-            pad_char = ' ';
-            prefix_char = NUL;
-
-            fmt++;
-
-            /*
-             * Try to avoid checking for flags, width or precision
-             */
-            if (isascii((int)*fmt) && !islower((int)*fmt)) {
-                /*
-                 * Recognize flags: -, #, BLANK, +
-                 */
-                for (;; fmt++) {
-                    if (*fmt == '-')
-                        adjust = LEFT;
-                    else if (*fmt == '+')
-                        print_sign = YES;
-                    else if (*fmt == '#')
-                        alternate_form = YES;
-                    else if (*fmt == ' ')
-                        print_blank = YES;
-                    else if (*fmt == '0')
-                        pad_char = '0';
-                    else
-                        break;
-                }
-
-                /*
-                 * Check if a width was specified
-                 */
-                if (isdigit((int)*fmt)) {
-                    STR_TO_DEC(fmt, min_width);
-                    adjust_width = YES;
-                } else if (*fmt == '*') {
-                    min_width = va_arg(ap, int);
-                    fmt++;
-                    adjust_width = YES;
-                    if (min_width < 0) {
-                        adjust = LEFT;
-                        min_width = -min_width;
-                    }
-                } else
-                    adjust_width = NO;
-
-                /*
-                 * Check if a precision was specified
-                 *
-                 * XXX: an unreasonable amount of precision may be specified
-                 * resulting in overflow of num_buf. Currently we
-                 * ignore this possibility.
-                 */
-                if (*fmt == '.') {
-                    adjust_precision = YES;
-                    fmt++;
-                    if (isdigit((int)*fmt)) {
-                        STR_TO_DEC(fmt, precision);
-                    } else if (*fmt == '*') {
-                        precision = va_arg(ap, int);
-                        fmt++;
-                        if (precision < 0)
-                            precision = 0;
-                    } else
-                        precision = 0;
-                } else
-                    adjust_precision = NO;
-            } else
-                adjust_precision = adjust_width = NO;
-
-            /*
-             * Modifier check
-             */
-            if (*fmt == 'l') {
-                is_long = YES;
-                fmt++;
-            } else
-                is_long = NO;
-
-            /*
-             * Argument extraction and printing.
-             * First we determine the argument type.
-             * Then, we convert the argument to a string.
-             * On exit from the switch, s points to the string that
-             * must be printed, s_len has the length of the string
-             * The precision requirements, if any, are reflected in s_len.
-             *
-             * NOTE: pad_char may be set to '0' because of the 0 flag.
-             *   It is reset to ' ' by non-numeric formats
-             */
-            switch (*fmt) {
-            case 'u':
-                if (is_long)
-                    i_num = va_arg(ap, u_wide_int);
-                else
-                    i_num = (wide_int) va_arg(ap, unsigned int);
-                /*
-                 * The rest also applies to other integer formats, so fall
-                 * into that case.
-                 */
-            case 'd':
-            case 'i':
-                /*
-                 * Get the arg if we haven't already.
-                 */
-                if ((*fmt) != 'u') {
-                    if (is_long)
-                        i_num = va_arg(ap, wide_int);
-                    else
-                        i_num = (wide_int) va_arg(ap, int);
-                };
-                s = conv_10(i_num, (*fmt) == 'u', &is_negative,
-                            &num_buf[NUM_BUF_SIZE], &s_len);
-                FIX_PRECISION(adjust_precision, precision, s, s_len);
-
-                if (*fmt != 'u') {
-                    if (is_negative)
-                        prefix_char = '-';
-                    else if (print_sign)
-                        prefix_char = '+';
-                    else if (print_blank)
-                        prefix_char = ' ';
-                }
-                break;
-
-
-            case 'o':
-                if (is_long)
-                    ui_num = va_arg(ap, u_wide_int);
-                else
-                    ui_num = (u_wide_int) va_arg(ap, unsigned int);
-                s = conv_p2(ui_num, 3, *fmt,
-                            &num_buf[NUM_BUF_SIZE], &s_len);
-                FIX_PRECISION(adjust_precision, precision, s, s_len);
-                if (alternate_form && *s != '0') {
-                    *--s = '0';
-                    s_len++;
-                }
-                break;
-
-
-            case 'x':
-            case 'X':
-                if (is_long)
-                    ui_num = (u_wide_int) va_arg(ap, u_wide_int);
-                else
-                    ui_num = (u_wide_int) va_arg(ap, unsigned int);
-                s = conv_p2(ui_num, 4, *fmt,
-                            &num_buf[NUM_BUF_SIZE], &s_len);
-                FIX_PRECISION(adjust_precision, precision, s, s_len);
-                if (alternate_form && i_num != 0) {
-                    *--s = *fmt;    /* 'x' or 'X' */
-                    *--s = '0';
-                    s_len += 2;
-                }
-                break;
-
-
-            case 's':
-                s = va_arg(ap, char *);
-                if (s != NULL) {
-                    s_len = strlen(s);
-                    if (adjust_precision && precision < s_len)
-                        s_len = precision;
-                } else {
-                    s = S_NULL;
-                    s_len = S_NULL_LEN;
-                }
-                pad_char = ' ';
-                break;
-
-
-            case 'f':
-            case 'e':
-            case 'E':
-                fp_num = va_arg(ap, double);
-
-                s = conv_fp(*fmt, fp_num, alternate_form,
-                            (adjust_precision == NO) ? FLOAT_DIGITS : precision,
-                            &is_negative, &num_buf[1], &s_len);
-                if (is_negative)
-                    prefix_char = '-';
-                else if (print_sign)
-                    prefix_char = '+';
-                else if (print_blank)
-                    prefix_char = ' ';
-                break;
-
-
-            case 'g':
-            case 'G':
-                if (adjust_precision == NO)
-                    precision = FLOAT_DIGITS;
-                else if (precision == 0)
-                    precision = 1;
-                /*
-                 * * We use &num_buf[ 1 ], so that we have room for the sign
-                 */
-                s = ap_gcvt(va_arg(ap, double), precision, &num_buf[1]);
-                if (*s == '-')
-                    prefix_char = *s++;
-                else if (print_sign)
-                    prefix_char = '+';
-                else if (print_blank)
-                    prefix_char = ' ';
-
-                s_len = strlen(s);
-
-                if (alternate_form && (q = strchr(s, '.')) == NULL)
-                    s[s_len++] = '.';
-                if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL)
-                    *q = 'E';
-                break;
-
-
-            case 'c':
-                char_buf[0] = (char) (va_arg(ap, int));
-                s = &char_buf[0];
-                s_len = 1;
-                pad_char = ' ';
-                break;
-
-
-            case '%':
-                char_buf[0] = '%';
-                s = &char_buf[0];
-                s_len = 1;
-                pad_char = ' ';
-                break;
-
-
-            case 'n':
-                *(va_arg(ap, int *)) = cc;
-                break;
-
-                /*
-                 * Always extract the argument as a "char *" pointer. We 
-                 * should be using "void *" but there are still machines 
-                 * that don't understand it.
-                 * If the pointer size is equal to the size of an unsigned
-                 * integer we convert the pointer to a hex number, otherwise 
-                 * we print "%p" to indicate that we don't handle "%p".
-                 */
-            case 'p':
-                ui_num = (u_wide_int) va_arg(ap, char *);
-
-                if (sizeof(char *) <= sizeof(u_wide_int))
-                    s = conv_p2(ui_num, 4, 'x',
-                                &num_buf[NUM_BUF_SIZE], &s_len);
-                else {
-                    s = "%p";
-                    s_len = 2;
-                }
-                pad_char = ' ';
-                break;
-
-
-            case NUL:
-                /*
-                 * The last character of the format string was %.
-                 * We ignore it.
-                 */
-                continue;
-
-
-                /*
-                 * The default case is for unrecognized %'s.
-                 * We print %<char> to help the user identify what
-                 * option is not understood.
-                 * This is also useful in case the user wants to pass
-                 * the output of format_converter to another function
-                 * that understands some other %<char> (like syslog).
-                 * Note that we can't point s inside fmt because the
-                 * unknown <char> could be preceded by width etc.
-                 */
-            default:
-                char_buf[0] = '%';
-                char_buf[1] = *fmt;
-                s = char_buf;
-                s_len = 2;
-                pad_char = ' ';
-                break;
-            }
-
-            if (prefix_char != NUL) {
-                *--s = prefix_char;
-                s_len++;
-            }
-            if (adjust_width && adjust == RIGHT && min_width > s_len) {
-                if (pad_char == '0' && prefix_char != NUL) {
-                    INS_CHAR(*s, sp, bep, cc)
-                    s++;
-                    s_len--;
-                    min_width--;
-                }
-                PAD(min_width, s_len, pad_char);
-            }
-            /*
-             * Print the string s. 
-             */
-            for (i = s_len; i != 0; i--) {
-                INS_CHAR(*s, sp, bep, cc);
-                s++;
-            }
-
-            if (adjust_width && adjust == LEFT && min_width > s_len)
-                PAD(min_width, s_len, pad_char);
-        }
-        fmt++;
-    }
-    odp->nextb = sp;
-    return (cc);
-}
-
-
-/*
- * This is the general purpose conversion function.
- */
-static void strx_printv(int *ccp, char *buf, size_t len, const char *format,
-                        va_list ap)
-{
-    buffy od;
-    int cc;
-
-    /*
-     * First initialize the descriptor
-     * Notice that if no length is given, we initialize buf_end to the
-     * highest possible address.
-     */
-    od.buf_end = len ? &buf[len] : (char *) ~0;
-    od.nextb = buf;
-
-    /*
-     * Do the conversion
-     */
-    cc = format_converter(&od, format, ap);
-    if (len == 0 || od.nextb <= od.buf_end)
-        *(od.nextb) = '\0';
-    if (ccp)
-        *ccp = cc;
-}
-
-
-int ap_snprintf(char *buf, size_t len, const char *format,...)
-{
-    int cc;
-    va_list ap;
-
-    va_start(ap, format);
-    strx_printv(&cc, buf, (len - 1), format, ap);
-    va_end(ap);
-    return (cc);
-}
-
-
-int ap_vsnprintf(char *buf, size_t len, const char *format, va_list ap)
-{
-    int cc;
-
-    strx_printv(&cc, buf, (len - 1), format, ap);
-    return (cc);
-}
-
-#endif                          /* HAVE_SNPRINTF */
--- a/src/protocols/jabber/socket.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-/* --------------------------------------------------------------------------
- *
- * License
- *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
- *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
- *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
-
-#include "lib.h"
-
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
-
-/* socket.c
- *
- * Simple wrapper to make socket creation easy.
- * type = NETSOCKET_SERVER is local listening socket
- * type = NETSOCKET_CLIENT is connection socket
- * type = NETSOCKET_UDP is a UDP connection socket
- */
-
-int make_netsocket(unsigned short port, char *host, int type)
-{
-    int s, flag = 1;
-    struct sockaddr_in sa;
-    struct in_addr *saddr;
-    int socket_type;
-
-    /* is this a UDP socket or a TCP socket? */
-    socket_type = (type == NETSOCKET_UDP)?SOCK_DGRAM:SOCK_STREAM;
-
-    bzero((void *)&sa,sizeof(struct sockaddr_in));
-
-    if((s = socket(AF_INET,socket_type,0)) < 0)
-        return(-1);
-    if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(flag)) < 0)
-        return(-1);
-
-    saddr = make_addr(host);
-    if(saddr == NULL && type != NETSOCKET_UDP)
-        return(-1);
-    sa.sin_family = AF_INET;
-    sa.sin_port = htons(port);
-
-    if(type == NETSOCKET_SERVER)
-    {
-        /* bind to specific address if specified */
-        if(host != NULL)
-            sa.sin_addr.s_addr = saddr->s_addr;
-
-        if(bind(s,(struct sockaddr*)&sa,sizeof sa) < 0)
-        {
-            close(s);
-            return(-1);
-        }
-    }
-    if(type == NETSOCKET_CLIENT)
-    {
-        sa.sin_addr.s_addr = saddr->s_addr;
-        if(connect(s,(struct sockaddr*)&sa,sizeof sa) < 0)
-        {
-            close(s);
-            return(-1);
-        }
-    }
-    if(type == NETSOCKET_UDP)
-    {
-        /* bind to all addresses for now */
-        if(bind(s,(struct sockaddr*)&sa,sizeof sa) < 0)
-        {
-            close(s);
-            return(-1);
-        }
-
-        /* if specified, use a default recipient for read/write */
-        if(host != NULL && saddr != NULL)
-        {
-            sa.sin_addr.s_addr = saddr->s_addr;
-            if(connect(s,(struct sockaddr*)&sa,sizeof sa) < 0)
-            {
-                close(s);
-                return(-1);
-            }
-        }
-    }
-
-
-    return(s);
-}
-
-
-struct in_addr *make_addr(char *host)
-{
-    struct hostent *hp;
-    static struct in_addr addr;
-    char myname[MAXHOSTNAMELEN + 1];
-
-    if(host == NULL || strlen(host) == 0)
-    {
-        gethostname(myname,MAXHOSTNAMELEN);
-        hp = gethostbyname(myname);
-        if(hp != NULL)
-        {
-            return (struct in_addr *) *hp->h_addr_list;
-        }
-    }else{
-        addr.s_addr = inet_addr(host);
-        if(addr.s_addr != -1)
-        {
-            return &addr;
-        }
-        hp = gethostbyname(host);
-        if(hp != NULL)
-        {
-            return (struct in_addr *) *hp->h_addr_list;
-        }
-    }
-    return NULL;
-}
-
-#ifndef _WIN32
-/* Sets a file descriptor to close on exec.  "flag" is 1 to close on exec, 0 to
- * leave open across exec.
- * -- EJB 7/31/2000
- */
-int set_fd_close_on_exec(int fd, int flag)
-{
-    int oldflags = fcntl(fd,F_GETFL);
-    int newflags;
-
-    if(flag)
-        newflags = oldflags | FD_CLOEXEC;
-    else
-        newflags = oldflags & (~FD_CLOEXEC);
-
-    if(newflags==oldflags)
-        return 0;
-    return fcntl(fd,F_SETFL,(long)newflags);
-}
-#endif
-
--- a/src/protocols/jabber/str.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,408 +0,0 @@
-/* --------------------------------------------------------------------------
- *
- * License
- *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
- *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
- *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
-
-#include "lib.h"
-
-#ifdef _WIN32
-#include "win32dep.h"
-#endif
-
-char *j_strdup(const char *str)
-{
-    if(str == NULL)
-        return NULL;
-    else
-        return strdup(str);
-}
-
-char *j_strcat(char *dest, char *txt)
-{
-    if(!txt) return(dest);
-
-    while(*txt)
-        *dest++ = *txt++;
-    *dest = '\0';
-
-    return(dest);
-}
-
-int j_strcmp(const char *a, const char *b)
-{
-    if(a == NULL || b == NULL)
-        return -1;
-
-    while(*a == *b && *a != '\0' && *b != '\0'){ a++; b++; }
-
-    if(*a == *b) return 0;
-
-    return -1;
-}
-
-int j_strcasecmp(const char *a, const char *b)
-{
-    if(a == NULL || b == NULL)
-        return -1;
-    else
-        return strcasecmp(a, b);
-}
-
-int j_strncmp(const char *a, const char *b, int i)
-{
-    if(a == NULL || b == NULL)
-        return -1;
-    else
-        return strncmp(a, b, i);
-}
-
-int j_strncasecmp(const char *a, const char *b, int i)
-{
-    if(a == NULL || b == NULL)
-        return -1;
-    else
-        return strncasecmp(a, b, i);
-}
-
-int j_strlen(const char *a)
-{
-    if(a == NULL)
-        return 0;
-    else
-        return strlen(a);
-}
-
-int j_atoi(const char *a, int def)
-{
-    if(a == NULL)
-        return def;
-    else
-        return atoi(a);
-}
-
-spool spool_new(pool p)
-{
-    spool s;
-
-    s = pmalloc(p, sizeof(struct spool_struct));
-    s->p = p;
-    s->len = 0;
-    s->last = NULL;
-    s->first = NULL;
-    return s;
-}
-
-void spool_add(spool s, char *str)
-{
-    struct spool_node *sn;
-    int len;
-
-    if(str == NULL)
-        return;
-
-    len = strlen(str);
-    if(len == 0)
-        return;
-
-    sn = pmalloc(s->p, sizeof(struct spool_node));
-    sn->c = pstrdup(s->p, str);
-    sn->next = NULL;
-
-    s->len += len;
-    if(s->last != NULL)
-        s->last->next = sn;
-    s->last = sn;
-    if(s->first == NULL)
-        s->first = sn;
-}
-
-void spooler(spool s, ...)
-{
-    va_list ap;
-    char *arg = NULL;
-
-    if(s == NULL)
-        return;
-
-    va_start(ap, s);
-
-    /* loop till we hit our end flag, the first arg */
-    while(1)
-    {
-        arg = va_arg(ap,char *);
-        if((spool)arg == s)
-            break;
-        else
-            spool_add(s, arg);
-    }
-
-    va_end(ap);
-}
-
-char *spool_print(spool s)
-{
-    char *ret,*tmp;
-    struct spool_node *next;
-
-    if(s == NULL || s->len == 0 || s->first == NULL)
-        return NULL;
-
-    ret = pmalloc(s->p, s->len + 1);
-    *ret = '\0';
-
-    next = s->first;
-    tmp = ret;
-    while(next != NULL)
-    {
-        tmp = j_strcat(tmp,next->c);
-        next = next->next;
-    }
-
-    return ret;
-}
-
-/* convenience :) */
-char *spools(pool p, ...)
-{
-    va_list ap;
-    spool s;
-    char *arg = NULL;
-
-    if(p == NULL)
-        return NULL;
-
-    s = spool_new(p);
-
-    va_start(ap, p);
-
-    /* loop till we hit our end flag, the first arg */
-    while(1)
-    {
-        arg = va_arg(ap,char *);
-        if((pool)arg == p)
-            break;
-        else
-            spool_add(s, arg);
-    }
-
-    va_end(ap);
-
-    return spool_print(s);
-}
-
-
-char *strunescape(pool p, char *buf)
-{
-    int i,j=0;
-    char *temp;
-
-    if (p == NULL || buf == NULL) return(NULL);
-
-    if (strchr(buf,'&') == NULL) return(buf);
-
-    temp = pmalloc(p,strlen(buf)+1);
-
-    if (temp == NULL) return(NULL);
-
-    for(i=0;i<strlen(buf);i++)
-    {
-        if (buf[i]=='&')
-        {
-            if (strncmp(&buf[i],"&amp;",5)==0)
-            {
-                temp[j] = '&';
-                i += 4;
-            } else if (strncmp(&buf[i],"&quot;",6)==0) {
-                temp[j] = '\"';
-                i += 5;
-            } else if (strncmp(&buf[i],"&apos;",6)==0) {
-                temp[j] = '\'';
-                i += 5;
-            } else if (strncmp(&buf[i],"&lt;",4)==0) {
-                temp[j] = '<';
-                i += 3;
-            } else if (strncmp(&buf[i],"&gt;",4)==0) {
-                temp[j] = '>';
-                i += 3;
-            }
-        } else {
-            temp[j]=buf[i];
-        }
-        j++;
-    }
-    temp[j]='\0';
-    return(temp);
-}
-
-
-char *strescape(pool p, char *buf)
-{
-    int i,j,oldlen,newlen;
-    char *temp;
-
-    if (p == NULL || buf == NULL) return(NULL);
-
-    oldlen = newlen = strlen(buf);
-    for(i=0;i<oldlen;i++)
-    {
-        switch(buf[i])
-        {
-        case '&':
-            newlen+=5;
-            break;
-        case '\'':
-            newlen+=6;
-            break;
-        case '\"':
-            newlen+=6;
-            break;
-        case '<':
-            newlen+=4;
-            break;
-        case '>':
-            newlen+=4;
-            break;
-        }
-    }
-
-    if(oldlen == newlen) return buf;
-
-    temp = pmalloc(p,newlen+1);
-
-    if (temp==NULL) return(NULL);
-
-    for(i=j=0;i<oldlen;i++)
-    {
-        switch(buf[i])
-        {
-        case '&':
-            memcpy(&temp[j],"&amp;",5);
-            j += 5;
-            break;
-        case '\'':
-            memcpy(&temp[j],"&apos;",6);
-            j += 6;
-            break;
-        case '\"':
-            memcpy(&temp[j],"&quot;",6);
-            j += 6;
-            break;
-        case '<':
-            memcpy(&temp[j],"&lt;",4);
-            j += 4;
-            break;
-        case '>':
-            memcpy(&temp[j],"&gt;",4);
-            j += 4;
-            break;
-        default:
-            temp[j++] = buf[i];
-        }
-    }
-    temp[j] = '\0';
-    return temp;
-}
-
-char *zonestr(char *file, int line)
-{
-    static char buff[64];
-    int i;
-
-    i = snprintf(buff,63,"%s:%d",file,line);
-    buff[i] = '\0';
-
-    return buff;
-}
-
-void str_b64decode(char* str)
-{
-    char *cur;
-    int d, dlast, phase;
-    unsigned char c;
-    static int table[256] = {
-        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 00-0F */
-        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 10-1F */
-        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,  /* 20-2F */
-        52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,  /* 30-3F */
-        -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,  /* 40-4F */
-        15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,  /* 50-5F */
-        -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,  /* 60-6F */
-        41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1,  /* 70-7F */
-        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 80-8F */
-        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* 90-9F */
-        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* A0-AF */
-        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* B0-BF */
-        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* C0-CF */
-        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* D0-DF */
-        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,  /* E0-EF */
-        -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1   /* F0-FF */
-    };
-
-    d = dlast = phase = 0;
-    for (cur = str; *cur != '\0'; ++cur )
-    {
-        d = table[(int)*cur];
-        if(d != -1)
-        {
-            switch(phase)
-            {
-            case 0:
-                ++phase;
-                break;
-            case 1:
-                c = ((dlast << 2) | ((d & 0x30) >> 4));
-                *str++ = c;
-                ++phase;
-                break;
-            case 2:
-                c = (((dlast & 0xf) << 4) | ((d & 0x3c) >> 2));
-                *str++ = c;
-                ++phase;
-                break;
-            case 3:
-                c = (((dlast & 0x03 ) << 6) | d);
-                *str++ = c;
-                phase = 0;
-                break;
-            }
-            dlast = d;
-        }
-    }
-    *str = '\0';
-}
--- a/src/protocols/jabber/utf8tab.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-
-/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
-/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
-/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
-/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
-/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
-/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
--- a/src/protocols/jabber/xhash.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,194 +0,0 @@
-/* --------------------------------------------------------------------------
- *
- * License
- *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
- *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
- *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
-
-#include "lib.h"
-
-
-/* Generates a hash code for a string.
- * This function uses the ELF hashing algorithm as reprinted in 
- * Andrew Binstock, "Hashing Rehashed," Dr. Dobb's Journal, April 1996.
- */
-int _xhasher(const char *s)
-{
-    /* ELF hash uses unsigned chars and unsigned arithmetic for portability */
-    const unsigned char *name = (const unsigned char *)s;
-    unsigned long h = 0, g;
-
-    while (*name)
-    { /* do some fancy bitwanking on the string */
-        h = (h << 4) + (unsigned long)(*name++);
-        if ((g = (h & 0xF0000000UL))!=0)
-            h ^= (g >> 24);
-        h &= ~g;
-
-    }
-
-    return (int)h;
-}
-
-
-xhn _xhash_node_new(xht h, int index)
-{
-    xhn n;
-    int i = index % h->prime;
-
-    /* get existing empty one */
-    for(n = &h->zen[i]; n != NULL; n = n->next)
-        if(n->key == NULL)
-            return n;
-
-    /* overflowing, new one! */
-    n = pmalloco(h->p, sizeof(_xhn));
-    n->next = h->zen[i].next;
-    h->zen[i].next = n;
-    return n;
-}
-
-
-xhn _xhash_node_get(xht h, const char *key, int index)
-{
-    xhn n;
-    int i = index % h->prime;
-    for(n = &h->zen[i]; n != NULL; n = n->next)
-        if(j_strcmp(key, n->key) == 0)
-            return n;
-    return NULL;
-}
-
-
-xht xhash_new(int prime)
-{
-    xht xnew;
-    pool p;
-
-/*    log_debug(ZONE,"creating new hash table of size %d",prime); */
-
-    p = pool_heap(sizeof(_xhn)*prime + sizeof(_xht));
-    xnew = pmalloco(p, sizeof(_xht));
-    xnew->prime = prime;
-    xnew->p = p;
-    xnew->zen = pmalloco(p, sizeof(_xhn)*prime); /* array of xhn size of prime */
-    return xnew;
-}
-
-
-void xhash_put(xht h, const char *key, void *val)
-{
-    int index;
-    xhn n;
-
-    if(h == NULL || key == NULL)
-        return;
-
-    index = _xhasher(key);
-
-    /* if existing key, replace it */
-    if((n = _xhash_node_get(h, key, index)) != NULL)
-    {
-/*        log_debug(ZONE,"replacing %s with new val %X",key,val); */
-
-        n->key = key;
-        n->val = val;
-        return;
-    }
-
-/*    log_debug(ZONE,"saving %s val %X",key,val); */
-
-    /* new node */
-    n = _xhash_node_new(h, index);
-    n->key = key;
-    n->val = val;
-}
-
-
-void *xhash_get(xht h, const char *key)
-{
-    xhn n;
-
-    if(h == NULL || key == NULL || (n = _xhash_node_get(h, key, _xhasher(key))) == NULL)
-    {
-/*        log_debug(ZONE,"failed lookup of %s",key); */
-        return NULL;
-    }
-
-/*    log_debug(ZONE,"found %s returning %X",key,n->val); */
-    return n->val;
-}
-
-
-void xhash_zap(xht h, const char *key)
-{
-    xhn n;
-
-    if(h == NULL || key == NULL || (n = _xhash_node_get(h, key, _xhasher(key))) == NULL)
-        return;
-
-/*    log_debug(ZONE,"zapping %s",key); */
-
-    /* kill an entry by zeroing out the key */
-    n->key = NULL;
-}
-
-
-void xhash_free(xht h)
-{
-/*    log_debug(ZONE,"hash free %X",h); */
-
-    if(h != NULL)
-        pool_free(h->p);
-}
-
-void xhash_walk(xht h, xhash_walker w, void *arg)
-{
-    int i;
-    xhn n;
-
-    if(h == NULL || w == NULL)
-        return;
-
-/*    log_debug(ZONE,"walking %X",h); */
-
-    for(i = 0; i < h->prime; i++)
-        for(n = &h->zen[i]; n != NULL; n = n->next)
-            if(n->key != NULL && n->val != NULL)
-                (*w)(h, n->key, n->val, arg);
-}
-
--- a/src/protocols/jabber/xmldef.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#include <string.h>
-
-#ifdef XML_WINLIB
-
-#define WIN32_LEAN_AND_MEAN
-#define STRICT
-#include <windows.h>
-
-#define malloc(x) HeapAlloc(GetProcessHeap(), 0, (x))
-#define calloc(x, y) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (x)*(y))
-#define free(x) HeapFree(GetProcessHeap(), 0, (x))
-#define realloc(x, y) HeapReAlloc(GetProcessHeap(), 0, x, y)
-#define abort() /* as nothing */
-
-#else /* not XML_WINLIB */
-
-#include <stdlib.h>
-
-#endif /* not XML_WINLIB */
-
-/* This file can be used for any definitions needed in
-particular environments. */
-
-#ifdef MOZILLA
-
-#include "nspr.h"
-#define malloc(x) PR_Malloc(x)
-#define realloc(x, y) PR_Realloc((x), (y))
-#define calloc(x, y) PR_Calloc((x),(y))
-#define free(x) PR_Free(x)
-#define int int32
-
-#endif /* MOZILLA */
--- a/src/protocols/jabber/xmlnode.c	Mon Sep 29 13:00:55 2003 +0000
+++ b/src/protocols/jabber/xmlnode.c	Mon Sep 29 15:23:19 2003 +0000
@@ -1,846 +1,372 @@
-/* --------------------------------------------------------------------------
- *
- * License
+/**
+ * @file xmlnode.c XML DOM functions
  *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
+ * gaim
  *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
+ * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
  *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
+ * 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.
  *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
+ * 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 "lib.h"
-
-/* Internal routines */
-xmlnode _xmlnode_new(pool p, const char* name, unsigned int type)
-{
-    xmlnode result = NULL;
-    if (type > NTYPE_LAST)
-        return NULL;
+/* A lot of this code at least resembles the code in libxode, but since
+ * libxode uses memory pools that we simply have no need for, I decided to
+ * write my own stuff.  Also, re-writing this lets me be as lightweight
+ * as I want to be.  Thank you libxode for giving me a good starting point */
 
-    if (type != NTYPE_CDATA && name == NULL)
-        return NULL;
+#include "internal.h"
 
-    if (p == NULL)
-    {
-        p = pool_heap(1*1024);
-    }
-
-    /* Allocate & zero memory */
-    result = (xmlnode)pmalloco(p, sizeof(_xmlnode));
+#include <string.h>
+#include <glib.h>
 
-    /* Initialize fields */
-    if (type != NTYPE_CDATA)
-        result->name = pstrdup(p,name);
-    result->type = type;
-    result->p = p;
-    return result;
-}
+#include "xmlnode.h"
 
-static xmlnode _xmlnode_append_sibling(xmlnode lastsibling, const char* name, unsigned int type)
+static xmlnode*
+new_node(const char *name, NodeType type)
 {
-    xmlnode result;
+	xmlnode *node = g_new0(xmlnode, 1);
+	if(name)
+		node->name = g_strdup(name);
+	node->type = type;
 
-    result = _xmlnode_new(xmlnode_pool(lastsibling), name, type);
-    if (result != NULL)
-    {
-        /* Setup sibling pointers */
-        result->prev = lastsibling;
-        lastsibling->next = result;
-    }
-    return result;
+	return node;
 }
 
-static xmlnode _xmlnode_insert(xmlnode parent, const char* name, unsigned int type)
+xmlnode*
+xmlnode_new(const char *name)
 {
-    xmlnode result;
-
-    if(parent == NULL || (type != NTYPE_CDATA && name == NULL)) return NULL;
+	g_return_val_if_fail(name != NULL, NULL);
 
-    /* If parent->firstchild is NULL, simply create a new node for the first child */
-    if (parent->firstchild == NULL)
-    {
-        result = _xmlnode_new(parent->p, name, type);
-        parent->firstchild = result;
-    }
-    /* Otherwise, append this to the lastchild */
-    else
-    {
-        result= _xmlnode_append_sibling(parent->lastchild, name, type);
-    }
-    result->parent = parent;
-    parent->lastchild = result;
-    return result;
-
+	return new_node(name, NODE_TYPE_TAG);
 }
 
-static xmlnode _xmlnode_search(xmlnode firstsibling, const char* name, unsigned int type)
+xmlnode *xmlnode_new_child(xmlnode *parent, const char *name)
 {
-    xmlnode current;
+	xmlnode *node;
 
-    /* Walk the sibling list, looking for a NTYPE_TAG xmlnode with
-    the specified name */
-    current = firstsibling;
-    while (current != NULL)
-    {
-        if ((current->type == type) && (j_strcmp(current->name, name) == 0))
-            return current;
-        else
-            current = current->next;
-    }
-    return NULL;
+	g_return_val_if_fail(parent != NULL, NULL);
+	g_return_val_if_fail(name != NULL, NULL);
+
+	node = new_node(name, NODE_TYPE_TAG);
+
+	xmlnode_insert_child(parent, node);
+
+	return node;
 }
 
-void _xmlnode_merge(xmlnode data)
+void
+xmlnode_insert_child(xmlnode *parent, xmlnode *child)
 {
-    xmlnode cur;
-    char *merge, *scur;
-    int imerge;
+	g_return_if_fail(parent != NULL);
+	g_return_if_fail(child != NULL);
 
-    /* get total size of all merged cdata */
-    imerge = 0;
-    for(cur = data; cur != NULL && cur->type == NTYPE_CDATA; cur = cur->next)
-        imerge += cur->data_sz;
+	child->parent = parent;
 
-    /* copy in current data and then spin through all of them and merge */
-    scur = merge = pmalloc(data->p,imerge + 1);
-    for(cur = data; cur != NULL && cur->type == NTYPE_CDATA; cur = cur->next)
-    {
-        memcpy(scur,cur->data,cur->data_sz);
-        scur += cur->data_sz;
-    }
-    *scur = '\0';
-
-    /* this effectively hides all of the merged-in chunks */
-    data->next = cur;
-    if(cur == NULL)
-        data->parent->lastchild = data;
-    else
-        cur->prev = data;
-
-    /* reset data */
-    data->data = merge;
-    data->data_sz = imerge;
-    
+	if(parent->child) {
+		xmlnode *x;
+		for(x = parent->child; x->next; x = x->next);
+		x->next = child;
+	} else {
+		parent->child = child;
+	}
 }
 
-static void _xmlnode_hide_sibling(xmlnode child)
+void
+xmlnode_insert_data(xmlnode *parent, const char *data, size_t size)
 {
-    if(child == NULL)
-        return;
-
-    if(child->prev != NULL)
-        child->prev->next = child->next;
-    if(child->next != NULL)
-        child->next->prev = child->prev;
-}
-
-void _xmlnode_tag2str(spool s, xmlnode node, int flag)
-{
-    xmlnode tmp;
+	xmlnode *node;
+	size_t real_size;
 
-    if(flag==0 || flag==1)
-    {
-	    spooler(s,"<",xmlnode_get_name(node),s);
-	    tmp = xmlnode_get_firstattrib(node);
-	    while(tmp) {
-	        spooler(s," ",xmlnode_get_name(tmp),"='",strescape(xmlnode_pool(node),xmlnode_get_data(tmp)),"'",s);
-	        tmp = xmlnode_get_nextsibling(tmp);
-	    }
-	    if(flag==0)
-	        spool_add(s,"/>");
-	    else
-	        spool_add(s,">");
-    }
-    else
-    {
-	    spooler(s,"</",xmlnode_get_name(node),">",s);
-    }
+	g_return_if_fail(parent != NULL);
+	g_return_if_fail(data != NULL);
+	g_return_if_fail(size != 0);
+
+	real_size = size == -1 ? strlen(data) : size;
+
+	node = new_node(NULL, NODE_TYPE_DATA);
+
+	node->data = g_memdup(data, real_size);
+	node->data_sz = real_size;
+
+	xmlnode_insert_child(parent, node);
 }
 
-spool _xmlnode2spool(xmlnode node)
+void
+xmlnode_remove_attrib(xmlnode *node, const char *attr)
 {
-    spool s;
-    int level=0,dir=0;
-    xmlnode tmp;
+	xmlnode *attr_node, *sibling = NULL;
 
-    if(!node || xmlnode_get_type(node)!=NTYPE_TAG)
-        return NULL;
-
-    s = spool_new(xmlnode_pool(node));
-    if(!s) return(NULL);
+	g_return_if_fail(node != NULL);
+	g_return_if_fail(attr != NULL);
 
-    while(1)
-    {
-        if(dir==0)
-        {
-    	    if(xmlnode_get_type(node) == NTYPE_TAG)
-            {
-                if(xmlnode_has_children(node))
-                {
-                    _xmlnode_tag2str(s,node,1);
-                    node = xmlnode_get_firstchild(node);
-                    level++;
-                    continue;
-                }else{
-                    _xmlnode_tag2str(s,node,0);
-                }
-            }else{
-                spool_add(s,strescape(xmlnode_pool(node),xmlnode_get_data(node)));
-            }
-        }
-
-    	tmp = xmlnode_get_nextsibling(node);
-        if(!tmp)
-        {
-            node = xmlnode_get_parent(node);
-            level--;
-            if(level>=0) _xmlnode_tag2str(s,node,2);
-            if(level<1) break;
-            dir = 1;
-        }else{
-            node = tmp;
-            dir = 0;
-        }
-    }
-
-    return s;
+	for(attr_node = node->child; attr_node; attr_node = attr_node->next)
+	{
+		if(attr_node->type == NODE_TYPE_ATTRIB &&
+				!strcmp(attr_node->name, attr)) {
+			if(node->child == attr_node) {
+				node->child = attr_node->next;
+			} else {
+				sibling->next = attr_node->next;
+			}
+			xmlnode_free(attr_node);
+			return;
+		}
+		sibling = attr_node;
+	}
 }
 
-
-/* External routines */
-
+void
+xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value)
+{
+	xmlnode *attrib_node;
 
-/*
- *  xmlnode_new_tag -- create a tag node
- *  Automatically creates a memory pool for the node.
- *
- *  parameters
- *      name -- name of the tag
- *
- *  returns
- *      a pointer to the tag node
- *      or NULL if it was unsuccessfull
- */
-xmlnode xmlnode_new_tag(const char* name)
-{
-    return _xmlnode_new(NULL, name, NTYPE_TAG);
+	g_return_if_fail(node != NULL);
+	g_return_if_fail(attr != NULL);
+	g_return_if_fail(value != NULL);
+
+	xmlnode_remove_attrib(node, attr);
+
+	attrib_node = new_node(attr, NODE_TYPE_ATTRIB);
+
+	attrib_node->data = g_strdup(value);
+
+	xmlnode_insert_child(node, attrib_node);
 }
 
-
-/*
- *  xmlnode_new_tag_pool -- create a tag node within given pool
- *
- *  parameters
- *      p -- previously created memory pool
- *      name -- name of the tag
- *
- *  returns
- *      a pointer to the tag node
- *      or NULL if it was unsuccessfull
- */
-xmlnode xmlnode_new_tag_pool(pool p, const char* name)
+const char*
+xmlnode_get_attrib(xmlnode *node, const char *attr)
 {
-    return _xmlnode_new(p, name, NTYPE_TAG);
-}
+	xmlnode *x;
 
+	g_return_val_if_fail(node != NULL, NULL);
 
-/*
- *  xmlnode_insert_tag -- append a child tag to a tag
- *
- *  parameters
- *      parent -- pointer to the parent tag
- *      name -- name of the child tag
- *
- *  returns
- *      a pointer to the child tag node
- *      or NULL if it was unsuccessfull
- */
-xmlnode xmlnode_insert_tag(xmlnode parent, const char* name)
-{
-    return _xmlnode_insert(parent, name, NTYPE_TAG);
+	for(x = node->child; x; x = x->next) {
+		if(x->type == NODE_TYPE_ATTRIB && !strcmp(attr, x->name)) {
+			return x->data;
+		}
+	}
+
+	return NULL;
 }
 
-
-/*
- *  xmlnode_insert_cdata -- append character data to a tag
- *
- *  parameters
- *      parent -- parent tag
- *      CDATA -- character data
- *      size -- size of CDATA
- *              or -1 for null-terminated CDATA strings
- *
- *  returns
- *      a pointer to the child CDATA node
- *      or NULL if it was unsuccessfull
- */
-xmlnode xmlnode_insert_cdata(xmlnode parent, const char* CDATA, unsigned int size)
+void xmlnode_free(xmlnode *node)
 {
-    xmlnode result;
+	xmlnode *x, *y;
 
-    if(CDATA == NULL || parent == NULL)
-        return NULL;
-
-    if(size == -1)
-        size = strlen(CDATA);
+	g_return_if_fail(node != NULL);
 
-    result = _xmlnode_insert(parent, NULL, NTYPE_CDATA);
-    if (result != NULL)
-    {
-        result->data = (char*)pmalloc(result->p, size + 1);
-        memcpy(result->data, CDATA, size);
-        result->data[size] = '\0';
-        result->data_sz = size;
-    }
+	x = node->child;
+	while(x) {
+		y = x->next;
+		xmlnode_free(x);
+		x = y;
+	}
 
-    return result;
+	if(node->name)
+		g_free(node->name);
+	if(node->data)
+		g_free(node->data);
+	g_free(node);
 }
 
+xmlnode*
+xmlnode_get_child(xmlnode *parent, const char *name)
+{
+	xmlnode *x, *ret = NULL;
+	char **names;
+	char *parent_name, *child_name;
 
-/*
- *  xmlnode_get_tag -- find given tag in an xmlnode tree
- *
- *  parameters
- *      parent -- pointer to the parent tag
- *      name -- "name" for the child tag of that name
- *              "name/name" for a sub child (recurses)
- *              "?attrib" to match the first tag with that attrib defined
- *              "?attrib=value" to match the first tag with that attrib and value
- *              "=cdata" to match the cdata contents of the child
- *              or any combination: "name/name/?attrib", "name=cdata", etc
- *
- *  results
- *      a pointer to the tag matching search criteria
- *      or NULL if search was unsuccessfull
- */
-xmlnode xmlnode_get_tag(xmlnode parent, const char* name)
-{
-    char *str, *slash, *qmark, *equals;
-    xmlnode step, ret;
+	g_return_val_if_fail(parent != NULL, NULL);
+
+	names = g_strsplit(name, "/", 2);
+	parent_name = names[0];
+	child_name = names[1];
 
-
-    if(parent == NULL || parent->firstchild == NULL || name == NULL || name == '\0') return NULL;
-
-    if(strstr(name, "/") == NULL && strstr(name,"?") == NULL && strstr(name, "=") == NULL)
-        return _xmlnode_search(parent->firstchild, name, NTYPE_TAG);
-
-    str = strdup(name);
-    slash = strstr(str, "/");
-    qmark = strstr(str, "?");
-    equals = strstr(str, "=");
+	for(x = parent->child; x; x = x->next) {
+		if(x->type == NODE_TYPE_TAG && name && !strcmp(parent_name, x->name)) {
+			ret = x;
+			break;
+		}
+	}
 
-    if(equals != NULL && (slash == NULL || equals < slash) && (qmark == NULL || equals < qmark))
-    { /* of type =cdata */
+	if(child_name && ret)
+		ret = xmlnode_get_child(x, child_name);
 
-        *equals = '\0';
-        equals++;
-
-        for(step = parent->firstchild; step != NULL; step = xmlnode_get_nextsibling(step))
-        {
-            if(xmlnode_get_type(step) != NTYPE_TAG)
-                continue;
+	g_strfreev(names);
+	return ret;
+}
 
-            if(*str != '\0')
-                if(j_strcmp(xmlnode_get_name(step),str) != 0)
-                    continue;
-
-            if(j_strcmp(xmlnode_get_data(step),equals) != 0)
-                continue;
+char *
+xmlnode_get_data(xmlnode *node)
+{
+	GString *str;
+	char *ret;
+	xmlnode *c;
 
-            break;
-        }
+	g_return_val_if_fail(node != NULL, NULL);
+
+	str = g_string_new("");
 
-        free(str);
-        return step;
-    }
-
-
-    if(qmark != NULL && (slash == NULL || qmark < slash))
-    { /* of type ?attrib */
+	for(c = node->child; c; c = c->next) {
+		if(c->type == NODE_TYPE_DATA)
+			str = g_string_append_len(str, c->data, c->data_sz);
+	}
 
-        *qmark = '\0';
-        qmark++;
-        if(equals != NULL)
-        {
-            *equals = '\0';
-            equals++;
-        }
+	ret = str->str;
+	g_string_free(str, FALSE);
 
-        for(step = parent->firstchild; step != NULL; step = xmlnode_get_nextsibling(step))
-        {
-            if(xmlnode_get_type(step) != NTYPE_TAG)
-                continue;
+	return ret;
+}
 
-            if(*str != '\0')
-                if(j_strcmp(xmlnode_get_name(step),str) != 0)
-                    continue;
-
-            if(xmlnode_get_attrib(step,qmark) == NULL)
-                continue;
+char *xmlnode_to_str(xmlnode *node)
+{
+	char *ret;
+	GString *text = g_string_new("");
+	xmlnode *c;
+	char *node_name, *esc, *esc2;
+	gboolean need_end = FALSE;
 
-            if(equals != NULL && j_strcmp(xmlnode_get_attrib(step,qmark),equals) != 0)
-                continue;
-
-            break;
-        }
-
-        free(str);
-        return step;
-    }
+	node_name = g_markup_escape_text(node->name, -1);
+	g_string_append_printf(text, "<%s", node_name);
 
 
-    *slash = '\0';
-    ++slash;
-
-    for(step = parent->firstchild; step != NULL; step = xmlnode_get_nextsibling(step))
-    {
-        if(xmlnode_get_type(step) != NTYPE_TAG) continue;
-
-        if(j_strcmp(xmlnode_get_name(step),str) != 0)
-            continue;
-
-        ret = xmlnode_get_tag(step, slash);
-        if(ret != NULL)
-        {
-            free(str);
-            return ret;
-        }
-    }
-
-    free(str);
-    return NULL;
-}
-
-
-/* return the cdata from any tag */
-char *xmlnode_get_tag_data(xmlnode parent, const char *name)
-{
-    xmlnode tag;
-
-    tag = xmlnode_get_tag(parent, name);
-    if(tag == NULL) return NULL;
-
-    return xmlnode_get_data(tag);
-}
-
-
-void xmlnode_put_attrib(xmlnode owner, const char* name, const char* value)
-{
-    xmlnode attrib;
-
-    if(owner == NULL || name == NULL || value == NULL) return;
+	for(c = node->child; c; c = c->next)
+	{
+		if(c->type == NODE_TYPE_ATTRIB) {
+			esc = g_markup_escape_text(c->name, -1);
+			esc2 = g_markup_escape_text(c->data, -1);
+			g_string_append_printf(text, " %s='%s'", esc, esc2);
+			g_free(esc);
+			g_free(esc2);
+		} else if(c->type == NODE_TYPE_TAG || c->type == NODE_TYPE_DATA) {
+			need_end = TRUE;
+		}
+	}
 
-    /* If there are no existing attributs, allocate a new one to start
-    the list */
-    if (owner->firstattrib == NULL)
-    {
-        attrib = _xmlnode_new(owner->p, name, NTYPE_ATTRIB);
-        owner->firstattrib = attrib;
-        owner->lastattrib  = attrib;
-    }
-    else
-    {
-        attrib = _xmlnode_search(owner->firstattrib, name, NTYPE_ATTRIB);
-        if(attrib == NULL)
-        {
-            attrib = _xmlnode_append_sibling(owner->lastattrib, name, NTYPE_ATTRIB);
-            owner->lastattrib = attrib;
-        }
-    }
-    /* Update the value of the attribute */
-    attrib->data_sz = strlen(value);
-    attrib->data    = pstrdup(owner->p, value);
-
-}
-
-char* xmlnode_get_attrib(xmlnode owner, const char* name)
-{
-    xmlnode attrib;
-
-    if (owner != NULL && owner->firstattrib != NULL)
-    {
-        attrib = _xmlnode_search(owner->firstattrib, name, NTYPE_ATTRIB);
-        if (attrib != NULL)
-            return (char*)attrib->data;
-    }
-    return NULL;
-}
-
-void xmlnode_put_vattrib(xmlnode owner, const char* name, void *value)
-{
-    xmlnode attrib;
-
-    if (owner != NULL)
-    {
-        attrib = _xmlnode_search(owner->firstattrib, name, NTYPE_ATTRIB);
-        if (attrib == NULL)
-        {
-            xmlnode_put_attrib(owner, name, "");
-            attrib = _xmlnode_search(owner->firstattrib, name, NTYPE_ATTRIB);
-        }
-        if (attrib != NULL)
-            attrib->firstchild = (xmlnode)value;
-    }
-}
-
-void* xmlnode_get_vattrib(xmlnode owner, const char* name)
-{
-    xmlnode attrib;
+	if(need_end) {
+		text = g_string_append_c(text, '>');
 
-    if (owner != NULL && owner->firstattrib != NULL)
-    {
-        attrib = _xmlnode_search(owner->firstattrib, name, NTYPE_ATTRIB);
-        if (attrib != NULL)
-            return (void*)attrib->firstchild;
-    }
-    return NULL;
-}
-
-xmlnode xmlnode_get_firstattrib(xmlnode parent)
-{
-    if (parent != NULL)
-        return parent->firstattrib;
-    return NULL;
-}
-
-xmlnode xmlnode_get_firstchild(xmlnode parent)
-{
-    if (parent != NULL)
-        return parent->firstchild;
-    return NULL;
-}
-
-xmlnode xmlnode_get_lastchild(xmlnode parent)
-{
-    if (parent != NULL)
-        return parent->lastchild;
-    return NULL;
-}
-
-xmlnode xmlnode_get_nextsibling(xmlnode sibling)
-{
-    if (sibling != NULL)
-        return sibling->next;
-    return NULL;
-}
-
-xmlnode xmlnode_get_prevsibling(xmlnode sibling)
-{
-    if (sibling != NULL)
-        return sibling->prev;
-    return NULL;
-}
-
-xmlnode xmlnode_get_parent(xmlnode node)
-{
-    if (node != NULL)
-        return node->parent;
-    return NULL;
-}
+		for(c = node->child; c; c = c->next)
+		{
+			if(c->type == NODE_TYPE_TAG) {
+				esc = xmlnode_to_str(c);
+				g_string_append_printf(text, "%s", esc);
+				g_free(esc);
+			} else if(c->type == NODE_TYPE_DATA) {
+				esc = g_markup_escape_text(c->data, c->data_sz);
+				g_string_append_printf(text, "%s", esc);
+				g_free(esc);
+			}
+		}
 
-char* xmlnode_get_name(xmlnode node)
-{
-    if (node != NULL)
-        return node->name;
-    return NULL;
-}
-
-char* xmlnode_get_data(xmlnode node)
-{
-    if(xmlnode_get_type(node) == NTYPE_TAG) /* loop till we find a CDATA in the children */
-        for(node = xmlnode_get_firstchild(node); node != NULL; node = xmlnode_get_nextsibling(node))
-            if(xmlnode_get_type(node) == NTYPE_CDATA) break;
-
-    if(node == NULL) return NULL;
-
-    /* check for a dirty node w/ unassembled cdata chunks */
-    if(xmlnode_get_type(node->next) == NTYPE_CDATA)
-        _xmlnode_merge(node);
-
-    return node->data;
-}
-
-int xmlnode_get_datasz(xmlnode node)
-{
-    if(xmlnode_get_type(node) != NTYPE_CDATA) return 0;
+		g_string_append_printf(text, "</%s>", node_name);
+	} else {
+		g_string_append_printf(text, "/>");
+	}
 
-    /* check for a dirty node w/ unassembled cdata chunks */
-    if(xmlnode_get_type(node->next) == NTYPE_CDATA)
-        _xmlnode_merge(node);
-    return node->data_sz;
-}
-
-int xmlnode_get_type(xmlnode node)
-{
-    if (node != NULL)
-        return node->type;
-    return NTYPE_UNDEF;
-}
+	g_free(node_name);
 
-int xmlnode_has_children(xmlnode node)
-{
-    if ((node != NULL) && (node->firstchild != NULL))
-        return 1;
-    return 0;
-}
-
-int xmlnode_has_attribs(xmlnode node)
-{
-    if ((node != NULL) && (node->firstattrib != NULL))
-        return 1;
-    return 0;
-}
-
-pool xmlnode_pool(xmlnode node)
-{
-    if (node != NULL)
-        return node->p;
-    return (pool)NULL;
+	ret = text->str;
+	g_string_free(text, FALSE);
+	return ret;
 }
 
-void xmlnode_hide(xmlnode child)
-{
-    xmlnode parent;
+struct _xmlnode_parser_data {
+	xmlnode *current;
+};
 
-    if(child == NULL || child->parent == NULL)
-        return;
-
-    parent = child->parent;
+static void
+xmlnode_parser_element_start(GMarkupParseContext *context,
+		const char *element_name, const char **attrib_names,
+		const char **attrib_values, gpointer user_data, GError **error)
+{
+	struct _xmlnode_parser_data *xpd = user_data;
+	xmlnode *node;
+	int i;
 
-    /* first fix up at the child level */
-    _xmlnode_hide_sibling(child);
+	if(!element_name) {
+		return;
+	} else {
+		if(xpd->current)
+			node = xmlnode_new_child(xpd->current, element_name);
+		else
+			node = xmlnode_new(element_name);
 
-    /* next fix up at the parent level */
-    if(parent->firstchild == child)
-        parent->firstchild = child->next;
-    if(parent->lastchild == child)
-        parent->lastchild = child->prev;
+		for(i=0; attrib_names[i]; i++)
+			xmlnode_set_attrib(node, attrib_names[i], attrib_values[i]);
+
+		xpd->current = node;
+	}
 }
 
-void xmlnode_hide_attrib(xmlnode parent, const char *name)
+static void
+xmlnode_parser_element_end(GMarkupParseContext *context,
+		const char *element_name, gpointer user_data, GError **error)
 {
-    xmlnode attrib;
-
-    if(parent == NULL || parent->firstattrib == NULL || name == NULL)
-        return;
+	struct _xmlnode_parser_data *xpd = user_data;
 
-    attrib = _xmlnode_search(parent->firstattrib, name, NTYPE_ATTRIB);
-    if(attrib == NULL)
-        return;
+	if(!element_name || !xpd->current)
+		return;
 
-    /* first fix up at the child level */
-    _xmlnode_hide_sibling(attrib);
-
-    /* next fix up at the parent level */
-    if(parent->firstattrib == attrib)
-        parent->firstattrib = attrib->next;
-    if(parent->lastattrib == attrib)
-        parent->lastattrib = attrib->prev;
+	if(xpd->current->parent) {
+		if(!strcmp(xpd->current->name, element_name))
+			xpd->current = xpd->current->parent;
+	}
 }
 
-
+static void
+xmlnode_parser_element_text(GMarkupParseContext *context, const char *text,
+		gsize text_len, gpointer user_data, GError **error)
+{
+	struct _xmlnode_parser_data *xpd = user_data;
 
-/*
- *  xmlnode2str -- convert given xmlnode tree into a string
- *
- *  parameters
- *      node -- pointer to the xmlnode structure
- *
- *  results
- *      a pointer to the created string
- *      or NULL if it was unsuccessfull
- */
-char *xmlnode2str(xmlnode node)
-{
-     return spool_print(_xmlnode2spool(node));
+	if(!xpd->current)
+		return;
+
+	if(!text || !text_len)
+		return;
+
+	xmlnode_insert_data(xpd->current, text, text_len);
 }
 
-/*
- *  xmlnode2tstr -- convert given xmlnode tree into a newline terminated string
- *
- *  parameters
- *      node -- pointer to the xmlnode structure
- *
- *  results
- *      a pointer to the created string
- *      or NULL if it was unsuccessfull
- */
-char*    xmlnode2tstr(xmlnode node)
-{
-     spool s = _xmlnode2spool(node);
-     if (s != NULL)
-	  spool_add(s, "\n");
-    return spool_print(s);
-}
+static GMarkupParser xmlnode_parser = {
+	xmlnode_parser_element_start,
+	xmlnode_parser_element_end,
+	xmlnode_parser_element_text,
+	NULL,
+	NULL
+};
 
 
-/* loop through both a and b comparing everything, attribs, cdata, children, etc */
-int xmlnode_cmp(xmlnode a, xmlnode b)
+xmlnode *xmlnode_from_str(const char *str, size_t size)
 {
-    int ret = 0;
-
-    while(1)
-    {
-        if(a == NULL && b == NULL)
-            return 0;
-
-        if(a == NULL || b == NULL)
-            return -1;
-
-        if(xmlnode_get_type(a) != xmlnode_get_type(b))
-            return -1;
+	struct _xmlnode_parser_data *xpd = g_new0(struct _xmlnode_parser_data, 1);
+	xmlnode *ret;
+	GMarkupParseContext *context;
+	size_t real_size = size == -1 ? strlen(str) : size;
 
-        switch(xmlnode_get_type(a))
-        {
-        case NTYPE_ATTRIB:
-            ret = j_strcmp(xmlnode_get_name(a), xmlnode_get_name(b));
-            if(ret != 0)
-                return -1;
-            ret = j_strcmp(xmlnode_get_data(a), xmlnode_get_data(b));
-            if(ret != 0)
-                return -1;
-            break;
-        case NTYPE_TAG:
-            ret = j_strcmp(xmlnode_get_name(a), xmlnode_get_name(b));
-            if(ret != 0)
-                return -1;
-            ret = xmlnode_cmp(xmlnode_get_firstattrib(a), xmlnode_get_firstattrib(b));
-            if(ret != 0)
-                return -1;
-            ret = xmlnode_cmp(xmlnode_get_firstchild(a), xmlnode_get_firstchild(b));
-            if(ret != 0)
-                return -1;
-            break;
-        case NTYPE_CDATA:
-            ret = j_strcmp(xmlnode_get_data(a), xmlnode_get_data(b));
-            if(ret != 0)
-                return -1;
-        }
-        a = xmlnode_get_nextsibling(a);
-        b = xmlnode_get_nextsibling(b);
-    }
-}
-
-
-xmlnode xmlnode_insert_tag_node(xmlnode parent, xmlnode node)
-{
-    xmlnode child;
-
-    child = xmlnode_insert_tag(parent, xmlnode_get_name(node));
-    if (xmlnode_has_attribs(node))
-        xmlnode_insert_node(child, xmlnode_get_firstattrib(node));
-    if (xmlnode_has_children(node))
-        xmlnode_insert_node(child, xmlnode_get_firstchild(node));
-
-    return child;
-}
-
-/* places copy of node and node's siblings in parent */
-void xmlnode_insert_node(xmlnode parent, xmlnode node)
-{
-    if(node == NULL || parent == NULL)
-        return;
+	context = g_markup_parse_context_new(&xmlnode_parser, 0, xpd, NULL);
 
-    while(node != NULL)
-    {
-        switch(xmlnode_get_type(node))
-        {
-        case NTYPE_ATTRIB:
-            xmlnode_put_attrib(parent, xmlnode_get_name(node), xmlnode_get_data(node));
-            break;
-        case NTYPE_TAG:
-            xmlnode_insert_tag_node(parent, node);
-            break;
-        case NTYPE_CDATA:
-            xmlnode_insert_cdata(parent, xmlnode_get_data(node), xmlnode_get_datasz(node));
-        }
-        node = xmlnode_get_nextsibling(node);
-    }
-}
-
-
-/* produce full duplicate of x with a new pool, x must be a tag! */
-xmlnode xmlnode_dup(xmlnode x)
-{
-    xmlnode x2;
-
-    if(x == NULL)
-        return NULL;
-
-    x2 = xmlnode_new_tag(xmlnode_get_name(x));
-
-    if (xmlnode_has_attribs(x))
-        xmlnode_insert_node(x2, xmlnode_get_firstattrib(x));
-    if (xmlnode_has_children(x))
-        xmlnode_insert_node(x2, xmlnode_get_firstchild(x));
-
-    return x2;
-}
+	if(!g_markup_parse_context_parse(context, str, real_size, NULL)) {
+		while(xpd->current && xpd->current->parent)
+			xpd->current = xpd->current->parent;
+		xmlnode_free(xpd->current);
+		xpd->current = NULL;
+	}
+	g_markup_parse_context_free(context);
 
-xmlnode xmlnode_dup_pool(pool p, xmlnode x)
-{
-    xmlnode x2;
-
-    if(x == NULL)
-        return NULL;
-
-    x2 = xmlnode_new_tag_pool(p, xmlnode_get_name(x));
-
-    if (xmlnode_has_attribs(x))
-        xmlnode_insert_node(x2, xmlnode_get_firstattrib(x));
-    if (xmlnode_has_children(x))
-        xmlnode_insert_node(x2, xmlnode_get_firstchild(x));
-
-    return x2;
+	ret = xpd->current;
+	g_free(xpd);
+	return ret;
 }
-
-xmlnode xmlnode_wrap(xmlnode x,const char *wrapper)
-{
-    xmlnode wrap;
-    if(x==NULL||wrapper==NULL) return NULL;
-    wrap=xmlnode_new_tag_pool(xmlnode_pool(x),wrapper);
-    if(wrap==NULL) return NULL;
-    wrap->firstchild=x;
-    wrap->lastchild=x;
-    x->parent=wrap;
-    return wrap;
-}
-
-void xmlnode_free(xmlnode node)
-{
-    if(node == NULL)
-        return;
-
-    pool_free(node->p);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/protocols/jabber/xmlnode.h	Mon Sep 29 15:23:19 2003 +0000
@@ -0,0 +1,57 @@
+/**
+ * @file xmlnode.h XML DOM functions
+ *
+ * gaim
+ *
+ * Copyright (C) 2003 Nathan Walp <faceprint@faceprint.com>
+ *
+ * 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
+ */
+#ifndef _GAIM_XMLNODE_H_
+#define _GAIM_XMLNODE_H_
+
+typedef enum _NodeType
+{
+	NODE_TYPE_TAG,
+	NODE_TYPE_ATTRIB,
+	NODE_TYPE_DATA
+} NodeType;
+
+typedef struct _xmlnode
+{
+	char *name;
+	NodeType type;
+	char *data;
+	size_t data_sz;
+	struct _xmlnode *parent;
+	struct _xmlnode *child;
+	struct _xmlnode *next;
+} xmlnode;
+
+xmlnode *xmlnode_new(const char *name);
+xmlnode *xmlnode_new_child(xmlnode *parent, const char *name);
+void xmlnode_insert_child(xmlnode *parent, xmlnode *child);
+xmlnode *xmlnode_get_child(xmlnode *parent, const char *name);
+void xmlnode_insert_data(xmlnode *parent, const char *data, size_t size);
+char *xmlnode_get_data(xmlnode *node);
+void xmlnode_set_attrib(xmlnode *node, const char *attr, const char *value);
+const char *xmlnode_get_attrib(xmlnode *node, const char *attr);
+void xmlnode_remove_attrib(xmlnode *node, const char *attr);
+char *xmlnode_to_str(xmlnode *node);
+xmlnode *xmlnode_from_str(const char *str, size_t size);
+
+void xmlnode_free(xmlnode *node);
+
+#endif /* _GAIM_XMLNODE_H_ */
--- a/src/protocols/jabber/xmlparse.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3232 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-*/
-
-#include "xmldef.h"
-#include "xmlparse.h"
-
-#ifdef XML_UNICODE
-#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
-#define XmlConvert XmlUtf16Convert
-#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
-#define XmlEncode XmlUtf16Encode
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
-typedef unsigned short ICHAR;
-#else
-#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
-#define XmlConvert XmlUtf8Convert
-#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
-#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
-#define XmlEncode XmlUtf8Encode
-#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
-typedef char ICHAR;
-#endif
-
-
-#ifndef XML_NS
-
-#define XmlInitEncodingNS XmlInitEncoding
-#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
-#undef XmlGetInternalEncodingNS
-#define XmlGetInternalEncodingNS XmlGetInternalEncoding
-#define XmlParseXmlDeclNS XmlParseXmlDecl
-
-#endif
-
-
-#ifdef XML_UNICODE_WCHAR_T
-#define XML_T(x) L ## x
-#else
-#define XML_T(x) x
-#endif
-
-/* Round up n to be a multiple of sz, where sz is a power of 2. */
-#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
-
-#include "xmltok.h"
-#include "xmlrole.h"
-#include "hashtable.h"
-
-#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
-#define INIT_DATA_BUF_SIZE 1024
-#define INIT_ATTS_SIZE 16
-#define INIT_BLOCK_SIZE 1024
-#define INIT_BUFFER_SIZE 1024
-
-#define EXPAND_SPARE 24
-
-typedef struct binding {
-    struct prefix *prefix;
-    struct binding *nextTagBinding;
-    struct binding *prevPrefixBinding;
-    const struct attribute_id *attId;
-    XML_Char *uri;
-    int uriLen;
-    int uriAlloc;
-} BINDING;
-
-typedef struct prefix {
-    const XML_Char *name;
-    BINDING *binding;
-} PREFIX;
-
-typedef struct {
-    const XML_Char *str;
-    const XML_Char *localPart;
-    int uriLen;
-} TAG_NAME;
-
-typedef struct tag {
-    struct tag *parent;
-    const char *rawName;
-    int rawNameLength;
-    TAG_NAME name;
-    char *buf;
-    char *bufEnd;
-    BINDING *bindings;
-} TAG;
-
-typedef struct {
-    const XML_Char *name;
-    const XML_Char *textPtr;
-    int textLen;
-    const XML_Char *systemId;
-    const XML_Char *base;
-    const XML_Char *publicId;
-    const XML_Char *notation;
-    char open;
-} ENTITY;
-
-typedef struct block {
-    struct block *next;
-    int size;
-    XML_Char s[1];
-} BLOCK;
-
-typedef struct {
-    BLOCK *blocks;
-    BLOCK *freeBlocks;
-    const XML_Char *end;
-    XML_Char *ptr;
-    XML_Char *start;
-} STRING_POOL;
-
-/* The XML_Char before the name is used to determine whether
-an attribute has been specified. */
-typedef struct attribute_id {
-    XML_Char *name;
-    PREFIX *prefix;
-    char maybeTokenized;
-    char xmlns;
-} ATTRIBUTE_ID;
-
-typedef struct {
-    const ATTRIBUTE_ID *id;
-    char isCdata;
-    const XML_Char *value;
-} DEFAULT_ATTRIBUTE;
-
-typedef struct {
-    const XML_Char *name;
-    PREFIX *prefix;
-    int nDefaultAtts;
-    int allocDefaultAtts;
-    DEFAULT_ATTRIBUTE *defaultAtts;
-} ELEMENT_TYPE;
-
-typedef struct {
-    HASH_TABLE generalEntities;
-    HASH_TABLE elementTypes;
-    HASH_TABLE attributeIds;
-    HASH_TABLE prefixes;
-    STRING_POOL pool;
-    int complete;
-    int standalone;
-    const XML_Char *base;
-    PREFIX defaultPrefix;
-} DTD;
-
-typedef struct open_internal_entity {
-    const char *internalEventPtr;
-    const char *internalEventEndPtr;
-    struct open_internal_entity *next;
-    ENTITY *entity;
-} OPEN_INTERNAL_ENTITY;
-
-typedef enum XML_Error Processor(XML_Parser parser,
-                                 const char *start,
-                                 const char *end,
-                                 const char **endPtr);
-
-static Processor prologProcessor;
-static Processor prologInitProcessor;
-static Processor contentProcessor;
-static Processor cdataSectionProcessor;
-static Processor epilogProcessor;
-static Processor externalEntityInitProcessor;
-static Processor externalEntityInitProcessor2;
-static Processor externalEntityInitProcessor3;
-static Processor externalEntityContentProcessor;
-
-static enum XML_Error
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
-static enum XML_Error
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
-static enum XML_Error
-initializeEncoding(XML_Parser parser);
-static enum XML_Error
-doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
-          const char *start, const char *end, const char **endPtr);
-static enum XML_Error
-doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
-static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
-                                TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
-static
-int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
-static int
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *, int isCdata, const XML_Char *dfltValue);
-static enum XML_Error
-storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
-                    STRING_POOL *);
-static enum XML_Error
-appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
-                     STRING_POOL *);
-static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
-static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
-static enum XML_Error
-storeEntityValue(XML_Parser parser, const char *start, const char *end);
-static int
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
-static int
-reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
-static void
-reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
-
-static const XML_Char *getContext(XML_Parser parser);
-static int setContext(XML_Parser parser, const XML_Char *context);
-static void normalizePublicId(XML_Char *s);
-static int dtdInit(DTD *);
-static void dtdDestroy(DTD *);
-static int dtdCopy(DTD *newDtd, const DTD *oldDtd);
-static void poolInit(STRING_POOL *);
-static void poolClear(STRING_POOL *);
-static void poolDestroy(STRING_POOL *);
-static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
-                            const char *ptr, const char *end);
-static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
-                                 const char *ptr, const char *end);
-static int poolGrow(STRING_POOL *pool);
-static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
-static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
-
-#define poolStart(pool) ((pool)->start)
-#define poolEnd(pool) ((pool)->ptr)
-#define poolLength(pool) ((pool)->ptr - (pool)->start)
-#define poolChop(pool) ((void)--(pool->ptr))
-#define poolLastChar(pool) (((pool)->ptr)[-1])
-#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
-#define poolFinish(pool) ((pool)->start = (pool)->ptr)
-#define poolAppendChar(pool, c) \
-  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
-   ? 0 \
-   : ((*((pool)->ptr)++ = c), 1))
-
-typedef struct {
-    /* The first member must be userData so that the XML_GetUserData macro works. */
-    void *m_userData;
-    void *m_handlerArg;
-    char *m_buffer;
-    /* first character to be parsed */
-    const char *m_bufferPtr;
-    /* past last character to be parsed */
-    char *m_bufferEnd;
-    /* allocated end of buffer */
-    const char *m_bufferLim;
-    long m_parseEndByteIndex;
-    const char *m_parseEndPtr;
-    XML_Char *m_dataBuf;
-    XML_Char *m_dataBufEnd;
-    XML_StartElementHandler m_startElementHandler;
-    XML_EndElementHandler m_endElementHandler;
-    XML_CharacterDataHandler m_characterDataHandler;
-    XML_ProcessingInstructionHandler m_processingInstructionHandler;
-    XML_CommentHandler m_commentHandler;
-    XML_StartCdataSectionHandler m_startCdataSectionHandler;
-    XML_EndCdataSectionHandler m_endCdataSectionHandler;
-    XML_DefaultHandler m_defaultHandler;
-    XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
-    XML_NotationDeclHandler m_notationDeclHandler;
-    XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
-    XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
-    XML_NotStandaloneHandler m_notStandaloneHandler;
-    XML_ExternalEntityRefHandler m_externalEntityRefHandler;
-    void *m_externalEntityRefHandlerArg;
-    XML_UnknownEncodingHandler m_unknownEncodingHandler;
-    const ENCODING *m_encoding;
-    INIT_ENCODING m_initEncoding;
-    const XML_Char *m_protocolEncodingName;
-    int m_ns;
-    void *m_unknownEncodingMem;
-    void *m_unknownEncodingData;
-    void *m_unknownEncodingHandlerData;
-    void (*m_unknownEncodingRelease)(void *);
-    PROLOG_STATE m_prologState;
-    Processor *m_processor;
-    enum XML_Error m_errorCode;
-    const char *m_eventPtr;
-    const char *m_eventEndPtr;
-    const char *m_positionPtr;
-    OPEN_INTERNAL_ENTITY *m_openInternalEntities;
-    int m_defaultExpandInternalEntities;
-    int m_tagLevel;
-    ENTITY *m_declEntity;
-    const XML_Char *m_declNotationName;
-    const XML_Char *m_declNotationPublicId;
-    ELEMENT_TYPE *m_declElementType;
-    ATTRIBUTE_ID *m_declAttributeId;
-    char m_declAttributeIsCdata;
-    DTD m_dtd;
-    TAG *m_tagStack;
-    TAG *m_freeTagList;
-    BINDING *m_inheritedBindings;
-    BINDING *m_freeBindingList;
-    int m_attsSize;
-    int m_nSpecifiedAtts;
-    ATTRIBUTE *m_atts;
-    POSITION m_position;
-    STRING_POOL m_tempPool;
-    STRING_POOL m_temp2Pool;
-    char *m_groupConnector;
-    unsigned m_groupSize;
-    int m_hadExternalDoctype;
-    XML_Char m_namespaceSeparator;
-} Parser;
-
-#define userData (((Parser *)parser)->m_userData)
-#define handlerArg (((Parser *)parser)->m_handlerArg)
-#define startElementHandler (((Parser *)parser)->m_startElementHandler)
-#define endElementHandler (((Parser *)parser)->m_endElementHandler)
-#define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
-#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
-#define commentHandler (((Parser *)parser)->m_commentHandler)
-#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
-#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
-#define defaultHandler (((Parser *)parser)->m_defaultHandler)
-#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
-#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
-#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
-#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
-#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
-#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
-#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
-#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
-#define encoding (((Parser *)parser)->m_encoding)
-#define initEncoding (((Parser *)parser)->m_initEncoding)
-#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
-#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
-#define unknownEncodingHandlerData \
-  (((Parser *)parser)->m_unknownEncodingHandlerData)
-#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
-#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
-#define ns (((Parser *)parser)->m_ns)
-#define prologState (((Parser *)parser)->m_prologState)
-#define processor (((Parser *)parser)->m_processor)
-#define errorCode (((Parser *)parser)->m_errorCode)
-#define eventPtr (((Parser *)parser)->m_eventPtr)
-#define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
-#define positionPtr (((Parser *)parser)->m_positionPtr)
-#define position (((Parser *)parser)->m_position)
-#define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
-#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
-#define tagLevel (((Parser *)parser)->m_tagLevel)
-#define buffer (((Parser *)parser)->m_buffer)
-#define bufferPtr (((Parser *)parser)->m_bufferPtr)
-#define bufferEnd (((Parser *)parser)->m_bufferEnd)
-#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
-#define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
-#define bufferLim (((Parser *)parser)->m_bufferLim)
-#define dataBuf (((Parser *)parser)->m_dataBuf)
-#define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
-#define dtd (((Parser *)parser)->m_dtd)
-#define declEntity (((Parser *)parser)->m_declEntity)
-#define declNotationName (((Parser *)parser)->m_declNotationName)
-#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
-#define declElementType (((Parser *)parser)->m_declElementType)
-#define declAttributeId (((Parser *)parser)->m_declAttributeId)
-#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
-#define freeTagList (((Parser *)parser)->m_freeTagList)
-#define freeBindingList (((Parser *)parser)->m_freeBindingList)
-#define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
-#define tagStack (((Parser *)parser)->m_tagStack)
-#define atts (((Parser *)parser)->m_atts)
-#define attsSize (((Parser *)parser)->m_attsSize)
-#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
-#define tempPool (((Parser *)parser)->m_tempPool)
-#define temp2Pool (((Parser *)parser)->m_temp2Pool)
-#define groupConnector (((Parser *)parser)->m_groupConnector)
-#define groupSize (((Parser *)parser)->m_groupSize)
-#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
-#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
-
-#ifdef _MSC_VER
-#ifdef _DEBUG
-Parser *asParser(XML_Parser parser)
-{
-    return parser;
-}
-#endif
-#endif
-
-XML_Parser XML_ParserCreate(const XML_Char *encodingName)
-{
-    XML_Parser parser = malloc(sizeof(Parser));
-    if (!parser)
-        return parser;
-    processor = prologInitProcessor;
-    XmlPrologStateInit(&prologState);
-    userData = 0;
-    handlerArg = 0;
-    startElementHandler = 0;
-    endElementHandler = 0;
-    characterDataHandler = 0;
-    processingInstructionHandler = 0;
-    commentHandler = 0;
-    startCdataSectionHandler = 0;
-    endCdataSectionHandler = 0;
-    defaultHandler = 0;
-    unparsedEntityDeclHandler = 0;
-    notationDeclHandler = 0;
-    startNamespaceDeclHandler = 0;
-    endNamespaceDeclHandler = 0;
-    notStandaloneHandler = 0;
-    externalEntityRefHandler = 0;
-    externalEntityRefHandlerArg = parser;
-    unknownEncodingHandler = 0;
-    buffer = 0;
-    bufferPtr = 0;
-    bufferEnd = 0;
-    parseEndByteIndex = 0;
-    parseEndPtr = 0;
-    bufferLim = 0;
-    declElementType = 0;
-    declAttributeId = 0;
-    declEntity = 0;
-    declNotationName = 0;
-    declNotationPublicId = 0;
-    memset(&position, 0, sizeof(POSITION));
-    errorCode = XML_ERROR_NONE;
-    eventPtr = 0;
-    eventEndPtr = 0;
-    positionPtr = 0;
-    openInternalEntities = 0;
-    tagLevel = 0;
-    tagStack = 0;
-    freeTagList = 0;
-    freeBindingList = 0;
-    inheritedBindings = 0;
-    attsSize = INIT_ATTS_SIZE;
-    atts = malloc(attsSize * sizeof(ATTRIBUTE));
-    nSpecifiedAtts = 0;
-    dataBuf = malloc(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
-    groupSize = 0;
-    groupConnector = 0;
-    hadExternalDoctype = 0;
-    unknownEncodingMem = 0;
-    unknownEncodingRelease = 0;
-    unknownEncodingData = 0;
-    unknownEncodingHandlerData = 0;
-    namespaceSeparator = '!';
-    ns = 0;
-    poolInit(&tempPool);
-    poolInit(&temp2Pool);
-    protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
-    if (!dtdInit(&dtd) || !atts || !dataBuf
-            || (encodingName && !protocolEncodingName)) {
-        XML_ParserFree(parser);
-        return 0;
-    }
-    dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
-    XmlInitEncoding(&initEncoding, &encoding, 0);
-    return parser;
-}
-
-XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
-{
-    static
-    const XML_Char implicitContext[] = {
-        XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
-        XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
-        XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
-        XML_T('.'), XML_T('w'), XML_T('3'),
-        XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
-        XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
-        XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
-        XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
-        XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
-        XML_T('\0')
-    };
-
-    XML_Parser parser = XML_ParserCreate(encodingName);
-    if (parser) {
-        XmlInitEncodingNS(&initEncoding, &encoding, 0);
-        ns = 1;
-        namespaceSeparator = nsSep;
-    }
-    if (!setContext(parser, implicitContext)) {
-        XML_ParserFree(parser);
-        return 0;
-    }
-    return parser;
-}
-
-int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
-{
-    if (!encodingName)
-        protocolEncodingName = 0;
-    else {
-        protocolEncodingName = poolCopyString(&tempPool, encodingName);
-        if (!protocolEncodingName)
-            return 0;
-    }
-    return 1;
-}
-
-XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
-        const XML_Char *context,
-        const XML_Char *encodingName)
-{
-    XML_Parser parser = oldParser;
-    DTD *oldDtd = &dtd;
-    XML_StartElementHandler oldStartElementHandler = startElementHandler;
-    XML_EndElementHandler oldEndElementHandler = endElementHandler;
-    XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
-    XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
-    XML_CommentHandler oldCommentHandler = commentHandler;
-    XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
-    XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
-    XML_DefaultHandler oldDefaultHandler = defaultHandler;
-    XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
-    XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
-    XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
-    XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
-    XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
-    void *oldUserData = userData;
-    void *oldHandlerArg = handlerArg;
-    int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
-    void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
-
-    parser = (ns
-              ? XML_ParserCreateNS(encodingName, namespaceSeparator)
-              : XML_ParserCreate(encodingName));
-    if (!parser)
-        return 0;
-    startElementHandler = oldStartElementHandler;
-    endElementHandler = oldEndElementHandler;
-    characterDataHandler = oldCharacterDataHandler;
-    processingInstructionHandler = oldProcessingInstructionHandler;
-    commentHandler = oldCommentHandler;
-    startCdataSectionHandler = oldStartCdataSectionHandler;
-    endCdataSectionHandler = oldEndCdataSectionHandler;
-    defaultHandler = oldDefaultHandler;
-    startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
-    endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
-    notStandaloneHandler = oldNotStandaloneHandler;
-    externalEntityRefHandler = oldExternalEntityRefHandler;
-    unknownEncodingHandler = oldUnknownEncodingHandler;
-    userData = oldUserData;
-    if (oldUserData == oldHandlerArg)
-        handlerArg = userData;
-    else
-        handlerArg = parser;
-    if (oldExternalEntityRefHandlerArg != oldParser)
-        externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
-    defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
-    if (!dtdCopy(&dtd, oldDtd) || !setContext(parser, context)) {
-        XML_ParserFree(parser);
-        return 0;
-    }
-    processor = externalEntityInitProcessor;
-    return parser;
-}
-
-static
-void destroyBindings(BINDING *bindings)
-{
-    for (;;) {
-        BINDING *b = bindings;
-        if (!b)
-            break;
-        bindings = b->nextTagBinding;
-        free(b->uri);
-        free(b);
-    }
-}
-
-void XML_ParserFree(XML_Parser parser)
-{
-    for (;;) {
-        TAG *p;
-        if (tagStack == 0) {
-            if (freeTagList == 0)
-                break;
-            tagStack = freeTagList;
-            freeTagList = 0;
-        }
-        p = tagStack;
-        tagStack = tagStack->parent;
-        free(p->buf);
-        destroyBindings(p->bindings);
-        free(p);
-    }
-    destroyBindings(freeBindingList);
-    destroyBindings(inheritedBindings);
-    poolDestroy(&tempPool);
-    poolDestroy(&temp2Pool);
-    dtdDestroy(&dtd);
-    free((void *)atts);
-    free(groupConnector);
-    free(buffer);
-    free(dataBuf);
-    free(unknownEncodingMem);
-    if (unknownEncodingRelease)
-        unknownEncodingRelease(unknownEncodingData);
-    free(parser);
-}
-
-void XML_UseParserAsHandlerArg(XML_Parser parser)
-{
-    handlerArg = parser;
-}
-
-void XML_SetUserData(XML_Parser parser, void *p)
-{
-    if (handlerArg == userData)
-        handlerArg = userData = p;
-    else
-        userData = p;
-}
-
-int XML_SetBase(XML_Parser parser, const XML_Char *p)
-{
-    if (p) {
-        p = poolCopyString(&dtd.pool, p);
-        if (!p)
-            return 0;
-        dtd.base = p;
-    }
-    else
-        dtd.base = 0;
-    return 1;
-}
-
-const XML_Char *XML_GetBase(XML_Parser parser)
-{
-    return dtd.base;
-}
-
-int XML_GetSpecifiedAttributeCount(XML_Parser parser)
-{
-    return nSpecifiedAtts;
-}
-
-void XML_SetElementHandler(XML_Parser parser,
-                           XML_StartElementHandler start,
-                           XML_EndElementHandler end)
-{
-    startElementHandler = start;
-    endElementHandler = end;
-}
-
-void XML_SetCharacterDataHandler(XML_Parser parser,
-                                 XML_CharacterDataHandler handler)
-{
-    characterDataHandler = handler;
-}
-
-void XML_SetProcessingInstructionHandler(XML_Parser parser,
-        XML_ProcessingInstructionHandler handler)
-{
-    processingInstructionHandler = handler;
-}
-
-void XML_SetCommentHandler(XML_Parser parser,
-                           XML_CommentHandler handler)
-{
-    commentHandler = handler;
-}
-
-void XML_SetCdataSectionHandler(XML_Parser parser,
-                                XML_StartCdataSectionHandler start,
-                                XML_EndCdataSectionHandler end)
-{
-    startCdataSectionHandler = start;
-    endCdataSectionHandler = end;
-}
-
-void XML_SetDefaultHandler(XML_Parser parser,
-                           XML_DefaultHandler handler)
-{
-    defaultHandler = handler;
-    defaultExpandInternalEntities = 0;
-}
-
-void XML_SetDefaultHandlerExpand(XML_Parser parser,
-                                 XML_DefaultHandler handler)
-{
-    defaultHandler = handler;
-    defaultExpandInternalEntities = 1;
-}
-
-void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
-                                      XML_UnparsedEntityDeclHandler handler)
-{
-    unparsedEntityDeclHandler = handler;
-}
-
-void XML_SetNotationDeclHandler(XML_Parser parser,
-                                XML_NotationDeclHandler handler)
-{
-    notationDeclHandler = handler;
-}
-
-void XML_SetNamespaceDeclHandler(XML_Parser parser,
-                                 XML_StartNamespaceDeclHandler start,
-                                 XML_EndNamespaceDeclHandler end)
-{
-    startNamespaceDeclHandler = start;
-    endNamespaceDeclHandler = end;
-}
-
-void XML_SetNotStandaloneHandler(XML_Parser parser,
-                                 XML_NotStandaloneHandler handler)
-{
-    notStandaloneHandler = handler;
-}
-
-void XML_SetExternalEntityRefHandler(XML_Parser parser,
-                                     XML_ExternalEntityRefHandler handler)
-{
-    externalEntityRefHandler = handler;
-}
-
-void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
-{
-    if (arg)
-        externalEntityRefHandlerArg = arg;
-    else
-        externalEntityRefHandlerArg = parser;
-}
-
-void XML_SetUnknownEncodingHandler(XML_Parser parser,
-                                   XML_UnknownEncodingHandler handler,
-                                   void *data)
-{
-    unknownEncodingHandler = handler;
-    unknownEncodingHandlerData = data;
-}
-
-int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
-{
-    if (len == 0) {
-        if (!isFinal)
-            return 1;
-        positionPtr = bufferPtr;
-        errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
-        if (errorCode == XML_ERROR_NONE)
-            return 1;
-        eventEndPtr = eventPtr;
-        return 0;
-    }
-    else if (bufferPtr == bufferEnd) {
-        const char *end;
-        int nLeftOver;
-        parseEndByteIndex += len;
-        positionPtr = s;
-        if (isFinal) {
-            errorCode = processor(parser, s, parseEndPtr = s + len, 0);
-            if (errorCode == XML_ERROR_NONE)
-                return 1;
-            eventEndPtr = eventPtr;
-            return 0;
-        }
-        errorCode = processor(parser, s, parseEndPtr = s + len, &end);
-        if (errorCode != XML_ERROR_NONE) {
-            eventEndPtr = eventPtr;
-            return 0;
-        }
-        XmlUpdatePosition(encoding, positionPtr, end, &position);
-        nLeftOver = s + len - end;
-        if (nLeftOver) {
-            if (buffer == 0 || nLeftOver > bufferLim - buffer) {
-                /* FIXME avoid integer overflow */
-                buffer = buffer == 0 ? malloc(len * 2) : realloc(buffer, len * 2);
-                if (!buffer) {
-                    errorCode = XML_ERROR_NO_MEMORY;
-                    eventPtr = eventEndPtr = 0;
-                    return 0;
-                }
-                bufferLim = buffer + len * 2;
-            }
-            memcpy(buffer, end, nLeftOver);
-            bufferPtr = buffer;
-            bufferEnd = buffer + nLeftOver;
-        }
-        return 1;
-    }
-    else {
-        memcpy(XML_GetBuffer(parser, len), s, len);
-        return XML_ParseBuffer(parser, len, isFinal);
-    }
-}
-
-int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
-{
-    const char *start = bufferPtr;
-    positionPtr = start;
-    bufferEnd += len;
-    parseEndByteIndex += len;
-    errorCode = processor(parser, start, parseEndPtr = bufferEnd,
-                          isFinal ? (const char **)0 : &bufferPtr);
-    if (errorCode == XML_ERROR_NONE) {
-        if (!isFinal)
-            XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
-        return 1;
-    }
-    else {
-        eventEndPtr = eventPtr;
-        return 0;
-    }
-}
-
-void *XML_GetBuffer(XML_Parser parser, int len)
-{
-    if (len > bufferLim - bufferEnd) {
-        /* FIXME avoid integer overflow */
-        int neededSize = len + (bufferEnd - bufferPtr);
-        if (neededSize  <= bufferLim - buffer) {
-            memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
-            bufferEnd = buffer + (bufferEnd - bufferPtr);
-            bufferPtr = buffer;
-        }
-        else {
-            char *newBuf;
-            int bufferSize = bufferLim - bufferPtr;
-            if (bufferSize == 0)
-                bufferSize = INIT_BUFFER_SIZE;
-            do {
-                bufferSize *= 2;
-            } while (bufferSize < neededSize);
-            newBuf = malloc(bufferSize);
-            if (newBuf == 0) {
-                errorCode = XML_ERROR_NO_MEMORY;
-                return 0;
-            }
-            bufferLim = newBuf + bufferSize;
-            if (bufferPtr) {
-                memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
-                free(buffer);
-            }
-            bufferEnd = newBuf + (bufferEnd - bufferPtr);
-            bufferPtr = buffer = newBuf;
-        }
-    }
-    return bufferEnd;
-}
-
-enum XML_Error XML_GetErrorCode(XML_Parser parser)
-{
-    return errorCode;
-}
-
-long XML_GetCurrentByteIndex(XML_Parser parser)
-{
-    if (eventPtr)
-        return parseEndByteIndex - (parseEndPtr - eventPtr);
-    return -1;
-}
-
-int XML_GetCurrentByteCount(XML_Parser parser)
-{
-    if (eventEndPtr && eventPtr)
-        return eventEndPtr - eventPtr;
-    return 0;
-}
-
-int XML_GetCurrentLineNumber(XML_Parser parser)
-{
-    if (eventPtr) {
-        XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
-        positionPtr = eventPtr;
-    }
-    return position.lineNumber + 1;
-}
-
-int XML_GetCurrentColumnNumber(XML_Parser parser)
-{
-    if (eventPtr) {
-        XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
-        positionPtr = eventPtr;
-    }
-    return position.columnNumber;
-}
-
-void XML_DefaultCurrent(XML_Parser parser)
-{
-    if (defaultHandler) {
-        if (openInternalEntities)
-            reportDefault(parser,
-                          ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding(),
-                          openInternalEntities->internalEventPtr,
-                          openInternalEntities->internalEventEndPtr);
-        else
-            reportDefault(parser, encoding, eventPtr, eventEndPtr);
-    }
-}
-
-const XML_LChar *XML_ErrorString(int code)
-{
-    static const XML_LChar *message[] = {
-        0,
-        XML_T("out of memory"),
-        XML_T("syntax error"),
-        XML_T("no element found"),
-        XML_T("not well-formed"),
-        XML_T("unclosed token"),
-        XML_T("unclosed token"),
-        XML_T("mismatched tag"),
-        XML_T("duplicate attribute"),
-        XML_T("junk after document element"),
-        XML_T("illegal parameter entity reference"),
-        XML_T("undefined entity"),
-        XML_T("recursive entity reference"),
-        XML_T("asynchronous entity"),
-        XML_T("reference to invalid character number"),
-        XML_T("reference to binary entity"),
-        XML_T("reference to external entity in attribute"),
-        XML_T("xml processing instruction not at start of external entity"),
-        XML_T("unknown encoding"),
-        XML_T("encoding specified in XML declaration is incorrect"),
-        XML_T("unclosed CDATA section"),
-        XML_T("error in processing external entity reference"),
-        XML_T("document is not standalone")
-    };
-    if (code > 0 && code < sizeof(message)/sizeof(message[0]))
-        return message[code];
-    return 0;
-}
-
-static
-enum XML_Error contentProcessor(XML_Parser parser,
-                                const char *start,
-                                const char *end,
-                                const char **endPtr)
-{
-    return doContent(parser, 0, encoding, start, end, endPtr);
-}
-
-static
-enum XML_Error externalEntityInitProcessor(XML_Parser parser,
-        const char *start,
-        const char *end,
-        const char **endPtr)
-{
-    enum XML_Error result = initializeEncoding(parser);
-    if (result != XML_ERROR_NONE)
-        return result;
-    processor = externalEntityInitProcessor2;
-    return externalEntityInitProcessor2(parser, start, end, endPtr);
-}
-
-static
-enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
-        const char *start,
-        const char *end,
-        const char **endPtr)
-{
-    const char *next;
-    int tok = XmlContentTok(encoding, start, end, &next);
-    switch (tok) {
-    case XML_TOK_BOM:
-        start = next;
-        break;
-    case XML_TOK_PARTIAL:
-        if (endPtr) {
-            *endPtr = start;
-            return XML_ERROR_NONE;
-        }
-        eventPtr = start;
-        return XML_ERROR_UNCLOSED_TOKEN;
-    case XML_TOK_PARTIAL_CHAR:
-        if (endPtr) {
-            *endPtr = start;
-            return XML_ERROR_NONE;
-        }
-        eventPtr = start;
-        return XML_ERROR_PARTIAL_CHAR;
-    }
-    processor = externalEntityInitProcessor3;
-    return externalEntityInitProcessor3(parser, start, end, endPtr);
-}
-
-static
-enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
-        const char *start,
-        const char *end,
-        const char **endPtr)
-{
-    const char *next;
-    int tok = XmlContentTok(encoding, start, end, &next);
-    switch (tok) {
-    case XML_TOK_XML_DECL:
-        {
-            enum XML_Error result = processXmlDecl(parser, 1, start, next);
-            if (result != XML_ERROR_NONE)
-                return result;
-            start = next;
-        }
-        break;
-    case XML_TOK_PARTIAL:
-        if (endPtr) {
-            *endPtr = start;
-            return XML_ERROR_NONE;
-        }
-        eventPtr = start;
-        return XML_ERROR_UNCLOSED_TOKEN;
-    case XML_TOK_PARTIAL_CHAR:
-        if (endPtr) {
-            *endPtr = start;
-            return XML_ERROR_NONE;
-        }
-        eventPtr = start;
-        return XML_ERROR_PARTIAL_CHAR;
-    }
-    processor = externalEntityContentProcessor;
-    tagLevel = 1;
-    return doContent(parser, 1, encoding, start, end, endPtr);
-}
-
-static
-enum XML_Error externalEntityContentProcessor(XML_Parser parser,
-        const char *start,
-        const char *end,
-        const char **endPtr)
-{
-    return doContent(parser, 1, encoding, start, end, endPtr);
-}
-
-static enum XML_Error
-doContent(XML_Parser parser,
-          int startTagLevel,
-          const ENCODING *enc,
-          const char *s,
-          const char *end,
-          const char **nextPtr)
-{
-    const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding();
-    const char **eventPP;
-    const char **eventEndPP;
-    if (enc == encoding) {
-        eventPP = &eventPtr;
-        eventEndPP = &eventEndPtr;
-    }
-    else {
-        eventPP = &(openInternalEntities->internalEventPtr);
-        eventEndPP = &(openInternalEntities->internalEventEndPtr);
-    }
-    *eventPP = s;
-    for (;;) {
-        const char *next = s; /* XmlContentTok doesn't always set the last arg */
-        int tok = XmlContentTok(enc, s, end, &next);
-        *eventEndPP = next;
-        switch (tok) {
-        case XML_TOK_TRAILING_CR:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            *eventEndPP = end;
-            if (characterDataHandler) {
-                XML_Char c = 0xA;
-                characterDataHandler(handlerArg, &c, 1);
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, end);
-            if (startTagLevel == 0)
-                return XML_ERROR_NO_ELEMENTS;
-            if (tagLevel != startTagLevel)
-                return XML_ERROR_ASYNC_ENTITY;
-            return XML_ERROR_NONE;
-        case XML_TOK_NONE:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            if (startTagLevel > 0) {
-                if (tagLevel != startTagLevel)
-                    return XML_ERROR_ASYNC_ENTITY;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_NO_ELEMENTS;
-        case XML_TOK_INVALID:
-            *eventPP = next;
-            return XML_ERROR_INVALID_TOKEN;
-        case XML_TOK_PARTIAL:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_UNCLOSED_TOKEN;
-        case XML_TOK_PARTIAL_CHAR:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_PARTIAL_CHAR;
-        case XML_TOK_ENTITY_REF:
-            {
-                const XML_Char *name;
-                ENTITY *entity;
-                XML_Char ch = XmlPredefinedEntityName(enc,
-                                                      s + enc->minBytesPerChar,
-                                                      next - enc->minBytesPerChar);
-                if (ch) {
-                    if (characterDataHandler)
-                        characterDataHandler(handlerArg, &ch, 1);
-                    else if (defaultHandler)
-                        reportDefault(parser, enc, s, next);
-                    break;
-                }
-                name = poolStoreString(&dtd.pool, enc,
-                                       s + enc->minBytesPerChar,
-                                       next - enc->minBytesPerChar);
-                if (!name)
-                    return XML_ERROR_NO_MEMORY;
-                entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
-                poolDiscard(&dtd.pool);
-                if (!entity) {
-                    if (dtd.complete || dtd.standalone)
-                        return XML_ERROR_UNDEFINED_ENTITY;
-                    if (defaultHandler)
-                        reportDefault(parser, enc, s, next);
-                    break;
-                }
-                if (entity->open)
-                    return XML_ERROR_RECURSIVE_ENTITY_REF;
-                if (entity->notation)
-                    return XML_ERROR_BINARY_ENTITY_REF;
-                if (entity) {
-                    if (entity->textPtr) {
-                        enum XML_Error result;
-                        OPEN_INTERNAL_ENTITY openEntity;
-                        if (defaultHandler && !defaultExpandInternalEntities) {
-                            reportDefault(parser, enc, s, next);
-                            break;
-                        }
-                        entity->open = 1;
-                        openEntity.next = openInternalEntities;
-                        openInternalEntities = &openEntity;
-                        openEntity.entity = entity;
-                        openEntity.internalEventPtr = 0;
-                        openEntity.internalEventEndPtr = 0;
-                        result = doContent(parser,
-                                           tagLevel,
-                                           internalEnc,
-                                           (char *)entity->textPtr,
-                                           (char *)(entity->textPtr + entity->textLen),
-                                           0);
-                        entity->open = 0;
-                        openInternalEntities = openEntity.next;
-                        if (result)
-                            return result;
-                    }
-                    else if (externalEntityRefHandler) {
-                        const XML_Char *context;
-                        entity->open = 1;
-                        context = getContext(parser);
-                        entity->open = 0;
-                        if (!context)
-                            return XML_ERROR_NO_MEMORY;
-                        if (!externalEntityRefHandler(externalEntityRefHandlerArg,
-                                                      context,
-                                                      dtd.base,
-                                                      entity->systemId,
-                                                      entity->publicId))
-                            return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
-                        poolDiscard(&tempPool);
-                    }
-                    else if (defaultHandler)
-                        reportDefault(parser, enc, s, next);
-                }
-                break;
-            }
-        case XML_TOK_START_TAG_WITH_ATTS:
-            if (!startElementHandler) {
-                enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
-                if (result)
-                    return result;
-            }
-            /* fall through */
-        case XML_TOK_START_TAG_NO_ATTS:
-            {
-                TAG *tag;
-                if (freeTagList) {
-                    tag = freeTagList;
-                    freeTagList = freeTagList->parent;
-                }
-                else {
-                    tag = malloc(sizeof(TAG));
-                    if (!tag)
-                        return XML_ERROR_NO_MEMORY;
-                    tag->buf = malloc(INIT_TAG_BUF_SIZE);
-                    if (!tag->buf)
-                        return XML_ERROR_NO_MEMORY;
-                    tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
-                }
-                tag->bindings = 0;
-                tag->parent = tagStack;
-                tagStack = tag;
-                tag->name.localPart = 0;
-                tag->rawName = s + enc->minBytesPerChar;
-                tag->rawNameLength = XmlNameLength(enc, tag->rawName);
-                if (nextPtr) {
-                    /* Need to guarantee that:
-                       tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
-                    if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
-                        int bufSize = tag->rawNameLength * 4;
-                        bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
-                        tag->buf = realloc(tag->buf, bufSize);
-                        if (!tag->buf)
-                            return XML_ERROR_NO_MEMORY;
-                        tag->bufEnd = tag->buf + bufSize;
-                    }
-                    memcpy(tag->buf, tag->rawName, tag->rawNameLength);
-                    tag->rawName = tag->buf;
-                }
-                ++tagLevel;
-                if (startElementHandler) {
-                    enum XML_Error result;
-                    XML_Char *toPtr;
-                    for (;;) {
-                        const char *rawNameEnd = tag->rawName + tag->rawNameLength;
-                        const char *fromPtr = tag->rawName;
-                        int bufSize;
-                        if (nextPtr)
-                            toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
-                        else
-                            toPtr = (XML_Char *)tag->buf;
-                        tag->name.str = toPtr;
-                        XmlConvert(enc,
-                                   &fromPtr, rawNameEnd,
-                                   (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
-                        if (fromPtr == rawNameEnd)
-                            break;
-                        bufSize = (tag->bufEnd - tag->buf) << 1;
-                        tag->buf = realloc(tag->buf, bufSize);
-                        if (!tag->buf)
-                            return XML_ERROR_NO_MEMORY;
-                        tag->bufEnd = tag->buf + bufSize;
-                        if (nextPtr)
-                            tag->rawName = tag->buf;
-                    }
-                    *toPtr = XML_T('\0');
-                    result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
-                    if (result)
-                        return result;
-                    startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
-                    poolClear(&tempPool);
-                }
-                else {
-                    tag->name.str = 0;
-                    if (defaultHandler)
-                        reportDefault(parser, enc, s, next);
-                }
-                break;
-            }
-        case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
-            if (!startElementHandler) {
-                enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
-                if (result)
-                    return result;
-            }
-            /* fall through */
-        case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
-            if (startElementHandler || endElementHandler) {
-                const char *rawName = s + enc->minBytesPerChar;
-                enum XML_Error result;
-                BINDING *bindings = 0;
-                TAG_NAME name;
-                name.str = poolStoreString(&tempPool, enc, rawName,
-                                           rawName + XmlNameLength(enc, rawName));
-                if (!name.str)
-                    return XML_ERROR_NO_MEMORY;
-                poolFinish(&tempPool);
-                result = storeAtts(parser, enc, s, &name, &bindings);
-                if (result)
-                    return result;
-                poolFinish(&tempPool);
-                if (startElementHandler)
-                    startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
-                if (endElementHandler) {
-                    if (startElementHandler)
-                        *eventPP = *eventEndPP;
-                    endElementHandler(handlerArg, name.str);
-                }
-                poolClear(&tempPool);
-                while (bindings) {
-                    BINDING *b = bindings;
-                    if (endNamespaceDeclHandler)
-                        endNamespaceDeclHandler(handlerArg, b->prefix->name);
-                    bindings = bindings->nextTagBinding;
-                    b->nextTagBinding = freeBindingList;
-                    freeBindingList = b;
-                    b->prefix->binding = b->prevPrefixBinding;
-                }
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            if (tagLevel == 0)
-                return epilogProcessor(parser, next, end, nextPtr);
-            break;
-        case XML_TOK_END_TAG:
-            if (tagLevel == startTagLevel)
-                return XML_ERROR_ASYNC_ENTITY;
-            else {
-                int len;
-                const char *rawName;
-                TAG *tag = tagStack;
-                tagStack = tag->parent;
-                tag->parent = freeTagList;
-                freeTagList = tag;
-                rawName = s + enc->minBytesPerChar*2;
-                len = XmlNameLength(enc, rawName);
-                if (len != tag->rawNameLength
-                        || memcmp(tag->rawName, rawName, len) != 0) {
-                    *eventPP = rawName;
-                    return XML_ERROR_TAG_MISMATCH;
-                }
-                --tagLevel;
-                if (endElementHandler && tag->name.str) {
-                    if (tag->name.localPart) {
-                        XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
-                        const XML_Char *from = tag->name.localPart;
-                        while ((*to++ = *from++) != 0)
-                            ;
-                    }
-                    endElementHandler(handlerArg, tag->name.str);
-                }
-                else if (defaultHandler)
-                    reportDefault(parser, enc, s, next);
-                while (tag->bindings) {
-                    BINDING *b = tag->bindings;
-                    if (endNamespaceDeclHandler)
-                        endNamespaceDeclHandler(handlerArg, b->prefix->name);
-                    tag->bindings = tag->bindings->nextTagBinding;
-                    b->nextTagBinding = freeBindingList;
-                    freeBindingList = b;
-                    b->prefix->binding = b->prevPrefixBinding;
-                }
-                if (tagLevel == 0)
-                    return epilogProcessor(parser, next, end, nextPtr);
-            }
-            break;
-        case XML_TOK_CHAR_REF:
-            {
-                int n = XmlCharRefNumber(enc, s);
-                if (n < 0)
-                    return XML_ERROR_BAD_CHAR_REF;
-                if (characterDataHandler) {
-                    XML_Char buf[XML_ENCODE_MAX];
-                    characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
-                }
-                else if (defaultHandler)
-                    reportDefault(parser, enc, s, next);
-            }
-            break;
-        case XML_TOK_XML_DECL:
-            return XML_ERROR_MISPLACED_XML_PI;
-        case XML_TOK_DATA_NEWLINE:
-            if (characterDataHandler) {
-                XML_Char c = 0xA;
-                characterDataHandler(handlerArg, &c, 1);
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            break;
-        case XML_TOK_CDATA_SECT_OPEN:
-            {
-                enum XML_Error result;
-                if (startCdataSectionHandler)
-                    startCdataSectionHandler(handlerArg);
-#if 0
-                /* Suppose you doing a transformation on a document that involves
-                   changing only the character data.  You set up a defaultHandler
-                   and a characterDataHandler.  The defaultHandler simply copies
-                   characters through.  The characterDataHandler does the transformation
-                   and writes the characters out escaping them as necessary.  This case
-                   will fail to work if we leave out the following two lines (because &
-                   and < inside CDATA sections will be incorrectly escaped).
-
-                   However, now we have a start/endCdataSectionHandler, so it seems
-                   easier to let the user deal with this. */
-
-                else if (characterDataHandler)
-                    characterDataHandler(handlerArg, dataBuf, 0);
-#endif
-                else if (defaultHandler)
-                    reportDefault(parser, enc, s, next);
-                result = doCdataSection(parser, enc, &next, end, nextPtr);
-                if (!next) {
-                    processor = cdataSectionProcessor;
-                    return result;
-                }
-            }
-            break;
-        case XML_TOK_TRAILING_RSQB:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            if (characterDataHandler) {
-                if (MUST_CONVERT(enc, s)) {
-                    ICHAR *dataPtr = (ICHAR *)dataBuf;
-                    XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
-                    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
-                }
-                else
-                    characterDataHandler(handlerArg,
-                                         (XML_Char *)s,
-                                         (XML_Char *)end - (XML_Char *)s);
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, end);
-            if (startTagLevel == 0) {
-                *eventPP = end;
-                return XML_ERROR_NO_ELEMENTS;
-            }
-            if (tagLevel != startTagLevel) {
-                *eventPP = end;
-                return XML_ERROR_ASYNC_ENTITY;
-            }
-            return XML_ERROR_NONE;
-        case XML_TOK_DATA_CHARS:
-            if (characterDataHandler) {
-                if (MUST_CONVERT(enc, s)) {
-                    for (;;) {
-                        ICHAR *dataPtr = (ICHAR *)dataBuf;
-                        XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
-                        *eventEndPP = s;
-                        characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
-                        if (s == next)
-                            break;
-                        *eventPP = s;
-                    }
-                }
-                else
-                    characterDataHandler(handlerArg,
-                                         (XML_Char *)s,
-                                         (XML_Char *)next - (XML_Char *)s);
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            break;
-        case XML_TOK_PI:
-            if (!reportProcessingInstruction(parser, enc, s, next))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        case XML_TOK_COMMENT:
-            if (!reportComment(parser, enc, s, next))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        default:
-            if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            break;
-        }
-        *eventPP = s = next;
-    }
-    /* not reached */
-}
-
-/* If tagNamePtr is non-null, build a real list of attributes,
-otherwise just check the attributes for well-formedness. */
-
-static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
-                                const char *s, TAG_NAME *tagNamePtr,
-                                BINDING **bindingsPtr)
-{
-    ELEMENT_TYPE *elementType = 0;
-    int nDefaultAtts = 0;
-    const XML_Char **appAtts;
-    int attIndex = 0;
-    int i;
-    int n;
-    int nPrefixes = 0;
-    BINDING *binding;
-    const XML_Char *localPart;
-
-    if (tagNamePtr) {
-        elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, 0);
-        if (!elementType) {
-            tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
-            if (!tagNamePtr->str)
-                return XML_ERROR_NO_MEMORY;
-            elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
-            if (!elementType)
-                return XML_ERROR_NO_MEMORY;
-            if (ns && !setElementTypePrefix(parser, elementType))
-                return XML_ERROR_NO_MEMORY;
-        }
-        nDefaultAtts = elementType->nDefaultAtts;
-    }
-    n = XmlGetAttributes(enc, s, attsSize, atts);
-    if (n + nDefaultAtts > attsSize) {
-        int oldAttsSize = attsSize;
-        attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
-        atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
-        if (!atts)
-            return XML_ERROR_NO_MEMORY;
-        if (n > oldAttsSize)
-            XmlGetAttributes(enc, s, n, atts);
-    }
-    appAtts = (const XML_Char **)atts;
-    for (i = 0; i < n; i++) {
-        ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
-                                             atts[i].name
-                                             + XmlNameLength(enc, atts[i].name));
-        if (!attId)
-            return XML_ERROR_NO_MEMORY;
-        if ((attId->name)[-1]) {
-            if (enc == encoding)
-                eventPtr = atts[i].name;
-            return XML_ERROR_DUPLICATE_ATTRIBUTE;
-        }
-        (attId->name)[-1] = 1;
-        appAtts[attIndex++] = attId->name;
-        if (!atts[i].normalized) {
-            enum XML_Error result;
-            int isCdata = 1;
-
-            if (attId->maybeTokenized) {
-                int j;
-                for (j = 0; j < nDefaultAtts; j++) {
-                    if (attId == elementType->defaultAtts[j].id) {
-                        isCdata = elementType->defaultAtts[j].isCdata;
-                        break;
-                    }
-                }
-            }
-
-            result = storeAttributeValue(parser, enc, isCdata,
-                                         atts[i].valuePtr, atts[i].valueEnd,
-                                         &tempPool);
-            if (result)
-                return result;
-            if (tagNamePtr) {
-                appAtts[attIndex] = poolStart(&tempPool);
-                poolFinish(&tempPool);
-            }
-            else
-                poolDiscard(&tempPool);
-        }
-        else if (tagNamePtr) {
-            appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
-            if (appAtts[attIndex] == 0)
-                return XML_ERROR_NO_MEMORY;
-            poolFinish(&tempPool);
-        }
-        if (attId->prefix && tagNamePtr) {
-            if (attId->xmlns) {
-                if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
-                    return XML_ERROR_NO_MEMORY;
-                --attIndex;
-            }
-            else {
-                attIndex++;
-                nPrefixes++;
-                (attId->name)[-1] = 2;
-            }
-        }
-        else
-            attIndex++;
-    }
-    nSpecifiedAtts = attIndex;
-    if (tagNamePtr) {
-        int j;
-        for (j = 0; j < nDefaultAtts; j++) {
-            const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
-            if (!(da->id->name)[-1] && da->value) {
-                if (da->id->prefix) {
-                    if (da->id->xmlns) {
-                        if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
-                            return XML_ERROR_NO_MEMORY;
-                    }
-                    else {
-                        (da->id->name)[-1] = 2;
-                        nPrefixes++;
-                        appAtts[attIndex++] = da->id->name;
-                        appAtts[attIndex++] = da->value;
-                    }
-                }
-                else {
-                    (da->id->name)[-1] = 1;
-                    appAtts[attIndex++] = da->id->name;
-                    appAtts[attIndex++] = da->value;
-                }
-            }
-        }
-        appAtts[attIndex] = 0;
-    }
-    i = 0;
-    if (nPrefixes) {
-        for (; i < attIndex; i += 2) {
-            if (appAtts[i][-1] == 2) {
-                ATTRIBUTE_ID *id;
-                ((XML_Char *)(appAtts[i]))[-1] = 0;
-                id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
-                if (id->prefix->binding) {
-                    int j;
-                    const BINDING *b = id->prefix->binding;
-                    const XML_Char *s = appAtts[i];
-                    for (j = 0; j < b->uriLen; j++) {
-                        if (!poolAppendChar(&tempPool, b->uri[j]))
-                            return XML_ERROR_NO_MEMORY;
-                    }
-                    while (*s++ != ':')
-                        ;
-                    do {
-                        if (!poolAppendChar(&tempPool, *s))
-                            return XML_ERROR_NO_MEMORY;
-                    } while (*s++);
-                    appAtts[i] = poolStart(&tempPool);
-                    poolFinish(&tempPool);
-                }
-                if (!--nPrefixes)
-                    break;
-            }
-            else
-                ((XML_Char *)(appAtts[i]))[-1] = 0;
-        }
-    }
-    for (; i < attIndex; i += 2)
-        ((XML_Char *)(appAtts[i]))[-1] = 0;
-    if (!tagNamePtr)
-        return XML_ERROR_NONE;
-    for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
-        binding->attId->name[-1] = 0;
-    if (elementType->prefix) {
-        binding = elementType->prefix->binding;
-        if (!binding)
-            return XML_ERROR_NONE;
-        localPart = tagNamePtr->str;
-        while (*localPart++ != XML_T(':'))
-            ;
-    }
-    else if (dtd.defaultPrefix.binding) {
-        binding = dtd.defaultPrefix.binding;
-        localPart = tagNamePtr->str;
-    }
-    else
-        return XML_ERROR_NONE;
-    tagNamePtr->localPart = localPart;
-    tagNamePtr->uriLen = binding->uriLen;
-    i = binding->uriLen;
-    do {
-        if (i == binding->uriAlloc) {
-            binding->uri = realloc(binding->uri, binding->uriAlloc *= 2);
-            if (!binding->uri)
-                return XML_ERROR_NO_MEMORY;
-        }
-        binding->uri[i++] = *localPart;
-    } while (*localPart++);
-    tagNamePtr->str = binding->uri;
-    return XML_ERROR_NONE;
-}
-
-static
-int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
-{
-    BINDING *b;
-    int len;
-    for (len = 0; uri[len]; len++)
-        ;
-    if (namespaceSeparator)
-        len++;
-    if (freeBindingList) {
-        b = freeBindingList;
-        if (len > b->uriAlloc) {
-            b->uri = realloc(b->uri, len + EXPAND_SPARE);
-            if (!b->uri)
-                return 0;
-            b->uriAlloc = len + EXPAND_SPARE;
-        }
-        freeBindingList = b->nextTagBinding;
-    }
-    else {
-        b = malloc(sizeof(BINDING));
-        if (!b)
-            return 0;
-        b->uri = malloc(sizeof(XML_Char) * len + EXPAND_SPARE);
-        if (!b->uri) {
-            free(b);
-            return 0;
-        }
-        b->uriAlloc = len;
-    }
-    b->uriLen = len;
-    memcpy(b->uri, uri, len * sizeof(XML_Char));
-    if (namespaceSeparator)
-        b->uri[len - 1] = namespaceSeparator;
-    b->prefix = prefix;
-    b->attId = attId;
-    b->prevPrefixBinding = prefix->binding;
-    if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
-        prefix->binding = 0;
-    else
-        prefix->binding = b;
-    b->nextTagBinding = *bindingsPtr;
-    *bindingsPtr = b;
-    if (startNamespaceDeclHandler)
-        startNamespaceDeclHandler(handlerArg, prefix->name,
-                                  prefix->binding ? uri : 0);
-    return 1;
-}
-
-/* The idea here is to avoid using stack for each CDATA section when
-the whole file is parsed with one call. */
-
-static
-enum XML_Error cdataSectionProcessor(XML_Parser parser,
-                                     const char *start,
-                                     const char *end,
-                                     const char **endPtr)
-{
-    enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
-    if (start) {
-        processor = contentProcessor;
-        return contentProcessor(parser, start, end, endPtr);
-    }
-    return result;
-}
-
-/* startPtr gets set to non-null is the section is closed, and to null if
-the section is not yet closed. */
-
-static
-enum XML_Error doCdataSection(XML_Parser parser,
-                              const ENCODING *enc,
-                              const char **startPtr,
-                              const char *end,
-                              const char **nextPtr)
-{
-    const char *s = *startPtr;
-    const char **eventPP;
-    const char **eventEndPP;
-    if (enc == encoding) {
-        eventPP = &eventPtr;
-        *eventPP = s;
-        eventEndPP = &eventEndPtr;
-    }
-    else {
-        eventPP = &(openInternalEntities->internalEventPtr);
-        eventEndPP = &(openInternalEntities->internalEventEndPtr);
-    }
-    *eventPP = s;
-    *startPtr = 0;
-    for (;;) {
-        const char *next;
-        int tok = XmlCdataSectionTok(enc, s, end, &next);
-        *eventEndPP = next;
-        switch (tok) {
-        case XML_TOK_CDATA_SECT_CLOSE:
-            if (endCdataSectionHandler)
-                endCdataSectionHandler(handlerArg);
-#if 0
-            /* see comment under XML_TOK_CDATA_SECT_OPEN */
-            else if (characterDataHandler)
-                characterDataHandler(handlerArg, dataBuf, 0);
-#endif
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            *startPtr = next;
-            return XML_ERROR_NONE;
-        case XML_TOK_DATA_NEWLINE:
-            if (characterDataHandler) {
-                XML_Char c = 0xA;
-                characterDataHandler(handlerArg, &c, 1);
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            break;
-        case XML_TOK_DATA_CHARS:
-            if (characterDataHandler) {
-                if (MUST_CONVERT(enc, s)) {
-                    for (;;) {
-                        ICHAR *dataPtr = (ICHAR *)dataBuf;
-                        XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
-                        *eventEndPP = next;
-                        characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
-                        if (s == next)
-                            break;
-                        *eventPP = s;
-                    }
-                }
-                else
-                    characterDataHandler(handlerArg,
-                                         (XML_Char *)s,
-                                         (XML_Char *)next - (XML_Char *)s);
-            }
-            else if (defaultHandler)
-                reportDefault(parser, enc, s, next);
-            break;
-        case XML_TOK_INVALID:
-            *eventPP = next;
-            return XML_ERROR_INVALID_TOKEN;
-        case XML_TOK_PARTIAL_CHAR:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_PARTIAL_CHAR;
-        case XML_TOK_PARTIAL:
-        case XML_TOK_NONE:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_UNCLOSED_CDATA_SECTION;
-        default:
-            abort();
-        }
-        *eventPP = s = next;
-    }
-    /* not reached */
-}
-
-static enum XML_Error
-initializeEncoding(XML_Parser parser)
-{
-    const char *s;
-#ifdef XML_UNICODE
-    char encodingBuf[128];
-    if (!protocolEncodingName)
-        s = 0;
-    else {
-        int i;
-        for (i = 0; protocolEncodingName[i]; i++) {
-            if (i == sizeof(encodingBuf) - 1
-                    || protocolEncodingName[i] >= 0x80
-                    || protocolEncodingName[i] < 0) {
-                encodingBuf[0] = '\0';
-                break;
-            }
-            encodingBuf[i] = (char)protocolEncodingName[i];
-        }
-        encodingBuf[i] = '\0';
-        s = encodingBuf;
-    }
-#else
-s = protocolEncodingName;
-#endif
-    if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
-        return XML_ERROR_NONE;
-    return handleUnknownEncoding(parser, protocolEncodingName);
-}
-
-static enum XML_Error
-processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
-               const char *s, const char *next)
-{
-    const char *encodingName = 0;
-    const ENCODING *newEncoding = 0;
-    const char *version;
-    int standalone = -1;
-    if (!(ns
-            ? XmlParseXmlDeclNS
-            : XmlParseXmlDecl)(isGeneralTextEntity,
-                               encoding,
-                               s,
-                               next,
-                               &eventPtr,
-                               &version,
-                               &encodingName,
-                               &newEncoding,
-                               &standalone))
-        return XML_ERROR_SYNTAX;
-    if (!isGeneralTextEntity && standalone == 1)
-        dtd.standalone = 1;
-    if (defaultHandler)
-        reportDefault(parser, encoding, s, next);
-    if (!protocolEncodingName) {
-        if (newEncoding) {
-            if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
-                eventPtr = encodingName;
-                return XML_ERROR_INCORRECT_ENCODING;
-            }
-            encoding = newEncoding;
-        }
-        else if (encodingName) {
-            enum XML_Error result;
-            const XML_Char *s = poolStoreString(&tempPool,
-                                                encoding,
-                                                encodingName,
-                                                encodingName
-                                                + XmlNameLength(encoding, encodingName));
-            if (!s)
-                return XML_ERROR_NO_MEMORY;
-            result = handleUnknownEncoding(parser, s);
-            poolDiscard(&tempPool);
-            if (result == XML_ERROR_UNKNOWN_ENCODING)
-                eventPtr = encodingName;
-            return result;
-        }
-    }
-    return XML_ERROR_NONE;
-}
-
-static enum XML_Error
-handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
-{
-    if (unknownEncodingHandler) {
-        XML_Encoding info;
-        int i;
-        for (i = 0; i < 256; i++)
-            info.map[i] = -1;
-        info.convert = 0;
-        info.data = 0;
-        info.release = 0;
-        if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
-            ENCODING *enc;
-            unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding());
-            if (!unknownEncodingMem) {
-                if (info.release)
-                    info.release(info.data);
-                return XML_ERROR_NO_MEMORY;
-            }
-            enc = (ns
-                   ? XmlInitUnknownEncodingNS
-                   : XmlInitUnknownEncoding)(unknownEncodingMem,
-                                             info.map,
-                                             info.convert,
-                                             info.data);
-            if (enc) {
-                unknownEncodingData = info.data;
-                unknownEncodingRelease = info.release;
-                encoding = enc;
-                return XML_ERROR_NONE;
-            }
-        }
-        if (info.release)
-            info.release(info.data);
-    }
-    return XML_ERROR_UNKNOWN_ENCODING;
-}
-
-static enum XML_Error
-prologInitProcessor(XML_Parser parser,
-                    const char *s,
-                    const char *end,
-                    const char **nextPtr)
-{
-    enum XML_Error result = initializeEncoding(parser);
-    if (result != XML_ERROR_NONE)
-        return result;
-    processor = prologProcessor;
-    return prologProcessor(parser, s, end, nextPtr);
-}
-
-static enum XML_Error
-prologProcessor(XML_Parser parser,
-                const char *s,
-                const char *end,
-                const char **nextPtr)
-{
-    for (;;) {
-        const char *next;
-        int tok = XmlPrologTok(encoding, s, end, &next);
-        if (tok <= 0) {
-            if (nextPtr != 0 && tok != XML_TOK_INVALID) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            switch (tok) {
-            case XML_TOK_INVALID:
-                eventPtr = next;
-                return XML_ERROR_INVALID_TOKEN;
-            case XML_TOK_NONE:
-                return XML_ERROR_NO_ELEMENTS;
-            case XML_TOK_PARTIAL:
-                return XML_ERROR_UNCLOSED_TOKEN;
-            case XML_TOK_PARTIAL_CHAR:
-                return XML_ERROR_PARTIAL_CHAR;
-            case XML_TOK_TRAILING_CR:
-                eventPtr = s + encoding->minBytesPerChar;
-                return XML_ERROR_NO_ELEMENTS;
-            default:
-                abort();
-            }
-        }
-        switch (XmlTokenRole(&prologState, tok, s, next, encoding)) {
-        case XML_ROLE_XML_DECL:
-            {
-                enum XML_Error result = processXmlDecl(parser, 0, s, next);
-                if (result != XML_ERROR_NONE)
-                    return result;
-            }
-            break;
-        case XML_ROLE_DOCTYPE_SYSTEM_ID:
-            if (!dtd.standalone
-                    && notStandaloneHandler
-                    && !notStandaloneHandler(handlerArg))
-                return XML_ERROR_NOT_STANDALONE;
-            hadExternalDoctype = 1;
-            break;
-        case XML_ROLE_DOCTYPE_PUBLIC_ID:
-        case XML_ROLE_ENTITY_PUBLIC_ID:
-            if (!XmlIsPublicId(encoding, s, next, &eventPtr))
-                return XML_ERROR_SYNTAX;
-            if (declEntity) {
-                XML_Char *tem = poolStoreString(&dtd.pool,
-                                                encoding,
-                                                s + encoding->minBytesPerChar,
-                                                next - encoding->minBytesPerChar);
-                if (!tem)
-                    return XML_ERROR_NO_MEMORY;
-                normalizePublicId(tem);
-                declEntity->publicId = tem;
-                poolFinish(&dtd.pool);
-            }
-            break;
-        case XML_ROLE_INSTANCE_START:
-            processor = contentProcessor;
-            if (hadExternalDoctype)
-                dtd.complete = 0;
-            return contentProcessor(parser, s, end, nextPtr);
-        case XML_ROLE_ATTLIST_ELEMENT_NAME:
-            {
-                const XML_Char *name = poolStoreString(&dtd.pool, encoding, s, next);
-                if (!name)
-                    return XML_ERROR_NO_MEMORY;
-                declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
-                if (!declElementType)
-                    return XML_ERROR_NO_MEMORY;
-                if (declElementType->name != name)
-                    poolDiscard(&dtd.pool);
-                else {
-                    poolFinish(&dtd.pool);
-                    if (!setElementTypePrefix(parser, declElementType))
-                        return XML_ERROR_NO_MEMORY;
-                }
-                break;
-            }
-        case XML_ROLE_ATTRIBUTE_NAME:
-            declAttributeId = getAttributeId(parser, encoding, s, next);
-            if (!declAttributeId)
-                return XML_ERROR_NO_MEMORY;
-            declAttributeIsCdata = 0;
-            break;
-        case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
-            declAttributeIsCdata = 1;
-            break;
-        case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
-        case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
-            if (dtd.complete
-                    && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
-        case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
-            {
-                const XML_Char *attVal;
-                enum XML_Error result
-                = storeAttributeValue(parser, encoding, declAttributeIsCdata,
-                                      s + encoding->minBytesPerChar,
-                                      next - encoding->minBytesPerChar,
-                                      &dtd.pool);
-                if (result)
-                    return result;
-                attVal = poolStart(&dtd.pool);
-                poolFinish(&dtd.pool);
-                if (dtd.complete
-                        && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal))
-                    return XML_ERROR_NO_MEMORY;
-                break;
-            }
-        case XML_ROLE_ENTITY_VALUE:
-            {
-                enum XML_Error result = storeEntityValue(parser, s, next);
-                if (result != XML_ERROR_NONE)
-                    return result;
-            }
-            break;
-        case XML_ROLE_ENTITY_SYSTEM_ID:
-            if (declEntity) {
-                declEntity->systemId = poolStoreString(&dtd.pool, encoding,
-                                                       s + encoding->minBytesPerChar,
-                                                       next - encoding->minBytesPerChar);
-                if (!declEntity->systemId)
-                    return XML_ERROR_NO_MEMORY;
-                declEntity->base = dtd.base;
-                poolFinish(&dtd.pool);
-            }
-            break;
-        case XML_ROLE_ENTITY_NOTATION_NAME:
-            if (declEntity) {
-                declEntity->notation = poolStoreString(&dtd.pool, encoding, s, next);
-                if (!declEntity->notation)
-                    return XML_ERROR_NO_MEMORY;
-                poolFinish(&dtd.pool);
-                if (unparsedEntityDeclHandler) {
-                    eventPtr = eventEndPtr = s;
-                    unparsedEntityDeclHandler(handlerArg,
-                                              declEntity->name,
-                                              declEntity->base,
-                                              declEntity->systemId,
-                                              declEntity->publicId,
-                                              declEntity->notation);
-                }
-
-            }
-            break;
-        case XML_ROLE_GENERAL_ENTITY_NAME:
-            {
-                const XML_Char *name;
-                if (XmlPredefinedEntityName(encoding, s, next)) {
-                    declEntity = 0;
-                    break;
-                }
-                name = poolStoreString(&dtd.pool, encoding, s, next);
-                if (!name)
-                    return XML_ERROR_NO_MEMORY;
-                if (dtd.complete) {
-                    declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
-                    if (!declEntity)
-                        return XML_ERROR_NO_MEMORY;
-                    if (declEntity->name != name) {
-                        poolDiscard(&dtd.pool);
-                        declEntity = 0;
-                    }
-                    else
-                        poolFinish(&dtd.pool);
-                }
-                else {
-                    poolDiscard(&dtd.pool);
-                    declEntity = 0;
-                }
-            }
-            break;
-        case XML_ROLE_PARAM_ENTITY_NAME:
-            declEntity = 0;
-            break;
-        case XML_ROLE_NOTATION_NAME:
-            declNotationPublicId = 0;
-            declNotationName = 0;
-            if (notationDeclHandler) {
-                declNotationName = poolStoreString(&tempPool, encoding, s, next);
-                if (!declNotationName)
-                    return XML_ERROR_NO_MEMORY;
-                poolFinish(&tempPool);
-            }
-            break;
-        case XML_ROLE_NOTATION_PUBLIC_ID:
-            if (!XmlIsPublicId(encoding, s, next, &eventPtr))
-                return XML_ERROR_SYNTAX;
-            if (declNotationName) {
-                XML_Char *tem = poolStoreString(&tempPool,
-                                                encoding,
-                                                s + encoding->minBytesPerChar,
-                                                next - encoding->minBytesPerChar);
-                if (!tem)
-                    return XML_ERROR_NO_MEMORY;
-                normalizePublicId(tem);
-                declNotationPublicId = tem;
-                poolFinish(&tempPool);
-            }
-            break;
-        case XML_ROLE_NOTATION_SYSTEM_ID:
-            if (declNotationName && notationDeclHandler) {
-                const XML_Char *systemId
-                = poolStoreString(&tempPool, encoding,
-                                  s + encoding->minBytesPerChar,
-                                  next - encoding->minBytesPerChar);
-                if (!systemId)
-                    return XML_ERROR_NO_MEMORY;
-                eventPtr = eventEndPtr = s;
-                notationDeclHandler(handlerArg,
-                                    declNotationName,
-                                    dtd.base,
-                                    systemId,
-                                    declNotationPublicId);
-            }
-            poolClear(&tempPool);
-            break;
-        case XML_ROLE_NOTATION_NO_SYSTEM_ID:
-            if (declNotationPublicId && notationDeclHandler) {
-                eventPtr = eventEndPtr = s;
-                notationDeclHandler(handlerArg,
-                                    declNotationName,
-                                    dtd.base,
-                                    0,
-                                    declNotationPublicId);
-            }
-            poolClear(&tempPool);
-            break;
-        case XML_ROLE_ERROR:
-            eventPtr = s;
-            switch (tok) {
-            case XML_TOK_PARAM_ENTITY_REF:
-                return XML_ERROR_PARAM_ENTITY_REF;
-            case XML_TOK_XML_DECL:
-                return XML_ERROR_MISPLACED_XML_PI;
-            default:
-                return XML_ERROR_SYNTAX;
-            }
-        case XML_ROLE_GROUP_OPEN:
-            if (prologState.level >= groupSize) {
-                if (groupSize)
-                    groupConnector = realloc(groupConnector, groupSize *= 2);
-                else
-                    groupConnector = malloc(groupSize = 32);
-                if (!groupConnector)
-                    return XML_ERROR_NO_MEMORY;
-            }
-            groupConnector[prologState.level] = 0;
-            break;
-        case XML_ROLE_GROUP_SEQUENCE:
-            if (groupConnector[prologState.level] == '|') {
-                eventPtr = s;
-                return XML_ERROR_SYNTAX;
-            }
-            groupConnector[prologState.level] = ',';
-            break;
-        case XML_ROLE_GROUP_CHOICE:
-            if (groupConnector[prologState.level] == ',') {
-                eventPtr = s;
-                return XML_ERROR_SYNTAX;
-            }
-            groupConnector[prologState.level] = '|';
-            break;
-        case XML_ROLE_PARAM_ENTITY_REF:
-            if (!dtd.standalone
-                    && notStandaloneHandler
-                    && !notStandaloneHandler(handlerArg))
-                return XML_ERROR_NOT_STANDALONE;
-            dtd.complete = 0;
-            break;
-        case XML_ROLE_NONE:
-            switch (tok) {
-            case XML_TOK_PI:
-                eventPtr = s;
-                eventEndPtr = next;
-                if (!reportProcessingInstruction(parser, encoding, s, next))
-                    return XML_ERROR_NO_MEMORY;
-                break;
-            case XML_TOK_COMMENT:
-                eventPtr = s;
-                eventEndPtr = next;
-                if (!reportComment(parser, encoding, s, next))
-                    return XML_ERROR_NO_MEMORY;
-                break;
-            }
-            break;
-        }
-        if (defaultHandler) {
-            switch (tok) {
-            case XML_TOK_PI:
-            case XML_TOK_COMMENT:
-            case XML_TOK_BOM:
-            case XML_TOK_XML_DECL:
-                break;
-            default:
-                eventPtr = s;
-                eventEndPtr = next;
-                reportDefault(parser, encoding, s, next);
-            }
-        }
-        s = next;
-    }
-    /* not reached */
-}
-
-static
-enum XML_Error epilogProcessor(XML_Parser parser,
-                               const char *s,
-                               const char *end,
-                               const char **nextPtr)
-{
-    processor = epilogProcessor;
-    eventPtr = s;
-    for (;;) {
-        const char *next;
-        int tok = XmlPrologTok(encoding, s, end, &next);
-        eventEndPtr = next;
-        switch (tok) {
-        case XML_TOK_TRAILING_CR:
-            if (defaultHandler) {
-                eventEndPtr = end;
-                reportDefault(parser, encoding, s, end);
-            }
-            /* fall through */
-        case XML_TOK_NONE:
-            if (nextPtr)
-                *nextPtr = end;
-            return XML_ERROR_NONE;
-        case XML_TOK_PROLOG_S:
-            if (defaultHandler)
-                reportDefault(parser, encoding, s, next);
-            break;
-        case XML_TOK_PI:
-            if (!reportProcessingInstruction(parser, encoding, s, next))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        case XML_TOK_COMMENT:
-            if (!reportComment(parser, encoding, s, next))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        case XML_TOK_INVALID:
-            eventPtr = next;
-            return XML_ERROR_INVALID_TOKEN;
-        case XML_TOK_PARTIAL:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_UNCLOSED_TOKEN;
-        case XML_TOK_PARTIAL_CHAR:
-            if (nextPtr) {
-                *nextPtr = s;
-                return XML_ERROR_NONE;
-            }
-            return XML_ERROR_PARTIAL_CHAR;
-        default:
-            return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
-        }
-        eventPtr = s = next;
-    }
-}
-
-static enum XML_Error
-storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
-                    const char *ptr, const char *end,
-                    STRING_POOL *pool)
-{
-    enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
-    if (result)
-        return result;
-    if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
-        poolChop(pool);
-    if (!poolAppendChar(pool, XML_T('\0')))
-        return XML_ERROR_NO_MEMORY;
-    return XML_ERROR_NONE;
-}
-
-static enum XML_Error
-appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
-                     const char *ptr, const char *end,
-                     STRING_POOL *pool)
-{
-    const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding();
-    for (;;) {
-        const char *next;
-        int tok = XmlAttributeValueTok(enc, ptr, end, &next);
-        switch (tok) {
-        case XML_TOK_NONE:
-            return XML_ERROR_NONE;
-        case XML_TOK_INVALID:
-            if (enc == encoding)
-                eventPtr = next;
-            return XML_ERROR_INVALID_TOKEN;
-        case XML_TOK_PARTIAL:
-            if (enc == encoding)
-                eventPtr = ptr;
-            return XML_ERROR_INVALID_TOKEN;
-        case XML_TOK_CHAR_REF:
-            {
-                XML_Char buf[XML_ENCODE_MAX];
-                int i;
-                int n = XmlCharRefNumber(enc, ptr);
-                if (n < 0) {
-                    if (enc == encoding)
-                        eventPtr = ptr;
-                    return XML_ERROR_BAD_CHAR_REF;
-                }
-                if (!isCdata
-                        && n == 0x20 /* space */
-                        && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
-                    break;
-                n = XmlEncode(n, (ICHAR *)buf);
-                if (!n) {
-                    if (enc == encoding)
-                        eventPtr = ptr;
-                    return XML_ERROR_BAD_CHAR_REF;
-                }
-                for (i = 0; i < n; i++) {
-                    if (!poolAppendChar(pool, buf[i]))
-                        return XML_ERROR_NO_MEMORY;
-                }
-            }
-            break;
-        case XML_TOK_DATA_CHARS:
-            if (!poolAppend(pool, enc, ptr, next))
-                return XML_ERROR_NO_MEMORY;
-            break;
-            break;
-        case XML_TOK_TRAILING_CR:
-            next = ptr + enc->minBytesPerChar;
-            /* fall through */
-        case XML_TOK_ATTRIBUTE_VALUE_S:
-        case XML_TOK_DATA_NEWLINE:
-            if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
-                break;
-            if (!poolAppendChar(pool, 0x20))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        case XML_TOK_ENTITY_REF:
-            {
-                const XML_Char *name;
-                ENTITY *entity;
-                XML_Char ch = XmlPredefinedEntityName(enc,
-                                                      ptr + enc->minBytesPerChar,
-                                                      next - enc->minBytesPerChar);
-                if (ch) {
-                    if (!poolAppendChar(pool, ch))
-                        return XML_ERROR_NO_MEMORY;
-                    break;
-                }
-                name = poolStoreString(&temp2Pool, enc,
-                                       ptr + enc->minBytesPerChar,
-                                       next - enc->minBytesPerChar);
-                if (!name)
-                    return XML_ERROR_NO_MEMORY;
-                entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
-                poolDiscard(&temp2Pool);
-                if (!entity) {
-                    if (dtd.complete) {
-                        if (enc == encoding)
-                            eventPtr = ptr;
-                        return XML_ERROR_UNDEFINED_ENTITY;
-                    }
-                }
-                else if (entity->open) {
-                    if (enc == encoding)
-                        eventPtr = ptr;
-                    return XML_ERROR_RECURSIVE_ENTITY_REF;
-                }
-                else if (entity->notation) {
-                    if (enc == encoding)
-                        eventPtr = ptr;
-                    return XML_ERROR_BINARY_ENTITY_REF;
-                }
-                else if (!entity->textPtr) {
-                    if (enc == encoding)
-                        eventPtr = ptr;
-                    return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
-                }
-                else {
-                    enum XML_Error result;
-                    const XML_Char *textEnd = entity->textPtr + entity->textLen;
-                    entity->open = 1;
-                    result = appendAttributeValue(parser, internalEnc, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
-                    entity->open = 0;
-                    if (result)
-                        return result;
-                }
-            }
-            break;
-        default:
-            abort();
-        }
-        ptr = next;
-    }
-    /* not reached */
-}
-
-static
-enum XML_Error storeEntityValue(XML_Parser parser,
-                                const char *entityTextPtr,
-                                const char *entityTextEnd)
-{
-    const ENCODING *internalEnc;
-    STRING_POOL *pool = &(dtd.pool);
-    entityTextPtr += encoding->minBytesPerChar;
-    entityTextEnd -= encoding->minBytesPerChar;
-    internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding();
-    for (;;) {
-        const char *next;
-        int tok = XmlEntityValueTok(encoding, entityTextPtr, entityTextEnd, &next);
-        switch (tok) {
-        case XML_TOK_PARAM_ENTITY_REF:
-            eventPtr = entityTextPtr;
-            return XML_ERROR_SYNTAX;
-        case XML_TOK_NONE:
-            if (declEntity) {
-                declEntity->textPtr = pool->start;
-                declEntity->textLen = pool->ptr - pool->start;
-                poolFinish(pool);
-            }
-            else
-                poolDiscard(pool);
-            return XML_ERROR_NONE;
-        case XML_TOK_ENTITY_REF:
-        case XML_TOK_DATA_CHARS:
-            if (!poolAppend(pool, encoding, entityTextPtr, next))
-                return XML_ERROR_NO_MEMORY;
-            break;
-        case XML_TOK_TRAILING_CR:
-            next = entityTextPtr + encoding->minBytesPerChar;
-            /* fall through */
-        case XML_TOK_DATA_NEWLINE:
-            if (pool->end == pool->ptr && !poolGrow(pool))
-                return XML_ERROR_NO_MEMORY;
-            *(pool->ptr)++ = 0xA;
-            break;
-        case XML_TOK_CHAR_REF:
-            {
-                XML_Char buf[XML_ENCODE_MAX];
-                int i;
-                int n = XmlCharRefNumber(encoding, entityTextPtr);
-                if (n < 0) {
-                    eventPtr = entityTextPtr;
-                    return XML_ERROR_BAD_CHAR_REF;
-                }
-                n = XmlEncode(n, (ICHAR *)buf);
-                if (!n) {
-                    eventPtr = entityTextPtr;
-                    return XML_ERROR_BAD_CHAR_REF;
-                }
-                for (i = 0; i < n; i++) {
-                    if (pool->end == pool->ptr && !poolGrow(pool))
-                        return XML_ERROR_NO_MEMORY;
-                    *(pool->ptr)++ = buf[i];
-                }
-            }
-            break;
-        case XML_TOK_PARTIAL:
-            eventPtr = entityTextPtr;
-            return XML_ERROR_INVALID_TOKEN;
-        case XML_TOK_INVALID:
-            eventPtr = next;
-            return XML_ERROR_INVALID_TOKEN;
-        default:
-            abort();
-        }
-        entityTextPtr = next;
-    }
-    /* not reached */
-}
-
-static void
-normalizeLines(XML_Char *s)
-{
-    XML_Char *p;
-    for (;; s++) {
-        if (*s == XML_T('\0'))
-            return;
-        if (*s == 0xD)
-            break;
-    }
-    p = s;
-    do {
-        if (*s == 0xD) {
-            *p++ = 0xA;
-            if (*++s == 0xA)
-                s++;
-        }
-        else
-            *p++ = *s++;
-    } while (*s);
-    *p = XML_T('\0');
-}
-
-static int
-reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
-{
-    const XML_Char *target;
-    XML_Char *data;
-    const char *tem;
-    if (!processingInstructionHandler) {
-        if (defaultHandler)
-            reportDefault(parser, enc, start, end);
-        return 1;
-    }
-    start += enc->minBytesPerChar * 2;
-    tem = start + XmlNameLength(enc, start);
-    target = poolStoreString(&tempPool, enc, start, tem);
-    if (!target)
-        return 0;
-    poolFinish(&tempPool);
-    data = poolStoreString(&tempPool, enc,
-                           XmlSkipS(enc, tem),
-                           end - enc->minBytesPerChar*2);
-    if (!data)
-        return 0;
-    normalizeLines(data);
-    processingInstructionHandler(handlerArg, target, data);
-    poolClear(&tempPool);
-    return 1;
-}
-
-static int
-reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
-{
-    XML_Char *data;
-    if (!commentHandler) {
-        if (defaultHandler)
-            reportDefault(parser, enc, start, end);
-        return 1;
-    }
-    data = poolStoreString(&tempPool,
-                           enc,
-                           start + enc->minBytesPerChar * 4,
-                           end - enc->minBytesPerChar * 3);
-    if (!data)
-        return 0;
-    normalizeLines(data);
-    commentHandler(handlerArg, data);
-    poolClear(&tempPool);
-    return 1;
-}
-
-static void
-reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
-{
-    if (MUST_CONVERT(enc, s)) {
-        const char **eventPP;
-        const char **eventEndPP;
-        if (enc == encoding) {
-            eventPP = &eventPtr;
-            eventEndPP = &eventEndPtr;
-        }
-        else {
-            eventPP = &(openInternalEntities->internalEventPtr);
-            eventEndPP = &(openInternalEntities->internalEventEndPtr);
-        }
-        do {
-            ICHAR *dataPtr = (ICHAR *)dataBuf;
-            XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
-            *eventEndPP = s;
-            defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
-            *eventPP = s;
-        } while (s != end);
-    }
-    else
-        defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
-}
-
-
-static int
-defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value)
-{
-    DEFAULT_ATTRIBUTE *att;
-    if (type->nDefaultAtts == type->allocDefaultAtts) {
-        if (type->allocDefaultAtts == 0) {
-            type->allocDefaultAtts = 8;
-            type->defaultAtts = malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
-        }
-        else {
-            type->allocDefaultAtts *= 2;
-            type->defaultAtts = realloc(type->defaultAtts,
-                                        type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
-        }
-        if (!type->defaultAtts)
-            return 0;
-    }
-    att = type->defaultAtts + type->nDefaultAtts;
-    att->id = attId;
-    att->value = value;
-    att->isCdata = isCdata;
-    if (!isCdata)
-        attId->maybeTokenized = 1;
-    type->nDefaultAtts += 1;
-    return 1;
-}
-
-static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
-{
-    const XML_Char *name;
-    for (name = elementType->name; *name; name++) {
-        if (*name == XML_T(':')) {
-            PREFIX *prefix;
-            const XML_Char *s;
-            for (s = elementType->name; s != name; s++) {
-                if (!poolAppendChar(&dtd.pool, *s))
-                    return 0;
-            }
-            if (!poolAppendChar(&dtd.pool, XML_T('\0')))
-                return 0;
-            prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
-            if (!prefix)
-                return 0;
-            if (prefix->name == poolStart(&dtd.pool))
-                poolFinish(&dtd.pool);
-            else
-                poolDiscard(&dtd.pool);
-            elementType->prefix = prefix;
-
-        }
-    }
-    return 1;
-}
-
-static ATTRIBUTE_ID *
-getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
-{
-    ATTRIBUTE_ID *id;
-    const XML_Char *name;
-    if (!poolAppendChar(&dtd.pool, XML_T('\0')))
-        return 0;
-    name = poolStoreString(&dtd.pool, enc, start, end);
-    if (!name)
-        return 0;
-    ++name;
-    id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
-    if (!id)
-        return 0;
-    if (id->name != name)
-        poolDiscard(&dtd.pool);
-    else {
-        poolFinish(&dtd.pool);
-        if (!ns)
-            ;
-        else if (name[0] == 'x'
-                 && name[1] == 'm'
-                 && name[2] == 'l'
-                 && name[3] == 'n'
-                 && name[4] == 's'
-                 && (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
-            if (name[5] == '\0')
-                id->prefix = &dtd.defaultPrefix;
-            else
-                id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
-            id->xmlns = 1;
-        }
-        else {
-            int i;
-            for (i = 0; name[i]; i++) {
-                if (name[i] == XML_T(':')) {
-                    int j;
-                    for (j = 0; j < i; j++) {
-                        if (!poolAppendChar(&dtd.pool, name[j]))
-                            return 0;
-                    }
-                    if (!poolAppendChar(&dtd.pool, XML_T('\0')))
-                        return 0;
-                    id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
-                    if (id->prefix->name == poolStart(&dtd.pool))
-                        poolFinish(&dtd.pool);
-                    else
-                        poolDiscard(&dtd.pool);
-                    break;
-                }
-            }
-        }
-    }
-    return id;
-}
-
-#define CONTEXT_SEP XML_T('\f')
-
-static
-const XML_Char *getContext(XML_Parser parser)
-{
-    HASH_TABLE_ITER iter;
-    int needSep = 0;
-
-    if (dtd.defaultPrefix.binding) {
-        int i;
-        int len;
-        if (!poolAppendChar(&tempPool, XML_T('=')))
-            return 0;
-        len = dtd.defaultPrefix.binding->uriLen;
-        if (namespaceSeparator != XML_T('\0'))
-            len--;
-        for (i = 0; i < len; i++)
-            if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
-                return 0;
-        needSep = 1;
-    }
-
-    hashTableIterInit(&iter, &(dtd.prefixes));
-    for (;;) {
-        int i;
-        int len;
-        const XML_Char *s;
-        PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
-        if (!prefix)
-            break;
-        if (!prefix->binding)
-            continue;
-        if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
-            return 0;
-        for (s = prefix->name; *s; s++)
-            if (!poolAppendChar(&tempPool, *s))
-                return 0;
-        if (!poolAppendChar(&tempPool, XML_T('=')))
-            return 0;
-        len = prefix->binding->uriLen;
-        if (namespaceSeparator != XML_T('\0'))
-            len--;
-        for (i = 0; i < len; i++)
-            if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
-                return 0;
-        needSep = 1;
-    }
-
-
-    hashTableIterInit(&iter, &(dtd.generalEntities));
-    for (;;) {
-        const XML_Char *s;
-        ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
-        if (!e)
-            break;
-        if (!e->open)
-            continue;
-        if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
-            return 0;
-        for (s = e->name; *s; s++)
-            if (!poolAppendChar(&tempPool, *s))
-                return 0;
-        needSep = 1;
-    }
-
-    if (!poolAppendChar(&tempPool, XML_T('\0')))
-        return 0;
-    return tempPool.start;
-}
-
-static
-int setContext(XML_Parser parser, const XML_Char *context)
-{
-    const XML_Char *s = context;
-
-    while (*context != XML_T('\0')) {
-        if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
-            ENTITY *e;
-            if (!poolAppendChar(&tempPool, XML_T('\0')))
-                return 0;
-            e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
-            if (e)
-                e->open = 1;
-            if (*s != XML_T('\0'))
-                s++;
-            context = s;
-            poolDiscard(&tempPool);
-        }
-        else if (*s == '=') {
-            PREFIX *prefix;
-            if (poolLength(&tempPool) == 0)
-                prefix = &dtd.defaultPrefix;
-            else {
-                if (!poolAppendChar(&tempPool, XML_T('\0')))
-                    return 0;
-                prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
-                if (!prefix)
-                    return 0;
-                if (prefix->name == poolStart(&tempPool))
-                    poolFinish(&tempPool);
-                else
-                    poolDiscard(&tempPool);
-            }
-            for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
-                if (!poolAppendChar(&tempPool, *context))
-                    return 0;
-            if (!poolAppendChar(&tempPool, XML_T('\0')))
-                return 0;
-            if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
-                return 0;
-            poolDiscard(&tempPool);
-            if (*context != XML_T('\0'))
-                ++context;
-            s = context;
-        }
-        else {
-            if (!poolAppendChar(&tempPool, *s))
-                return 0;
-            s++;
-        }
-    }
-    return 1;
-}
-
-
-static
-void normalizePublicId(XML_Char *publicId)
-{
-    XML_Char *p = publicId;
-    XML_Char *s;
-    for (s = publicId; *s; s++) {
-        switch (*s) {
-        case 0x20:
-        case 0xD:
-        case 0xA:
-            if (p != publicId && p[-1] != 0x20)
-                *p++ = 0x20;
-            break;
-        default:
-            *p++ = *s;
-        }
-    }
-    if (p != publicId && p[-1] == 0x20)
-        --p;
-    *p = XML_T('\0');
-}
-
-static int dtdInit(DTD *p)
-{
-    poolInit(&(p->pool));
-    hashTableInit(&(p->generalEntities));
-    hashTableInit(&(p->elementTypes));
-    hashTableInit(&(p->attributeIds));
-    hashTableInit(&(p->prefixes));
-    p->complete = 1;
-    p->standalone = 0;
-    p->base = 0;
-    p->defaultPrefix.name = 0;
-    p->defaultPrefix.binding = 0;
-    return 1;
-}
-
-static void dtdDestroy(DTD *p)
-{
-    HASH_TABLE_ITER iter;
-    hashTableIterInit(&iter, &(p->elementTypes));
-    for (;;) {
-        ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
-        if (!e)
-            break;
-        if (e->allocDefaultAtts != 0)
-            free(e->defaultAtts);
-    }
-    hashTableDestroy(&(p->generalEntities));
-    hashTableDestroy(&(p->elementTypes));
-    hashTableDestroy(&(p->attributeIds));
-    hashTableDestroy(&(p->prefixes));
-    poolDestroy(&(p->pool));
-}
-
-/* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
-The new DTD has already been initialized. */
-
-static int dtdCopy(DTD *newDtd, const DTD *oldDtd)
-{
-    HASH_TABLE_ITER iter;
-
-    if (oldDtd->base) {
-        const XML_Char *tem = poolCopyString(&(newDtd->pool), oldDtd->base);
-        if (!tem)
-            return 0;
-        newDtd->base = tem;
-    }
-
-    /* Copy the prefix table. */
-
-    hashTableIterInit(&iter, &(oldDtd->prefixes));
-    for (;;) {
-        const XML_Char *name;
-        const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
-        if (!oldP)
-            break;
-        name = poolCopyString(&(newDtd->pool), oldP->name);
-        if (!name)
-            return 0;
-        if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
-            return 0;
-    }
-
-    hashTableIterInit(&iter, &(oldDtd->attributeIds));
-
-    /* Copy the attribute id table. */
-
-    for (;;) {
-        ATTRIBUTE_ID *newA;
-        const XML_Char *name;
-        const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
-
-        if (!oldA)
-            break;
-        /* Remember to allocate the scratch byte before the name. */
-        if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
-            return 0;
-        name = poolCopyString(&(newDtd->pool), oldA->name);
-        if (!name)
-            return 0;
-        ++name;
-        newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
-        if (!newA)
-            return 0;
-        newA->maybeTokenized = oldA->maybeTokenized;
-        if (oldA->prefix) {
-            newA->xmlns = oldA->xmlns;
-            if (oldA->prefix == &oldDtd->defaultPrefix)
-                newA->prefix = &newDtd->defaultPrefix;
-            else
-                newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
-        }
-    }
-
-    /* Copy the element type table. */
-
-    hashTableIterInit(&iter, &(oldDtd->elementTypes));
-
-    for (;;) {
-        int i;
-        ELEMENT_TYPE *newE;
-        const XML_Char *name;
-        const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
-        if (!oldE)
-            break;
-        name = poolCopyString(&(newDtd->pool), oldE->name);
-        if (!name)
-            return 0;
-        newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
-        if (!newE)
-            return 0;
-        if (oldE->nDefaultAtts) {
-            newE->defaultAtts = (DEFAULT_ATTRIBUTE *)malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
-            if (!newE->defaultAtts)
-                return 0;
-        }
-        newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
-        if (oldE->prefix)
-            newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
-        for (i = 0; i < newE->nDefaultAtts; i++) {
-            newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
-            newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
-            if (oldE->defaultAtts[i].value) {
-                newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
-                if (!newE->defaultAtts[i].value)
-                    return 0;
-            }
-            else
-                newE->defaultAtts[i].value = 0;
-        }
-    }
-
-    /* Copy the entity table. */
-
-    hashTableIterInit(&iter, &(oldDtd->generalEntities));
-
-    for (;;) {
-        ENTITY *newE;
-        const XML_Char *name;
-        const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
-        if (!oldE)
-            break;
-        name = poolCopyString(&(newDtd->pool), oldE->name);
-        if (!name)
-            return 0;
-        newE = (ENTITY *)lookup(&(newDtd->generalEntities), name, sizeof(ENTITY));
-        if (!newE)
-            return 0;
-        if (oldE->systemId) {
-            const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->systemId);
-            if (!tem)
-                return 0;
-            newE->systemId = tem;
-            if (oldE->base) {
-                if (oldE->base == oldDtd->base)
-                    newE->base = newDtd->base;
-                tem = poolCopyString(&(newDtd->pool), oldE->base);
-                if (!tem)
-                    return 0;
-                newE->base = tem;
-            }
-        }
-        else {
-            const XML_Char *tem = poolCopyStringN(&(newDtd->pool), oldE->textPtr, oldE->textLen);
-            if (!tem)
-                return 0;
-            newE->textPtr = tem;
-            newE->textLen = oldE->textLen;
-        }
-        if (oldE->notation) {
-            const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->notation);
-            if (!tem)
-                return 0;
-            newE->notation = tem;
-        }
-    }
-
-    newDtd->complete = oldDtd->complete;
-    newDtd->standalone = oldDtd->standalone;
-    return 1;
-}
-
-static
-void poolInit(STRING_POOL *pool)
-{
-    pool->blocks = 0;
-    pool->freeBlocks = 0;
-    pool->start = 0;
-    pool->ptr = 0;
-    pool->end = 0;
-}
-
-static
-void poolClear(STRING_POOL *pool)
-{
-    if (!pool->freeBlocks)
-        pool->freeBlocks = pool->blocks;
-    else {
-        BLOCK *p = pool->blocks;
-        while (p) {
-            BLOCK *tem = p->next;
-            p->next = pool->freeBlocks;
-            pool->freeBlocks = p;
-            p = tem;
-        }
-    }
-    pool->blocks = 0;
-    pool->start = 0;
-    pool->ptr = 0;
-    pool->end = 0;
-}
-
-static
-void poolDestroy(STRING_POOL *pool)
-{
-    BLOCK *p = pool->blocks;
-    while (p) {
-        BLOCK *tem = p->next;
-        free(p);
-        p = tem;
-    }
-    pool->blocks = 0;
-    p = pool->freeBlocks;
-    while (p) {
-        BLOCK *tem = p->next;
-        free(p);
-        p = tem;
-    }
-    pool->freeBlocks = 0;
-    pool->ptr = 0;
-    pool->start = 0;
-    pool->end = 0;
-}
-
-static
-XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
-                     const char *ptr, const char *end)
-{
-    if (!pool->ptr && !poolGrow(pool))
-        return 0;
-    for (;;) {
-        XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
-        if (ptr == end)
-            break;
-        if (!poolGrow(pool))
-            return 0;
-    }
-    return pool->start;
-}
-
-static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
-{
-    do {
-        if (!poolAppendChar(pool, *s))
-            return 0;
-    } while (*s++);
-    s = pool->start;
-    poolFinish(pool);
-    return s;
-}
-
-static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
-{
-    if (!pool->ptr && !poolGrow(pool))
-        return 0;
-    for (; n > 0; --n, s++) {
-        if (!poolAppendChar(pool, *s))
-            return 0;
-
-    }
-    s = pool->start;
-    poolFinish(pool);
-    return s;
-}
-
-static
-XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
-                          const char *ptr, const char *end)
-{
-    if (!poolAppend(pool, enc, ptr, end))
-        return 0;
-    if (pool->ptr == pool->end && !poolGrow(pool))
-        return 0;
-    *(pool->ptr)++ = 0;
-    return pool->start;
-}
-
-static
-int poolGrow(STRING_POOL *pool)
-{
-    if (pool->freeBlocks) {
-        if (pool->start == 0) {
-            pool->blocks = pool->freeBlocks;
-            pool->freeBlocks = pool->freeBlocks->next;
-            pool->blocks->next = 0;
-            pool->start = pool->blocks->s;
-            pool->end = pool->start + pool->blocks->size;
-            pool->ptr = pool->start;
-            return 1;
-        }
-        if (pool->end - pool->start < pool->freeBlocks->size) {
-            BLOCK *tem = pool->freeBlocks->next;
-            pool->freeBlocks->next = pool->blocks;
-            pool->blocks = pool->freeBlocks;
-            pool->freeBlocks = tem;
-            memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
-            pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
-            pool->start = pool->blocks->s;
-            pool->end = pool->start + pool->blocks->size;
-            return 1;
-        }
-    }
-    if (pool->blocks && pool->start == pool->blocks->s) {
-        int blockSize = (pool->end - pool->start)*2;
-        pool->blocks = realloc(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
-        if (!pool->blocks)
-            return 0;
-        pool->blocks->size = blockSize;
-        pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
-        pool->start = pool->blocks->s;
-        pool->end = pool->start + blockSize;
-    }
-    else {
-        BLOCK *tem;
-        int blockSize = pool->end - pool->start;
-        if (blockSize < INIT_BLOCK_SIZE)
-            blockSize = INIT_BLOCK_SIZE;
-        else
-            blockSize *= 2;
-        tem = malloc(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
-        if (!tem)
-            return 0;
-        tem->size = blockSize;
-        tem->next = pool->blocks;
-        pool->blocks = tem;
-        memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
-        pool->ptr = tem->s + (pool->ptr - pool->start);
-        pool->start = tem->s;
-        pool->end = tem->s + blockSize;
-    }
-    return 1;
-}
--- a/src/protocols/jabber/xmlparse.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,482 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#ifndef XmlParse_INCLUDED
-#define XmlParse_INCLUDED 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef XMLPARSEAPI
-#define XMLPARSEAPI /* as nothing */
-#endif
-
-typedef void *XML_Parser;
-
-#ifdef XML_UNICODE_WCHAR_T
-
-/* XML_UNICODE_WCHAR_T will work only if sizeof(wchar_t) == 2 and wchar_t
-uses Unicode. */
-/* Information is UTF-16 encoded as wchar_ts */
-
-#ifndef XML_UNICODE
-#define XML_UNICODE
-#endif
-
-#include <stddef.h>
-typedef wchar_t XML_Char;
-typedef wchar_t XML_LChar;
-
-#else /* not XML_UNICODE_WCHAR_T */
-
-#ifdef XML_UNICODE
-
-/* Information is UTF-16 encoded as unsigned shorts */
-typedef unsigned short XML_Char;
-typedef char XML_LChar;
-
-#else /* not XML_UNICODE */
-
-/* Information is UTF-8 encoded. */
-typedef char XML_Char;
-typedef char XML_LChar;
-
-#endif /* not XML_UNICODE */
-
-#endif /* not XML_UNICODE_WCHAR_T */
-
-
-/* Constructs a new parser; encoding is the encoding specified by the external
-protocol or null if there is none specified. */
-
-XML_Parser XMLPARSEAPI
-XML_ParserCreate(const XML_Char *encoding);
-
-/* Constructs a new parser and namespace processor.  Element type names
-and attribute names that belong to a namespace will be expanded;
-unprefixed attribute names are never expanded; unprefixed element type
-names are expanded only if there is a default namespace. The expanded
-name is the concatenation of the namespace URI, the namespace separator character,
-and the local part of the name.  If the namespace separator is '\0' then
-the namespace URI and the local part will be concatenated without any
-separator.  When a namespace is not declared, the name and prefix will be
-passed through without expansion. */
-
-XML_Parser XMLPARSEAPI
-XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
-
-
-/* atts is array of name/value pairs, terminated by 0;
-   names and values are 0 terminated. */
-
-typedef void (*XML_StartElementHandler)(void *userData,
-					const XML_Char *name,
-					const XML_Char **atts);
-
-typedef void (*XML_EndElementHandler)(void *userData,
-				      const XML_Char *name);
-
-/* s is not 0 terminated. */
-typedef void (*XML_CharacterDataHandler)(void *userData,
-					 const XML_Char *s,
-					 int len);
-
-/* target and data are 0 terminated */
-typedef void (*XML_ProcessingInstructionHandler)(void *userData,
-						 const XML_Char *target,
-						 const XML_Char *data);
-
-/* data is 0 terminated */
-typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data);
-
-typedef void (*XML_StartCdataSectionHandler)(void *userData);
-typedef void (*XML_EndCdataSectionHandler)(void *userData);
-
-/* This is called for any characters in the XML document for
-which there is no applicable handler.  This includes both
-characters that are part of markup which is of a kind that is
-not reported (comments, markup declarations), or characters
-that are part of a construct which could be reported but
-for which no handler has been supplied. The characters are passed
-exactly as they were in the XML document except that
-they will be encoded in UTF-8.  Line boundaries are not normalized.
-Note that a byte order mark character is not passed to the default handler.
-There are no guarantees about how characters are divided between calls
-to the default handler: for example, a comment might be split between
-multiple calls. */
-
-typedef void (*XML_DefaultHandler)(void *userData,
-				   const XML_Char *s,
-				   int len);
-
-/* This is called for a declaration of an unparsed (NDATA)
-entity.  The base argument is whatever was set by XML_SetBase.
-The entityName, systemId and notationName arguments will never be null.
-The other arguments may be. */
-
-typedef void (*XML_UnparsedEntityDeclHandler)(void *userData,
-					      const XML_Char *entityName,
-					      const XML_Char *base,
-					      const XML_Char *systemId,
-					      const XML_Char *publicId,
-					      const XML_Char *notationName);
-
-/* This is called for a declaration of notation.
-The base argument is whatever was set by XML_SetBase.
-The notationName will never be null.  The other arguments can be. */
-
-typedef void (*XML_NotationDeclHandler)(void *userData,
-					const XML_Char *notationName,
-					const XML_Char *base,
-					const XML_Char *systemId,
-					const XML_Char *publicId);
-
-/* When namespace processing is enabled, these are called once for
-each namespace declaration. The call to the start and end element
-handlers occur between the calls to the start and end namespace
-declaration handlers. For an xmlns attribute, prefix will be null.
-For an xmlns="" attribute, uri will be null. */
-
-typedef void (*XML_StartNamespaceDeclHandler)(void *userData,
-					      const XML_Char *prefix,
-					      const XML_Char *uri);
-
-typedef void (*XML_EndNamespaceDeclHandler)(void *userData,
-					    const XML_Char *prefix);
-
-/* This is called if the document is not standalone (it has an
-external subset or a reference to a parameter entity, but does not
-have standalone="yes"). If this handler returns 0, then processing
-will not continue, and the parser will return a
-XML_ERROR_NOT_STANDALONE error. */
-
-typedef int (*XML_NotStandaloneHandler)(void *userData);
-
-/* This is called for a reference to an external parsed general entity.
-The referenced entity is not automatically parsed.
-The application can parse it immediately or later using
-XML_ExternalEntityParserCreate.
-The parser argument is the parser parsing the entity containing the reference;
-it can be passed as the parser argument to XML_ExternalEntityParserCreate.
-The systemId argument is the system identifier as specified in the entity declaration;
-it will not be null.
-The base argument is the system identifier that should be used as the base for
-resolving systemId if systemId was relative; this is set by XML_SetBase;
-it may be null.
-The publicId argument is the public identifier as specified in the entity declaration,
-or null if none was specified; the whitespace in the public identifier
-will have been normalized as required by the XML spec.
-The context argument specifies the parsing context in the format
-expected by the context argument to
-XML_ExternalEntityParserCreate; context is valid only until the handler
-returns, so if the referenced entity is to be parsed later, it must be copied.
-The handler should return 0 if processing should not continue because of
-a fatal error in the handling of the external entity.
-In this case the calling parser will return an XML_ERROR_EXTERNAL_ENTITY_HANDLING
-error.
-Note that unlike other handlers the first argument is the parser, not userData. */
-
-typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser,
-					    const XML_Char *context,
-					    const XML_Char *base,
-					    const XML_Char *systemId,
-					    const XML_Char *publicId);
-
-/* This structure is filled in by the XML_UnknownEncodingHandler
-to provide information to the parser about encodings that are unknown
-to the parser.
-The map[b] member gives information about byte sequences
-whose first byte is b.
-If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c.
-If map[b] is -1, then the byte sequence is malformed.
-If map[b] is -n, where n >= 2, then b is the first byte of an n-byte
-sequence that encodes a single Unicode scalar value.
-The data member will be passed as the first argument to the convert function.
-The convert function is used to convert multibyte sequences;
-s will point to a n-byte sequence where map[(unsigned char)*s] == -n.
-The convert function must return the Unicode scalar value
-represented by this byte sequence or -1 if the byte sequence is malformed.
-The convert function may be null if the encoding is a single-byte encoding,
-that is if map[b] >= -1 for all bytes b.
-When the parser is finished with the encoding, then if release is not null,
-it will call release passing it the data member;
-once release has been called, the convert function will not be called again.
-
-Expat places certain restrictions on the encodings that are supported
-using this mechanism.
-
-1. Every ASCII character that can appear in a well-formed XML document,
-other than the characters
-
-  $@\^`{}~
-
-must be represented by a single byte, and that byte must be the
-same byte that represents that character in ASCII.
-
-2. No character may require more than 4 bytes to encode.
-
-3. All characters encoded must have Unicode scalar values <= 0xFFFF,
-(ie characters that would be encoded by surrogates in UTF-16
-are  not allowed).  Note that this restriction doesn't apply to
-the built-in support for UTF-8 and UTF-16.
-
-4. No Unicode character may be encoded by more than one distinct sequence
-of bytes. */
-
-typedef struct {
-  int map[256];
-  void *data;
-  int (*convert)(void *data, const char *s);
-  void (*release)(void *data);
-} XML_Encoding;
-
-/* This is called for an encoding that is unknown to the parser.
-The encodingHandlerData argument is that which was passed as the
-second argument to XML_SetUnknownEncodingHandler.
-The name argument gives the name of the encoding as specified in
-the encoding declaration.
-If the callback can provide information about the encoding,
-it must fill in the XML_Encoding structure, and return 1.
-Otherwise it must return 0.
-If info does not describe a suitable encoding,
-then the parser will return an XML_UNKNOWN_ENCODING error. */
-
-typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData,
-					  const XML_Char *name,
-					  XML_Encoding *info);
-
-void XMLPARSEAPI
-XML_SetElementHandler(XML_Parser parser,
-		      XML_StartElementHandler start,
-		      XML_EndElementHandler end);
-
-void XMLPARSEAPI
-XML_SetCharacterDataHandler(XML_Parser parser,
-			    XML_CharacterDataHandler handler);
-
-void XMLPARSEAPI
-XML_SetProcessingInstructionHandler(XML_Parser parser,
-				    XML_ProcessingInstructionHandler handler);
-void XMLPARSEAPI
-XML_SetCommentHandler(XML_Parser parser,
-                      XML_CommentHandler handler);
-
-void XMLPARSEAPI
-XML_SetCdataSectionHandler(XML_Parser parser,
-			   XML_StartCdataSectionHandler start,
-			   XML_EndCdataSectionHandler end);
-
-/* This sets the default handler and also inhibits expansion of internal entities.
-The entity reference will be passed to the default handler. */
-
-void XMLPARSEAPI
-XML_SetDefaultHandler(XML_Parser parser,
-		      XML_DefaultHandler handler);
-
-/* This sets the default handler but does not inhibit expansion of internal entities.
-The entity reference will not be passed to the default handler. */
-
-void XMLPARSEAPI
-XML_SetDefaultHandlerExpand(XML_Parser parser,
-		            XML_DefaultHandler handler);
-
-void XMLPARSEAPI
-XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
-				 XML_UnparsedEntityDeclHandler handler);
-
-void XMLPARSEAPI
-XML_SetNotationDeclHandler(XML_Parser parser,
-			   XML_NotationDeclHandler handler);
-
-void XMLPARSEAPI
-XML_SetNamespaceDeclHandler(XML_Parser parser,
-			    XML_StartNamespaceDeclHandler start,
-			    XML_EndNamespaceDeclHandler end);
-
-void XMLPARSEAPI
-XML_SetNotStandaloneHandler(XML_Parser parser,
-			    XML_NotStandaloneHandler handler);
-
-void XMLPARSEAPI
-XML_SetExternalEntityRefHandler(XML_Parser parser,
-				XML_ExternalEntityRefHandler handler);
-
-/* If a non-null value for arg is specified here, then it will be passed
-as the first argument to the external entity ref handler instead
-of the parser object. */
-void XMLPARSEAPI
-XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg);
-
-void XMLPARSEAPI
-XML_SetUnknownEncodingHandler(XML_Parser parser,
-			      XML_UnknownEncodingHandler handler,
-			      void *encodingHandlerData);
-
-/* This can be called within a handler for a start element, end element,
-processing instruction or character data.  It causes the corresponding
-markup to be passed to the default handler. */
-void XMLPARSEAPI XML_DefaultCurrent(XML_Parser parser);
-
-/* This value is passed as the userData argument to callbacks. */
-void XMLPARSEAPI
-XML_SetUserData(XML_Parser parser, void *userData);
-
-/* Returns the last value set by XML_SetUserData or null. */
-#define XML_GetUserData(parser) (*(void **)(parser))
-
-/* This is equivalent to supplying an encoding argument
-to XML_CreateParser. It must not be called after XML_Parse
-or XML_ParseBuffer. */
-
-int XMLPARSEAPI
-XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
-
-/* If this function is called, then the parser will be passed
-as the first argument to callbacks instead of userData.
-The userData will still be accessible using XML_GetUserData. */
-
-void XMLPARSEAPI
-XML_UseParserAsHandlerArg(XML_Parser parser);
-
-/* Sets the base to be used for resolving relative URIs in system identifiers in
-declarations.  Resolving relative identifiers is left to the application:
-this value will be passed through as the base argument to the
-XML_ExternalEntityRefHandler, XML_NotationDeclHandler
-and XML_UnparsedEntityDeclHandler. The base argument will be copied.
-Returns zero if out of memory, non-zero otherwise. */
-
-int XMLPARSEAPI
-XML_SetBase(XML_Parser parser, const XML_Char *base);
-
-const XML_Char XMLPARSEAPI *
-XML_GetBase(XML_Parser parser);
-
-/* Returns the number of the attributes passed in last call to the
-XML_StartElementHandler that were specified in the start-tag rather
-than defaulted. */
-
-int XMLPARSEAPI XML_GetSpecifiedAttributeCount(XML_Parser parser);
-
-/* Parses some input. Returns 0 if a fatal error is detected.
-The last call to XML_Parse must have isFinal true;
-len may be zero for this call (or any other). */
-int XMLPARSEAPI
-XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
-
-void XMLPARSEAPI *
-XML_GetBuffer(XML_Parser parser, int len);
-
-int XMLPARSEAPI
-XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
-
-/* Creates an XML_Parser object that can parse an external general entity;
-context is a '\0'-terminated string specifying the parse context;
-encoding is a '\0'-terminated string giving the name of the externally specified encoding,
-or null if there is no externally specified encoding.
-The context string consists of a sequence of tokens separated by formfeeds (\f);
-a token consisting of a name specifies that the general entity of the name
-is open; a token of the form prefix=uri specifies the namespace for a particular
-prefix; a token of the form =uri specifies the default namespace.
-This can be called at any point after the first call to an ExternalEntityRefHandler
-so longer as the parser has not yet been freed.
-The new parser is completely independent and may safely be used in a separate thread.
-The handlers and userData are initialized from the parser argument.
-Returns 0 if out of memory.  Otherwise returns a new XML_Parser object. */
-XML_Parser XMLPARSEAPI
-XML_ExternalEntityParserCreate(XML_Parser parser,
-			       const XML_Char *context,
-			       const XML_Char *encoding);
-
-enum XML_Error {
-  XML_ERROR_NONE,
-  XML_ERROR_NO_MEMORY,
-  XML_ERROR_SYNTAX,
-  XML_ERROR_NO_ELEMENTS,
-  XML_ERROR_INVALID_TOKEN,
-  XML_ERROR_UNCLOSED_TOKEN,
-  XML_ERROR_PARTIAL_CHAR,
-  XML_ERROR_TAG_MISMATCH,
-  XML_ERROR_DUPLICATE_ATTRIBUTE,
-  XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
-  XML_ERROR_PARAM_ENTITY_REF,
-  XML_ERROR_UNDEFINED_ENTITY,
-  XML_ERROR_RECURSIVE_ENTITY_REF,
-  XML_ERROR_ASYNC_ENTITY,
-  XML_ERROR_BAD_CHAR_REF,
-  XML_ERROR_BINARY_ENTITY_REF,
-  XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
-  XML_ERROR_MISPLACED_XML_PI,
-  XML_ERROR_UNKNOWN_ENCODING,
-  XML_ERROR_INCORRECT_ENCODING,
-  XML_ERROR_UNCLOSED_CDATA_SECTION,
-  XML_ERROR_EXTERNAL_ENTITY_HANDLING,
-  XML_ERROR_NOT_STANDALONE
-};
-
-/* If XML_Parse or XML_ParseBuffer have returned 0, then XML_GetErrorCode
-returns information about the error. */
-
-enum XML_Error XMLPARSEAPI XML_GetErrorCode(XML_Parser parser);
-
-/* These functions return information about the current parse location.
-They may be called when XML_Parse or XML_ParseBuffer return 0;
-in this case the location is the location of the character at which
-the error was detected.
-They may also be called from any other callback called to report
-some parse event; in this the location is the location of the first
-of the sequence of characters that generated the event. */
-
-int XMLPARSEAPI XML_GetCurrentLineNumber(XML_Parser parser);
-int XMLPARSEAPI XML_GetCurrentColumnNumber(XML_Parser parser);
-long XMLPARSEAPI XML_GetCurrentByteIndex(XML_Parser parser);
-
-/* Return the number of bytes in the current event.
-Returns 0 if the event is in an internal entity. */
-
-int XMLPARSEAPI XML_GetCurrentByteCount(XML_Parser parser);
-
-/* For backwards compatibility with previous versions. */
-#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
-#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
-#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
-
-/* Frees memory used by the parser. */
-void XMLPARSEAPI
-XML_ParserFree(XML_Parser parser);
-
-/* Returns a string describing the error. */
-const XML_LChar XMLPARSEAPI *XML_ErrorString(int code);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not XmlParse_INCLUDED */
--- a/src/protocols/jabber/xmlrole.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1104 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-*/
-
-#include "xmldef.h"
-#include "xmlrole.h"
-
-/* Doesn't check:
-
- that ,| are not mixed in a model group
- content of literals
-
-*/
-
-#ifndef MIN_BYTES_PER_CHAR
-#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
-#endif
-
-typedef int PROLOG_HANDLER(struct prolog_state *state,
-                           int tok,
-                           const char *ptr,
-                           const char *end,
-                           const ENCODING *enc);
-
-static PROLOG_HANDLER
-prolog0, prolog1, prolog2,
-doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
-internalSubset,
-entity0, entity1, entity2, entity3, entity4, entity5, entity6,
-entity7, entity8, entity9,
-notation0, notation1, notation2, notation3, notation4,
-attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
-attlist7, attlist8, attlist9,
-element0, element1, element2, element3, element4, element5, element6,
-element7,
-declClose,
-error;
-
-static
-int syntaxError(PROLOG_STATE *);
-
-static
-int prolog0(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        state->handler = prolog1;
-        return XML_ROLE_NONE;
-    case XML_TOK_XML_DECL:
-        state->handler = prolog1;
-        return XML_ROLE_XML_DECL;
-    case XML_TOK_PI:
-        state->handler = prolog1;
-        return XML_ROLE_NONE;
-    case XML_TOK_COMMENT:
-        state->handler = prolog1;
-    case XML_TOK_BOM:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_OPEN:
-        if (!XmlNameMatchesAscii(enc,
-                                 ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                                 "DOCTYPE"))
-            break;
-        state->handler = doctype0;
-        return XML_ROLE_NONE;
-    case XML_TOK_INSTANCE_START:
-        state->handler = error;
-        return XML_ROLE_INSTANCE_START;
-    }
-    return syntaxError(state);
-}
-
-static
-int prolog1(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_PI:
-    case XML_TOK_COMMENT:
-    case XML_TOK_BOM:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_OPEN:
-        if (!XmlNameMatchesAscii(enc,
-                                 ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                                 "DOCTYPE"))
-            break;
-        state->handler = doctype0;
-        return XML_ROLE_NONE;
-    case XML_TOK_INSTANCE_START:
-        state->handler = error;
-        return XML_ROLE_INSTANCE_START;
-    }
-    return syntaxError(state);
-}
-
-static
-int prolog2(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_PI:
-    case XML_TOK_COMMENT:
-        return XML_ROLE_NONE;
-    case XML_TOK_INSTANCE_START:
-        state->handler = error;
-        return XML_ROLE_INSTANCE_START;
-    }
-    return syntaxError(state);
-}
-
-static
-int doctype0(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = doctype1;
-        return XML_ROLE_DOCTYPE_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int doctype1(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_OPEN_BRACKET:
-        state->handler = internalSubset;
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = prolog2;
-        return XML_ROLE_DOCTYPE_CLOSE;
-    case XML_TOK_NAME:
-        if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) {
-            state->handler = doctype3;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) {
-            state->handler = doctype2;
-            return XML_ROLE_NONE;
-        }
-        break;
-    }
-    return syntaxError(state);
-}
-
-static
-int doctype2(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = doctype3;
-        return XML_ROLE_DOCTYPE_PUBLIC_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int doctype3(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = doctype4;
-        return XML_ROLE_DOCTYPE_SYSTEM_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int doctype4(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_OPEN_BRACKET:
-        state->handler = internalSubset;
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = prolog2;
-        return XML_ROLE_DOCTYPE_CLOSE;
-    }
-    return syntaxError(state);
-}
-
-static
-int doctype5(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = prolog2;
-        return XML_ROLE_DOCTYPE_CLOSE;
-    }
-    return syntaxError(state);
-}
-
-static
-int internalSubset(PROLOG_STATE *state,
-                   int tok,
-                   const char *ptr,
-                   const char *end,
-                   const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_OPEN:
-        if (XmlNameMatchesAscii(enc,
-                                ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                                "ENTITY")) {
-            state->handler = entity0;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc,
-                                ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                                "ATTLIST")) {
-            state->handler = attlist0;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc,
-                                ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                                "ELEMENT")) {
-            state->handler = element0;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc,
-                                ptr + 2 * MIN_BYTES_PER_CHAR(enc),
-                                "NOTATION")) {
-            state->handler = notation0;
-            return XML_ROLE_NONE;
-        }
-        break;
-    case XML_TOK_PI:
-    case XML_TOK_COMMENT:
-        return XML_ROLE_NONE;
-    case XML_TOK_PARAM_ENTITY_REF:
-        return XML_ROLE_PARAM_ENTITY_REF;
-    case XML_TOK_CLOSE_BRACKET:
-        state->handler = doctype5;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity0(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_PERCENT:
-        state->handler = entity1;
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        state->handler = entity2;
-        return XML_ROLE_GENERAL_ENTITY_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity1(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        state->handler = entity7;
-        return XML_ROLE_PARAM_ENTITY_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity2(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) {
-            state->handler = entity4;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) {
-            state->handler = entity3;
-            return XML_ROLE_NONE;
-        }
-        break;
-    case XML_TOK_LITERAL:
-        state->handler = declClose;
-        return XML_ROLE_ENTITY_VALUE;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity3(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = entity4;
-        return XML_ROLE_ENTITY_PUBLIC_ID;
-    }
-    return syntaxError(state);
-}
-
-
-static
-int entity4(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = entity5;
-        return XML_ROLE_ENTITY_SYSTEM_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity5(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = internalSubset;
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        if (XmlNameMatchesAscii(enc, ptr, "NDATA")) {
-            state->handler = entity6;
-            return XML_ROLE_NONE;
-        }
-        break;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity6(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        state->handler = declClose;
-        return XML_ROLE_ENTITY_NOTATION_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity7(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) {
-            state->handler = entity9;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) {
-            state->handler = entity8;
-            return XML_ROLE_NONE;
-        }
-        break;
-    case XML_TOK_LITERAL:
-        state->handler = declClose;
-        return XML_ROLE_ENTITY_VALUE;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity8(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = entity9;
-        return XML_ROLE_ENTITY_PUBLIC_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int entity9(PROLOG_STATE *state,
-            int tok,
-            const char *ptr,
-            const char *end,
-            const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = declClose;
-        return XML_ROLE_ENTITY_SYSTEM_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int notation0(PROLOG_STATE *state,
-              int tok,
-              const char *ptr,
-              const char *end,
-              const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        state->handler = notation1;
-        return XML_ROLE_NOTATION_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int notation1(PROLOG_STATE *state,
-              int tok,
-              const char *ptr,
-              const char *end,
-              const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        if (XmlNameMatchesAscii(enc, ptr, "SYSTEM")) {
-            state->handler = notation3;
-            return XML_ROLE_NONE;
-        }
-        if (XmlNameMatchesAscii(enc, ptr, "PUBLIC")) {
-            state->handler = notation2;
-            return XML_ROLE_NONE;
-        }
-        break;
-    }
-    return syntaxError(state);
-}
-
-static
-int notation2(PROLOG_STATE *state,
-              int tok,
-              const char *ptr,
-              const char *end,
-              const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = notation4;
-        return XML_ROLE_NOTATION_PUBLIC_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int notation3(PROLOG_STATE *state,
-              int tok,
-              const char *ptr,
-              const char *end,
-              const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = declClose;
-        return XML_ROLE_NOTATION_SYSTEM_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int notation4(PROLOG_STATE *state,
-              int tok,
-              const char *ptr,
-              const char *end,
-              const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = declClose;
-        return XML_ROLE_NOTATION_SYSTEM_ID;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = internalSubset;
-        return XML_ROLE_NOTATION_NO_SYSTEM_ID;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist0(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = attlist1;
-        return XML_ROLE_ATTLIST_ELEMENT_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist1(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = internalSubset;
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = attlist2;
-        return XML_ROLE_ATTRIBUTE_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist2(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        {
-            static const char *types[] = {
-                "CDATA",
-                "ID",
-                "IDREF",
-                "IDREFS",
-                "ENTITY",
-                "ENTITIES",
-                "NMTOKEN",
-                "NMTOKENS",
-            };
-            int i;
-            for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
-                if (XmlNameMatchesAscii(enc, ptr, types[i])) {
-                    state->handler = attlist8;
-                    return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
-                }
-        }
-        if (XmlNameMatchesAscii(enc, ptr, "NOTATION")) {
-            state->handler = attlist5;
-            return XML_ROLE_NONE;
-        }
-        break;
-    case XML_TOK_OPEN_PAREN:
-        state->handler = attlist3;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist3(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NMTOKEN:
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = attlist4;
-        return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist4(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_CLOSE_PAREN:
-        state->handler = attlist8;
-        return XML_ROLE_NONE;
-    case XML_TOK_OR:
-        state->handler = attlist3;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist5(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_OPEN_PAREN:
-        state->handler = attlist6;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-
-static
-int attlist6(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        state->handler = attlist7;
-        return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist7(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_CLOSE_PAREN:
-        state->handler = attlist8;
-        return XML_ROLE_NONE;
-    case XML_TOK_OR:
-        state->handler = attlist6;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-/* default value */
-static
-int attlist8(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_POUND_NAME:
-        if (XmlNameMatchesAscii(enc,
-                                ptr + MIN_BYTES_PER_CHAR(enc),
-                                "IMPLIED")) {
-            state->handler = attlist1;
-            return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
-        }
-        if (XmlNameMatchesAscii(enc,
-                                ptr + MIN_BYTES_PER_CHAR(enc),
-                                "REQUIRED")) {
-            state->handler = attlist1;
-            return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
-        }
-        if (XmlNameMatchesAscii(enc,
-                                ptr + MIN_BYTES_PER_CHAR(enc),
-                                "FIXED")) {
-            state->handler = attlist9;
-            return XML_ROLE_NONE;
-        }
-        break;
-    case XML_TOK_LITERAL:
-        state->handler = attlist1;
-        return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
-    }
-    return syntaxError(state);
-}
-
-static
-int attlist9(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_LITERAL:
-        state->handler = attlist1;
-        return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
-    }
-    return syntaxError(state);
-}
-
-static
-int element0(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = element1;
-        return XML_ROLE_ELEMENT_NAME;
-    }
-    return syntaxError(state);
-}
-
-static
-int element1(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-        if (XmlNameMatchesAscii(enc, ptr, "EMPTY")) {
-            state->handler = declClose;
-            return XML_ROLE_CONTENT_EMPTY;
-        }
-        if (XmlNameMatchesAscii(enc, ptr, "ANY")) {
-            state->handler = declClose;
-            return XML_ROLE_CONTENT_ANY;
-        }
-        break;
-    case XML_TOK_OPEN_PAREN:
-        state->handler = element2;
-        state->level = 1;
-        return XML_ROLE_GROUP_OPEN;
-    }
-    return syntaxError(state);
-}
-
-static
-int element2(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_POUND_NAME:
-        if (XmlNameMatchesAscii(enc,
-                                ptr + MIN_BYTES_PER_CHAR(enc),
-                                "PCDATA")) {
-            state->handler = element3;
-            return XML_ROLE_CONTENT_PCDATA;
-        }
-        break;
-    case XML_TOK_OPEN_PAREN:
-        state->level = 2;
-        state->handler = element6;
-        return XML_ROLE_GROUP_OPEN;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT;
-    case XML_TOK_NAME_QUESTION:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT_OPT;
-    case XML_TOK_NAME_ASTERISK:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT_REP;
-    case XML_TOK_NAME_PLUS:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT_PLUS;
-    }
-    return syntaxError(state);
-}
-
-static
-int element3(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_CLOSE_PAREN:
-    case XML_TOK_CLOSE_PAREN_ASTERISK:
-        state->handler = declClose;
-        return XML_ROLE_GROUP_CLOSE_REP;
-    case XML_TOK_OR:
-        state->handler = element4;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-static
-int element4(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = element5;
-        return XML_ROLE_CONTENT_ELEMENT;
-    }
-    return syntaxError(state);
-}
-
-static
-int element5(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_CLOSE_PAREN_ASTERISK:
-        state->handler = declClose;
-        return XML_ROLE_GROUP_CLOSE_REP;
-    case XML_TOK_OR:
-        state->handler = element4;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-static
-int element6(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_OPEN_PAREN:
-        state->level += 1;
-        return XML_ROLE_GROUP_OPEN;
-    case XML_TOK_NAME:
-    case XML_TOK_PREFIXED_NAME:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT;
-    case XML_TOK_NAME_QUESTION:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT_OPT;
-    case XML_TOK_NAME_ASTERISK:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT_REP;
-    case XML_TOK_NAME_PLUS:
-        state->handler = element7;
-        return XML_ROLE_CONTENT_ELEMENT_PLUS;
-    }
-    return syntaxError(state);
-}
-
-static
-int element7(PROLOG_STATE *state,
-             int tok,
-             const char *ptr,
-             const char *end,
-             const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_CLOSE_PAREN:
-        state->level -= 1;
-        if (state->level == 0)
-            state->handler = declClose;
-        return XML_ROLE_GROUP_CLOSE;
-    case XML_TOK_CLOSE_PAREN_ASTERISK:
-        state->level -= 1;
-        if (state->level == 0)
-            state->handler = declClose;
-        return XML_ROLE_GROUP_CLOSE_REP;
-    case XML_TOK_CLOSE_PAREN_QUESTION:
-        state->level -= 1;
-        if (state->level == 0)
-            state->handler = declClose;
-        return XML_ROLE_GROUP_CLOSE_OPT;
-    case XML_TOK_CLOSE_PAREN_PLUS:
-        state->level -= 1;
-        if (state->level == 0)
-            state->handler = declClose;
-        return XML_ROLE_GROUP_CLOSE_PLUS;
-    case XML_TOK_COMMA:
-        state->handler = element6;
-        return XML_ROLE_GROUP_SEQUENCE;
-    case XML_TOK_OR:
-        state->handler = element6;
-        return XML_ROLE_GROUP_CHOICE;
-    }
-    return syntaxError(state);
-}
-
-static
-int declClose(PROLOG_STATE *state,
-              int tok,
-              const char *ptr,
-              const char *end,
-              const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_PROLOG_S:
-        return XML_ROLE_NONE;
-    case XML_TOK_DECL_CLOSE:
-        state->handler = internalSubset;
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-
-#if 0
-
-static
-int ignore(PROLOG_STATE *state,
-           int tok,
-           const char *ptr,
-           const char *end,
-           const ENCODING *enc)
-{
-    switch (tok) {
-    case XML_TOK_DECL_CLOSE:
-        state->handler = internalSubset;
-        return 0;
-    default:
-        return XML_ROLE_NONE;
-    }
-    return syntaxError(state);
-}
-#endif
-
-static
-int error(PROLOG_STATE *state,
-          int tok,
-          const char *ptr,
-          const char *end,
-          const ENCODING *enc)
-{
-    return XML_ROLE_NONE;
-}
-
-static
-int syntaxError(PROLOG_STATE *state)
-{
-    state->handler = error;
-    return XML_ROLE_ERROR;
-}
-
-void XmlPrologStateInit(PROLOG_STATE *state)
-{
-    state->handler = prolog0;
-}
--- a/src/protocols/jabber/xmlrole.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#ifndef XmlRole_INCLUDED
-#define XmlRole_INCLUDED 1
-
-#include "xmltok.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
-  XML_ROLE_ERROR = -1,
-  XML_ROLE_NONE = 0,
-  XML_ROLE_XML_DECL,
-  XML_ROLE_INSTANCE_START,
-  XML_ROLE_DOCTYPE_NAME,
-  XML_ROLE_DOCTYPE_SYSTEM_ID,
-  XML_ROLE_DOCTYPE_PUBLIC_ID,
-  XML_ROLE_DOCTYPE_CLOSE,
-  XML_ROLE_GENERAL_ENTITY_NAME,
-  XML_ROLE_PARAM_ENTITY_NAME,
-  XML_ROLE_ENTITY_VALUE,
-  XML_ROLE_ENTITY_SYSTEM_ID,
-  XML_ROLE_ENTITY_PUBLIC_ID,
-  XML_ROLE_ENTITY_NOTATION_NAME,
-  XML_ROLE_NOTATION_NAME,
-  XML_ROLE_NOTATION_SYSTEM_ID,
-  XML_ROLE_NOTATION_NO_SYSTEM_ID,
-  XML_ROLE_NOTATION_PUBLIC_ID,
-  XML_ROLE_ATTRIBUTE_NAME,
-  XML_ROLE_ATTRIBUTE_TYPE_CDATA,
-  XML_ROLE_ATTRIBUTE_TYPE_ID,
-  XML_ROLE_ATTRIBUTE_TYPE_IDREF,
-  XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
-  XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
-  XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
-  XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
-  XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
-  XML_ROLE_ATTRIBUTE_ENUM_VALUE,
-  XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
-  XML_ROLE_ATTLIST_ELEMENT_NAME,
-  XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
-  XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
-  XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
-  XML_ROLE_FIXED_ATTRIBUTE_VALUE,
-  XML_ROLE_ELEMENT_NAME,
-  XML_ROLE_CONTENT_ANY,
-  XML_ROLE_CONTENT_EMPTY,
-  XML_ROLE_CONTENT_PCDATA,
-  XML_ROLE_GROUP_OPEN,
-  XML_ROLE_GROUP_CLOSE,
-  XML_ROLE_GROUP_CLOSE_REP,
-  XML_ROLE_GROUP_CLOSE_OPT,
-  XML_ROLE_GROUP_CLOSE_PLUS,
-  XML_ROLE_GROUP_CHOICE,
-  XML_ROLE_GROUP_SEQUENCE,
-  XML_ROLE_CONTENT_ELEMENT,
-  XML_ROLE_CONTENT_ELEMENT_REP,
-  XML_ROLE_CONTENT_ELEMENT_OPT,
-  XML_ROLE_CONTENT_ELEMENT_PLUS,
-  XML_ROLE_PARAM_ENTITY_REF
-};
-
-typedef struct prolog_state {
-  int (*handler)(struct prolog_state *state,
-	         int tok,
-		 const char *ptr,
-		 const char *end,
-		 const ENCODING *enc);
-  unsigned level;
-} PROLOG_STATE;
-
-void XMLTOKAPI XmlPrologStateInit(PROLOG_STATE *);
-
-#define XmlTokenRole(state, tok, ptr, end, enc) \
- (((state)->handler)(state, tok, ptr, end, enc))
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not XmlRole_INCLUDED */
--- a/src/protocols/jabber/xmltok.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1518 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-*/
-
-#include "xmldef.h"
-#include "xmltok.h"
-#include "nametab.h"
-
-#define VTABLE1 \
-  { PREFIX(prologTok), PREFIX(contentTok), PREFIX(cdataSectionTok) }, \
-  { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
-  PREFIX(sameName), \
-  PREFIX(nameMatchesAscii), \
-  PREFIX(nameLength), \
-  PREFIX(skipS), \
-  PREFIX(getAtts), \
-  PREFIX(charRefNumber), \
-  PREFIX(predefinedEntityName), \
-  PREFIX(updatePosition), \
-  PREFIX(isPublicId)
-
-#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
-
-#define UCS2_GET_NAMING(pages, hi, lo) \
-   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
-
-/* A 2 byte UTF-8 representation splits the characters 11 bits
-between the bottom 5 and 6 bits of the bytes.
-We need 8 bits to index into pages, 3 bits to add to that index and
-5 bits to generate the mask. */
-#define UTF8_GET_NAMING2(pages, byte) \
-    (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
-                      + ((((byte)[0]) & 3) << 1) \
-                      + ((((byte)[1]) >> 5) & 1)] \
-         & (1 << (((byte)[1]) & 0x1F)))
-
-/* A 3 byte UTF-8 representation splits the characters 16 bits
-between the bottom 4, 6 and 6 bits of the bytes.
-We need 8 bits to index into pages, 3 bits to add to that index and
-5 bits to generate the mask. */
-#define UTF8_GET_NAMING3(pages, byte) \
-  (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
-                             + ((((byte)[1]) >> 2) & 0xF)] \
-               << 3) \
-                      + ((((byte)[1]) & 3) << 1) \
-                      + ((((byte)[2]) >> 5) & 1)] \
-         & (1 << (((byte)[2]) & 0x1F)))
-
-#define UTF8_GET_NAMING(pages, p, n) \
-  ((n) == 2 \
-  ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
-  : ((n) == 3 \
-     ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
-     : 0))
-
-#define UTF8_INVALID3(p) \
-  ((*p) == 0xED \
-  ? (((p)[1] & 0x20) != 0) \
-  : ((*p) == 0xEF \
-     ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \
-     : 0))
-
-#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0)
-
-static
-int isNever(const ENCODING *enc, const char *p)
-{
-    return 0;
-}
-
-static
-int utf8_isName2(const ENCODING *enc, const char *p)
-{
-    return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
-}
-
-static
-int utf8_isName3(const ENCODING *enc, const char *p)
-{
-    return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
-}
-
-#define utf8_isName4 isNever
-
-static
-int utf8_isNmstrt2(const ENCODING *enc, const char *p)
-{
-    return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
-}
-
-static
-int utf8_isNmstrt3(const ENCODING *enc, const char *p)
-{
-    return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
-}
-
-#define utf8_isNmstrt4 isNever
-
-#define utf8_isInvalid2 isNever
-
-static
-int utf8_isInvalid3(const ENCODING *enc, const char *p)
-{
-    return UTF8_INVALID3((const unsigned char *)p);
-}
-
-static
-int utf8_isInvalid4(const ENCODING *enc, const char *p)
-{
-    return UTF8_INVALID4((const unsigned char *)p);
-}
-
-struct normal_encoding {
-    ENCODING enc;
-    unsigned char type[256];
-#ifdef XML_MIN_SIZE
-    int (*byteType)(const ENCODING *, const char *);
-    int (*isNameMin)(const ENCODING *, const char *);
-    int (*isNmstrtMin)(const ENCODING *, const char *);
-    int (*byteToAscii)(const ENCODING *, const char *);
-    int (*charMatches)(const ENCODING *, const char *, int);
-#endif /* XML_MIN_SIZE */
-    int (*isName2)(const ENCODING *, const char *);
-    int (*isName3)(const ENCODING *, const char *);
-    int (*isName4)(const ENCODING *, const char *);
-    int (*isNmstrt2)(const ENCODING *, const char *);
-    int (*isNmstrt3)(const ENCODING *, const char *);
-    int (*isNmstrt4)(const ENCODING *, const char *);
-    int (*isInvalid2)(const ENCODING *, const char *);
-    int (*isInvalid3)(const ENCODING *, const char *);
-    int (*isInvalid4)(const ENCODING *, const char *);
-};
-
-#ifdef XML_MIN_SIZE
-
-#define STANDARD_VTABLE(E) \
- E ## byteType, \
- E ## isNameMin, \
- E ## isNmstrtMin, \
- E ## byteToAscii, \
- E ## charMatches,
-
-#else
-
-#define STANDARD_VTABLE(E) /* as nothing */
-
-#endif
-
-#define NORMAL_VTABLE(E) \
- E ## isName2, \
- E ## isName3, \
- E ## isName4, \
- E ## isNmstrt2, \
- E ## isNmstrt3, \
- E ## isNmstrt4, \
- E ## isInvalid2, \
- E ## isInvalid3, \
- E ## isInvalid4
-
-static int checkCharRefNumber(int);
-
-#include "xmltok_impl.h"
-
-#ifdef XML_MIN_SIZE
-#define sb_isNameMin isNever
-#define sb_isNmstrtMin isNever
-#endif
-
-#ifdef XML_MIN_SIZE
-#define MINBPC(enc) ((enc)->minBytesPerChar)
-#else
-/* minimum bytes per character */
-#define MINBPC(enc) 1
-#endif
-
-#define SB_BYTE_TYPE(enc, p) \
-  (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
-
-#ifdef XML_MIN_SIZE
-static
-int sb_byteType(const ENCODING *enc, const char *p)
-{
-    return SB_BYTE_TYPE(enc, p);
-}
-#define BYTE_TYPE(enc, p) \
- (((const struct normal_encoding *)(enc))->byteType(enc, p))
-#else
-#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
-#endif
-
-#ifdef XML_MIN_SIZE
-#define BYTE_TO_ASCII(enc, p) \
- (((const struct normal_encoding *)(enc))->byteToAscii(enc, p))
-static
-int sb_byteToAscii(const ENCODING *enc, const char *p)
-{
-    return *p;
-}
-#else
-#define BYTE_TO_ASCII(enc, p) (*p)
-#endif
-
-#define IS_NAME_CHAR(enc, p, n) \
- (((const struct normal_encoding *)(enc))->isName ## n(enc, p))
-#define IS_NMSTRT_CHAR(enc, p, n) \
- (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p))
-#define IS_INVALID_CHAR(enc, p, n) \
- (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p))
-
-#ifdef XML_MIN_SIZE
-#define IS_NAME_CHAR_MINBPC(enc, p) \
- (((const struct normal_encoding *)(enc))->isNameMin(enc, p))
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
- (((const struct normal_encoding *)(enc))->isNmstrtMin(enc, p))
-#else
-#define IS_NAME_CHAR_MINBPC(enc, p) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
-#endif
-
-#ifdef XML_MIN_SIZE
-#define CHAR_MATCHES(enc, p, c) \
- (((const struct normal_encoding *)(enc))->charMatches(enc, p, c))
-static
-int sb_charMatches(const ENCODING *enc, const char *p, int c)
-{
-    return *p == c;
-}
-#else
-/* c is an ASCII character */
-#define CHAR_MATCHES(enc, p, c) (*(p) == c)
-#endif
-
-#define PREFIX(ident) normal_ ## ident
-#include "xmltok_impl.c"
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
-
-enum {  /* UTF8_cvalN is value of masked first byte of N byte sequence */
-    UTF8_cval1 = 0x00,
-    UTF8_cval2 = 0xc0,
-    UTF8_cval3 = 0xe0,
-    UTF8_cval4 = 0xf0
-};
-
-static
-void utf8_toUtf8(const ENCODING *enc,
-                 const char **fromP, const char *fromLim,
-                 char **toP, const char *toLim)
-{
-    char *to;
-    const char *from;
-    if (fromLim - *fromP > toLim - *toP) {
-        /* Avoid copying partial characters. */
-        for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
-            if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
-                break;
-    }
-    for (to = *toP, from = *fromP; from != fromLim; from++, to++)
-        *to = *from;
-    *fromP = from;
-    *toP = to;
-}
-
-static
-void utf8_toUtf16(const ENCODING *enc,
-                  const char **fromP, const char *fromLim,
-                  unsigned short **toP, const unsigned short *toLim)
-{
-    unsigned short *to = *toP;
-    const char *from = *fromP;
-    while (from != fromLim && to != toLim) {
-        switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
-        case BT_LEAD2:
-            *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f);
-            from += 2;
-            break;
-        case BT_LEAD3:
-            *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f);
-            from += 3;
-            break;
-        case BT_LEAD4:
-            {
-                unsigned long n;
-                if (to + 1 == toLim)
-                    break;
-                n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
-                n -= 0x10000;
-                to[0] = (unsigned short)((n >> 10) | 0xD800);
-                to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
-                to += 2;
-                from += 4;
-            }
-            break;
-        default:
-            *to++ = *from++;
-            break;
-        }
-    }
-    *fromP = from;
-    *toP = to;
-}
-
-#ifdef XML_NS
-static const struct normal_encoding utf8_encoding_ns = {
-        { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
-            {
-#include "asciitab.h"
-#include "utf8tab.h"
-            },
-            STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-        };
-#endif
-
-static const struct normal_encoding utf8_encoding = {
-        { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
-            {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "utf8tab.h"
-            },
-            STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-        };
-
-#ifdef XML_NS
-
-static const struct normal_encoding internal_utf8_encoding_ns = {
-        { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
-            {
-#include "iasciitab.h"
-#include "utf8tab.h"
-            },
-            STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-        };
-
-#endif
-
-static const struct normal_encoding internal_utf8_encoding = {
-        { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
-            {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "utf8tab.h"
-            },
-            STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
-        };
-
-static
-void latin1_toUtf8(const ENCODING *enc,
-                   const char **fromP, const char *fromLim,
-                   char **toP, const char *toLim)
-{
-    for (;;) {
-        unsigned char c;
-        if (*fromP == fromLim)
-            break;
-        c = (unsigned char)**fromP;
-        if (c & 0x80) {
-            if (toLim - *toP < 2)
-                break;
-            *(*toP)++ = ((c >> 6) | UTF8_cval2);
-            *(*toP)++ = ((c & 0x3f) | 0x80);
-            (*fromP)++;
-        }
-        else {
-            if (*toP == toLim)
-                break;
-            *(*toP)++ = *(*fromP)++;
-        }
-    }
-}
-
-static
-void latin1_toUtf16(const ENCODING *enc,
-                    const char **fromP, const char *fromLim,
-                    unsigned short **toP, const unsigned short *toLim)
-{
-    while (*fromP != fromLim && *toP != toLim)
-        *(*toP)++ = (unsigned char)*(*fromP)++;
-}
-
-#ifdef XML_NS
-
-static const struct normal_encoding latin1_encoding_ns = {
-        { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
-            {
-#include "asciitab.h"
-#include "latin1tab.h"
-            },
-            STANDARD_VTABLE(sb_)
-        };
-
-#endif
-
-static const struct normal_encoding latin1_encoding = {
-        { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
-            {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
-            },
-            STANDARD_VTABLE(sb_)
-        };
-
-static
-void ascii_toUtf8(const ENCODING *enc,
-                  const char **fromP, const char *fromLim,
-                  char **toP, const char *toLim)
-{
-    while (*fromP != fromLim && *toP != toLim)
-        *(*toP)++ = *(*fromP)++;
-}
-
-#ifdef XML_NS
-
-static const struct normal_encoding ascii_encoding_ns = {
-        { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
-            {
-#include "asciitab.h"
-                /* BT_NONXML == 0 */
-            },
-            STANDARD_VTABLE(sb_)
-        };
-
-#endif
-
-static const struct normal_encoding ascii_encoding = {
-        { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
-            {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-                /* BT_NONXML == 0 */
-            },
-            STANDARD_VTABLE(sb_)
-        };
-
-static int unicode_byte_type(char hi, char lo)
-{
-    switch ((unsigned char)hi) {
-case 0xD8: case 0xD9: case 0xDA: case 0xDB:
-        return BT_LEAD4;
-case 0xDC: case 0xDD: case 0xDE: case 0xDF:
-        return BT_TRAIL;
-    case 0xFF:
-        switch ((unsigned char)lo) {
-        case 0xFF:
-        case 0xFE:
-            return BT_NONXML;
-        }
-        break;
-    }
-    return BT_NONASCII;
-}
-
-#define DEFINE_UTF16_TO_UTF8(E) \
-static \
-void E ## toUtf8(const ENCODING *enc, \
-         const char **fromP, const char *fromLim, \
-         char **toP, const char *toLim) \
-{ \
-  const char *from; \
-  for (from = *fromP; from != fromLim; from += 2) { \
-    int plane; \
-    unsigned char lo2; \
-    unsigned char lo = GET_LO(from); \
-    unsigned char hi = GET_HI(from); \
-    switch (hi) { \
-    case 0: \
-      if (lo < 0x80) { \
-        if (*toP == toLim) { \
-          *fromP = from; \
-      return; \
-        } \
-        *(*toP)++ = lo; \
-        break; \
-      } \
-      /* fall through */ \
-    case 0x1: case 0x2: case 0x3: \
-    case 0x4: case 0x5: case 0x6: case 0x7: \
-      if (toLim -  *toP < 2) { \
-        *fromP = from; \
-    return; \
-      } \
-      *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \
-      *(*toP)++ = ((lo & 0x3f) | 0x80); \
-      break; \
-    default: \
-      if (toLim -  *toP < 3)  { \
-        *fromP = from; \
-    return; \
-      } \
-      /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
-      *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
-      *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
-      *(*toP)++ = ((lo & 0x3f) | 0x80); \
-      break; \
-    case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
-      if (toLim -  *toP < 4) { \
-    *fromP = from; \
-    return; \
-      } \
-      plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
-      *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
-      *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
-      from += 2; \
-      lo2 = GET_LO(from); \
-      *(*toP)++ = (((lo & 0x3) << 4) \
-               | ((GET_HI(from) & 0x3) << 2) \
-           | (lo2 >> 6) \
-           | 0x80); \
-      *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
-      break; \
-    } \
-  } \
-  *fromP = from; \
-}
-
-#define DEFINE_UTF16_TO_UTF16(E) \
-static \
-void E ## toUtf16(const ENCODING *enc, \
-          const char **fromP, const char *fromLim, \
-          unsigned short **toP, const unsigned short *toLim) \
-{ \
-  /* Avoid copying first half only of surrogate */ \
-  if (fromLim - *fromP > ((toLim - *toP) << 1) \
-      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
-    fromLim -= 2; \
-  for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
-    *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
-}
-
-#define SET2(ptr, ch) \
-  (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
-#define GET_LO(ptr) ((unsigned char)(ptr)[0])
-#define GET_HI(ptr) ((unsigned char)(ptr)[1])
-
-DEFINE_UTF16_TO_UTF8(little2_)
-DEFINE_UTF16_TO_UTF16(little2_)
-
-#undef SET2
-#undef GET_LO
-#undef GET_HI
-
-#define SET2(ptr, ch) \
-  (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
-#define GET_LO(ptr) ((unsigned char)(ptr)[1])
-#define GET_HI(ptr) ((unsigned char)(ptr)[0])
-
-DEFINE_UTF16_TO_UTF8(big2_)
-DEFINE_UTF16_TO_UTF16(big2_)
-
-#undef SET2
-#undef GET_LO
-#undef GET_HI
-
-#define LITTLE2_BYTE_TYPE(enc, p) \
- ((p)[1] == 0 \
-  ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
-  : unicode_byte_type((p)[1], (p)[0]))
-#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
-#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
-#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
-  UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
-#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
-  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
-
-#ifdef XML_MIN_SIZE
-
-static
-int little2_byteType(const ENCODING *enc, const char *p)
-{
-    return LITTLE2_BYTE_TYPE(enc, p);
-}
-
-static
-int little2_byteToAscii(const ENCODING *enc, const char *p)
-{
-    return LITTLE2_BYTE_TO_ASCII(enc, p);
-}
-
-static
-int little2_charMatches(const ENCODING *enc, const char *p, int c)
-{
-    return LITTLE2_CHAR_MATCHES(enc, p, c);
-}
-
-static
-int little2_isNameMin(const ENCODING *enc, const char *p)
-{
-    return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
-}
-
-static
-int little2_isNmstrtMin(const ENCODING *enc, const char *p)
-{
-    return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
-}
-
-#undef VTABLE
-#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
-
-#else /* not XML_MIN_SIZE */
-
-#undef PREFIX
-#define PREFIX(ident) little2_ ## ident
-#define MINBPC(enc) 2
-/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
-#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) 
-#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
-#define IS_NAME_CHAR(enc, p, n) 0
-#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
-#define IS_NMSTRT_CHAR(enc, p, n) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
-
-#include "xmltok_impl.c"
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
-
-#endif /* not XML_MIN_SIZE */
-
-#ifdef XML_NS
-
-static const struct normal_encoding little2_encoding_ns = {
-            { VTABLE, 2, 0,
-#if XML_BYTE_ORDER == 12
-                1
-#else
-0
-#endif
-            },
-            {
-#include "asciitab.h"
-#include "latin1tab.h"
-            },
-            STANDARD_VTABLE(little2_)
-        };
-
-#endif
-
-static const struct normal_encoding little2_encoding = {
-            { VTABLE, 2, 0,
-#if XML_BYTE_ORDER == 12
-                1
-#else
-                0
-#endif
-            },
-            {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
-            },
-            STANDARD_VTABLE(little2_)
-        };
-
-#if XML_BYTE_ORDER != 21
-
-#ifdef XML_NS
-
-static const struct normal_encoding internal_little2_encoding_ns = {
-        { VTABLE, 2, 0, 1 },
-            {
-#include "iasciitab.h"
-#include "latin1tab.h"
-            },
-            STANDARD_VTABLE(little2_)
-        };
-
-#endif
-
-static const struct normal_encoding internal_little2_encoding = {
-        { VTABLE, 2, 0, 1 },
-            {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
-            },
-            STANDARD_VTABLE(little2_)
-        };
-
-#endif
-
-
-#define BIG2_BYTE_TYPE(enc, p) \
- ((p)[0] == 0 \
-  ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
-  : unicode_byte_type((p)[0], (p)[1]))
-#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
-#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
-#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
-  UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
-#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
-  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
-
-#ifdef XML_MIN_SIZE
-
-static
-int big2_byteType(const ENCODING *enc, const char *p)
-{
-    return BIG2_BYTE_TYPE(enc, p);
-}
-
-static
-int big2_byteToAscii(const ENCODING *enc, const char *p)
-{
-    return BIG2_BYTE_TO_ASCII(enc, p);
-}
-
-static
-int big2_charMatches(const ENCODING *enc, const char *p, int c)
-{
-    return BIG2_CHAR_MATCHES(enc, p, c);
-}
-
-static
-int big2_isNameMin(const ENCODING *enc, const char *p)
-{
-    return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
-}
-
-static
-int big2_isNmstrtMin(const ENCODING *enc, const char *p)
-{
-    return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
-}
-
-#undef VTABLE
-#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
-
-#else /* not XML_MIN_SIZE */
-
-#undef PREFIX
-#define PREFIX(ident) big2_ ## ident
-#define MINBPC(enc) 2
-/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
-#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
-#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) 
-#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
-#define IS_NAME_CHAR(enc, p, n) 0
-#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
-#define IS_NMSTRT_CHAR(enc, p, n) (0)
-#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
-
-#include "xmltok_impl.c"
-
-#undef MINBPC
-#undef BYTE_TYPE
-#undef BYTE_TO_ASCII
-#undef CHAR_MATCHES
-#undef IS_NAME_CHAR
-#undef IS_NAME_CHAR_MINBPC
-#undef IS_NMSTRT_CHAR
-#undef IS_NMSTRT_CHAR_MINBPC
-#undef IS_INVALID_CHAR
-
-#endif /* not XML_MIN_SIZE */
-
-#ifdef XML_NS
-
-static const struct normal_encoding big2_encoding_ns = {
-            { VTABLE, 2, 0,
-#if XML_BYTE_ORDER == 21
-                1
-#else
-0
-#endif
-            },
-            {
-#include "asciitab.h"
-#include "latin1tab.h"
-            },
-            STANDARD_VTABLE(big2_)
-        };
-
-#endif
-
-static const struct normal_encoding big2_encoding = {
-            { VTABLE, 2, 0,
-#if XML_BYTE_ORDER == 21
-                1
-#else
-                0
-#endif
-            },
-            {
-#define BT_COLON BT_NMSTRT
-#include "asciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
-            },
-            STANDARD_VTABLE(big2_)
-        };
-
-#if XML_BYTE_ORDER != 12
-
-#ifdef XML_NS
-
-static const struct normal_encoding internal_big2_encoding_ns = {
-        { VTABLE, 2, 0, 1 },
-            {
-#include "iasciitab.h"
-#include "latin1tab.h"
-            },
-            STANDARD_VTABLE(big2_)
-        };
-
-#endif
-
-static const struct normal_encoding internal_big2_encoding = {
-        { VTABLE, 2, 0, 1 },
-            {
-#define BT_COLON BT_NMSTRT
-#include "iasciitab.h"
-#undef BT_COLON
-#include "latin1tab.h"
-            },
-            STANDARD_VTABLE(big2_)
-        };
-
-#endif
-
-#undef PREFIX
-
-static
-int streqci(const char *s1, const char *s2)
-{
-    for (;;) {
-        char c1 = *s1++;
-        char c2 = *s2++;
-        if ('a' <= c1 && c1 <= 'z')
-            c1 += 'A' - 'a';
-        if ('a' <= c2 && c2 <= 'z')
-            c2 += 'A' - 'a';
-        if (c1 != c2)
-            return 0;
-        if (!c1)
-            break;
-    }
-    return 1;
-}
-
-static
-void initUpdatePosition(const ENCODING *enc, const char *ptr,
-                        const char *end, POSITION *pos)
-{
-    normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
-}
-
-static
-int toAscii(const ENCODING *enc, const char *ptr, const char *end)
-{
-    char buf[1];
-    char *p = buf;
-    XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
-    if (p == buf)
-        return -1;
-    else
-        return buf[0];
-}
-
-static
-int isSpace(int c)
-{
-    switch (c) {
-    case 0x20:
-    case 0xD:
-    case 0xA:
-    case 0x9:
-        return 1;
-    }
-    return 0;
-}
-
-/* Return 1 if there's just optional white space
-or there's an S followed by name=val. */
-static
-int parsePseudoAttribute(const ENCODING *enc,
-                         const char *ptr,
-                         const char *end,
-                         const char **namePtr,
-                         const char **valPtr,
-                         const char **nextTokPtr)
-{
-    int c;
-    char open;
-    if (ptr == end) {
-        *namePtr = 0;
-        return 1;
-    }
-    if (!isSpace(toAscii(enc, ptr, end))) {
-        *nextTokPtr = ptr;
-        return 0;
-    }
-    do {
-        ptr += enc->minBytesPerChar;
-    } while (isSpace(toAscii(enc, ptr, end)));
-    if (ptr == end) {
-        *namePtr = 0;
-        return 1;
-    }
-    *namePtr = ptr;
-    for (;;) {
-        c = toAscii(enc, ptr, end);
-        if (c == -1) {
-            *nextTokPtr = ptr;
-            return 0;
-        }
-        if (c == '=')
-            break;
-        if (isSpace(c)) {
-            do {
-                ptr += enc->minBytesPerChar;
-            } while (isSpace(c = toAscii(enc, ptr, end)));
-            if (c != '=') {
-                *nextTokPtr = ptr;
-                return 0;
-            }
-            break;
-        }
-        ptr += enc->minBytesPerChar;
-    }
-    if (ptr == *namePtr) {
-        *nextTokPtr = ptr;
-        return 0;
-    }
-    ptr += enc->minBytesPerChar;
-    c = toAscii(enc, ptr, end);
-    while (isSpace(c)) {
-        ptr += enc->minBytesPerChar;
-        c = toAscii(enc, ptr, end);
-    }
-    if (c != '"' && c != '\'') {
-        *nextTokPtr = ptr;
-        return 0;
-    }
-    open = c;
-    ptr += enc->minBytesPerChar;
-    *valPtr = ptr;
-    for (;; ptr += enc->minBytesPerChar) {
-        c = toAscii(enc, ptr, end);
-        if (c == open)
-            break;
-        if (!('a' <= c && c <= 'z')
-                && !('A' <= c && c <= 'Z')
-                && !('0' <= c && c <= '9')
-                && c != '.'
-                && c != '-'
-                && c != '_') {
-            *nextTokPtr = ptr;
-            return 0;
-        }
-    }
-    *nextTokPtr = ptr + enc->minBytesPerChar;
-    return 1;
-}
-
-static
-int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
-                   const char *,
-                   const char *),
-                   int isGeneralTextEntity,
-                   const ENCODING *enc,
-                   const char *ptr,
-                   const char *end,
-                   const char **badPtr,
-                   const char **versionPtr,
-                   const char **encodingName,
-                   const ENCODING **encoding,
-                   int *standalone)
-{
-    const char *val = 0;
-    const char *name = 0;
-    ptr += 5 * enc->minBytesPerChar;
-    end -= 2 * enc->minBytesPerChar;
-    if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr) || !name) {
-        *badPtr = ptr;
-        return 0;
-    }
-    if (!XmlNameMatchesAscii(enc, name, "version")) {
-        if (!isGeneralTextEntity) {
-            *badPtr = name;
-            return 0;
-        }
-    }
-    else {
-        if (versionPtr)
-            *versionPtr = val;
-        if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr)) {
-            *badPtr = ptr;
-            return 0;
-        }
-        if (!name) {
-            if (isGeneralTextEntity) {
-                /* a TextDecl must have an EncodingDecl */
-                *badPtr = ptr;
-                return 0;
-            }
-            return 1;
-        }
-    }
-    if (XmlNameMatchesAscii(enc, name, "encoding")) {
-        int c = toAscii(enc, val, end);
-        if (!('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z')) {
-            *badPtr = val;
-            return 0;
-        }
-        if (encodingName)
-            *encodingName = val;
-        if (encoding)
-            *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
-        if (!parsePseudoAttribute(enc, ptr, end, &name, &val, &ptr)) {
-            *badPtr = ptr;
-            return 0;
-        }
-        if (!name)
-            return 1;
-    }
-    if (!XmlNameMatchesAscii(enc, name, "standalone") || isGeneralTextEntity) {
-        *badPtr = name;
-        return 0;
-    }
-    if (XmlNameMatchesAscii(enc, val, "yes")) {
-        if (standalone)
-            *standalone = 1;
-    }
-    else if (XmlNameMatchesAscii(enc, val, "no")) {
-        if (standalone)
-            *standalone = 0;
-    }
-    else {
-        *badPtr = val;
-        return 0;
-    }
-    while (isSpace(toAscii(enc, ptr, end)))
-        ptr += enc->minBytesPerChar;
-    if (ptr != end) {
-        *badPtr = ptr;
-        return 0;
-    }
-    return 1;
-}
-
-static
-int checkCharRefNumber(int result)
-{
-    switch (result >> 8) {
-case 0xD8: case 0xD9: case 0xDA: case 0xDB:
-case 0xDC: case 0xDD: case 0xDE: case 0xDF:
-        return -1;
-    case 0:
-        if (latin1_encoding.type[result] == BT_NONXML)
-            return -1;
-        break;
-    case 0xFF:
-        if (result == 0xFFFE || result == 0xFFFF)
-            return -1;
-        break;
-    }
-    return result;
-}
-
-int XmlUtf8Encode(int c, char *buf)
-{
-    enum {
-        /* minN is minimum legal resulting value for N byte sequence */
-        min2 = 0x80,
-        min3 = 0x800,
-        min4 = 0x10000
-    };
-
-    if (c < 0)
-        return 0;
-    if (c < min2) {
-        buf[0] = (c | UTF8_cval1);
-        return 1;
-    }
-    if (c < min3) {
-        buf[0] = ((c >> 6) | UTF8_cval2);
-        buf[1] = ((c & 0x3f) | 0x80);
-        return 2;
-    }
-    if (c < min4) {
-        buf[0] = ((c >> 12) | UTF8_cval3);
-        buf[1] = (((c >> 6) & 0x3f) | 0x80);
-        buf[2] = ((c & 0x3f) | 0x80);
-        return 3;
-    }
-    if (c < 0x110000) {
-        buf[0] = ((c >> 18) | UTF8_cval4);
-        buf[1] = (((c >> 12) & 0x3f) | 0x80);
-        buf[2] = (((c >> 6) & 0x3f) | 0x80);
-        buf[3] = ((c & 0x3f) | 0x80);
-        return 4;
-    }
-    return 0;
-}
-
-int XmlUtf16Encode(int charNum, unsigned short *buf)
-{
-    if (charNum < 0)
-        return 0;
-    if (charNum < 0x10000) {
-        buf[0] = charNum;
-        return 1;
-    }
-    if (charNum < 0x110000) {
-        charNum -= 0x10000;
-        buf[0] = (charNum >> 10) + 0xD800;
-        buf[1] = (charNum & 0x3FF) + 0xDC00;
-        return 2;
-    }
-    return 0;
-}
-
-struct unknown_encoding {
-    struct normal_encoding normal;
-    int (*convert)(void *userData, const char *p);
-    void *userData;
-    unsigned short utf16[256];
-    char utf8[256][4];
-};
-
-int XmlSizeOfUnknownEncoding()
-{
-    return sizeof(struct unknown_encoding);
-}
-
-static
-int unknown_isName(const ENCODING *enc, const char *p)
-{
-    int c = ((const struct unknown_encoding *)enc)
-            ->convert(((const struct unknown_encoding *)enc)->userData, p);
-    if (c & ~0xFFFF)
-        return 0;
-    return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
-}
-
-static
-int unknown_isNmstrt(const ENCODING *enc, const char *p)
-{
-    int c = ((const struct unknown_encoding *)enc)
-            ->convert(((const struct unknown_encoding *)enc)->userData, p);
-    if (c & ~0xFFFF)
-        return 0;
-    return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
-}
-
-static
-int unknown_isInvalid(const ENCODING *enc, const char *p)
-{
-    int c = ((const struct unknown_encoding *)enc)
-            ->convert(((const struct unknown_encoding *)enc)->userData, p);
-    return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
-}
-
-static
-void unknown_toUtf8(const ENCODING *enc,
-                    const char **fromP, const char *fromLim,
-                    char **toP, const char *toLim)
-{
-    char buf[XML_UTF8_ENCODE_MAX];
-    for (;;) {
-        const char *utf8;
-        int n;
-        if (*fromP == fromLim)
-            break;
-        utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP];
-        n = *utf8++;
-        if (n == 0) {
-            int c = ((const struct unknown_encoding *)enc)
-                    ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
-            n = XmlUtf8Encode(c, buf);
-            if (n > toLim - *toP)
-                break;
-            utf8 = buf;
-            *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
-                      - (BT_LEAD2 - 2);
-        }
-        else {
-            if (n > toLim - *toP)
-                break;
-            (*fromP)++;
-        }
-        do {
-            *(*toP)++ = *utf8++;
-        } while (--n != 0);
-    }
-}
-
-static
-void unknown_toUtf16(const ENCODING *enc,
-                     const char **fromP, const char *fromLim,
-                     unsigned short **toP, const unsigned short *toLim)
-{
-    while (*fromP != fromLim && *toP != toLim) {
-        unsigned short c
-        = ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP];
-        if (c == 0) {
-            c = (unsigned short)((const struct unknown_encoding *)enc)
-                ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
-            *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
-                      - (BT_LEAD2 - 2);
-        }
-        else
-            (*fromP)++;
-        *(*toP)++ = c;
-    }
-}
-
-ENCODING *
-XmlInitUnknownEncoding(void *mem,
-                       int *table,
-                       int (*convert)(void *userData, const char *p),
-                       void *userData)
-{
-    int i;
-    struct unknown_encoding *e = mem;
-    for (i = 0; i < sizeof(struct normal_encoding); i++)
-        ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
-    for (i = 0; i < 128; i++)
-        if (latin1_encoding.type[i] != BT_OTHER
-                && latin1_encoding.type[i] != BT_NONXML
-                && table[i] != i)
-            return 0;
-    for (i = 0; i < 256; i++) {
-        int c = table[i];
-        if (c == -1) {
-            e->normal.type[i] = BT_MALFORM;
-            /* This shouldn't really get used. */
-            e->utf16[i] = 0xFFFF;
-            e->utf8[i][0] = 1;
-            e->utf8[i][1] = 0;
-        }
-        else if (c < 0) {
-            if (c < -4)
-                return 0;
-            e->normal.type[i] = BT_LEAD2 - (c + 2);
-            e->utf8[i][0] = 0;
-            e->utf16[i] = 0;
-        }
-        else if (c < 0x80) {
-            if (latin1_encoding.type[c] != BT_OTHER
-                    && latin1_encoding.type[c] != BT_NONXML
-                    && c != i)
-                return 0;
-            e->normal.type[i] = latin1_encoding.type[c];
-            e->utf8[i][0] = 1;
-            e->utf8[i][1] = (char)c;
-            e->utf16[i] = c == 0 ? 0xFFFF : c;
-        }
-        else if (checkCharRefNumber(c) < 0) {
-            e->normal.type[i] = BT_NONXML;
-            /* This shouldn't really get used. */
-            e->utf16[i] = 0xFFFF;
-            e->utf8[i][0] = 1;
-            e->utf8[i][1] = 0;
-        }
-        else {
-            if (c > 0xFFFF)
-                return 0;
-            if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
-                e->normal.type[i] = BT_NMSTRT;
-            else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
-                e->normal.type[i] = BT_NAME;
-            else
-                e->normal.type[i] = BT_OTHER;
-            e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
-            e->utf16[i] = c;
-        }
-    }
-    e->userData = userData;
-    e->convert = convert;
-    if (convert) {
-        e->normal.isName2 = unknown_isName;
-        e->normal.isName3 = unknown_isName;
-        e->normal.isName4 = unknown_isName;
-        e->normal.isNmstrt2 = unknown_isNmstrt;
-        e->normal.isNmstrt3 = unknown_isNmstrt;
-        e->normal.isNmstrt4 = unknown_isNmstrt;
-        e->normal.isInvalid2 = unknown_isInvalid;
-        e->normal.isInvalid3 = unknown_isInvalid;
-        e->normal.isInvalid4 = unknown_isInvalid;
-    }
-    e->normal.enc.utf8Convert = unknown_toUtf8;
-    e->normal.enc.utf16Convert = unknown_toUtf16;
-    return &(e->normal.enc);
-}
-
-/* If this enumeration is changed, getEncodingIndex and encodings
-must also be changed. */
-enum {
-    UNKNOWN_ENC = -1,
-    ISO_8859_1_ENC = 0,
-    US_ASCII_ENC,
-    UTF_8_ENC,
-    UTF_16_ENC,
-    UTF_16BE_ENC,
-    UTF_16LE_ENC,
-    /* must match encodingNames up to here */
-    NO_ENC
-};
-
-static
-int getEncodingIndex(const char *name)
-{
-    static const char *encodingNames[] = {
-        "ISO-8859-1",
-        "US-ASCII",
-        "UTF-8",
-        "UTF-16",
-        "UTF-16BE"
-        "UTF-16LE",
-    };
-    int i;
-    if (name == 0)
-        return NO_ENC;
-    for (i = 0; i < sizeof(encodingNames)/sizeof(encodingNames[0]); i++)
-        if (streqci(name, encodingNames[i]))
-            return i;
-    return UNKNOWN_ENC;
-}
-
-/* For binary compatibility, we store the index of the encoding specified
-at initialization in the isUtf16 member. */
-
-#define INIT_ENC_INDEX(enc) ((enc)->initEnc.isUtf16)
-
-/* This is what detects the encoding.
-encodingTable maps from encoding indices to encodings;
-INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding;
-state is XML_CONTENT_STATE if we're parsing an external text entity,
-and XML_PROLOG_STATE otherwise.
-*/
-
-
-static
-int initScan(const ENCODING **encodingTable,
-             const INIT_ENCODING *enc,
-             int state,
-             const char *ptr,
-             const char *end,
-             const char **nextTokPtr)
-{
-    const ENCODING **encPtr;
-
-    if (ptr == end)
-        return XML_TOK_NONE;
-    encPtr = enc->encPtr;
-    if (ptr + 1 == end) {
-        /* only a single byte available for auto-detection */
-        /* a well-formed document entity must have more than one byte */
-        if (state != XML_CONTENT_STATE)
-            return XML_TOK_PARTIAL;
-        /* so we're parsing an external text entity... */
-        /* if UTF-16 was externally specified, then we need at least 2 bytes */
-        switch (INIT_ENC_INDEX(enc)) {
-        case UTF_16_ENC:
-        case UTF_16LE_ENC:
-        case UTF_16BE_ENC:
-            return XML_TOK_PARTIAL;
-        }
-        switch ((unsigned char)*ptr) {
-        case 0xFE:
-        case 0xFF:
-        case 0xEF: /* possibly first byte of UTF-8 BOM */
-            if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
-                    && state == XML_CONTENT_STATE)
-                break;
-            /* fall through */
-        case 0x00:
-        case 0x3C:
-            return XML_TOK_PARTIAL;
-        }
-    }
-    else {
-        switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
-        case 0xFEFF:
-            if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
-                    && state == XML_CONTENT_STATE)
-                break;
-            *nextTokPtr = ptr + 2;
-            *encPtr = encodingTable[UTF_16BE_ENC];
-            return XML_TOK_BOM;
-            /* 00 3C is handled in the default case */
-        case 0x3C00:
-            if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
-                    || INIT_ENC_INDEX(enc) == UTF_16_ENC)
-                    && state == XML_CONTENT_STATE)
-                break;
-            *encPtr = encodingTable[UTF_16LE_ENC];
-            return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
-        case 0xFFFE:
-            if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
-                    && state == XML_CONTENT_STATE)
-                break;
-            *nextTokPtr = ptr + 2;
-            *encPtr = encodingTable[UTF_16LE_ENC];
-            return XML_TOK_BOM;
-        case 0xEFBB:
-            /* Maybe a UTF-8 BOM (EF BB BF) */
-            /* If there's an explicitly specified (external) encoding
-               of ISO-8859-1 or some flavour of UTF-16
-               and this is an external text entity,
-            don't look for the BOM,
-               because it might be a legal data. */
-            if (state == XML_CONTENT_STATE) {
-                int e = INIT_ENC_INDEX(enc);
-                if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC)
-                    break;
-            }
-            if (ptr + 2 == end)
-                return XML_TOK_PARTIAL;
-            if ((unsigned char)ptr[2] == 0xBF) {
-                *encPtr = encodingTable[UTF_8_ENC];
-                return XML_TOK_BOM;
-            }
-            break;
-        default:
-            if (ptr[0] == '\0') {
-                /* 0 isn't a legal data character. Furthermore a document entity can only
-                   start with ASCII characters.  So the only way this can fail to be big-endian
-                   UTF-16 if it it's an external parsed general entity that's labelled as
-                   UTF-16LE. */
-                if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
-                    break;
-                *encPtr = encodingTable[UTF_16BE_ENC];
-                return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
-            }
-            else if (ptr[1] == '\0') {
-                /* We could recover here in the case:
-                    - parsing an external entity
-                    - second byte is 0
-                    - no externally specified encoding
-                    - no encoding declaration
-                   by assuming UTF-16LE.  But we don't, because this would mean when
-                   presented just with a single byte, we couldn't reliably determine
-                   whether we needed further bytes. */
-                if (state == XML_CONTENT_STATE)
-                    break;
-                *encPtr = encodingTable[UTF_16LE_ENC];
-                return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
-            }
-            break;
-        }
-    }
-    *encPtr = encodingTable[(int)INIT_ENC_INDEX(enc)];
-    return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
-}
-
-
-#define NS(x) x
-#define ns(x) x
-#include "xmltok_ns.c"
-#undef NS
-#undef ns
-
-#ifdef XML_NS
-
-#define NS(x) x ## NS
-#define ns(x) x ## _ns
-
-#include "xmltok_ns.c"
-
-#undef NS
-#undef ns
-
-ENCODING *
-XmlInitUnknownEncodingNS(void *mem,
-                         int *table,
-                         int (*convert)(void *userData, const char *p),
-                         void *userData)
-{
-    ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
-    if (enc)
-        ((struct normal_encoding *)enc)->type[':'] = BT_COLON;
-    return enc;
-}
-
-#endif /* XML_NS */
--- a/src/protocols/jabber/xmltok.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,307 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-#ifndef XmlTok_INCLUDED
-#define XmlTok_INCLUDED 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef XMLTOKAPI
-#define XMLTOKAPI /* as nothing */
-#endif
-
-/* The following token may be returned by XmlContentTok */
-#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of
-                                    illegal ]]> sequence */
-/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
-#define XML_TOK_NONE -4    /* The string to be scanned is empty */
-#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
-                                  might be part of CRLF sequence */ 
-#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
-#define XML_TOK_PARTIAL -1 /* only part of a token */
-#define XML_TOK_INVALID 0
-
-/* The following tokens are returned by XmlContentTok; some are also
-  returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */
-
-#define XML_TOK_START_TAG_WITH_ATTS 1
-#define XML_TOK_START_TAG_NO_ATTS 2
-#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
-#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
-#define XML_TOK_END_TAG 5
-#define XML_TOK_DATA_CHARS 6
-#define XML_TOK_DATA_NEWLINE 7
-#define XML_TOK_CDATA_SECT_OPEN 8
-#define XML_TOK_ENTITY_REF 9
-#define XML_TOK_CHAR_REF 10     /* numeric character reference */
-
-/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
-#define XML_TOK_PI 11      /* processing instruction */
-#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
-#define XML_TOK_COMMENT 13
-#define XML_TOK_BOM 14     /* Byte order mark */
-
-/* The following tokens are returned only by XmlPrologTok */
-#define XML_TOK_PROLOG_S 15
-#define XML_TOK_DECL_OPEN 16 /* <!foo */
-#define XML_TOK_DECL_CLOSE 17 /* > */
-#define XML_TOK_NAME 18
-#define XML_TOK_NMTOKEN 19
-#define XML_TOK_POUND_NAME 20 /* #name */
-#define XML_TOK_OR 21 /* | */
-#define XML_TOK_PERCENT 22
-#define XML_TOK_OPEN_PAREN 23
-#define XML_TOK_CLOSE_PAREN 24
-#define XML_TOK_OPEN_BRACKET 25
-#define XML_TOK_CLOSE_BRACKET 26
-#define XML_TOK_LITERAL 27
-#define XML_TOK_PARAM_ENTITY_REF 28
-#define XML_TOK_INSTANCE_START 29
-
-/* The following occur only in element type declarations */
-#define XML_TOK_NAME_QUESTION 30 /* name? */
-#define XML_TOK_NAME_ASTERISK 31 /* name* */
-#define XML_TOK_NAME_PLUS 32 /* name+ */
-#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
-#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
-#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
-#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
-#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
-#define XML_TOK_COMMA 38
-
-/* The following token is returned only by XmlAttributeValueTok */
-#define XML_TOK_ATTRIBUTE_VALUE_S 39
-
-/* The following token is returned only by XmlCdataSectionTok */
-#define XML_TOK_CDATA_SECT_CLOSE 40
-
-/* With namespace processing this is returned by XmlPrologTok
-   for a name with a colon. */
-#define XML_TOK_PREFIXED_NAME 41
-
-#define XML_N_STATES 3
-#define XML_PROLOG_STATE 0
-#define XML_CONTENT_STATE 1
-#define XML_CDATA_SECTION_STATE 2
-
-#define XML_N_LITERAL_TYPES 2
-#define XML_ATTRIBUTE_VALUE_LITERAL 0
-#define XML_ENTITY_VALUE_LITERAL 1
-
-/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
-#define XML_UTF8_ENCODE_MAX 4
-/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
-#define XML_UTF16_ENCODE_MAX 2
-
-typedef struct position {
-  /* first line and first column are 0 not 1 */
-  unsigned long lineNumber;
-  unsigned long columnNumber;
-} POSITION;
-
-typedef struct {
-  const char *name;
-  const char *valuePtr;
-  const char *valueEnd;
-  char normalized;
-} ATTRIBUTE;
-
-struct encoding;
-typedef struct encoding ENCODING;
-
-struct encoding {
-  int (*scanners[XML_N_STATES])(const ENCODING *,
-			        const char *,
-			        const char *,
-			        const char **);
-  int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *,
-					      const char *,
-					      const char *,
-					      const char **);
-  int (*sameName)(const ENCODING *,
-	          const char *, const char *);
-  int (*nameMatchesAscii)(const ENCODING *,
-			  const char *, const char *);
-  int (*nameLength)(const ENCODING *, const char *);
-  const char *(*skipS)(const ENCODING *, const char *);
-  int (*getAtts)(const ENCODING *enc, const char *ptr,
-	         int attsMax, ATTRIBUTE *atts);
-  int (*charRefNumber)(const ENCODING *enc, const char *ptr);
-  int (*predefinedEntityName)(const ENCODING *, const char *, const char *);
-  void (*updatePosition)(const ENCODING *,
-			 const char *ptr,
-			 const char *end,
-			 POSITION *);
-  int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
-		    const char **badPtr);
-  void (*utf8Convert)(const ENCODING *enc,
-		      const char **fromP,
-		      const char *fromLim,
-		      char **toP,
-		      const char *toLim);
-  void (*utf16Convert)(const ENCODING *enc,
-		       const char **fromP,
-		       const char *fromLim,
-		       unsigned short **toP,
-		       const unsigned short *toLim);
-  int minBytesPerChar;
-  char isUtf8;
-  char isUtf16;
-};
-
-/*
-Scan the string starting at ptr until the end of the next complete token,
-but do not scan past eptr.  Return an integer giving the type of token.
-
-Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
-
-Return XML_TOK_PARTIAL when the string does not contain a complete token;
-nextTokPtr will not be set.
-
-Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr
-will be set to point to the character which made the token invalid.
-
-Otherwise the string starts with a valid token; nextTokPtr will be set to point
-to the character following the end of that token.
-
-Each data character counts as a single token, but adjacent data characters
-may be returned together.  Similarly for characters in the prolog outside
-literals, comments and processing instructions.
-*/
-
-
-#define XmlTok(enc, state, ptr, end, nextTokPtr) \
-  (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
-
-#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
-   XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
-
-#define XmlContentTok(enc, ptr, end, nextTokPtr) \
-   XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
-
-#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
-   XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
-
-/* This is used for performing a 2nd-level tokenization on
-the content of a literal that has already been returned by XmlTok. */ 
-
-#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
-  (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
-
-#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
-   XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
-
-#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
-   XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
-
-#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
-
-#define XmlNameMatchesAscii(enc, ptr1, ptr2) \
-  (((enc)->nameMatchesAscii)(enc, ptr1, ptr2))
-
-#define XmlNameLength(enc, ptr) \
-  (((enc)->nameLength)(enc, ptr))
-
-#define XmlSkipS(enc, ptr) \
-  (((enc)->skipS)(enc, ptr))
-
-#define XmlGetAttributes(enc, ptr, attsMax, atts) \
-  (((enc)->getAtts)(enc, ptr, attsMax, atts))
-
-#define XmlCharRefNumber(enc, ptr) \
-  (((enc)->charRefNumber)(enc, ptr))
-
-#define XmlPredefinedEntityName(enc, ptr, end) \
-  (((enc)->predefinedEntityName)(enc, ptr, end))
-
-#define XmlUpdatePosition(enc, ptr, end, pos) \
-  (((enc)->updatePosition)(enc, ptr, end, pos))
-
-#define XmlIsPublicId(enc, ptr, end, badPtr) \
-  (((enc)->isPublicId)(enc, ptr, end, badPtr))
-
-#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
-  (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
-
-#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
-  (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
-
-typedef struct {
-  ENCODING initEnc;
-  const ENCODING **encPtr;
-} INIT_ENCODING;
-
-int XMLTOKAPI XmlParseXmlDecl(int isGeneralTextEntity,
-			      const ENCODING *enc,
-			      const char *ptr,
-	  		      const char *end,
-			      const char **badPtr,
-			      const char **versionPtr,
-			      const char **encodingNamePtr,
-			      const ENCODING **namedEncodingPtr,
-			      int *standalonePtr);
-
-int XMLTOKAPI XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
-const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncoding();
-const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncoding();
-int XMLTOKAPI XmlUtf8Encode(int charNumber, char *buf);
-int XMLTOKAPI XmlUtf16Encode(int charNumber, unsigned short *buf);
-
-int XMLTOKAPI XmlSizeOfUnknownEncoding();
-ENCODING XMLTOKAPI *
-XmlInitUnknownEncoding(void *mem,
-		       int *table,
-		       int (*conv)(void *userData, const char *p),
-		       void *userData);
-
-int XMLTOKAPI XmlParseXmlDeclNS(int isGeneralTextEntity,
-			        const ENCODING *enc,
-			        const char *ptr,
-	  		        const char *end,
-			        const char **badPtr,
-			        const char **versionPtr,
-			        const char **encodingNamePtr,
-			        const ENCODING **namedEncodingPtr,
-			        int *standalonePtr);
-int XMLTOKAPI XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
-const ENCODING XMLTOKAPI *XmlGetUtf8InternalEncodingNS();
-const ENCODING XMLTOKAPI *XmlGetUtf16InternalEncodingNS();
-ENCODING XMLTOKAPI *
-XmlInitUnknownEncodingNS(void *mem,
-		         int *table,
-		         int (*conv)(void *userData, const char *p),
-		         void *userData);
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* not XmlTok_INCLUDED */
--- a/src/protocols/jabber/xmltok_impl.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1737 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-*/
-
-#ifndef IS_INVALID_CHAR
-#define IS_INVALID_CHAR(enc, ptr, n) (0)
-#endif
-
-#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
-    case BT_LEAD ## n: \
-      if (end - ptr < n) \
-    return XML_TOK_PARTIAL_CHAR; \
-      if (IS_INVALID_CHAR(enc, ptr, n)) { \
-        *(nextTokPtr) = (ptr); \
-        return XML_TOK_INVALID; \
-      } \
-      ptr += n; \
-      break;
-
-#define INVALID_CASES(ptr, nextTokPtr) \
-  INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
-  INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
-  INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
-  case BT_NONXML: \
-  case BT_MALFORM: \
-  case BT_TRAIL: \
-    *(nextTokPtr) = (ptr); \
-    return XML_TOK_INVALID;
-
-#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
-   case BT_LEAD ## n: \
-     if (end - ptr < n) \
-       return XML_TOK_PARTIAL_CHAR; \
-     if (!IS_NAME_CHAR(enc, ptr, n)) { \
-       *nextTokPtr = ptr; \
-       return XML_TOK_INVALID; \
-     } \
-     ptr += n; \
-     break;
-
-#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
-  case BT_NONASCII: \
-    if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
-      *nextTokPtr = ptr; \
-      return XML_TOK_INVALID; \
-    } \
-  case BT_NMSTRT: \
-  case BT_HEX: \
-  case BT_DIGIT: \
-  case BT_NAME: \
-  case BT_MINUS: \
-    ptr += MINBPC(enc); \
-    break; \
-  CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
-  CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
-  CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
-
-#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
-   case BT_LEAD ## n: \
-     if (end - ptr < n) \
-       return XML_TOK_PARTIAL_CHAR; \
-     if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
-       *nextTokPtr = ptr; \
-       return XML_TOK_INVALID; \
-     } \
-     ptr += n; \
-     break;
-
-#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
-  case BT_NONASCII: \
-    if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
-      *nextTokPtr = ptr; \
-      return XML_TOK_INVALID; \
-    } \
-  case BT_NMSTRT: \
-  case BT_HEX: \
-    ptr += MINBPC(enc); \
-    break; \
-  CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
-  CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
-  CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
-
-#ifndef PREFIX
-#define PREFIX(ident) ident
-#endif
-
-/* ptr points to character following "<!-" */
-
-static
-int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end,
-                        const char **nextTokPtr)
-{
-    if (ptr != end) {
-        if (!CHAR_MATCHES(enc, ptr, '-')) {
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-        ptr += MINBPC(enc);
-        while (ptr != end) {
-            switch (BYTE_TYPE(enc, ptr)) {
-                INVALID_CASES(ptr, nextTokPtr)
-            case BT_MINUS:
-                if ((ptr += MINBPC(enc)) == end)
-                    return XML_TOK_PARTIAL;
-                if (CHAR_MATCHES(enc, ptr, '-')) {
-                    if ((ptr += MINBPC(enc)) == end)
-                        return XML_TOK_PARTIAL;
-                    if (!CHAR_MATCHES(enc, ptr, '>')) {
-                        *nextTokPtr = ptr;
-                        return XML_TOK_INVALID;
-                    }
-                    *nextTokPtr = ptr + MINBPC(enc);
-                    return XML_TOK_COMMENT;
-                }
-                break;
-            default:
-                ptr += MINBPC(enc);
-                break;
-            }
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "<!" */
-
-static
-int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end,
-                     const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-    case BT_MINUS:
-        return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_LSQB:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_COND_SECT_OPEN;
-    case BT_NMSTRT:
-    case BT_HEX:
-        ptr += MINBPC(enc);
-        break;
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_PERCNT:
-            if (ptr + MINBPC(enc) == end)
-                return XML_TOK_PARTIAL;
-            /* don't allow <!ENTITY% foo "whatever"> */
-            switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
-case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            /* fall through */
-case BT_S: case BT_CR: case BT_LF:
-            *nextTokPtr = ptr;
-            return XML_TOK_DECL_OPEN;
-        case BT_NMSTRT:
-        case BT_HEX:
-            ptr += MINBPC(enc);
-            break;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-static
-int PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, int *tokPtr)
-{
-    int upper = 0;
-    *tokPtr = XML_TOK_PI;
-    if (end - ptr != MINBPC(enc)*3)
-        return 1;
-    switch (BYTE_TO_ASCII(enc, ptr)) {
-    case 'x':
-        break;
-    case 'X':
-        upper = 1;
-        break;
-    default:
-        return 1;
-    }
-    ptr += MINBPC(enc);
-    switch (BYTE_TO_ASCII(enc, ptr)) {
-    case 'm':
-        break;
-    case 'M':
-        upper = 1;
-        break;
-    default:
-        return 1;
-    }
-    ptr += MINBPC(enc);
-    switch (BYTE_TO_ASCII(enc, ptr)) {
-    case 'l':
-        break;
-    case 'L':
-        upper = 1;
-        break;
-    default:
-        return 1;
-    }
-    if (upper)
-        return 0;
-    *tokPtr = XML_TOK_XML_DECL;
-    return 1;
-}
-
-/* ptr points to character following "<?" */
-
-static
-int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end,
-                   const char **nextTokPtr)
-{
-    int tok;
-    const char *target = ptr;
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-case BT_S: case BT_CR: case BT_LF:
-            if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            ptr += MINBPC(enc);
-            while (ptr != end) {
-                switch (BYTE_TYPE(enc, ptr)) {
-                    INVALID_CASES(ptr, nextTokPtr)
-                case BT_QUEST:
-                    ptr += MINBPC(enc);
-                    if (ptr == end)
-                        return XML_TOK_PARTIAL;
-                    if (CHAR_MATCHES(enc, ptr, '>')) {
-                        *nextTokPtr = ptr + MINBPC(enc);
-                        return tok;
-                    }
-                    break;
-                default:
-                    ptr += MINBPC(enc);
-                    break;
-                }
-            }
-            return XML_TOK_PARTIAL;
-        case BT_QUEST:
-            if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            ptr += MINBPC(enc);
-            if (ptr == end)
-                return XML_TOK_PARTIAL;
-            if (CHAR_MATCHES(enc, ptr, '>')) {
-                *nextTokPtr = ptr + MINBPC(enc);
-                return tok;
-            }
-            /* fall through */
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-
-static
-int PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end,
-                             const char **nextTokPtr)
-{
-    int i;
-    /* CDATA[ */
-    if (end - ptr < 6 * MINBPC(enc))
-        return XML_TOK_PARTIAL;
-    for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
-        if (!CHAR_MATCHES(enc, ptr, "CDATA["[i])) {
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    *nextTokPtr = ptr;
-    return XML_TOK_CDATA_SECT_OPEN;
-}
-
-static
-int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
-                            const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_NONE;
-    if (MINBPC(enc) > 1) {
-        size_t n = end - ptr;
-        if (n & (MINBPC(enc) - 1)) {
-            n &= ~(MINBPC(enc) - 1);
-            if (n == 0)
-                return XML_TOK_PARTIAL;
-            end = ptr + n;
-        }
-    }
-    switch (BYTE_TYPE(enc, ptr)) {
-    case BT_RSQB:
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_PARTIAL;
-        if (!CHAR_MATCHES(enc, ptr, ']'))
-            break;
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_PARTIAL;
-        if (!CHAR_MATCHES(enc, ptr, '>')) {
-            ptr -= MINBPC(enc);
-            break;
-        }
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_CDATA_SECT_CLOSE;
-    case BT_CR:
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_PARTIAL;
-        if (BYTE_TYPE(enc, ptr) == BT_LF)
-            ptr += MINBPC(enc);
-        *nextTokPtr = ptr;
-        return XML_TOK_DATA_NEWLINE;
-    case BT_LF:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_DATA_NEWLINE;
-        INVALID_CASES(ptr, nextTokPtr)
-    default:
-        ptr += MINBPC(enc);
-        break;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: \
-      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
-    *nextTokPtr = ptr; \
-    return XML_TOK_DATA_CHARS; \
-      } \
-      ptr += n; \
-      break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_NONXML:
-        case BT_MALFORM:
-        case BT_TRAIL:
-        case BT_CR:
-        case BT_LF:
-        case BT_RSQB:
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        default:
-            ptr += MINBPC(enc);
-            break;
-        }
-    }
-    *nextTokPtr = ptr;
-    return XML_TOK_DATA_CHARS;
-}
-
-/* ptr points to character following "</" */
-
-static
-int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end,
-                       const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-case BT_S: case BT_CR: case BT_LF:
-            for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
-                switch (BYTE_TYPE(enc, ptr)) {
-        case BT_S: case BT_CR: case BT_LF:
-                    break;
-                case BT_GT:
-                    *nextTokPtr = ptr + MINBPC(enc);
-                    return XML_TOK_END_TAG;
-                default:
-                    *nextTokPtr = ptr;
-                    return XML_TOK_INVALID;
-                }
-            }
-            return XML_TOK_PARTIAL;
-#ifdef XML_NS
-        case BT_COLON:
-            /* no need to check qname syntax here, since end-tag must match exactly */
-            ptr += MINBPC(enc);
-            break;
-#endif
-        case BT_GT:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_END_TAG;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "&#X" */
-
-static
-int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end,
-                           const char **nextTokPtr)
-{
-    if (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_DIGIT:
-        case BT_HEX:
-            break;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-        for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
-            switch (BYTE_TYPE(enc, ptr)) {
-            case BT_DIGIT:
-            case BT_HEX:
-                break;
-            case BT_SEMI:
-                *nextTokPtr = ptr + MINBPC(enc);
-                return XML_TOK_CHAR_REF;
-            default:
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "&#" */
-
-static
-int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end,
-                        const char **nextTokPtr)
-{
-    if (ptr != end) {
-        if (CHAR_MATCHES(enc, ptr, 'x'))
-            return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_DIGIT:
-            break;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-        for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
-            switch (BYTE_TYPE(enc, ptr)) {
-            case BT_DIGIT:
-                break;
-            case BT_SEMI:
-                *nextTokPtr = ptr + MINBPC(enc);
-                return XML_TOK_CHAR_REF;
-            default:
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "&" */
-
-static
-int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
-                    const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-    case BT_NUM:
-        return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-        case BT_SEMI:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_ENTITY_REF;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following first character of attribute name */
-
-static
-int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
-                     const char **nextTokPtr)
-{
-#ifdef XML_NS
-    int hadColon = 0;
-#endif
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-#ifdef XML_NS
-        case BT_COLON:
-            if (hadColon) {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            hadColon = 1;
-            ptr += MINBPC(enc);
-            if (ptr == end)
-                return XML_TOK_PARTIAL;
-            switch (BYTE_TYPE(enc, ptr)) {
-                CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-            default:
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            break;
-#endif
-case BT_S: case BT_CR: case BT_LF:
-            for (;;) {
-                int t;
-
-                ptr += MINBPC(enc);
-                if (ptr == end)
-                    return XML_TOK_PARTIAL;
-                t = BYTE_TYPE(enc, ptr);
-                if (t == BT_EQUALS)
-                    break;
-                switch (t) {
-                case BT_S:
-                case BT_LF:
-                case BT_CR:
-                    break;
-                default:
-                    *nextTokPtr = ptr;
-                    return XML_TOK_INVALID;
-                }
-            }
-            /* fall through */
-        case BT_EQUALS:
-            {
-                int open;
-#ifdef XML_NS
-                hadColon = 0;
-#endif
-                for (;;) {
-
-                    ptr += MINBPC(enc);
-                    if (ptr == end)
-                        return XML_TOK_PARTIAL;
-                    open = BYTE_TYPE(enc, ptr);
-                    if (open == BT_QUOT || open == BT_APOS)
-                        break;
-                    switch (open) {
-                    case BT_S:
-                    case BT_LF:
-                    case BT_CR:
-                        break;
-                    default:
-                        *nextTokPtr = ptr;
-                        return XML_TOK_INVALID;
-                    }
-                }
-                ptr += MINBPC(enc);
-                /* in attribute value */
-                for (;;) {
-                    int t;
-                    if (ptr == end)
-                        return XML_TOK_PARTIAL;
-                    t = BYTE_TYPE(enc, ptr);
-                    if (t == open)
-                        break;
-                    switch (t) {
-                        INVALID_CASES(ptr, nextTokPtr)
-                    case BT_AMP:
-                        {
-                            int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
-                            if (tok <= 0) {
-                                if (tok == XML_TOK_INVALID)
-                                    *nextTokPtr = ptr;
-                                return tok;
-                            }
-                            break;
-                        }
-                    case BT_LT:
-                        *nextTokPtr = ptr;
-                        return XML_TOK_INVALID;
-                    default:
-                        ptr += MINBPC(enc);
-                        break;
-                    }
-                }
-                ptr += MINBPC(enc);
-                if (ptr == end)
-                    return XML_TOK_PARTIAL;
-                switch (BYTE_TYPE(enc, ptr)) {
-                case BT_S:
-                case BT_CR:
-                case BT_LF:
-                    break;
-                case BT_SOL:
-                    goto sol;
-                case BT_GT:
-                    goto gt;
-                default:
-                    *nextTokPtr = ptr;
-                    return XML_TOK_INVALID;
-                }
-                /* ptr points to closing quote */
-                for (;;) {
-                    ptr += MINBPC(enc);
-                    if (ptr == end)
-                        return XML_TOK_PARTIAL;
-                    switch (BYTE_TYPE(enc, ptr)) {
-                        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-            case BT_S: case BT_CR: case BT_LF:
-                        continue;
-                    case BT_GT:
-gt:
-                        *nextTokPtr = ptr + MINBPC(enc);
-                        return XML_TOK_START_TAG_WITH_ATTS;
-                    case BT_SOL:
-sol:
-                        ptr += MINBPC(enc);
-                        if (ptr == end)
-                            return XML_TOK_PARTIAL;
-                        if (!CHAR_MATCHES(enc, ptr, '>')) {
-                            *nextTokPtr = ptr;
-                            return XML_TOK_INVALID;
-                        }
-                        *nextTokPtr = ptr + MINBPC(enc);
-                        return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
-                    default:
-                        *nextTokPtr = ptr;
-                        return XML_TOK_INVALID;
-                    }
-                    break;
-                }
-                break;
-            }
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-/* ptr points to character following "<" */
-
-static
-int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
-                   const char **nextTokPtr)
-{
-#ifdef XML_NS
-    int hadColon;
-#endif
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-    case BT_EXCL:
-        if ((ptr += MINBPC(enc)) == end)
-            return XML_TOK_PARTIAL;
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_MINUS:
-            return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-        case BT_LSQB:
-            return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-        }
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    case BT_QUEST:
-        return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_SOL:
-        return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-#ifdef XML_NS
-    hadColon = 0;
-#endif
-    /* we have a start-tag */
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-#ifdef XML_NS
-        case BT_COLON:
-            if (hadColon) {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            hadColon = 1;
-            ptr += MINBPC(enc);
-            if (ptr == end)
-                return XML_TOK_PARTIAL;
-            switch (BYTE_TYPE(enc, ptr)) {
-                CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-            default:
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            break;
-#endif
-case BT_S: case BT_CR: case BT_LF:
-            {
-                ptr += MINBPC(enc);
-                while (ptr != end) {
-                    switch (BYTE_TYPE(enc, ptr)) {
-                        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-                    case BT_GT:
-                        goto gt;
-                    case BT_SOL:
-                        goto sol;
-            case BT_S: case BT_CR: case BT_LF:
-                        ptr += MINBPC(enc);
-                        continue;
-                    default:
-                        *nextTokPtr = ptr;
-                        return XML_TOK_INVALID;
-                    }
-                    return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
-                }
-                return XML_TOK_PARTIAL;
-            }
-        case BT_GT:
-gt:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_START_TAG_NO_ATTS;
-        case BT_SOL:
-sol:
-            ptr += MINBPC(enc);
-            if (ptr == end)
-                return XML_TOK_PARTIAL;
-            if (!CHAR_MATCHES(enc, ptr, '>')) {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-static
-int PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
-                       const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_NONE;
-    if (MINBPC(enc) > 1) {
-        size_t n = end - ptr;
-        if (n & (MINBPC(enc) - 1)) {
-            n &= ~(MINBPC(enc) - 1);
-            if (n == 0)
-                return XML_TOK_PARTIAL;
-            end = ptr + n;
-        }
-    }
-    switch (BYTE_TYPE(enc, ptr)) {
-    case BT_LT:
-        return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_AMP:
-        return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_CR:
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_TRAILING_CR;
-        if (BYTE_TYPE(enc, ptr) == BT_LF)
-            ptr += MINBPC(enc);
-        *nextTokPtr = ptr;
-        return XML_TOK_DATA_NEWLINE;
-    case BT_LF:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_DATA_NEWLINE;
-    case BT_RSQB:
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_TRAILING_RSQB;
-        if (!CHAR_MATCHES(enc, ptr, ']'))
-            break;
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_TRAILING_RSQB;
-        if (!CHAR_MATCHES(enc, ptr, '>')) {
-            ptr -= MINBPC(enc);
-            break;
-        }
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-        INVALID_CASES(ptr, nextTokPtr)
-    default:
-        ptr += MINBPC(enc);
-        break;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: \
-      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
-    *nextTokPtr = ptr; \
-    return XML_TOK_DATA_CHARS; \
-      } \
-      ptr += n; \
-      break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_RSQB:
-            if (ptr + MINBPC(enc) != end) {
-                if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ']')) {
-                    ptr += MINBPC(enc);
-                    break;
-                }
-                if (ptr + 2*MINBPC(enc) != end) {
-                    if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), '>')) {
-                        ptr += MINBPC(enc);
-                        break;
-                    }
-                    *nextTokPtr = ptr + 2*MINBPC(enc);
-                    return XML_TOK_INVALID;
-                }
-            }
-            /* fall through */
-        case BT_AMP:
-        case BT_LT:
-        case BT_NONXML:
-        case BT_MALFORM:
-        case BT_TRAIL:
-        case BT_CR:
-        case BT_LF:
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        default:
-            ptr += MINBPC(enc);
-            break;
-        }
-    }
-    *nextTokPtr = ptr;
-    return XML_TOK_DATA_CHARS;
-}
-
-/* ptr points to character following "%" */
-
-static
-int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
-                        const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
-        *nextTokPtr = ptr;
-        return XML_TOK_PERCENT;
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-        case BT_SEMI:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_PARAM_ENTITY_REF;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-static
-int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
-                          const char **nextTokPtr)
-{
-    if (ptr == end)
-        return XML_TOK_PARTIAL;
-    switch (BYTE_TYPE(enc, ptr)) {
-        CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-case BT_CR: case BT_LF: case BT_S:
-case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
-            *nextTokPtr = ptr;
-            return XML_TOK_POUND_NAME;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-static
-int PREFIX(scanLit)(int open, const ENCODING *enc,
-                    const char *ptr, const char *end,
-                    const char **nextTokPtr)
-{
-    while (ptr != end) {
-        int t = BYTE_TYPE(enc, ptr);
-        switch (t) {
-            INVALID_CASES(ptr, nextTokPtr)
-        case BT_QUOT:
-        case BT_APOS:
-            ptr += MINBPC(enc);
-            if (t != open)
-                break;
-            if (ptr == end)
-                return XML_TOK_PARTIAL;
-            *nextTokPtr = ptr;
-            switch (BYTE_TYPE(enc, ptr)) {
-    case BT_S: case BT_CR: case BT_LF:
-    case BT_GT: case BT_PERCNT: case BT_LSQB:
-                return XML_TOK_LITERAL;
-            default:
-                return XML_TOK_INVALID;
-            }
-        default:
-            ptr += MINBPC(enc);
-            break;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-static
-int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
-                      const char **nextTokPtr)
-{
-    int tok;
-    if (ptr == end)
-        return XML_TOK_NONE;
-    if (MINBPC(enc) > 1) {
-        size_t n = end - ptr;
-        if (n & (MINBPC(enc) - 1)) {
-            n &= ~(MINBPC(enc) - 1);
-            if (n == 0)
-                return XML_TOK_PARTIAL;
-            end = ptr + n;
-        }
-    }
-    switch (BYTE_TYPE(enc, ptr)) {
-    case BT_QUOT:
-        return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_APOS:
-        return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_LT:
-        {
-            ptr += MINBPC(enc);
-            if (ptr == end)
-                return XML_TOK_PARTIAL;
-            switch (BYTE_TYPE(enc, ptr)) {
-            case BT_EXCL:
-                return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-            case BT_QUEST:
-                return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-            case BT_NMSTRT:
-            case BT_HEX:
-            case BT_NONASCII:
-            case BT_LEAD2:
-            case BT_LEAD3:
-            case BT_LEAD4:
-                *nextTokPtr = ptr - MINBPC(enc);
-                return XML_TOK_INSTANCE_START;
-            }
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    case BT_CR:
-        if (ptr + MINBPC(enc) == end)
-            return XML_TOK_TRAILING_CR;
-        /* fall through */
-case BT_S: case BT_LF:
-        for (;;) {
-            ptr += MINBPC(enc);
-            if (ptr == end)
-                break;
-            switch (BYTE_TYPE(enc, ptr)) {
-        case BT_S: case BT_LF:
-                break;
-            case BT_CR:
-                /* don't split CR/LF pair */
-                if (ptr + MINBPC(enc) != end)
-                    break;
-                /* fall through */
-            default:
-                *nextTokPtr = ptr;
-                return XML_TOK_PROLOG_S;
-            }
-        }
-        *nextTokPtr = ptr;
-        return XML_TOK_PROLOG_S;
-    case BT_PERCNT:
-        return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-    case BT_COMMA:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_COMMA;
-    case BT_LSQB:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_OPEN_BRACKET;
-    case BT_RSQB:
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_PARTIAL;
-        if (CHAR_MATCHES(enc, ptr, ']')) {
-            if (ptr + MINBPC(enc) == end)
-                return XML_TOK_PARTIAL;
-            if (CHAR_MATCHES(enc, ptr + MINBPC(enc), '>')) {
-                *nextTokPtr = ptr + 2*MINBPC(enc);
-                return XML_TOK_COND_SECT_CLOSE;
-            }
-        }
-        *nextTokPtr = ptr;
-        return XML_TOK_CLOSE_BRACKET;
-    case BT_LPAR:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_OPEN_PAREN;
-    case BT_RPAR:
-        ptr += MINBPC(enc);
-        if (ptr == end)
-            return XML_TOK_PARTIAL;
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_AST:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_CLOSE_PAREN_ASTERISK;
-        case BT_QUEST:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_CLOSE_PAREN_QUESTION;
-        case BT_PLUS:
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_CLOSE_PAREN_PLUS;
-case BT_CR: case BT_LF: case BT_S:
-case BT_GT: case BT_COMMA: case BT_VERBAR:
-        case BT_RPAR:
-            *nextTokPtr = ptr;
-            return XML_TOK_CLOSE_PAREN;
-        }
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    case BT_VERBAR:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_OR;
-    case BT_GT:
-        *nextTokPtr = ptr + MINBPC(enc);
-        return XML_TOK_DECL_CLOSE;
-    case BT_NUM:
-        return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-#define LEAD_CASE(n) \
-  case BT_LEAD ## n: \
-    if (end - ptr < n) \
-      return XML_TOK_PARTIAL_CHAR; \
-    if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
-      ptr += n; \
-      tok = XML_TOK_NAME; \
-      break; \
-    } \
-    if (IS_NAME_CHAR(enc, ptr, n)) { \
-      ptr += n; \
-      tok = XML_TOK_NMTOKEN; \
-      break; \
-    } \
-    *nextTokPtr = ptr; \
-    return XML_TOK_INVALID;
-        LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-    case BT_NMSTRT:
-    case BT_HEX:
-        tok = XML_TOK_NAME;
-        ptr += MINBPC(enc);
-        break;
-    case BT_DIGIT:
-    case BT_NAME:
-    case BT_MINUS:
-#ifdef XML_NS
-    case BT_COLON:
-#endif
-        tok = XML_TOK_NMTOKEN;
-        ptr += MINBPC(enc);
-        break;
-    case BT_NONASCII:
-        if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
-            ptr += MINBPC(enc);
-            tok = XML_TOK_NAME;
-            break;
-        }
-        if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
-            ptr += MINBPC(enc);
-            tok = XML_TOK_NMTOKEN;
-            break;
-        }
-        /* fall through */
-    default:
-        *nextTokPtr = ptr;
-        return XML_TOK_INVALID;
-    }
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-            CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-case BT_GT: case BT_RPAR: case BT_COMMA:
-case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
-case BT_S: case BT_CR: case BT_LF:
-            *nextTokPtr = ptr;
-            return tok;
-#ifdef XML_NS
-        case BT_COLON:
-            ptr += MINBPC(enc);
-            switch (tok) {
-            case XML_TOK_NAME:
-                if (ptr == end)
-                    return XML_TOK_PARTIAL;
-                tok = XML_TOK_PREFIXED_NAME;
-                switch (BYTE_TYPE(enc, ptr)) {
-                    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
-                default:
-                    tok = XML_TOK_NMTOKEN;
-                    break;
-                }
-                break;
-            case XML_TOK_PREFIXED_NAME:
-                tok = XML_TOK_NMTOKEN;
-                break;
-            }
-            break;
-#endif
-        case BT_PLUS:
-            if (tok == XML_TOK_NMTOKEN)  {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_NAME_PLUS;
-        case BT_AST:
-            if (tok == XML_TOK_NMTOKEN)  {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_NAME_ASTERISK;
-        case BT_QUEST:
-            if (tok == XML_TOK_NMTOKEN)  {
-                *nextTokPtr = ptr;
-                return XML_TOK_INVALID;
-            }
-            *nextTokPtr = ptr + MINBPC(enc);
-            return XML_TOK_NAME_QUESTION;
-        default:
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        }
-    }
-    return XML_TOK_PARTIAL;
-}
-
-static
-int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end,
-                              const char **nextTokPtr)
-{
-    const char *start;
-    if (ptr == end)
-        return XML_TOK_NONE;
-    start = ptr;
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: ptr += n; break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_AMP:
-            if (ptr == start)
-                return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        case BT_LT:
-            /* this is for inside entity references */
-            *nextTokPtr = ptr;
-            return XML_TOK_INVALID;
-        case BT_LF:
-            if (ptr == start) {
-                *nextTokPtr = ptr + MINBPC(enc);
-                return XML_TOK_DATA_NEWLINE;
-            }
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        case BT_CR:
-            if (ptr == start) {
-                ptr += MINBPC(enc);
-                if (ptr == end)
-                    return XML_TOK_TRAILING_CR;
-                if (BYTE_TYPE(enc, ptr) == BT_LF)
-                    ptr += MINBPC(enc);
-                *nextTokPtr = ptr;
-                return XML_TOK_DATA_NEWLINE;
-            }
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        case BT_S:
-            if (ptr == start) {
-                *nextTokPtr = ptr + MINBPC(enc);
-                return XML_TOK_ATTRIBUTE_VALUE_S;
-            }
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        default:
-            ptr += MINBPC(enc);
-            break;
-        }
-    }
-    *nextTokPtr = ptr;
-    return XML_TOK_DATA_CHARS;
-}
-
-static
-int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end,
-                           const char **nextTokPtr)
-{
-    const char *start;
-    if (ptr == end)
-        return XML_TOK_NONE;
-    start = ptr;
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: ptr += n; break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_AMP:
-            if (ptr == start)
-                return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        case BT_PERCNT:
-            if (ptr == start)
-                return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        case BT_LF:
-            if (ptr == start) {
-                *nextTokPtr = ptr + MINBPC(enc);
-                return XML_TOK_DATA_NEWLINE;
-            }
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        case BT_CR:
-            if (ptr == start) {
-                ptr += MINBPC(enc);
-                if (ptr == end)
-                    return XML_TOK_TRAILING_CR;
-                if (BYTE_TYPE(enc, ptr) == BT_LF)
-                    ptr += MINBPC(enc);
-                *nextTokPtr = ptr;
-                return XML_TOK_DATA_NEWLINE;
-            }
-            *nextTokPtr = ptr;
-            return XML_TOK_DATA_CHARS;
-        default:
-            ptr += MINBPC(enc);
-            break;
-        }
-    }
-    *nextTokPtr = ptr;
-    return XML_TOK_DATA_CHARS;
-}
-
-static
-int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
-                       const char **badPtr)
-{
-    ptr += MINBPC(enc);
-    end -= MINBPC(enc);
-    for (; ptr != end; ptr += MINBPC(enc)) {
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_DIGIT:
-        case BT_HEX:
-        case BT_MINUS:
-        case BT_APOS:
-        case BT_LPAR:
-        case BT_RPAR:
-        case BT_PLUS:
-        case BT_COMMA:
-        case BT_SOL:
-        case BT_EQUALS:
-        case BT_QUEST:
-        case BT_CR:
-        case BT_LF:
-        case BT_SEMI:
-        case BT_EXCL:
-        case BT_AST:
-        case BT_PERCNT:
-        case BT_NUM:
-#ifdef XML_NS
-        case BT_COLON:
-#endif
-            break;
-        case BT_S:
-            if (CHAR_MATCHES(enc, ptr, '\t')) {
-                *badPtr = ptr;
-                return 0;
-            }
-            break;
-        case BT_NAME:
-        case BT_NMSTRT:
-            if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
-                break;
-        default:
-            switch (BYTE_TO_ASCII(enc, ptr)) {
-            case 0x24: /* $ */
-            case 0x40: /* @ */
-                break;
-            default:
-                *badPtr = ptr;
-                return 0;
-            }
-            break;
-        }
-    }
-    return 1;
-}
-
-/* This must only be called for a well-formed start-tag or empty element tag.
-Returns the number of attributes.  Pointers to the first attsMax attributes 
-are stored in atts. */
-
-static
-int PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
-                    int attsMax, ATTRIBUTE *atts)
-{
-    enum { other, inName, inValue } state = inName;
-    int nAtts = 0;
-    int open = 0;
-
-    for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define START_NAME \
-      if (state == other) { \
-    if (nAtts < attsMax) { \
-      atts[nAtts].name = ptr; \
-      atts[nAtts].normalized = 1; \
-    } \
-    state = inName; \
-      }
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_NONASCII:
-        case BT_NMSTRT:
-        case BT_HEX:
-            START_NAME
-            break;
-#undef START_NAME
-        case BT_QUOT:
-            if (state != inValue) {
-                if (nAtts < attsMax)
-                    atts[nAtts].valuePtr = ptr + MINBPC(enc);
-                state = inValue;
-                open = BT_QUOT;
-            }
-            else if (open == BT_QUOT) {
-                state = other;
-                if (nAtts < attsMax)
-                    atts[nAtts].valueEnd = ptr;
-                nAtts++;
-            }
-            break;
-        case BT_APOS:
-            if (state != inValue) {
-                if (nAtts < attsMax)
-                    atts[nAtts].valuePtr = ptr + MINBPC(enc);
-                state = inValue;
-                open = BT_APOS;
-            }
-            else if (open == BT_APOS) {
-                state = other;
-                if (nAtts < attsMax)
-                    atts[nAtts].valueEnd = ptr;
-                nAtts++;
-            }
-            break;
-        case BT_AMP:
-            if (nAtts < attsMax)
-                atts[nAtts].normalized = 0;
-            break;
-        case BT_S:
-            if (state == inName)
-                state = other;
-            else if (state == inValue
-                     && nAtts < attsMax
-                     && atts[nAtts].normalized
-                     && (ptr == atts[nAtts].valuePtr
-                         || BYTE_TO_ASCII(enc, ptr) != ' '
-                         || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ' '
-                         || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
-                atts[nAtts].normalized = 0;
-            break;
-    case BT_CR: case BT_LF:
-            /* This case ensures that the first attribute name is counted
-               Apart from that we could just change state on the quote. */
-            if (state == inName)
-                state = other;
-            else if (state == inValue && nAtts < attsMax)
-                atts[nAtts].normalized = 0;
-            break;
-        case BT_GT:
-        case BT_SOL:
-            if (state != inValue)
-                return nAtts;
-            break;
-        default:
-            break;
-        }
-    }
-    /* not reached */
-}
-
-static
-int PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
-{
-    int result = 0;
-    /* skip &# */
-    ptr += 2*MINBPC(enc);
-    if (CHAR_MATCHES(enc, ptr, 'x')) {
-        for (ptr += MINBPC(enc); !CHAR_MATCHES(enc, ptr, ';'); ptr += MINBPC(enc)) {
-            int c = BYTE_TO_ASCII(enc, ptr);
-            switch (c) {
-case '0': case '1': case '2': case '3': case '4':
-case '5': case '6': case '7': case '8': case '9':
-                result <<= 4;
-                result |= (c - '0');
-                break;
-case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
-                result <<= 4;
-                result += 10 + (c - 'A');
-                break;
-case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
-                result <<= 4;
-                result += 10 + (c - 'a');
-                break;
-            }
-            if (result >= 0x110000)
-                return -1;
-        }
-    }
-    else {
-        for (; !CHAR_MATCHES(enc, ptr, ';'); ptr += MINBPC(enc)) {
-            int c = BYTE_TO_ASCII(enc, ptr);
-            result *= 10;
-            result += (c - '0');
-            if (result >= 0x110000)
-                return -1;
-        }
-    }
-    return checkCharRefNumber(result);
-}
-
-static
-int PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, const char *end)
-{
-    switch ((end - ptr)/MINBPC(enc)) {
-    case 2:
-        if (CHAR_MATCHES(enc, ptr + MINBPC(enc), 't')) {
-            switch (BYTE_TO_ASCII(enc, ptr)) {
-            case 'l':
-                return '<';
-            case 'g':
-                return '>';
-            }
-        }
-        break;
-    case 3:
-        if (CHAR_MATCHES(enc, ptr, 'a')) {
-            ptr += MINBPC(enc);
-            if (CHAR_MATCHES(enc, ptr, 'm')) {
-                ptr += MINBPC(enc);
-                if (CHAR_MATCHES(enc, ptr, 'p'))
-                    return '&';
-            }
-        }
-        break;
-    case 4:
-        switch (BYTE_TO_ASCII(enc, ptr)) {
-        case 'q':
-            ptr += MINBPC(enc);
-            if (CHAR_MATCHES(enc, ptr, 'u')) {
-                ptr += MINBPC(enc);
-                if (CHAR_MATCHES(enc, ptr, 'o')) {
-                    ptr += MINBPC(enc);
-                    if (CHAR_MATCHES(enc, ptr, 't'))
-                        return '"';
-                }
-            }
-            break;
-        case 'a':
-            ptr += MINBPC(enc);
-            if (CHAR_MATCHES(enc, ptr, 'p')) {
-                ptr += MINBPC(enc);
-                if (CHAR_MATCHES(enc, ptr, 'o')) {
-                    ptr += MINBPC(enc);
-                    if (CHAR_MATCHES(enc, ptr, 's'))
-                        return '\'';
-                }
-            }
-            break;
-        }
-    }
-    return 0;
-}
-
-static
-int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
-{
-    for (;;) {
-        switch (BYTE_TYPE(enc, ptr1)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: \
-      if (*ptr1++ != *ptr2++) \
-    return 0;
-            LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
-#undef LEAD_CASE
-            /* fall through */
-            if (*ptr1++ != *ptr2++)
-                return 0;
-            break;
-        case BT_NONASCII:
-        case BT_NMSTRT:
-#ifdef XML_NS
-        case BT_COLON:
-#endif
-        case BT_HEX:
-        case BT_DIGIT:
-        case BT_NAME:
-        case BT_MINUS:
-            if (*ptr2++ != *ptr1++)
-                return 0;
-            if (MINBPC(enc) > 1) {
-                if (*ptr2++ != *ptr1++)
-                    return 0;
-                if (MINBPC(enc) > 2) {
-                    if (*ptr2++ != *ptr1++)
-                        return 0;
-                    if (MINBPC(enc) > 3) {
-                        if (*ptr2++ != *ptr1++)
-                            return 0;
-                    }
-                }
-            }
-            break;
-        default:
-            if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
-                return 1;
-            switch (BYTE_TYPE(enc, ptr2)) {
-            case BT_LEAD2:
-            case BT_LEAD3:
-            case BT_LEAD4:
-            case BT_NONASCII:
-            case BT_NMSTRT:
-#ifdef XML_NS
-            case BT_COLON:
-#endif
-            case BT_HEX:
-            case BT_DIGIT:
-            case BT_NAME:
-            case BT_MINUS:
-                return 0;
-            default:
-                return 1;
-            }
-        }
-    }
-    /* not reached */
-}
-
-static
-int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1, const char *ptr2)
-{
-    for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
-        if (!CHAR_MATCHES(enc, ptr1, *ptr2))
-            return 0;
-    }
-    switch (BYTE_TYPE(enc, ptr1)) {
-    case BT_LEAD2:
-    case BT_LEAD3:
-    case BT_LEAD4:
-    case BT_NONASCII:
-    case BT_NMSTRT:
-#ifdef XML_NS
-    case BT_COLON:
-#endif
-    case BT_HEX:
-    case BT_DIGIT:
-    case BT_NAME:
-    case BT_MINUS:
-        return 0;
-    default:
-        return 1;
-    }
-}
-
-static
-int PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
-{
-    const char *start = ptr;
-    for (;;) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: ptr += n; break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_NONASCII:
-        case BT_NMSTRT:
-#ifdef XML_NS
-        case BT_COLON:
-#endif
-        case BT_HEX:
-        case BT_DIGIT:
-        case BT_NAME:
-        case BT_MINUS:
-            ptr += MINBPC(enc);
-            break;
-        default:
-            return ptr - start;
-        }
-    }
-}
-
-static
-const char *PREFIX(skipS)(const ENCODING *enc, const char *ptr)
-{
-    for (;;) {
-        switch (BYTE_TYPE(enc, ptr)) {
-        case BT_LF:
-        case BT_CR:
-        case BT_S:
-            ptr += MINBPC(enc);
-            break;
-        default:
-            return ptr;
-        }
-    }
-}
-
-static
-void PREFIX(updatePosition)(const ENCODING *enc,
-                            const char *ptr,
-                            const char *end,
-                            POSITION *pos)
-{
-    while (ptr != end) {
-        switch (BYTE_TYPE(enc, ptr)) {
-#define LEAD_CASE(n) \
-    case BT_LEAD ## n: \
-      ptr += n; \
-      break;
-            LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
-#undef LEAD_CASE
-        case BT_LF:
-            pos->columnNumber = (unsigned)-1;
-            pos->lineNumber++;
-            ptr += MINBPC(enc);
-            break;
-        case BT_CR:
-            pos->lineNumber++;
-            ptr += MINBPC(enc);
-            if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
-                ptr += MINBPC(enc);
-            pos->columnNumber = (unsigned)-1;
-            break;
-        default:
-            ptr += MINBPC(enc);
-            break;
-        }
-        pos->columnNumber++;
-    }
-}
-
-#undef DO_LEAD_CASE
-#undef MULTIBYTE_CASES
-#undef INVALID_CASES
-#undef CHECK_NAME_CASE
-#undef CHECK_NAME_CASES
-#undef CHECK_NMSTRT_CASE
-#undef CHECK_NMSTRT_CASES
--- a/src/protocols/jabber/xmltok_impl.h	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-Alternatively, the contents of this file may be used under the terms
-of the GNU General Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.  If you
-wish to allow use of your version of this file only under the terms of
-the GPL and not to allow others to use your version of this file under
-the MPL, indicate your decision by deleting the provisions above and
-replace them with the notice and other provisions required by the
-GPL. If you do not delete the provisions above, a recipient may use
-your version of this file under either the MPL or the GPL.
-*/
-
-enum {
-  BT_NONXML,
-  BT_MALFORM,
-  BT_LT,
-  BT_AMP,
-  BT_RSQB,
-  BT_LEAD2,
-  BT_LEAD3,
-  BT_LEAD4,
-  BT_TRAIL,
-  BT_CR,
-  BT_LF,
-  BT_GT,
-  BT_QUOT,
-  BT_APOS,
-  BT_EQUALS,
-  BT_QUEST,
-  BT_EXCL,
-  BT_SOL,
-  BT_SEMI,
-  BT_NUM,
-  BT_LSQB,
-  BT_S,
-  BT_NMSTRT,
-  BT_COLON,
-  BT_HEX,
-  BT_DIGIT,
-  BT_NAME,
-  BT_MINUS,
-  BT_OTHER, /* known not to be a name or name start character */
-  BT_NONASCII, /* might be a name or name start character */
-  BT_PERCNT,
-  BT_LPAR,
-  BT_RPAR,
-  BT_AST,
-  BT_PLUS,
-  BT_COMMA,
-  BT_VERBAR
-};
-
-#include <stddef.h>
--- a/src/protocols/jabber/xmltok_ns.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/*
-The contents of this file are subject to the Mozilla Public License
-Version 1.1 (the "License"); you may not use this file except in
-compliance with the License. You may obtain a copy of the License at
-http://www.mozilla.org/MPL/
-
-Software distributed under the License is distributed on an "AS IS"
-basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
-License for the specific language governing rights and limitations
-under the License.
-
-The Original Code is expat.
-
-The Initial Developer of the Original Code is James Clark.
-Portions created by James Clark are Copyright (C) 1998, 1999
-James Clark. All Rights Reserved.
-
-Contributor(s):
-
-*/
-
-const ENCODING *NS(XmlGetUtf8InternalEncoding)()
-{
-    return &ns(internal_utf8_encoding).enc;
-}
-
-const ENCODING *NS(XmlGetUtf16InternalEncoding)()
-{
-#if XML_BYTE_ORDER == 12
-    return &ns(internal_little2_encoding).enc;
-#elif XML_BYTE_ORDER == 21
-return &ns(internal_big2_encoding).enc;
-#else
-const short n = 1;
-    return *(const char *)&n ? &ns(internal_little2_encoding).enc : &ns(internal_big2_encoding).enc;
-#endif
-}
-
-static
-const ENCODING *NS(encodings)[] = {
-    &ns(latin1_encoding).enc,
-    &ns(ascii_encoding).enc,
-    &ns(utf8_encoding).enc,
-    &ns(big2_encoding).enc,
-    &ns(big2_encoding).enc,
-    &ns(little2_encoding).enc,
-    &ns(utf8_encoding).enc /* NO_ENC */
-};
-
-static
-int NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
-                       const char **nextTokPtr)
-{
-    return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr);
-}
-
-static
-int NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
-                        const char **nextTokPtr)
-{
-    return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr);
-}
-
-int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *name)
-{
-    int i = getEncodingIndex(name);
-    if (i == UNKNOWN_ENC)
-        return 0;
-    INIT_ENC_INDEX(p) = (char)i;
-    p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
-    p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
-    p->initEnc.updatePosition = initUpdatePosition;
-    p->encPtr = encPtr;
-    *encPtr = &(p->initEnc);
-    return 1;
-}
-
-static
-const ENCODING *NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
-{
-#define ENCODING_MAX 128
-    char buf[ENCODING_MAX];
-    char *p = buf;
-    int i;
-    XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
-    if (ptr != end)
-        return 0;
-    *p = 0;
-    if (streqci(buf, "UTF-16") && enc->minBytesPerChar == 2)
-        return enc;
-    i = getEncodingIndex(buf);
-    if (i == UNKNOWN_ENC)
-        return 0;
-    return NS(encodings)[i];
-}
-
-int NS(XmlParseXmlDecl)(int isGeneralTextEntity,
-                        const ENCODING *enc,
-                        const char *ptr,
-                        const char *end,
-                        const char **badPtr,
-                        const char **versionPtr,
-                        const char **encodingName,
-                        const ENCODING **encoding,
-                        int *standalone)
-{
-    return doParseXmlDecl(NS(findEncoding),
-                          isGeneralTextEntity,
-                          enc,
-                          ptr,
-                          end,
-                          badPtr,
-                          versionPtr,
-                          encodingName,
-                          encoding,
-                          standalone);
-}
--- a/src/protocols/jabber/xstream.c	Mon Sep 29 13:00:55 2003 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-/* --------------------------------------------------------------------------
- *
- * License
- *
- * The contents of this file are subject to the Jabber Open Source License
- * Version 1.0 (the "JOSL").  You may not copy or use this file, in either
- * source code or executable form, except in compliance with the JOSL. You
- * may obtain a copy of the JOSL at http://www.jabber.org/ or at
- * http://www.opensource.org/.  
- *
- * Software distributed under the JOSL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the JOSL
- * for the specific language governing rights and limitations under the
- * JOSL.
- *
- * Copyrights
- * 
- * Portions created by or assigned to Jabber.com, Inc. are 
- * Copyright (c) 1999-2002 Jabber.com, Inc.  All Rights Reserved.  Contact
- * information for Jabber.com, Inc. is available at http://www.jabber.com/.
- *
- * Portions Copyright (c) 1998-1999 Jeremie Miller.
- * 
- * Acknowledgements
- * 
- * Special thanks to the Jabber Open Source Contributors for their
- * suggestions and support of Jabber.
- * 
- * Alternatively, the contents of this file may be used under the terms of the
- * GNU General Public License Version 2 or later (the "GPL"), in which case
- * the provisions of the GPL are applicable instead of those above.  If you
- * wish to allow use of your version of this file only under the terms of the
- * GPL and not to allow others to use your version of this file under the JOSL,
- * indicate your decision by deleting the provisions above and replace them
- * with the notice and other provisions required by the GPL.  If you do not
- * delete the provisions above, a recipient may use your version of this file
- * under either the JOSL or the GPL. 
- * 
- * 
- * --------------------------------------------------------------------------*/
-
-#include "lib.h"
-
-/* xstream is a way to have a consistent method of handling incoming XML Stream based events... it doesn't handle the generation of an XML Stream, but provides some facilities to help do that */
-
-/******* internal expat callbacks *********/
-void _xstream_startElement(xstream xs, const char* name, const char** atts)
-{
-    pool p;
-
-    /* if xstream is bad, get outa here */
-    if(xs->status > XSTREAM_NODE) return;
-
-    if(xs->node == NULL)
-    {
-        p = pool_heap(5*1024); /* 5k, typically 1-2k each plus copy of self and workspace */
-        xs->node = xmlnode_new_tag_pool(p,name);
-        xmlnode_put_expat_attribs(xs->node, atts);
-
-        if(xs->status == XSTREAM_ROOT)
-        {
-            xs->status = XSTREAM_NODE; /* flag status that we're processing nodes now */
-            (xs->f)(XSTREAM_ROOT, xs->node, xs->arg); /* send the root, f must free all nodes */
-            xs->node = NULL;
-        }
-    }else{
-        xs->node = xmlnode_insert_tag(xs->node, name);
-        xmlnode_put_expat_attribs(xs->node, atts);
-    }
-
-    /* depth check */
-    xs->depth++;
-    if(xs->depth > XSTREAM_MAXDEPTH)
-        xs->status = XSTREAM_ERR;
-}
-
-
-void _xstream_endElement(xstream xs, const char* name)
-{
-    xmlnode parent;
-
-    /* if xstream is bad, get outa here */
-    if(xs->status > XSTREAM_NODE) return;
-
-    /* if it's already NULL we've received </stream>, tell the app and we're outta here */
-    if(xs->node == NULL)
-    {
-        xs->status = XSTREAM_CLOSE;
-        (xs->f)(XSTREAM_CLOSE, NULL, xs->arg);
-    }else{
-        parent = xmlnode_get_parent(xs->node);
-
-        /* we are the top-most node, feed to the app who is responsible to delete it */
-        if(parent == NULL)
-            (xs->f)(XSTREAM_NODE, xs->node, xs->arg);
-
-        xs->node = parent;
-    }
-    xs->depth--;
-}
-
-
-void _xstream_charData(xstream xs, const char *str, int len)
-{
-    /* if xstream is bad, get outa here */
-    if(xs->status > XSTREAM_NODE) return;
-
-    if(xs->node == NULL)
-    {
-        /* we must be in the root of the stream where CDATA is irrelevant */
-        return;
-    }
-
-    xmlnode_insert_cdata(xs->node, str, len);
-}
-
-
-void _xstream_cleanup(void *arg)
-{
-    xstream xs = (xstream)arg;
-
-    xmlnode_free(xs->node); /* cleanup anything left over */
-    XML_ParserFree(xs->parser);
-}
-
-
-/* creates a new xstream with given pool, xstream will be cleaned up w/ pool */
-xstream xstream_new(pool p, xstream_onNode f, void *arg)
-{
-    xstream newx;
-
-    if(p == NULL || f == NULL)
-    {
-        fprintf(stderr,"Fatal Programming Error: xstream_new() was improperly called with NULL.\n");
-        return NULL;
-    }
-
-    newx = pmalloco(p, sizeof(_xstream));
-    newx->p = p;
-    newx->f = f;
-    newx->arg = arg;
-
-    /* create expat parser and ensure cleanup */
-    newx->parser = XML_ParserCreate(NULL);
-    XML_SetUserData(newx->parser, (void *)newx);
-    XML_SetElementHandler(newx->parser, (void *)_xstream_startElement, (void *)_xstream_endElement);
-    XML_SetCharacterDataHandler(newx->parser, (void *)_xstream_charData);
-    pool_cleanup(p, _xstream_cleanup, (void *)newx);
-
-    return newx;
-}
-
-/* attempts to parse the buff onto this stream firing events to the handler, returns the last known status */
-int xstream_eat(xstream xs, char *buff, int len)
-{
-    char *err = NULL;
-    xmlnode xerr;
-    static char maxerr[] = "maximum node size reached";
-    static char deeperr[] = "maximum node depth reached";
-
-    if(xs == NULL)
-    {
-        fprintf(stderr,"Fatal Programming Error: xstream_eat() was improperly called with NULL.\n");
-        return XSTREAM_ERR;
-    }
-
-    if(len == 0 || buff == NULL)
-        return xs->status;
-
-    if(len == -1) /* easy for hand-fed eat calls */
-        len = strlen(buff);
-
-    if(!XML_Parse(xs->parser, buff, len, 0))
-    {
-        err = (char *)XML_ErrorString(XML_GetErrorCode(xs->parser));
-        xs->status = XSTREAM_ERR;
-    }else if(pool_size(xmlnode_pool(xs->node)) > XSTREAM_MAXNODE || xs->cdata_len > XSTREAM_MAXNODE){
-        err = maxerr;
-        xs->status = XSTREAM_ERR;
-    }else if(xs->status == XSTREAM_ERR){ /* set within expat handlers */
-        err = deeperr;
-    }
-
-    /* fire parsing error event, make a node containing the error string */
-    if(xs->status == XSTREAM_ERR)
-    {
-        xerr = xmlnode_new_tag("error");
-        xmlnode_insert_cdata(xerr,err,-1);
-        (xs->f)(XSTREAM_ERR, xerr, xs->arg);
-    }
-
-    return xs->status;
-}
-
-
-/* STREAM CREATION UTILITIES */
-
-/* give a standard template xmlnode to work from */
-xmlnode xstream_header(char *namespace, char *to, char *from)
-{
-    xmlnode x;
-    char id[10];
-
-    sprintf(id,"%X",(int)time(NULL));
-
-    x = xmlnode_new_tag("stream:stream");
-    xmlnode_put_attrib(x, "xmlns:stream", "http://etherx.jabber.org/streams");
-    xmlnode_put_attrib(x, "id", id);
-    if(namespace != NULL)
-        xmlnode_put_attrib(x, "xmlns", namespace);
-    if(to != NULL)
-        xmlnode_put_attrib(x, "to", to);
-    if(from != NULL)
-        xmlnode_put_attrib(x, "from", from);
-
-    return x;
-}
-
-/* trim the xmlnode to only the opening header :) [NO CHILDREN ALLOWED] */
-char *xstream_header_char(xmlnode x)
-{
-    spool s;
-    char *fixr, *head;
-
-    if(xmlnode_has_children(x))
-    {
-        fprintf(stderr,"Fatal Programming Error: xstream_header_char() was sent a header with children!\n");
-        return NULL;
-    }
-
-    s = spool_new(xmlnode_pool(x));
-    spooler(s,"<?xml version='1.0'?>",xmlnode2str(x),s);
-    head = spool_print(s);
-    fixr = strstr(head,"/>");
-    *fixr = '>';
-    ++fixr;
-    *fixr = '\0';
-
-    return head;
-}
-