Git init
authorKibum Kim <kb0929.kim@samsung.com>
Fri, 6 Jan 2012 15:47:55 +0000 (00:47 +0900)
committerKibum Kim <kb0929.kim@samsung.com>
Fri, 6 Jan 2012 15:47:55 +0000 (00:47 +0900)
55 files changed:
AUTHORS [new file with mode: 0644]
COPYING [new file with mode: 0644]
ChangeLog [new file with mode: 0755]
Makefile.am [new file with mode: 0755]
NEWS [new file with mode: 0644]
README [new file with mode: 0755]
autogen.sh [new file with mode: 0644]
configure.ac [new file with mode: 0755]
debian/README.source [new file with mode: 0644]
debian/changelog [new file with mode: 0755]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0755]
debian/copyright [new file with mode: 0644]
debian/libice-dev.install [new file with mode: 0755]
debian/libice6.install [new file with mode: 0644]
debian/libice6.shlibs [new file with mode: 0644]
debian/rules [new file with mode: 0755]
debian/watch [new file with mode: 0644]
debian/xsfbs/repack.sh [new file with mode: 0644]
debian/xsfbs/xsfbs.mk [new file with mode: 0644]
debian/xsfbs/xsfbs.sh [new file with mode: 0644]
doc/ICElib.xml [new file with mode: 0755]
doc/Makefile.am [new file with mode: 0755]
ice.pc.in [new file with mode: 0644]
include/X11/ICE/ICE.h [new file with mode: 0755]
include/X11/ICE/ICEconn.h [new file with mode: 0755]
include/X11/ICE/ICElib.h [new file with mode: 0755]
include/X11/ICE/ICEmsg.h [new file with mode: 0755]
include/X11/ICE/ICEproto.h [new file with mode: 0755]
include/X11/ICE/ICEutil.h [new file with mode: 0755]
packaging/libICE.spec [new file with mode: 0644]
specs/Makefile.am [new file with mode: 0755]
specs/ice.xml [new file with mode: 0755]
src/ICElibint.h [new file with mode: 0755]
src/Makefile.am [new file with mode: 0755]
src/accept.c [new file with mode: 0755]
src/authutil.c [new file with mode: 0755]
src/connect.c [new file with mode: 0755]
src/error.c [new file with mode: 0755]
src/getauth.c [new file with mode: 0755]
src/globals.h [new file with mode: 0755]
src/iceauth.c [new file with mode: 0755]
src/icetrans.c [new file with mode: 0755]
src/listen.c [new file with mode: 0755]
src/listenwk.c [new file with mode: 0755]
src/locking.c [new file with mode: 0755]
src/misc.c [new file with mode: 0755]
src/ping.c [new file with mode: 0755]
src/process.c [new file with mode: 0755]
src/protosetup.c [new file with mode: 0755]
src/register.c [new file with mode: 0755]
src/replywait.c [new file with mode: 0755]
src/setauth.c [new file with mode: 0755]
src/shutdown.c [new file with mode: 0755]
src/watch.c [new file with mode: 0755]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..1352818
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,6 @@
+Ralph Mor, of the X Consortium is the original author.
+
+OS/2 support, Holger Veit, bug fixes by Keith Packard, Petter Reinholdtsen,
+others.
+
+Our apologies if we've overlooked a contributor.
diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..fa56591
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,23 @@
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
diff --git a/ChangeLog b/ChangeLog
new file mode 100755 (executable)
index 0000000..8c91b64
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,654 @@
+commit 59a8d5609398824c81b72deb82735a55332ca239
+Author: Jeremy Huddleston <jeremyhu@apple.com>
+Date:   Sun Oct 17 21:26:31 2010 -0700
+
+    Fix include ordering, so -I../include precedes $CPPFLAGS which could
+    cause us to include installed rather than packaged headers.
+    
+    Signed-off-by: Jeremy Huddleston <jeremyhu@apple.com>
+
+commit 4a6f7a357222b2c1fa289d6e7b5fcc8c361e20e9
+Author: Jesse Adkins <jesserayadkins@gmail.com>
+Date:   Tue Sep 28 13:30:01 2010 -0700
+
+    Purge cvs tags.
+    
+    Signed-off-by: Jesse Adkins <jesserayadkins@gmail.com>
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 5bb806a65bf23a507b135abe1e4a8b3cabc7b8aa
+Author: Matt Dew <matt@osource.org>
+Date:   Wed Jun 30 16:52:22 2010 -0400
+
+    specs: convert ICE doc/specs from xorg-docs module to DocBook XML
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 9b54f509832c50c1fac0edc0cb78e1a3454a56dc
+Author: Alan Coopersmith <alan.coopersmith@oracle.com>
+Date:   Tue Jun 8 20:12:53 2010 -0700
+
+    Move ICE protocol & API specs from xorg-docs module
+    
+    For now, just checked in and included in dist tarballs, not processed
+    into a usable format - same as it was in xorg-docs
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@oracle.com>
+
+commit 1967c04c021a4cfd7b3cdd4efdc13610b4385a65
+Author: Julien Cristau <jcristau@debian.org>
+Date:   Tue May 11 16:36:20 2010 +0200
+
+    Set the close-on-exec flag for listening sockets
+    
+    This prevents xsm from leaking file descriptors to the processes it
+    starts.
+    
+    X.Org bug#22932 <http://bugs.freedesktop.org/show_bug.cgi?id=22932>
+    
+    Reported-by: Kalle Olavi Niemitalo <kon@iki.fi>
+    Signed-off-by: Julien Cristau <jcristau@debian.org>
+
+commit b6478dbedcca4d4cf44bd588c050bcc70c2f4963
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Apr 5 19:50:40 2010 -0400
+
+    config: update AC_PREREQ statement to 2.60
+    
+    Unrelated to the previous patches, the new value simply reflects
+    the reality that the minimum level for autoconf to configure
+    all x.org modules is 2.60 dated June 2006.
+    
+    ftp://ftp.gnu.org/gnu/autoconf/autoconf-2.60.tar.gz
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 8e175ff18649bd30e862b6a6a5f82a4ed4d5241a
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Mar 29 14:53:48 2010 -0400
+
+    config: remove the pkgconfig pc.in file from EXTRA_DIST
+    
+    Automake always includes it in the tarball.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 09d61dc024d9846525e4c97d33cdf03c9f06c151
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Tue Feb 16 10:37:21 2010 -0500
+
+    config: move CWARNFLAGS from configure.ac to Makefile.am
+    
+    Compiler warning flags should be explicitly set in the makefile
+    rather than being merged with other packages compiler flags.
+    
+    Signed-off-by: Gaetan Nadon <memsize@videotron.ca>
+
+commit 72b8a2d39a57eb0640929b9bb9f276c6032f8213
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Fri Nov 27 20:56:03 2009 -0500
+
+    Makefile.am: add ChangeLog and INSTALL on MAINTAINERCLEANFILES
+    
+    Now that the INSTALL file is generated.
+    Allows running make maintainer-clean.
+
+commit 68231f8574e197a12eff1ddde37166d101567269
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Wed Oct 28 14:09:10 2009 -0400
+
+    INSTALL, NEWS, README or AUTHORS files are missing/incorrect #24206
+    
+    Add missing INSTALL file. Use standard GNU file on building tarball
+    README may have been updated
+    Remove AUTHORS file as it is empty and no content available yet.
+    Remove NEWS file as it is empty and no content available yet.
+
+commit b5cfc1cdd367c93660259a86b3b6683c57e5d76a
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Tue Oct 27 15:07:25 2009 -0400
+
+    Deploy the new XORG_DEFAULT_OPTIONS #24242
+    
+    This macro aggregate a number of existing macros that sets commmon
+    X.Org components configuration options. It shields the configuration file from
+    future changes.
+
+commit 5524fa4d543932e4565b2235515fef9a5d9a501d
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Mon Oct 26 22:08:41 2009 -0400
+
+    Makefile.am: ChangeLog not required: EXTRA_DIST or *CLEANFILES #24432
+    
+    ChangeLog filename is known to Automake and requires no further
+    coding in the makefile.
+
+commit 82ad2d2053af2ad37697793b9718721aa3ff80a0
+Author: Gaetan Nadon <memsize@videotron.ca>
+Date:   Thu Oct 22 12:34:18 2009 -0400
+
+    .gitignore: use common defaults with custom section # 24239
+    
+    Using common defaults will reduce errors and maintenance.
+    Only the very small or inexistent custom section need periodic maintenance
+    when the structure of the component changes. Do not edit defaults.
+
+commit 4b2289ad5481de7fa51941cf6c2ca7a2a3202690
+Author: Jeremy Huddleston <jeremyhu@freedesktop.org>
+Date:   Wed Oct 21 12:47:23 2009 -0700
+
+    This is not a GNU project, so declare it foreign.
+    
+    On Wed, 2009-10-21 at 13:36 +1000, Peter Hutterer wrote:
+    > On Tue, Oct 20, 2009 at 08:23:55PM -0700, Jeremy Huddleston wrote:
+    > > I noticed an INSTALL file in xlsclients and libXvMC today, and it
+    > > was quite annoying to work around since 'autoreconf -fvi' replaces
+    > > it and git wants to commit it.  Should these files even be in git?
+    > > Can I nuke them for the betterment of humanity and since they get
+    > > created by autoreconf anyways?
+    >
+    > See https://bugs.freedesktop.org/show_bug.cgi?id=24206
+    
+    As an interim measure, replace AM_INIT_AUTOMAKE([dist-bzip2]) with
+    AM_INIT_AUTOMAKE([foreign dist-bzip2]). This will prevent the generation
+    of the INSTALL file. It is also part of the 24206 solution.
+    
+    Signed-off-by: Jeremy Huddleston <jeremyhu@freedesktop.org>
+
+commit 94992c686a6850f2303aa78057a64a6369b64692
+Author: Peter Hutterer <peter.hutterer@who-t.net>
+Date:   Fri Aug 28 14:17:50 2009 +1000
+
+    libICE 1.0.6
+    
+    Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
+
+commit 7a8bb2a2c991919bcdef63359c74e239045a3f4c
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Mon Feb 2 20:34:30 2009 -0800
+
+    Add README with pointers to mailing list, bugzilla & git repos
+    
+    Signed-off-by: Alan Coopersmith <alan.coopersmith@sun.com>
+
+commit dbb950061f185e1ccf27bff9c71adc34ab4cfae0
+Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
+Date:   Wed Jan 28 16:55:37 2009 -0200
+
+    Janitor: Correct sparse warnings.
+    
+      Also reorders some code in configure.ac and Makefile.am to
+    match pattern used on other packages.
+
+commit 2f41ddb3a917c4e71184452b68561a15593d33b8
+Author: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
+Date:   Tue Jan 6 17:25:25 2009 -0200
+
+    Update .gitignore.
+    
+      Don't warn about files left after a build and/or make distcheck
+    in 'git status -a'.
+
+commit ab9dff549534c6d7b33f440bff7a841d60c1206c
+Author: Peter Breitenlohner <peb@mppmu.mpg.de>
+Date:   Mon Dec 8 18:45:44 2008 +0100
+
+    bump to 1.0.5
+
+commit 71695c4bf7ae07228605683f6cdeca0457c8495a
+Author: Peter Breitenlohner <peb@mppmu.mpg.de>
+Date:   Mon Dec 8 18:44:26 2008 +0100
+
+    remove ChangeLog from EXTRA_DIST and CLEANFILES
+
+commit 653f659fe65ae8c2a9fe5b1fdbfc78da43f2cf90
+Author: Peter Breitenlohner <peb@mppmu.mpg.de>
+Date:   Mon Dec 8 18:41:34 2008 +0100
+
+    use memcmp instead of binaryEqual
+    
+    suggested by Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
+    http://lists.freedesktop.org/archives/xorg/2008-December/041222.html
+
+commit bf138553afe6eecd0e6c218dc6ae4f63065e4196
+Author: Peter Breitenlohner <peb@mppmu.mpg.de>
+Date:   Tue Dec 2 22:06:15 2008 +0100
+
+    Use NULL, not zero, for pointers
+    
+    From Magnus Kessler <Magnus.Kessler@gmx.net>
+    http://lists.freedesktop.org/archives/xorg/2008-October/039799.html
+    http://lists.freedesktop.org/archives/xorg/attachments/20081030/b2ea5b1c/attachment-0001.bin
+
+commit b01e82ce1deedb36c9696d4d27a3b9a5d5a52d08
+Author: Peter Breitenlohner <peb@mppmu.mpg.de>
+Date:   Thu Oct 30 12:01:06 2008 +0100
+
+    ANSI C
+    
+    convert all old style function declarations
+    
+    see also: Paulo Cesar Pereira de Andrade <pcpa@mandriva.com.br>
+    http://bugs.freedesktop.org/show_bug.cgi?id=14683
+    http://bugs.freedesktop.org/attachment.cgi?id=14582
+    
+    see also: Magnus Kessler <Magnus.Kessler@gmx.net>
+    http://lists.freedesktop.org/archives/xorg/2008-October/039799.html
+    http://lists.freedesktop.org/archives/xorg/attachments/20081030/b2ea5b1c/attachment-0001.bin
+
+commit 2aba1bc0583aeb3ee6e26e3bfacd123abef744d9
+Author: Peter Breitenlohner <peb@mppmu.mpg.de>
+Date:   Mon Dec 1 23:06:22 2008 +0100
+
+    towards ANSI C
+    
+    make _IceProcessCoreMessage and default error handlers static
+
+commit 69a1b4b6d34291738dfbc3aa19d0ce3f2842ec8f
+Author: Peter Breitenlohner <peb@mppmu.mpg.de>
+Date:   Mon Dec 1 22:22:12 2008 +0100
+
+    Activate CWARNFLAGS with lots of gcc warnings
+
+commit 898ed95cad1133940a83dcf428865c5d3fb2c939
+Author: Peter Breitenlohner <peb@mppmu.mpg.de>
+Date:   Mon Dec 1 22:18:45 2008 +0100
+
+    use xorg-macros-1.2.1
+    
+    Use XORG_CHANGELOG for rule to generate ChangeLog from git log
+    Use XORG_CWARNFLAGS for compiler warning flags, leave CFLAGS to user
+
+commit a99fbad09ab850e65ddd57e4d4488e4726295e14
+Author: Peter Breitenlohner <peb@mppmu.mpg.de>
+Date:   Tue Oct 7 13:21:48 2008 -0700
+
+    Constify some arguments in libICE to clear warnings in libSM
+    
+    This patch avoids the gcc (3.4.6) warnings:
+     ../../libSM-1.0.3/src/sm_client.c:104: warning: passing arg 7 of `IceRegisterForProtocolSetup' from incompatible pointer type
+     ../../libSM-1.0.3/src/sm_manager.c:168: warning: passing arg 7 of `IceRegisterForProtocolReply' from incompatible pointer type
+    when compiling libSM
+
+commit 3bceaeb3192ca75a14854d614e1621d28fb82274
+Author: Peter Breitenlohner <peb@mppmu.mpg.de>
+Date:   Tue Oct 7 11:25:42 2008 -0700
+
+    define macros to 1 in icetrans.c to avoid redefined macro warnings
+    
+    X.Org Bug #17947 <http://bugs.freedesktop.org/show_bug.cgi?id=17947>
+    Patch #19444 <http://bugs.freedesktop.org/attachment.cgi?id=19444>
+    
+    Define as 1 (one) as done by autoconf and the command line
+    option, e.g. -DICE_t, not as empty.
+    
+    This avoids the gcc (3.4.6) warnings:
+     ../../libICE-1.0.4/src/icetrans.c:29:1: warning: "ICE_t" redefined
+     ../config.h:38:1: warning: this is the location of the previous definition
+     ../../libICE-1.0.4/src/icetrans.c:30:1: warning: "TRANS_CLIENT" redefined
+     <command line>:6:1: warning: this is the location of the previous definition
+     ../../libICE-1.0.4/src/icetrans.c:31:1: warning: "TRANS_SERVER" redefined
+     <command line>:7:1: warning: this is the location of the previous definition
+
+commit b707104f4dba0963ab17c1d6a29c1e3a848ea408
+Author: Alan Hourihane <alanh@tungstengraphics.com>
+Date:   Tue Apr 29 00:41:40 2008 +0100
+
+    silence warning
+
+commit e6b525aefc05b5203391699b00053ad52243cc6b
+Author: Colin Harrison <colin.harrison-at-virgin.net>
+Date:   Tue Apr 29 00:40:48 2008 +0100
+
+    include for sleep()
+
+commit ef58f37724b841ef2246757be27111775aa86559
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Sun Mar 9 09:02:40 2008 +0100
+
+    nuke RCS Ids
+
+commit 47d86e8343d3d0201166c4d75da2ec9c12638cc1
+Author: James Cloos <cloos@jhcloos.com>
+Date:   Thu Dec 6 15:51:13 2007 -0500
+
+    Add missing PHONY line for automatic ChangeLog generation
+
+commit f415da71dd26f128df7d550ecd7631f8888eb1d2
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Mon Aug 20 13:21:07 2007 -0700
+
+    Version bump: 1.0.4
+
+commit 8e08d3e4b8f00151b3a8b7eb88015dc15170e154
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Mon Jun 4 15:40:22 2007 -0700
+
+    Add $(AM_CFLAGS) to lint flags to get correct Xtrans flags
+
+commit cd900e40b5676874d076c35466fd7baa6a49b1f6
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Apr 5 15:05:52 2007 -0700
+
+    Replace many malloc(strlen()); strcpy() pairs with strdup()
+
+commit 27f9a9324d58c9a7472c724c62f5b7ea0e1f4681
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Apr 5 14:43:05 2007 -0700
+
+    Provide ANSI C prototypes for more static functions
+
+commit bb639803a779ceace05d183b653da88f010ab29c
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Apr 5 14:32:31 2007 -0700
+
+    Convert authutil.c static helpers to ANSI C prototypes to clear sparse warnings
+
+commit 2179b2d467d69e45559b8e4f161a904a21f05321
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Apr 5 14:28:06 2007 -0700
+
+    Add hooks for checking source code with lint/sparse/etc.
+
+commit 6b361c028b5ad931b61df86fae570f3ef9f41c15
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Apr 5 14:19:56 2007 -0700
+
+    Coverity #1086: Double free of pointer "*listenObjsRet"
+    
+    Same bug, different function.
+
+commit c9b3d016681d81aff32c74cdad75151bd538e6ab
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Apr 5 14:07:42 2007 -0700
+
+    Coverity #1085: Double free of pointer "*listenObjsRet"
+    
+    If malloc failed in the loop in IceListenForConnections, the error path
+    would free all previous allocations, then loop around and try again, and
+    if it failed again, free the previous allocations again.   On the other
+    hand, if it succeeded on the later tries, then the memory would just be
+    leaked, since the error would be returned and not the pointer to them.
+
+commit 6039e865470af23948b0fe7d5dc0ea72da436b0e
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Apr 5 14:04:01 2007 -0700
+
+    Add *~ to .gitignore to skip emacs/patch droppings
+
+commit bed718894bed98cbd45b02bd57fb7fc6fd5089aa
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sat Dec 16 01:21:17 2006 +0200
+
+    bump to 1.0.3
+
+commit cac788981906186442ddfb57a41f45911eb8223b
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Wed Dec 6 18:58:09 2006 +0200
+
+    Makefile.am: make ChangeLog hook safer
+    Make ChangeLog hook as safe as possible.
+
+commit 011d632e8ef3f738b9158e66d6da6876e3b53905
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Fri Oct 13 15:49:52 2006 -0400
+
+    Bump to 1.0.2
+
+commit 445661cd714685009ee9ba2358a274351381eabf
+Author: Adam Jackson <ajax@benzedrine.nwnk.net>
+Date:   Thu Oct 12 18:37:57 2006 -0400
+
+    Fix ChangeLog hook to distcheck.
+
+commit 5cba1c763ac9f79062523227b49a29f72e6069cf
+Author: Matthieu Herrb <matthieu.herrb@laas.fr>
+Date:   Sun Jul 16 10:52:30 2006 +0200
+
+    set GIT_DIR=${srcdir}/.git for git-log
+
+commit 86e0a93714a6ccdb8555fc2c48231d958cba383d
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Thu Jul 13 14:58:44 2006 -0700
+
+    renamed: .cvsignore -> .gitignore
+
+commit c87cb98979356fc55607c05a2b23207afc9beeb1
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Tue Jul 11 13:48:08 2006 -0700
+
+    Replace static ChangeLog with rule copied from libX11 to generate from git log
+
+commit 6066ab9b9914ec0cca3b8f36fa3f5ba323414621
+Author: Derek Wang <derek.wang@sun.com>
+Date:   Tue Nov 23 12:00:32 2004 -0800
+
+    Sun bug #6193975: kde session manager core dumps in _IceWrite()
+
+commit be25425ca38d23655a5a854c053e750e1cbd3dea
+Author: Alan Coopersmith <alan.coopersmith@sun.com>
+Date:   Tue Jul 11 13:42:07 2006 -0700
+
+    renamed: .cvsignore -> .gitignore
+
+commit 9b1bb5ab99bd386cc030cd456a576b37406da91c
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Wed Apr 26 23:57:50 2006 +0000
+
+    Bump to 1.0.1
+
+commit 96d7763487da6624ed85bee10b081e7138d2060d
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Mon Apr 10 16:44:40 2006 +0000
+
+    Coverity #664: Free memory allocated by EXTRACT_STRING in
+        _IceDefaultErrorHandler after we're done fprintf()'ing it.
+
+commit 2a30ec82f3bd2aa1f2566e97fee70403a8448de8
+Author: Kevin E Martin <kem@kem.org>
+Date:   Thu Dec 15 00:24:27 2005 +0000
+
+    Update package version number for final X11R7 release candidate.
+
+commit 881573d429c0a9ecfa2d6286d4eaece36ee50675
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sat Dec 3 05:49:42 2005 +0000
+
+    Update package version number for X11R7 RC3 release.
+
+commit a15b179f2e8e359161d9133bac58dde57b7e78ae
+Author: Kevin E Martin <kem@kem.org>
+Date:   Sat Nov 19 07:15:39 2005 +0000
+
+    Update pkgconfig files to separate library build-time dependencies from
+        application build-time dependencies, and update package deps to work
+        with separate build roots.
+
+commit c386a08047582240adefafd3afc062e52fccae6f
+Author: Kevin E Martin <kem@kem.org>
+Date:   Wed Nov 9 21:19:12 2005 +0000
+
+    Update package version number for X11R7 RC2 release.
+
+commit c361e3919f2de3f4742904b04e73178edc76bf95
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Sun Oct 23 20:12:19 2005 +0000
+
+    Bug #1893: Fix replies when peers use different major opcodes for the same
+        subprotocol. (016_ICE_subprotocol_reply_fix.diff from Debian, by Jochen
+        Voss)
+
+commit 0b8ff6fbd8cd7f47ab9e6ccb6d4917564a2d13ee
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Sat Jul 30 19:15:15 2005 +0000
+
+    Add -D flags to clear various warnings (Stefan Dirsch)
+
+commit 260d470a128c7eaa6d7484bb143aab353c4e98ec
+Author: Kevin E Martin <kem@kem.org>
+Date:   Fri Jul 29 21:22:50 2005 +0000
+
+    Various changes preparing packages for RC0:
+    - Verify and update package version numbers as needed
+    - Implement versioning scheme
+    - Change bug address to point to bugzilla bug entry form
+    - Disable loadable i18n in libX11 by default (use --enable-loadable-i18n to
+        reenable it)
+    - Fix makedepend to use pkgconfig and pass distcheck
+    - Update build script to build macros first
+    - Update modular Xorg version
+
+commit cf687b775f580a84a4a8e962814abe7bc47a3c52
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sat Jul 16 06:22:34 2005 +0000
+
+    Set soversion to 6.3.0.
+
+commit 6d1704defa0e57715bd22d30d6e789b36233dcf8
+Author: Keith Packard <keithp@keithp.com>
+Date:   Sat Jul 9 05:59:01 2005 +0000
+
+    Add .cvsignore files
+
+commit 2b6b8e40a63dd69a13f87c19dcf8dc2f477c304d
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Sun Jul 3 07:00:55 2005 +0000
+
+    Add Xtrans definitions (FONT_t, TRANS_CLIENT) to clean up warnings.
+    Add XSERV_t, TRANS_SERVER, TRANS_REOPEN to quash warnings.
+    Add #include <dix-config.h> or <xorg-config.h>, as appropriate, to all
+        source files in the xserver/xorg tree, predicated on defines of
+        HAVE_{DIX,XORG}_CONFIG_H. Change all Xfont includes to
+        <X11/fonts/foo.h>.
+
+commit 608ad35f102b188f554daf8c160a5edcf4e8031c
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Jun 10 14:11:36 2005 +0000
+
+    Remove pointless include of Xlib.h.
+    Fix #include path to bigreqstr.h.
+
+commit 795460992b0dcd4aa2591be462a94942415c6028
+Author: Alexander Gottwald <alexander.gottwald@s1999.tu-chemnitz.de>
+Date:   Thu Jun 9 15:54:47 2005 +0000
+
+    Replace <X11/transport.c> with <X11/Xtrans/transport.c>
+
+commit ae7b4cca6bd5c1f4edea8cde80d7a3dfaaf2c4d3
+Author: Alexander Gottwald <alexander.gottwald@s1999.tu-chemnitz.de>
+Date:   Thu Jun 9 15:52:02 2005 +0000
+
+    Replace <X11/Xtrans.h> with <X11/Xtrans/Xtrans.h>
+    Copy Xtrans.h to exports/include/X11/Xtrans only
+
+commit a0637be926e6da5db8d131e7914f1300f484c626
+Author: Alan Coopersmith <Alan.Coopersmith@sun.com>
+Date:   Sat May 21 23:07:47 2005 +0000
+
+    xtrans:
+    Create autoconf macro XTRANS_CONNECTION_FLAGS to provide standard set of
+        --enable flags for which transports to support and common place to
+        update for required libraries for platforms that need certain libs for
+        certain transports
+    ICE:
+    Add ICE_t #define required by Xtrans headers. Replace static defines of
+        LOCALCONN & UNIXCONN with new XTRANS_CONNECTION_FLAGS macro.
+    X11:
+    Moved transport type checks to new macro XTRANS_CONNECTION_FLAGS in
+        xtrans.m4 in xtrans module so they can be shared by all modules using
+        xtrans.
+
+commit efdb2468119be0c62a379d91088a708ca8d37e1b
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Thu May 19 00:22:32 2005 +0000
+
+    revert last change, didn't do right thing at all, sorry for the noise
+
+commit ccf4efa5e204d4569b9b590f72baae807ec19903
+Author: Adam Jackson <ajax@nwnk.net>
+Date:   Thu May 19 00:10:02 2005 +0000
+
+    Require automake 1.7 in AM_INIT_AUTOMAKE
+
+commit 3458da101c943530861485c798538ce014eee6b0
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Tue May 17 21:25:15 2005 +0000
+
+    - Conditionally include config.h in xc/lib/SM
+    - Add libSM to symlink.sh
+    - Add SM build system
+
+commit cae06ca0ce523eeb9a667ce3ae5bff066cf6ecd7
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Tue May 17 20:53:58 2005 +0000
+
+    - Conditionally include config.h in the ICE source.
+    - Add ICE to symlink.sh
+
+commit 9dd90f8f8e29bb1dd6fe84b4b1d2d75ef91bc336
+Author: Søren Sandmann Pedersen <sandmann@daimi.au.dk>
+Date:   Tue May 17 20:52:35 2005 +0000
+
+    Add ICE directory + build system.
+
+commit d1cfe2a6d4a392f64b6b9d9255ec329fb2a6a39a
+Author: Daniel Stone <daniel@fooishbar.org>
+Date:   Fri Jan 28 19:15:39 2005 +0000
+
+    Move _IceGetPeerName into the ICE public API as IceGetPeerName; bump ICE
+        soversion to 6.4 accordingly. Change SM's use to the public version.
+        The old version will be retained for compatibility.
+
+commit 8f0babf8450aa8097e063e13c95b1581843b2dd8
+Author: Egbert Eich <eich@suse.de>
+Date:   Fri Apr 23 18:43:22 2004 +0000
+
+    Merging XORG-CURRENT into trunk
+
+commit 111949a4a1d5b62e26016b555e12f8862c90ae44
+Author: Egbert Eich <eich@suse.de>
+Date:   Sun Mar 14 08:31:52 2004 +0000
+
+    Importing vendor version xf86-4_4_99_1 on Sun Mar 14 00:26:39 PST 2004
+
+commit d4054eea34b2f4d345796ecadec8a96af93c4d0d
+Author: Egbert Eich <eich@suse.de>
+Date:   Wed Mar 3 12:11:10 2004 +0000
+
+    Importing vendor version xf86-4_4_0 on Wed Mar 3 04:09:24 PST 2004
+
+commit 569bf16d182b043e7ab914202d4195baf4a8413a
+Author: Egbert Eich <eich@suse.de>
+Date:   Thu Feb 26 13:35:18 2004 +0000
+
+    readding XFree86's cvs IDs
+
+commit 14c9e41e551ab1b3a00807dbb8f2f215b96bcc81
+Author: Egbert Eich <eich@suse.de>
+Date:   Thu Feb 26 09:22:34 2004 +0000
+
+    Importing vendor version xf86-4_3_99_903 on Wed Feb 26 01:21:00 PST 2004
+
+commit 45b73c360dc68b023194758bbb1cc59c021742a6
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Thu Dec 4 22:02:52 2003 +0000
+
+    XFree86 4.3.99.901 (RC 1)
+
+commit c919c3d0b355ef67dfa0b511eb1da488e5786d1b
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Tue Nov 25 19:28:07 2003 +0000
+
+    XFree86 4.3.99.16 Bring the tree up to date for the Cygwin folks
+
+commit 72e353567f8927996a26e72848d86f692c3f0737
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Fri Nov 14 16:48:46 2003 +0000
+
+    XFree86 4.3.0.1
+
+commit ee452992357329f7af846eba8f5bbe61c5d27bfa
+Author: Kaleb Keithley <kaleb@freedesktop.org>
+Date:   Fri Nov 14 15:54:36 2003 +0000
+
+    R6.6 is the Xorg base-line
diff --git a/Makefile.am b/Makefile.am
new file mode 100755 (executable)
index 0000000..c2110ec
--- /dev/null
@@ -0,0 +1,21 @@
+SUBDIRS = doc specs src
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = ice.pc
+
+MAINTAINERCLEANFILES = ChangeLog INSTALL
+
+.PHONY: ChangeLog INSTALL
+
+INSTALL:
+       $(INSTALL_CMD)
+
+ChangeLog:
+       $(CHANGELOG_CMD)
+
+dist-hook: ChangeLog INSTALL
+
+if LINT
+lint:
+       (cd src && $(MAKE) $(MFLAGS) lint)
+endif LINT
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/README b/README
new file mode 100755 (executable)
index 0000000..1ed24f2
--- /dev/null
+++ b/README
@@ -0,0 +1,30 @@
+libICE - Inter-Client Exchange Library
+
+Documentation for this API can be found in the doc directory of the source
+code, or online at:
+
+       http://xorg.freedesktop.org/releases/X11R7.0/doc/PDF/ICElib.pdf 
+
+All questions regarding this software should be directed at the
+Xorg mailing list:
+
+        http://lists.freedesktop.org/mailman/listinfo/xorg
+
+Please submit bug reports to the Xorg bugzilla:
+
+        https://bugs.freedesktop.org/enter_bug.cgi?product=xorg
+
+The master development code repository can be found at:
+
+        git://anongit.freedesktop.org/git/xorg/lib/libICE
+
+        http://cgit.freedesktop.org/xorg/lib/libICE
+
+For patch submission instructions, see:
+
+       http://www.x.org/wiki/Development/Documentation/SubmittingPatches
+
+For more information on the git code manager, see:
+
+        http://wiki.x.org/wiki/GitPage
+
diff --git a/autogen.sh b/autogen.sh
new file mode 100644 (file)
index 0000000..904cd67
--- /dev/null
@@ -0,0 +1,12 @@
+#! /bin/sh
+
+srcdir=`dirname $0`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd $srcdir
+
+autoreconf -v --install || exit 1
+cd $ORIGDIR || exit $?
+
+$srcdir/configure --enable-maintainer-mode "$@"
diff --git a/configure.ac b/configure.ac
new file mode 100755 (executable)
index 0000000..172b885
--- /dev/null
@@ -0,0 +1,57 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.60])
+AC_INIT([libICE],
+        [1.0.7],
+        [https://bugs.freedesktop.org/enter_bug.cgi?product=xorg],
+        [libICE])
+
+AC_CONFIG_SRCDIR([Makefile.am])
+AM_INIT_AUTOMAKE([foreign dist-bzip2])
+
+AM_MAINTAINER_MODE
+AM_CONFIG_HEADER([config.h])
+
+# Require xorg-macros minimum of 1.10 for DocBook XML documentation
+m4_ifndef([XORG_MACROS_VERSION],
+          [m4_fatal([must install xorg-macros 1.10 or later before running autoconf/autogen])])
+XORG_MACROS_VERSION(1.10)
+XORG_DEFAULT_OPTIONS
+XORG_ENABLE_DOCS
+XORG_ENABLE_SPECS
+XORG_WITH_XMLTO(0.0.20)
+XORG_WITH_FOP
+XORG_CHECK_SGML_DOCTOOLS(1.5)
+
+# Checks for programs.
+AC_PROG_LIBTOOL
+AC_PROG_CC
+
+# Checks for pkg-config packages
+PKG_CHECK_MODULES(ICE, xproto)
+
+PKG_CHECK_MODULES(XTRANS, xtrans)
+AC_SUBST(XTRANS_CFLAGS)
+AC_SUBST(XTRANS_LIBS)
+
+# Transport selection macro from xtrans.m4
+XTRANS_CONNECTION_FLAGS
+AC_DEFINE(ICE_t, 1, [Xtrans transport type])
+
+# Checks for libraries.
+
+# Checks for header files.
+AC_HEADER_STDC
+
+dnl Allow checking code with lint, sparse, etc.
+XORG_WITH_LINT
+XORG_LINT_LIBRARY([ICE])
+LINT_FLAGS="${LINT_FLAGS} ${ICE_CFLAGS} ${XTRANS_CFLAGS}"
+
+
+AC_OUTPUT([Makefile
+          doc/Makefile
+          specs/Makefile
+          src/Makefile
+          ice.pc])
diff --git a/debian/README.source b/debian/README.source
new file mode 100644 (file)
index 0000000..34ab4bf
--- /dev/null
@@ -0,0 +1,73 @@
+------------------------------------------------------
+Quick Guide To Patching This Package For The Impatient
+------------------------------------------------------
+
+1. Make sure you have quilt installed
+2. Unpack the package as usual with "dpkg-source -x"
+3. Run the "patch" target in debian/rules
+4. Create a new patch with "quilt new" (see quilt(1))
+5. Edit all the files you want to include in the patch with "quilt edit" 
+   (see quilt(1)).
+6. Write the patch with "quilt refresh" (see quilt(1))
+7. Run the "clean" target in debian/rules
+
+Alternatively, instead of using quilt directly, you can drop the patch in to 
+debian/patches and add the name of the patch to debian/patches/series.
+
+------------------------------------
+Guide To The X Strike Force Packages
+------------------------------------
+
+The X Strike Force team maintains X packages in git repositories on
+git.debian.org in the pkg-xorg subdirectory. Most upstream packages
+are actually maintained in git repositories as well, so they often
+just need to be pulled into git.debian.org in a "upstream-*" branch.
+Otherwise, the upstream sources are manually installed in the Debian
+git repository.
+
+The .orig.tar.gz upstream source file could be generated this
+"upstream-*" branch in the Debian git repository but it is actually
+copied from upstream tarballs directly.
+
+Due to X.org being highly modular, packaging all X.org applications
+as their own independent packages would have created too many Debian
+packages. For this reason, some X.org applications have been grouped
+into larger packages: xutils, xutils-dev, x11-apps, x11-session-utils,
+x11-utils, x11-xfs-utils, x11-xkb-utils, x11-xserver-utils.
+Most packages, including the X.org server itself and all libraries
+and drivers are, however maintained independently.
+
+The Debian packaging is added by creating the "debian-*" git branch
+which contains the aforementioned "upstream-*" branch plus the debian/
+repository files.
+When a patch has to be applied to the Debian package, two solutions
+are involved:
+* If the patch is available in one of the upstream branches, it
+  may be git'cherry-picked into the Debian repository. In this
+  case, it appears directly in the .diff.gz.
+* Otherwise, the patch is added to debian/patches/ which is managed
+  with quilt as documented in /usr/share/doc/quilt/README.source.
+
+quilt is actually invoked by the Debian X packaging through a larger
+set of scripts called XSFBS. XSFBS brings some other X specific
+features such as managing dependencies and conflicts due to the video
+and input driver ABIs.
+XSFBS itself is maintained in a separate repository at
+  git://git.debian.org/pkg-xorg/xsfbs.git
+and it is pulled inside the other Debian X repositories when needed.
+
+The XSFBS patching system requires a build dependency on quilt. Also
+a dependency on $(STAMP_DIR)/patch has to be added to debian/rules
+so that the XSFBS patching occurs before the actual build. So the
+very first target of the build (likely the one running autoreconf)
+should depend on $(STAMP_DIR)/patch. It should also not depend on
+anything so that parallel builds are correctly supported (nothing
+should probably run while patching is being done). And finally, the
+clean target should depend on the xsfclean target so that patches
+are unapplied on clean.
+
+When the upstream sources contain some DFSG-nonfree files, they are
+listed in text files in debian/prune/ in the "debian-*" branch of
+the Debian repository. XSFBS' scripts then take care of removing
+these listed files during the build so as to generate a modified
+DFSG-free .orig.tar.gz tarball.
diff --git a/debian/changelog b/debian/changelog
new file mode 100755 (executable)
index 0000000..9bd53a4
--- /dev/null
@@ -0,0 +1,193 @@
+libice (2:1.0.7-1slp2) unstable; urgency=low
+
+  * [X11R7.6] upgrade package
+  * Git: 165.213.180.234:slp/pkgs/xorg/lib/libice
+  * Tag: libice_1.0.7-1slp2
+
+ -- SooChan Lim <sc1.lim@samsung.com>  Mon, 03 Jan 2011 21:57:16 +0900
+
+libice (2:1.0.6-6slp2) unstable; urgency=low
+
+  * Fix Git info and modify package maintainer information
+  * Git: 165.213.180.234:/git/slp/pkgs/xorg/lib/libice
+  * Tag: libice_1.0.6-6slp2
+
+ -- Sung-Jin Park <sj76.park@samsung.com>  Thu, 02 Dec 2010 10:56:19 +0900
+
+libice (2:1.0.6-5slp2) unstable; urgency=low
+
+  * Update maintainer
+  * Git: 165.213.180.234:/git/slp2.0/slp2.0-pkgs/X11
+  * Tag: libice_1.0.6-5slp2
+
+ -- Sung-Jin Park <sj76.park@samsung.com>  Wed, 21 Apr 2010 14:32:06 +0900
+
+libice (2:1.0.6-4slp2) unstable; urgency=low
+
+  * modify the package name
+
+ -- SooChan Lim <sc1.lim@samsung.com>  Thu, 25 Mar 2010 17:34:52 +0900
+
+libice (2:1.0.6-3) unstable; urgency=low
+
+  * Fix debian/rules to install .la file properly
+
+ -- Sung-Jin Park <sj76.park@samsung.com>  Mon, 07 Dec 2009 14:33:14 +0900
+
+libice (2:1.0.6-2) unstable; urgency=low
+
+  * Import debian package
+  * Install .la files
+
+ -- Sung-Jin Park <sj76.park@samsung.com>  Mon, 07 Dec 2009 10:29:59 +0900
+
+libice (2:1.0.6-1) unstable; urgency=low
+
+  [ Julien Cristau ]
+  * libice6-dbg doesn't need to depend on x11-common.
+  * Remove the debian revision from the xtrans-dev build-dep.
+  * Move -dbg package to the debug section.
+
+  [ Timo Aaltonen ]
+  * New upstream release.
+  * Bump Standards-Version to 3.8.3.
+
+ -- Julien Cristau <jcristau@debian.org>  Mon, 23 Nov 2009 17:41:57 +0100
+
+libice (2:1.0.5-1) unstable; urgency=low
+
+  [ Brice Goglin ]
+  * Bump Standards-Version to 3.7.3 (no changes).
+  * Drop the XS- prefix from Vcs-Git and Vcs-Browser fields in debian/control.
+  * Add a link to www.X.org and a reference to the upstream module
+    in the long description.
+
+  [ Julien Cristau ]
+  * New upstream release.
+  * Run autoreconf on build.  Build-depend on automake, libtool and xutils-dev
+    (>= 1:7.4+4).
+  * Handle parallel builds.
+
+ -- Julien Cristau <jcristau@debian.org>  Thu, 19 Feb 2009 17:34:32 +0100
+
+libice (2:1.0.4-1) unstable; urgency=low
+
+  [ Julien Cristau ]
+  * Sync package sections with the override.
+
+  [ Brice Goglin ]
+  * New upstream release.
+  * Fix typo in long descriptions, thanks Philippe Cloutier
+    (closes: #436009).
+
+ -- Brice Goglin <bgoglin@debian.org>  Tue, 21 Aug 2007 09:16:11 +0200
+
+libice (2:1.0.3-3) unstable; urgency=low
+
+  [ Julien Cristau ]
+  * Fix the name of the XS-Vcs-Browser field.
+  * Add the upstream URL to debian/copyright.
+  * Add myself to Uploaders, and remove Fabio and Branden with their
+    permission.
+  * s/Source-Version/binary:Version/ in debian/control.
+
+  [ Timo Aaltonen ]
+  * Bump the epoch so that this can be synced to Ubuntu in the future.
+
+ -- Julien Cristau <jcristau@debian.org>  Mon, 23 Jul 2007 18:26:56 +0200
+
+libice (1:1.0.3-2) unstable; urgency=low
+
+  * Remove outdated cvs information from the package descriptions, and add
+    XS-Vcs-* headers.
+  * Upload to unstable.
+
+ -- Julien Cristau <jcristau@debian.org>  Tue, 10 Apr 2007 19:00:04 +0200
+
+libice (1:1.0.3-1) experimental; urgency=low
+
+  * New upstream release.
+  * Install the upstream ChangeLog.
+
+ -- Julien Cristau <jcristau@debian.org>  Fri,  9 Feb 2007 17:10:45 +0100
+
+libice (1:1.0.1-2) unstable; urgency=low
+
+  [ David Nusinow ]
+  * Add shlibs file to the package, and have it require libice from modular.
+    Thanks Daniel Stone. (closes: #374775)
+
+  [ Andres Salomon ]
+  * Test for obj-$(DEB_BUILD_GNU_TYPE) before creating it during build;
+    idempotency fix.
+
+  [ Drew Parsons ]
+  * dbg package has priority extra.
+  * exclude libICE.la from dh_install
+  * upload to unstable (X11R7.1)
+
+ -- Drew Parsons <dparsons@debian.org>  Fri,  8 Sep 2006 22:26:27 +1000
+
+libice (1:1.0.1-1) experimental; urgency=low
+
+  * New upstream release
+  * Run dh_install with --list-missing
+  * Bump debhelper compat to 5
+  * Remove extra x11-common dep in -dev package
+  * Version x11-common pre-dep in -dev package to use 1:7.0.0 to match the
+    rest of Debian and shut lintian up
+  * Bump build-dep version on xtrans-dev to 1.0.1-1 to make sure we get the
+    security fix
+  * Bump standards version to 3.7.2.0
+  * Don't look to install manpages for the -dev package, there aren't any
+
+ -- David Nusinow <dnusinow@debian.org>  Mon,  3 Jul 2006 16:54:13 -0400
+
+libice (1:1.0.0-3) unstable; urgency=low
+
+  * Reorder makeshlib command in rules file so that ldconfig is run
+    properly. Thanks Drew Parsons and Steve Langasek.
+
+ -- David Nusinow <dnusinow@debian.org>  Tue, 18 Apr 2006 21:49:55 -0400
+
+libice (1:1.0.0-2) unstable; urgency=low
+
+  * Upload to unstable
+
+ -- David Nusinow <dnusinow@debian.org>  Thu, 23 Mar 2006 22:44:24 -0500
+
+libice (1:1.0.0-1) experimental; urgency=low
+
+  * First upload to Debian
+  * Remove 016_ICE_subprotocol_reply_fix.diff as it is now obsolete. Thanks
+    Eugene Konev.
+
+ -- David Nusinow <dnusinow@debian.org>  Thu,  5 Jan 2006 01:19:13 -0500
+
+libice (1:6.3.5-4) breezy; urgency=low
+
+  * Implicit deps are bad, mmmk?
+    Fixed those, so ICE nolonger SEGV's on ia64.
+
+ -- LaMont Jones <lamont@ubuntu.com>  Tue,  4 Oct 2005 04:52:10 -0600
+
+libice (1:6.3.5-3) breezy; urgency=low
+
+  * Add 016_ICE_subprotocol_reply_fix.diff, from the monolithic tree.
+  * Remove pointless <X11/Xlib.h> #include in ICEutil.h.
+  * Make Build-Depend xtrans versioned to a fixed one, to keep buildds a
+    little bit happier.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Wed,  1 Jun 2005 12:34:51 +1000
+
+libice (1:6.3.5-2) breezy; urgency=low
+
+  * Fix Build-Depends-Indep vs B-D hilary/stupidity.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Wed,  1 Jun 2005 00:33:36 +1000
+
+libice (1:6.3.5-1) breezy; urgency=low
+
+  * First libice release.
+
+ -- Daniel Stone <daniel.stone@ubuntu.com>  Mon, 16 May 2005 22:10:17 +1000
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100755 (executable)
index 0000000..6be4a14
--- /dev/null
@@ -0,0 +1,65 @@
+Source: libice
+Section: x11
+Priority: optional
+Maintainer: Sung-Jin Park <sj76.park@samsung.com>, Sangjin Lee <lsj119@samsung.com>, Debian X Strike Force <debian-x@lists.debian.org>
+Uploaders: Sung-Jin Park <sj76.park@samsung.com>, David Nusinow <dnusinow@debian.org>, Drew Parsons <dparsons@debian.org>, Julien Cristau <jcristau@debian.org>
+Build-Depends: debhelper (>= 5.0.0), quilt, pkg-config, x11proto-core-dev, xtrans-dev (>= 1.0.1), automake, libtool, xutils-dev (>= 1:7.4+4)
+Standards-Version: 3.8.3
+Vcs-Git: git://git.debian.org/git/pkg-xorg/lib/libice
+Vcs-Browser: http://git.debian.org/?p=pkg-xorg/lib/libice.git
+
+Package: libice6
+Section: libs
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}, x11-common
+Description: X11 Inter-Client Exchange library
+ This package provides the main interface to the X11 Inter-Client Exchange
+ library, which allows for communication of data between X clients.
+ .
+ More information about X.Org can be found at:
+ <URL:http://www.X.org>
+ <URL:http://xorg.freedesktop.org>
+ <URL:http://lists.freedesktop.org/mailman/listinfo/xorg>
+ .
+ This module can be found at
+ git://anongit.freedesktop.org/git/xorg/lib/libICE
+
+Package: libice6-dbg
+Architecture: any
+Section: debug
+Priority: extra
+Depends: ${shlibs:Depends}, ${misc:Depends}, libice6 (= ${binary:Version})
+Description: X11 Inter-Client Exchange library (debug package)
+ This package provides the main interface to the X11 Inter-Client Exchange
+ library, which allows for communication of data between X clients.
+ .
+ This package contains the debug versions of the library found in libice6.
+ Non-developers likely have little use for this package.
+ .
+ More information about X.Org can be found at:
+ <URL:http://www.X.org>
+ <URL:http://xorg.freedesktop.org>
+ <URL:http://lists.freedesktop.org/mailman/listinfo/xorg>
+ .
+ This module can be found at
+ git://anongit.freedesktop.org/git/xorg/lib/libICE
+
+Package: libice-dev
+Architecture: any
+Section: libdevel
+Depends: ${shlibs:Depends}, ${misc:Depends}, libice6 (= ${binary:Version}), x11proto-core-dev
+Pre-Depends: x11-common (>= 1:7.0.0)
+Description: X11 Inter-Client Exchange library (development headers)
+ This package provides the main interface to the X11 Inter-Client Exchange
+ library, which allows for communication of data between X clients.
+ .
+ This package contains the development headers for the library found in libice6.
+ Non-developers likely have little use for this package.
+ .
+ More information about X.Org can be found at:
+ <URL:http://www.X.org>
+ <URL:http://xorg.freedesktop.org>
+ <URL:http://lists.freedesktop.org/mailman/listinfo/xorg>
+ .
+ This module can be found at
+ git://anongit.freedesktop.org/git/xorg/lib/libICE
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..29dba2f
--- /dev/null
@@ -0,0 +1,26 @@
+This package was downloaded from
+http://xorg.freedesktop.org/releases/individual/lib/
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
diff --git a/debian/libice-dev.install b/debian/libice-dev.install
new file mode 100755 (executable)
index 0000000..91e7591
--- /dev/null
@@ -0,0 +1,5 @@
+usr/include/X11/*
+usr/lib/libICE.a
+usr/lib/libICE.la
+usr/lib/libICE.so
+usr/lib/pkgconfig/ice.pc
diff --git a/debian/libice6.install b/debian/libice6.install
new file mode 100644 (file)
index 0000000..5f5d14d
--- /dev/null
@@ -0,0 +1 @@
+usr/lib/libICE.so.6*
diff --git a/debian/libice6.shlibs b/debian/libice6.shlibs
new file mode 100644 (file)
index 0000000..27bb03d
--- /dev/null
@@ -0,0 +1 @@
+libICE 6 libice6 (>= 1:1.0.0)
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..9aac7a6
--- /dev/null
@@ -0,0 +1,101 @@
+#!/usr/bin/make -f
+# debian/rules for the Debian libice package.
+# Copyright Â© 2004 Scott James Remnant <scott@netsplit.com>
+# Copyright Â© 2005 Daniel Stone <daniel@fooishbar.org>
+# Copyright Â© 2005 David Nusinow <dnusinow@debian.org>
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# set this to the name of the main shlib's binary package
+PACKAGE = libice6
+
+include debian/xsfbs/xsfbs.mk
+
+CFLAGS = -Wall -g
+ifneq (,$(filter noopt,$(DEB_BUILD_OPTIONS)))
+       CFLAGS += -O0
+else
+       CFLAGS += -O2
+endif
+ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+       NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
+       MAKEFLAGS += -j$(NUMJOBS)
+endif
+
+DEB_HOST_ARCH      ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
+DEB_HOST_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
+DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
+ifeq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE))
+       confflags += --build=$(DEB_HOST_GNU_TYPE)
+else
+       confflags += --build=$(DEB_HOST_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE)
+#      confflags += --build=$(DEB_BUILD_GNU_TYPE) --host=$(DEB_HOST_GNU_TYPE)
+endif
+
+configure: $(STAMP_DIR)/patch
+       dh_testdir
+       autoreconf -vfi
+
+build: build-stamp
+build-stamp: configure
+       dh_testdir
+
+       test -d obj-$(DEB_BUILD_GNU_TYPE) || mkdir obj-$(DEB_BUILD_GNU_TYPE)
+       cd obj-$(DEB_BUILD_GNU_TYPE) && \
+       ../configure --prefix=/usr --mandir=\$${prefix}/share/man \
+                    --infodir=\$${prefix}/share/info $(confflags) \
+                    CFLAGS="$(CFLAGS)" 
+       cd obj-$(DEB_BUILD_GNU_TYPE) && $(MAKE)
+       >$@
+
+clean: xsfclean
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp
+
+       rm -f config.cache config.log config.status
+       rm -f */config.cache */config.log */config.status
+       rm -f conftest* */conftest*
+       rm -rf autom4te.cache */autom4te.cache
+       rm -rf obj-*
+       rm -f aclocal.m4 config.guess config.sub config.h.in configure
+       rm -f depcomp install-sh ltmain.sh missing mkinstalldirs INSTALL
+       rm -f $$(find -name Makefile.in)
+
+       dh_clean
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k
+       dh_installdirs
+
+       cd obj-$(DEB_BUILD_GNU_TYPE) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+
+#      dh_installdocs
+       dh_install --sourcedir=debian/tmp --list-missing
+       #dh_install --sourcedir=debian/tmp --list-missing --exclude=libICE.la
+#      dh_installchangelogs ChangeLog
+       dh_link
+       dh_strip --dbg-package=$(PACKAGE)-dbg
+       dh_compress
+       dh_fixperms
+       dh_makeshlibs
+       dh_shlibdeps
+       dh_installdeb
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+# Build architecture-independent files here.
+binary-indep: build install
+# Nothing to do
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install
diff --git a/debian/watch b/debian/watch
new file mode 100644 (file)
index 0000000..9541a03
--- /dev/null
@@ -0,0 +1,2 @@
+version=3
+http://xorg.freedesktop.org/releases/individual/lib/ libICE-(.*)\.tar\.gz
diff --git a/debian/xsfbs/repack.sh b/debian/xsfbs/repack.sh
new file mode 100644 (file)
index 0000000..5935cc9
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+set -e
+
+if ! [ -d debian/prune ]; then
+       exit 0
+fi
+
+if [ "x$1" != x--upstream-version ]; then
+       exit 1
+fi
+
+version="$2"
+filename="$3"
+
+if [ -z "$version" ] || ! [ -f "$filename" ]; then
+       exit 1
+fi
+
+dir="$(pwd)"
+tempdir="$(mktemp -d)"
+
+cd "$tempdir"
+tar xf "$dir/$filename"
+cat "$dir"/debian/prune/* | while read file; do rm -f */$file; done
+
+tar czf "$dir/$filename" *
+cd "$dir"
+rm -rf "$tempdir"
+echo "Done pruning upstream tarball"
+
+exit 0
diff --git a/debian/xsfbs/xsfbs.mk b/debian/xsfbs/xsfbs.mk
new file mode 100644 (file)
index 0000000..5e16b10
--- /dev/null
@@ -0,0 +1,276 @@
+#!/usr/bin/make -f
+
+# Debian X Strike Force Build System (XSFBS): Make portion
+
+# Copyright 1996 Stephen Early
+# Copyright 1997 Mark Eichin
+# Copyright 1998-2005, 2007 Branden Robinson
+# Copyright 2005 David Nusinow
+#
+# Licensed under the GNU General Public License, version 2.  See the file
+# /usr/share/common-licenses/GPL or <http://www.gnu.org/copyleft/gpl.txt>.
+
+# Originally by Stephen Early <sde1000@debian.org>
+# Modified by Mark W. Eichin <eichin@kitten.gen.ma.us>
+# Modified by Adam Heath <doogie@debian.org>
+# Modified by Branden Robinson <branden@debian.org>
+# Modified by Fabio Massimo Di Nitto <fabbione@fabbione.net>
+# Modified by David Nusinow <dnusinow@debian.org>
+# Acknowledgements to Manoj Srivastava.
+
+# Pass $(DH_OPTIONS) into the environment for debhelper's benefit.
+export DH_OPTIONS
+
+# force quilt to not use ~/.quiltrc and to use debian/patches
+QUILT = QUILT_PATCHES=debian/patches quilt --quiltrc /dev/null
+
+# Set up parameters for the upstream build environment.
+
+# Determine (source) package name from Debian changelog.
+SOURCE_NAME:=$(shell dpkg-parsechangelog -ldebian/changelog \
+                        | grep '^Source:' | awk '{print $$2}')
+
+# Determine package version from Debian changelog.
+SOURCE_VERSION:=$(shell dpkg-parsechangelog -ldebian/changelog \
+                        | grep '^Version:' | awk '{print $$2}')
+
+# Determine upstream version number.
+UPSTREAM_VERSION:=$(shell echo $(SOURCE_VERSION) | sed 's/-.*//')
+
+# Determine the source version without the epoch for make-orig-tar-gz
+NO_EPOCH_VER:=$(shell echo $(UPSTREAM_VERSION) | sed 's/^.://')
+
+# Figure out who's building this package.
+BUILDER:=$(shell echo $${DEBEMAIL:-$${EMAIL:-$$(echo $$LOGNAME@$$(cat /etc/mailname 2>/dev/null))}})
+
+# Find out if this is an official build; an official build has nothing but
+# digits, dots, and/or the codename of a release in the Debian part of the
+# version number.  Anything else indicates an unofficial build.
+OFFICIAL_BUILD:=$(shell VERSION=$(SOURCE_VERSION); if ! expr "$$(echo $${VERSION\#\#*-} | sed 's/\(woody\|sarge\|etch\|lenny\)//g')" : ".*[^0-9.].*" >/dev/null 2>&1; then echo yes; fi)
+
+# Set up parameters for the Debian build environment.
+
+# Determine our architecture.
+BUILD_ARCH:=$(shell dpkg-architecture -qDEB_BUILD_ARCH)
+# Work around some old-time dpkg braindamage.
+BUILD_ARCH:=$(subst i486,i386,$(BUILD_ARCH))
+# The DEB_HOST_ARCH variable may be set per the Debian cross-compilation policy.
+ifdef DEB_HOST_ARCH
+ ARCH:=$(DEB_HOST_ARCH)
+else
+ # dpkg-cross sets the ARCH environment variable; if set, use it.
+ ifdef ARCH
+  ARCH:=$(ARCH)
+ else
+  ARCH:=$(BUILD_ARCH)
+ endif
+endif
+
+# $(STAMP_DIR) houses stamp files for complex targets.
+STAMP_DIR:=stampdir
+
+# $(DEBTREEDIR) is where all install rules are told (via $(DESTDIR)) to place
+# their files.
+DEBTREEDIR:=$(CURDIR)/debian/tmp
+
+# All "important" targets have four lines:
+#   1) A target name that is invoked by a package-building tool or the user.
+#      This consists of a dependency on a "$(STAMP_DIR)/"-prefixed counterpart.
+#   2) A line delcaring 1) as a phony target (".PHONY:").
+#   3) A "$(STAMP_DIR)/"-prefixed target which does the actual work, and may
+#   depend on other targets.
+#   4) A line declaring 3) as a member of the $(stampdir_targets) variable; the
+#   "$(STAMP_DIR)/" prefix is omitted.
+#
+# This indirection is needed so that the "stamp" files that signify when a rule
+# is done can be located in a separate "stampdir".  Recall that make has no way
+# to know when a goal has been met for a phony target (like "build" or
+# "install").
+#
+# At the end of each "$(STAMP_DIR)/" target, be sure to run the command ">$@"
+# so that the target will not be run again.  Removing the file will make Make
+# run the target over.
+
+# All phony targets should be declared as dependencies of .PHONY, even if they
+# do not have "($STAMP_DIR)/"-prefixed counterparts.
+
+# Define a harmless default rule to keep things from going nuts by accident.
+.PHONY: default
+default:
+
+# Set up the $(STAMP_DIR) directory.
+.PHONY: stampdir
+stampdir_targets+=stampdir
+stampdir: $(STAMP_DIR)/stampdir
+$(STAMP_DIR)/stampdir:
+       mkdir $(STAMP_DIR)
+       >$@
+
+# Set up the package build directory as quilt expects to find it.
+.PHONY: prepare
+stampdir_targets+=prepare
+prepare: $(STAMP_DIR)/prepare
+$(STAMP_DIR)/prepare: $(STAMP_DIR)/log $(STAMP_DIR)/genscripts
+       >$@
+
+.PHONY: log
+stampdir_targets+=log
+log: $(STAMP_DIR)/log
+$(STAMP_DIR)/log: $(STAMP_DIR)/stampdir
+       mkdir -p $(STAMP_DIR)/log
+
+# Apply all patches to the upstream source.
+.PHONY: patch
+stampdir_targets+=patch
+patch: $(STAMP_DIR)/patch
+$(STAMP_DIR)/patch: $(STAMP_DIR)/prepare
+       if ! [ `which quilt` ]; then \
+               echo "Couldn't find quilt. Please install it or add it to the build-depends for this package."; \
+               exit 1; \
+       fi; \
+       if $(QUILT) next >/dev/null 2>&1; then \
+         echo -n "Applying patches..."; \
+         if $(QUILT) push -a -v >$(STAMP_DIR)/log/patch 2>&1; then \
+           cat $(STAMP_DIR)/log/patch; \
+           echo "successful."; \
+         else \
+           cat $(STAMP_DIR)/log/patch; \
+           echo "failed! (check $(STAMP_DIR)/log/patch for details)"; \
+           exit 1; \
+         fi; \
+       else \
+         echo "No patches to apply"; \
+       fi; \
+       >$@
+
+# Revert all patches to the upstream source.
+.PHONY: unpatch
+unpatch: $(STAMP_DIR)/log
+       rm -f $(STAMP_DIR)/patch
+       @echo -n "Unapplying patches..."; \
+       if $(QUILT) applied >/dev/null 2>/dev/null; then \
+         if $(QUILT) pop -a -v >$(STAMP_DIR)/log/unpatch 2>&1; then \
+           cat $(STAMP_DIR)/log/unpatch; \
+           echo "successful."; \
+         else \
+           cat $(STAMP_DIR)/log/unpatch; \
+           echo "failed! (check $(STAMP_DIR)/log/unpatch for details)"; \
+           exit 1; \
+         fi; \
+       else \
+         echo "nothing to do."; \
+       fi
+
+# Clean the generated maintainer scripts.
+.PHONY: cleanscripts
+cleanscripts:
+       rm -f $(STAMP_DIR)/genscripts
+       rm -f debian/*.config \
+             debian/*.postinst \
+             debian/*.postrm \
+             debian/*.preinst \
+             debian/*.prerm
+
+# Clean the package build tree.
+.PHONY: xsfclean
+xsfclean: cleanscripts unpatch
+       dh_testdir
+       rm -rf .pc
+       rm -rf $(STAMP_DIR)
+       dh_clean
+
+# Remove files from the upstream source tree that we don't need, or which have
+# licensing problems.  It must be run before creating the .orig.tar.gz.
+#
+# Note: This rule is for Debian package maintainers' convenience, and is not
+# needed for conventional build scenarios.
+.PHONY: prune-upstream-tree
+prune-upstream-tree:
+       # Ensure we're in the correct directory.
+       dh_testdir
+       grep -rvh '^#' debian/prune/ | xargs --no-run-if-empty rm -rf
+
+# Verify that there are no offsets or fuzz in the patches we apply.
+#
+# Note: This rule is for Debian package maintainers' convenience, and is not
+# needed for conventional build scenarios.
+.PHONY: patch-audit
+patch-audit: prepare unpatch
+       @echo -n "Auditing patches..."; \
+       >$(STAMP_DIR)/log/patch; \
+       FUZZY=; \
+       while [ -n "$$($(QUILT) next)" ]; do \
+         RESULT=$$($(QUILT) push -v | tee -a $(STAMP_DIR)/log/patch | grep ^Hunk | sed 's/^Hunk.*\(succeeded\|FAILED\).*/\1/');\
+         case "$$RESULT" in \
+           succeeded) \
+             echo "fuzzy patch: $$($(QUILT) top)" \
+               | tee -a $(STAMP_DIR)/log/$$($(QUILT) top); \
+             FUZZY=yes; \
+             ;; \
+           FAILED) \
+             echo "broken patch: $$($(QUILT) next)" \
+               | tee -a $(STAMP_DIR)/log/$$($(QUILT) next); \
+             exit 1; \
+             ;; \
+         esac; \
+       done; \
+       if [ -n "$$FUZZY" ]; then \
+         echo "there were fuzzy patches; please fix."; \
+         exit 1; \
+       else \
+         echo "done."; \
+       fi
+
+# Generate the maintainer scripts.
+.PHONY: genscripts
+stampdir_targets+=genscripts
+genscripts: $(STAMP_DIR)/genscripts
+$(STAMP_DIR)/genscripts: $(STAMP_DIR)/stampdir
+       for FILE in debian/*.config.in \
+                   debian/*.postinst.in \
+                   debian/*.postrm.in \
+                   debian/*.preinst.in \
+                   debian/*.prerm.in; do \
+         if [ -e "$$FILE" ]; then \
+           MAINTSCRIPT=$$(echo $$FILE | sed 's/.in$$//'); \
+           sed -n '1,/^#INCLUDE_SHELL_LIB#$$/p' <$$FILE \
+             | sed -e '/^#INCLUDE_SHELL_LIB#$$/d' >$$MAINTSCRIPT.tmp; \
+           cat debian/xsfbs/xsfbs.sh >>$$MAINTSCRIPT.tmp; \
+           sed -n '/^#INCLUDE_SHELL_LIB#$$/,$$p' <$$FILE \
+             | sed -e '/^#INCLUDE_SHELL_LIB#$$/d' >>$$MAINTSCRIPT.tmp; \
+           sed -e 's/@SOURCE_VERSION@/$(SOURCE_VERSION)/' \
+               -e 's/@OFFICIAL_BUILD@/$(OFFICIAL_BUILD)/' \
+             <$$MAINTSCRIPT.tmp >$$MAINTSCRIPT; \
+           rm $$MAINTSCRIPT.tmp; \
+         fi; \
+       done
+       # Validate syntax of generated shell scripts.
+       #sh debian/scripts/validate-posix-sh debian/*.config \
+       #                                    debian/*.postinst \
+       #                                    debian/*.postrm \
+       #                                    debian/*.preinst \
+       #                                    debian/*.prerm
+       >$@
+
+SERVERMINVERS = $(shell cat /usr/share/xserver-xorg/serverminver 2>/dev/null)
+VIDEOABI = $(shell cat /usr/share/xserver-xorg/videoabiver 2>/dev/null)
+INPUTABI = $(shell cat /usr/share/xserver-xorg/inputabiver 2>/dev/null)
+SERVER_DEPENDS = xserver-xorg-core (>= $(SERVERMINVERS))
+VIDDRIVER_PROVIDES = xserver-xorg-video-$(VIDEOABI)
+INPDRIVER_PROVIDES = xserver-xorg-input-$(INPUTABI)
+ifeq ($(PACKAGE),)
+PACKAGE=$(shell awk '/^Package:/ { print $$2; exit }' < debian/control)
+endif
+
+.PHONY: serverabi
+serverabi: install
+ifeq ($(SERVERMINVERS),)
+       @echo error: xserver-xorg-dev needs to be installed
+       @exit 1
+else
+       echo "xserver:Depends=$(SERVER_DEPENDS)" >> debian/$(PACKAGE).substvars
+       echo "xviddriver:Provides=$(VIDDRIVER_PROVIDES)" >> debian/$(PACKAGE).substvars
+       echo "xinpdriver:Provides=$(INPDRIVER_PROVIDES)" >> debian/$(PACKAGE).substvars
+endif
+
+# vim:set noet ai sts=8 sw=8 tw=0:
diff --git a/debian/xsfbs/xsfbs.sh b/debian/xsfbs/xsfbs.sh
new file mode 100644 (file)
index 0000000..813fd8d
--- /dev/null
@@ -0,0 +1,622 @@
+# This is the X Strike Force shell library for X Window System package
+# maintainer scripts.  It serves to define shell functions commonly used by
+# such packages, and performs some error checking necessary for proper operation
+# of those functions.  By itself, it does not "do" much; the maintainer scripts
+# invoke the functions defined here to accomplish package installation and
+# removal tasks.
+
+# If you are reading this within a Debian package maintainer script (e.g.,
+# /var/lib/dpkg/info/PACKAGE.{config,preinst,postinst,prerm,postrm}), you can
+# skip past this library by scanning forward in this file to the string
+# "GOBSTOPPER".
+
+SOURCE_VERSION=@SOURCE_VERSION@
+OFFICIAL_BUILD=@OFFICIAL_BUILD@
+
+# Use special abnormal exit codes so that problems with this library are more
+# easily tracked down.
+SHELL_LIB_INTERNAL_ERROR=86
+SHELL_LIB_THROWN_ERROR=74
+SHELL_LIB_USAGE_ERROR=99
+
+# old -> new variable names
+if [ -z "$DEBUG_XORG_PACKAGE" ] && [ -n "$DEBUG_XFREE86_PACKAGE" ]; then
+  DEBUG_XORG_PACKAGE="$DEBUG_XFREE86_PACKAGE"
+fi
+if [ -z "$DEBUG_XORG_DEBCONF" ] && [ -n "$DEBUG_XFREE86_DEBCONF" ]; then
+  DEBUG_XORG_DEBCONF="$DEBUG_XFREE86_DEBCONF"
+fi
+
+# initial sanity checks
+if [ -z "$THIS_PACKAGE" ]; then
+  cat >&2 <<EOF
+Error: package maintainer script attempted to use shell library without
+definining \$THIS_PACKAGE shell variable.  Please report the package name,
+version, and the text of this error message to the Debian Bug Tracking System.
+Visit <http://www.debian.org/Bugs/Reporting> on the World Wide Web for
+instructions, read the file /usr/share/doc/debian/bug-reporting.txt from the
+"doc-debian" package, or install the "reportbug" package and use the command of
+the same name to file a report against version $SOURCE_VERSION of this package.
+EOF
+  exit $SHELL_LIB_USAGE_ERROR
+fi
+
+if [ -z "$THIS_SCRIPT" ]; then
+  cat >&2 <<EOF
+Error: package maintainer script attempted to use shell library without
+definining \$THIS_SCRIPT shell variable.  Please report the package name,
+version, and the text of this error message to the Debian Bug Tracking System.
+Visit <http://www.debian.org/Bugs/Reporting> on the World Wide Web for
+instructions, read the file /usr/share/doc/debian/bug-reporting.txt from the
+"doc-debian" package, or install the "reportbug" package and use the command of
+the same name to file a report against version $SOURCE_VERSION of the
+"$THIS_PACKAGE" package.
+EOF
+  exit $SHELL_LIB_USAGE_ERROR
+fi
+
+if [ "$1" = "reconfigure" ] || [ -n "$DEBCONF_RECONFIGURE" ]; then
+  RECONFIGURE="true"
+else
+  RECONFIGURE=
+fi
+
+if ([ "$1" = "install" ] || [ "$1" = "configure" ]) && [ -z "$2" ]; then
+  FIRSTINST="yes"
+fi
+
+if [ -z "$RECONFIGURE" ] && [ -z "$FIRSTINST" ]; then
+  UPGRADE="yes"
+fi
+
+trap "message;\
+      message \"Received signal.  Aborting $THIS_PACKAGE package $THIS_SCRIPT script.\";\
+      message;\
+      exit 1" HUP INT QUIT TERM
+
+reject_nondigits () {
+  # syntax: reject_nondigits [ operand ... ]
+  #
+  # scan operands (typically shell variables whose values cannot be trusted) for
+  # characters other than decimal digits and barf if any are found
+  while [ -n "$1" ]; do
+    # does the operand contain anything but digits?
+    if ! expr "$1" : "[[:digit:]]\+$" > /dev/null 2>&1; then
+      # can't use die(), because it wraps message() which wraps this function
+      echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_nondigits() encountered" \
+           "possibly malicious garbage \"$1\"" >&2
+      exit $SHELL_LIB_THROWN_ERROR
+    fi
+    shift
+  done
+}
+
+reject_unlikely_path_chars () {
+  # syntax: reject_unlikely_path_chars [ operand ... ]
+  #
+  # scan operands (typically shell variables whose values cannot be trusted) for
+  # characters unlikely to be seen in a path and which the shell might
+  # interpret and barf if any are found
+  while [ -n "$1" ]; do
+    # does the operand contain any funny characters?
+    if expr "$1" : '.*[!$&()*;<>?|].*' > /dev/null 2>&1; then
+      # can't use die(), because I want to avoid forward references
+      echo "$THIS_PACKAGE $THIS_SCRIPT error: reject_unlikely_path_chars()" \
+           "encountered possibly malicious garbage \"$1\"" >&2
+      exit $SHELL_LIB_THROWN_ERROR
+    fi
+    shift
+  done
+}
+
+# Query the terminal to establish a default number of columns to use for
+# displaying messages to the user.  This is used only as a fallback in the
+# event the COLUMNS variable is not set.  ($COLUMNS can react to SIGWINCH while
+# the script is running, and this cannot, only being calculated once.)
+DEFCOLUMNS=$(stty size 2> /dev/null | awk '{print $2}') || true
+if ! expr "$DEFCOLUMNS" : "[[:digit:]]\+$" > /dev/null 2>&1; then
+  DEFCOLUMNS=80
+fi
+
+message () {
+  # pretty-print messages of arbitrary length
+  reject_nondigits "$COLUMNS"
+  echo "$*" | fmt -t -w ${COLUMNS:-$DEFCOLUMNS} >&2
+}
+
+observe () {
+  # syntax: observe message ...
+  #
+  # issue observational message suitable for logging someday when support for
+  # it exists in dpkg
+  if [ -n "$DEBUG_XORG_PACKAGE" ]; then
+    message "$THIS_PACKAGE $THIS_SCRIPT note: $*"
+  fi
+}
+
+warn () {
+  # syntax: warn message ...
+  #
+  # issue warning message suitable for logging someday when support for
+  # it exists in dpkg; also send to standard error
+  message "$THIS_PACKAGE $THIS_SCRIPT warning: $*"
+}
+
+die () {
+  # syntax: die message ...
+  #
+  # exit script with error message
+  message "$THIS_PACKAGE $THIS_SCRIPT error: $*"
+  exit $SHELL_LIB_THROWN_ERROR
+}
+
+internal_error () {
+  # exit script with error; essentially a "THIS SHOULD NEVER HAPPEN" message
+  message "internal error: $*"
+  if [ -n "$OFFICIAL_BUILD" ]; then
+    message "Please report a bug in the $THIS_SCRIPT script of the" \
+            "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \
+            "Tracking System.  Include all messages above that mention the" \
+            "$THIS_PACKAGE package.  Visit " \
+            "<http://www.debian.org/Bugs/Reporting> on the World Wide Web for" \
+            "instructions, read the file" \
+            "/usr/share/doc/debian/bug-reporting.txt from the doc-debian" \
+            "package, or install the reportbug package and use the command of" \
+            "the same name to file a report."
+  fi
+  exit $SHELL_LIB_INTERNAL_ERROR
+}
+
+usage_error () {
+  message "usage error: $*"
+  message "Please report a bug in the $THIS_SCRIPT script of the" \
+          "$THIS_PACKAGE package, version $SOURCE_VERSION to the Debian Bug" \
+          "Tracking System.  Include all messages above that mention the" \
+          "$THIS_PACKAGE package.  Visit " \
+          "<http://www.debian.org/Bugs/Reporting> on the World Wide Web for" \
+          "instructions, read the file" \
+          "/usr/share/doc/debian/bug-reporting.txt from the doc-debian" \
+          "package, or install the reportbug package and use the command of" \
+          "the same name to file a report."
+  exit $SHELL_LIB_USAGE_ERROR
+}
+
+font_update () {
+  # run $UPDATECMDS in $FONTDIRS
+
+  local dir cmd shortcmd x_font_dir_prefix
+
+  x_font_dir_prefix="/usr/share/fonts/X11"
+
+  if [ -z "$UPDATECMDS" ]; then
+    usage_error "font_update() called but \$UPDATECMDS not set"
+  fi
+  if [ -z "$FONTDIRS" ]; then
+    usage_error "font_update() called but \$FONTDIRS not set"
+  fi
+
+  reject_unlikely_path_chars "$UPDATECMDS"
+  reject_unlikely_path_chars "$FONTDIRS"
+
+  for dir in $FONTDIRS; do
+    if [ -d "$x_font_dir_prefix/$dir" ]; then
+      for cmd in $UPDATECMDS; do
+        if which "$cmd" > /dev/null 2>&1; then
+          shortcmd=${cmd##*/}
+          observe "running $shortcmd in $dir font directory"
+         cmd_opts=
+          if [ "$shortcmd" = "update-fonts-alias" ]; then
+            cmd_opts=--x11r7-layout
+          fi
+          if [ "$shortcmd" = "update-fonts-dir" ]; then
+            cmd_opts=--x11r7-layout
+          fi
+          if [ "$shortcmd" = "update-fonts-scale" ]; then
+            cmd_opts=--x11r7-layout
+          fi
+          $cmd $cmd_opts $dir || warn "$cmd $cmd_opts $dir" \
+                              "failed; font directory data may not" \
+                              "be up to date"
+        else
+          warn "$cmd not found; not updating corresponding $dir font" \
+               "directory data"
+        fi
+      done
+    else
+      warn "$dir is not a directory; not updating font directory data"
+    fi
+  done
+}
+
+remove_conffile_prepare () {
+  # syntax: remove_conffile_prepare filename official_md5sum ...
+  #
+  # Check a conffile "filename" against a list of canonical MD5 checksums.
+  # If the file's current MD5 checksum matches one of the "official_md5sum"
+  # operands provided, then prepare the conffile for removal from the system.
+  # We defer actual deletion until the package is configured so that we can
+  # roll this operation back if package installation fails.
+  #
+  # Call this function from a preinst script in the event $1 is "upgrade" or
+  # "install" and verify $2 to ensure the package is being upgraded from a
+  # version (or installed over a version removed-but-not-purged) prior to the
+  # one in which the conffile was obsoleted.
+
+  local conffile current_checksum
+
+  # validate arguments
+  if [ $# -lt 2 ]; then
+    usage_error "remove_conffile_prepare() called with wrong number of" \
+                "arguments; expected at least 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+  shift
+
+  # does the conffile even exist?
+  if [ -e "$conffile" ]; then
+    # calculate its checksum
+    current_checksum=$(md5sum < "$conffile" | sed 's/[[:space:]].*//')
+    # compare it to each supplied checksum
+    while [ -n "$1" ]; do
+      if [ "$current_checksum" = "$1" ]; then
+        # we found a match; move the confffile and stop looking
+        observe "preparing obsolete conffile $conffile for removal"
+        mv "$conffile" "$conffile.$THIS_PACKAGE-tmp"
+        break
+      fi
+      shift
+    done
+  fi
+}
+
+remove_conffile_lookup () {
+  # syntax: remove_conffile_lookup package filename
+  #
+  # Lookup the md5sum of a conffile in dpkg's database, and prepare for removal
+  # if it matches the actual file's md5sum.
+  #
+  # Call this function when you would call remove_conffile_prepare but only
+  # want to check against dpkg's status database instead of known checksums.
+
+  local package conffile old_md5sum
+
+  # validate arguments
+  if [ $# -ne 2 ]; then
+    usage_error "remove_conffile_lookup() called with wrong number of" \
+                "arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  package="$1"
+  conffile="$2"
+
+  if ! [ -e "$conffile" ]; then
+    return
+  fi
+  old_md5sum="$(dpkg-query -W -f='${Conffiles}' "$package" | \
+    awk '{ if (match($0, "^ '"$conffile"' ")) print $2}')"
+  if [ -n "$old_md5sum" ]; then
+    remove_conffile_prepare "$conffile" "$old_md5sum"
+  fi
+}
+
+remove_conffile_commit () {
+  # syntax: remove_conffile_commit filename
+  #
+  # Complete the removal of a conffile "filename" that has become obsolete.
+  #
+  # Call this function from a postinst script after having used
+  # remove_conffile_prepare() in the preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 1 ]; then
+    usage_error "remove_conffile_commit() called with wrong number of" \
+                "arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+
+  # if the temporary file created by remove_conffile_prepare() exists, remove it
+  if [ -e "$conffile.$THIS_PACKAGE-tmp" ]; then
+    observe "committing removal of obsolete conffile $conffile"
+    rm "$conffile.$THIS_PACKAGE-tmp"
+  fi
+}
+
+remove_conffile_rollback () {
+  # syntax: remove_conffile_rollback filename
+  #
+  # Roll back the removal of a conffile "filename".
+  #
+  # Call this function from a postrm script in the event $1 is "abort-upgrade"
+  # or "abort-install" is  after having used remove_conffile_prepare() in the
+  # preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 1 ]; then
+    usage_error "remove_conffile_rollback() called with wrong number of" \
+                "arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+
+  # if the temporary file created by remove_conffile_prepare() exists, move it
+  # back
+  if [ -e "$conffile.$THIS_PACKAGE-tmp" ]; then
+    observe "rolling back removal of obsolete conffile $conffile"
+    mv "$conffile.$THIS_PACKAGE-tmp" "$conffile"
+  fi
+}
+
+replace_conffile_with_symlink_prepare () {
+  # syntax: replace_conffile_with_symlink_prepare oldfilename newfilename \
+  # official_md5sum ...
+  #
+  # Check a conffile "oldfilename" against a list of canonical MD5 checksums.
+  # If the file's current MD5 checksum matches one of the "official_md5sum"
+  # operands provided, then prepare the conffile for removal from the system.
+  # We defer actual deletion until the package is configured so that we can
+  # roll this operation back if package installation fails. Otherwise copy it
+  # to newfilename and let dpkg handle it through conffiles mechanism.
+  #
+  # Call this function from a preinst script in the event $1 is "upgrade" or
+  # "install" and verify $2 to ensure the package is being upgraded from a
+  # version (or installed over a version removed-but-not-purged) prior to the
+  # one in which the conffile was obsoleted.
+
+  local conffile current_checksum
+
+  # validate arguments
+  if [ $# -lt 3 ]; then
+    usage_error "replace_conffile_with_symlink_prepare() called with wrong" \
+                " number of arguments; expected at least 3, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  oldconffile="$1"
+  shift
+  newconffile="$1"
+  shift
+
+  remove_conffile_prepare "$_oldconffile" "$@"
+  # If $oldconffile still exists, then md5sums didn't match.
+  # Copy it to new one.
+  if [ -f "$oldconffile" ]; then
+    cp "$oldconffile" "$newconffile"
+  fi
+
+}
+
+replace_conffile_with_symlink_commit () {
+  # syntax: replace_conffile_with_symlink_commit oldfilename
+  #
+  # Complete the removal of a conffile "oldfilename" that has been
+  # replaced by a symlink.
+  #
+  # Call this function from a postinst script after having used
+  # replace_conffile_with_symlink_prepare() in the preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 1 ]; then
+    usage_error "replace_conffile_with_symlink_commit() called with wrong" \
+                "number of arguments; expected 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  conffile="$1"
+
+  remove_conffile_commit "$conffile"
+}
+
+replace_conffile_with_symlink_rollback () {
+  # syntax: replace_conffile_with_symlink_rollback oldfilename newfilename
+  #
+  # Roll back the replacing of a conffile "oldfilename" with symlink to
+  # "newfilename".
+  #
+  # Call this function from a postrm script in the event $1 is "abort-upgrade"
+  # or "abort-install" and verify $2 to ensure the package failed to upgrade
+  # from a version (or install over a version removed-but-not-purged) prior
+  # to the one in which the conffile was obsoleted.
+  # You should have  used replace_conffile_with_symlink_prepare() in the
+  # preinst.
+
+  local conffile
+
+  # validate arguments
+  if [ $# -ne 2 ]; then
+    usage_error "replace_conffile_with_symlink_rollback() called with wrong" \
+                "number of arguments; expected 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  oldconffile="$1"
+  newconffile="$2"
+
+  remove_conffile_rollback "$_oldconffile"
+  if [ -f "$newconffile" ]; then
+    rm "$newconffile"
+  fi
+}
+
+run () {
+  # syntax: run command [ argument ... ]
+  #
+  # Run specified command with optional arguments and report its exit status.
+  # Useful for commands whose exit status may be nonzero, but still acceptable,
+  # or commands whose failure is not fatal to us.
+  #
+  # NOTE: Do *not* use this function with db_get or db_metaget commands; in
+  # those cases the return value of the debconf command *must* be checked
+  # before the string returned by debconf is used for anything.
+
+  local retval
+
+  # validate arguments
+  if [ $# -lt 1 ]; then
+    usage_error "run() called with wrong number of arguments; expected at" \
+                "least 1, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  "$@" || retval=$?
+
+  if [ ${retval:-0} -ne 0 ]; then
+    observe "command \"$*\" exited with status $retval"
+  fi
+}
+
+make_symlink_sane () {
+  # syntax: make_symlink_sane symlink target
+  #
+  # Ensure that the symbolic link symlink exists, and points to target.
+  #
+  # If symlink does not exist, create it and point it at target.
+  #
+  # If symlink exists but is not a symbolic link, back it up.
+  #
+  # If symlink exists, is a symbolic link, but points to the wrong location, fix
+  # it.
+  #
+  # If symlink exists, is a symbolic link, and already points to target, do
+  # nothing.
+  #
+  # This function wouldn't be needed if ln had an -I, --idempotent option.
+
+  # Validate arguments.
+  if [ $# -ne 2 ]; then
+    usage_error "make_symlink_sane() called with wrong number of arguments;" \
+      "expected 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  # We could just use the positional parameters as-is, but that makes things
+  # harder to follow.
+  local symlink target
+
+  symlink="$1"
+  target="$2"
+
+  if [ -L "$symlink" ] && [ "$(readlink "$symlink")" = "$target" ]; then
+      observe "link from $symlink to $target already exists"
+  else
+    observe "creating symbolic link from $symlink to $target"
+    mkdir -p "${target%/*}" "${symlink%/*}"
+    ln -s -b -S ".dpkg-old" "$target" "$symlink"
+  fi
+}
+
+migrate_dir_to_symlink () {
+  # syntax: migrate_dir_to_symlink old_location new_location
+  #
+  # Per Debian Policy section 6.5.4, "A directory will never be replaced by a
+  # symbolic link to a directory or vice versa; instead, the existing state
+  # (symlink or not) will be left alone and dpkg will follow the symlink if
+  # there is one."
+  #
+  # We have to do it ourselves.
+  #
+  # This function moves the contents of old_location, a directory, into
+  # new_location, a directory, then makes old_location a symbolic link to
+  # new_location.
+  #
+  # old_location need not exist, but if it does, it must be a directory (or a
+  # symlink to a directory).  If it is not, it is backed up.  If new_location
+  # exists already and is not a directory, it is backed up.
+  #
+  # This function should be called from a package's preinst so that other
+  # packages unpacked after this one --- but before this package's postinst runs
+  # --- are unpacked into new_location even if their payloads contain
+  # old_location filespecs.
+
+  # Validate arguments.
+  if [ $# -ne 2 ]; then
+    usage_error "migrate_dir_to_symlink() called with wrong number of"
+                "arguments; expected 2, got $#"
+    exit $SHELL_LIB_USAGE_ERROR
+  fi
+
+  # We could just use the positional parameters as-is, but that makes things
+  # harder to follow.
+  local new old
+
+  old="$1"
+  new="$2"
+
+  # Is old location a symlink?
+  if [ -L "$old" ]; then
+    # Does it already point to new location?
+    if [ "$(readlink "$old")" = "$new" ]; then
+      # Nothing to do; migration has already been done.
+      observe "migration of $old to $new already done"
+      return 0
+    else
+      # Back it up.
+      warn "backing up symbolic link $old as $old.dpkg-old"
+      mv -b "$old" "$old.dpkg-old"
+    fi
+  fi
+
+  # Does old location exist, but is not a directory?
+  if [ -e "$old" ] && ! [ -d "$old" ]; then
+      # Back it up.
+      warn "backing up non-directory $old as $old.dpkg-old"
+      mv -b "$old" "$old.dpkg-old"
+  fi
+
+  observe "migrating $old to $new"
+
+  # Is new location a symlink?
+  if [ -L "$new" ]; then
+    # Does it point the wrong way, i.e., back to where we're migrating from?
+    if [ "$(readlink "$new")" = "$old" ]; then
+      # Get rid of it.
+      observe "removing symbolic link $new which points to $old"
+      rm "$new"
+    else
+      # Back it up.
+      warn "backing up symbolic link $new as $new.dpkg-old"
+      mv -b "$new" "$new.dpkg-old"
+    fi
+  fi
+
+  # Does new location exist, but is not a directory?
+  if [ -e "$new" ] && ! [ -d "$new" ]; then
+    warn "backing up non-directory $new as $new.dpkg-old"
+    mv -b "$new" "$new.dpkg-old"
+  fi
+
+  # Create new directory if it does not yet exist.
+  if ! [ -e "$new" ]; then
+    observe "creating $new"
+    mkdir -p "$new"
+  fi
+
+  # Copy files in old location to new location.  Back up any filenames that
+  # already exist in the new location with the extension ".dpkg-old".
+  observe "copying files from $old to $new"
+  if ! (cd "$old" && cp -a -b -S ".dpkg-old" . "$new"); then
+    die "error(s) encountered while copying files from $old to $new"
+  fi
+
+  # Remove files at old location.
+  observe "removing $old"
+  rm -r "$old"
+
+  # Create symlink from old location to new location.
+  make_symlink_sane "$old" "$new"
+}
+
+# vim:set ai et sw=2 ts=2 tw=80:
+
+# GOBSTOPPER: The X Strike Force shell library ends here.
diff --git a/doc/ICElib.xml b/doc/ICElib.xml
new file mode 100755 (executable)
index 0000000..27f3f0d
--- /dev/null
@@ -0,0 +1,4588 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+                   "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+
+
+<book id="icelib">
+
+<bookinfo>
+   <title>Inter-Client Exchange Library</title>
+   <subtitle>X Consortium Standard</subtitle>
+   <releaseinfo>X Version 11, Release 6.4</releaseinfo>
+   <authorgroup>
+     <author>
+       <firstname>Ralph</firstname><surname>Mor</surname>
+       <affiliation><orgname>X Consortium</orgname></affiliation>
+     </author>
+   </authorgroup>
+   <corpname>X Consortium Standard</corpname>
+   <copyright><year>1993</year><holder>X Consortium</holder></copyright>
+   <copyright><year>1994</year><holder>X Consortium</holder></copyright>
+   <copyright><year>1996</year><holder>X Consortium</holder></copyright>
+   <revhistory><revision><revnumber>1.0</revnumber><date></date></revision></revhistory>
+
+<legalnotice>
+<para>
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction,
+including without limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of the Software, and
+to permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+</para>
+
+<para>The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+</para>
+
+<para>
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+</para>
+
+<para>
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+</para>
+
+</legalnotice>
+</bookinfo>
+
+<chapter id='overview_of_ice'>
+<title>Overview of ICE</title>
+
+<para>
+There are numerous possible inter-client protocols, with many similarities
+and common needs - authentication, version negotiation, byte
+order negotiation, and so on.
+The Inter-Client Exchange (ICE) protocol is intended to provide a framework
+for building such protocols, allowing them to make use of common negotiation
+mechanisms and to be multiplexed over a single transport connection.
+</para>
+</chapter>
+
+<chapter id='the_ice_library__c_language_interface_to'>
+<title>The ICE Library - C Language Interface to ICE</title>
+
+<para>
+A client that wishes to utilize ICE must first register the protocols it
+understands with the ICE library.  Each protocol is dynamically assigned
+a major opcode ranging from 1-255 (two clients can use different
+major opcodes for the same protocol).  The next step for the client is either
+to open a connection with another client or to wait for connections made
+by other clients.  Authentication may be required.  A client can both
+initiate connections with other clients and be
+waiting for clients to connect to itself (a nested session manager is an
+example).  Once an ICE connection is established between the two clients, one
+of the clients needs to initiate a
+<function>ProtocolSetup</function>
+in order to
+"activate" a given protocol.  Once the other client accepts the
+<function>ProtocolSetup</function>
+(once again, authentication may be required), the
+two clients are ready to start passing messages specific to that protocol to
+each other.  Multiple protocols may be active on a single ICE connection.
+Clients are responsible for notifying the ICE library when a protocol is no
+longer active on an ICE connection, although ICE does not define how each
+subprotocol triggers a protocol shutdown.
+</para>
+
+<para>
+The ICE library utilizes callbacks to process incoming messages.  Using
+callbacks allows
+<function>ProtocolSetup</function>
+messages and authentication to happen
+behind the scenes.  An additional benefit is that messages never need
+to be buffered up by the library when the client blocks waiting for a
+particular message.
+</para>
+</chapter>
+
+<chapter id='intended_audience'>
+<title>Intended Audience</title>
+
+<para>This document is intended primarily for implementors of protocol libraries
+layered on top of ICE.  Typically, applications that wish to utilize ICE
+will make calls into individual protocol libraries rather than directly
+make calls into the ICE library.  However, some applications will have to
+make some initial calls into the ICE library in order to accept ICE
+connections (for example, a session manager accepting connections from
+clients).  But in general, protocol libraries should be designed to hide
+the inner details of ICE from applications.</para>
+</chapter>
+
+<chapter id='header_files_and_library_name'>
+<title>Header Files and Library Name</title>
+
+
+<para>The header file
+&lt;<symbol role='Pn'>X11/ICE/ICElib.h</symbol>&gt;
+defines all of the ICElib data structures and function prototypes.
+<function>ICElib.h</function>
+includes the header file
+&lt;<symbol role='Pn'>X11/ICE/ICE.h</symbol>&gt;,
+which defines all of the ICElib constants.
+Protocol libraries that need to read and write messages should include
+the header file
+&lt;<symbol role='Pn'>X11/ICE/ICEmsg.h</symbol>&gt;.</para>
+
+<para>Applications should link against ICElib using -lICE.</para>
+</chapter>
+
+<chapter id='note_on_prefixes'>
+<title>Note on Prefixes</title>
+
+
+<para>The following name prefixes are used in the library to distinguish between
+a client that initiates a
+<function>ProtocolSetup</function>
+and a client that
+responds with a
+<function>ProtocolReply</function></para>
+
+<itemizedlist>
+  <listitem>
+<para><function>IcePo</function>
+- Ice Protocol Originator</para>
+  </listitem>
+  <listitem>
+<para><function>IcePa</function>
+- Ice Protocol Acceptor</para>
+  </listitem>
+</itemizedlist>
+</chapter>
+
+<chapter id='protocol_registration'>
+<title>Protocol Registration</title>
+
+<para>
+In order for two clients to exchange messages for a given protocol, each
+side must register the protocol with the ICE library.  The purpose of
+registration is for each side to obtain a major opcode for the protocol
+and to provide callbacks for processing messages and handling authentication.
+There are two separate registration functions:
+</para>
+
+<itemizedlist>
+  <listitem>
+    <para>
+One to handle the side that does a
+<function>ProtocolSetup</function>
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+One to handle the side that responds with a
+<function>ProtocolReply</function>
+    </para>
+  </listitem>
+</itemizedlist>
+
+<para>
+It is recommended that protocol registration occur before the two clients
+establish an ICE connection.  If protocol registration occurs after an
+ICE connection is created, there can be a brief interval of time in which a
+<function>ProtocolSetup</function>
+is received, but the protocol is not registered.
+If it is not possible to register a protocol before the creation of an
+ICE connection, proper precautions should be taken to avoid the above race
+condition.
+</para>
+
+
+<para>
+The <function>IceRegisterForProtocolSetup</function>
+function should be called for the client that initiates a
+<function>ProtocolSetup</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>int <function>IceRegisterForProtocolSetup</function></funcdef>
+    <paramdef>char<parameter> *protocol_name</parameter></paramdef>
+    <paramdef>char<parameter> *vendor</parameter></paramdef>
+    <paramdef>char<parameter> *release</parameter></paramdef>
+    <paramdef>int<parameter> *version_count</parameter></paramdef>
+    <paramdef>int<parameter> *version_count</parameter></paramdef>
+    <paramdef>IcePoVersionRec<parameter> *version_recs</parameter></paramdef>
+    <paramdef>int<parameter> auth_names</parameter></paramdef>
+    <paramdef>char<parameter> **auth_names</parameter></paramdef>
+    <paramdef>IcePoAuthProc<parameter> *auth_procs</parameter></paramdef>
+    <paramdef>IceIOErrorProc<parameter> *io_error_proc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>protocol_name</emphasis></term>
+    <listitem>
+      <para>
+A string specifying the name of the protocol to register.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>vendor</emphasis></term>
+    <listitem>
+      <para>A vendor string with semantics specified by the protocol.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>release</emphasis></term>
+    <listitem>
+      <para>A release string with semantics specified by the protocol.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>version_count</emphasis></term>
+    <listitem>
+      <para>The number of different versions of the protocol supported.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>version_recs</emphasis></term>
+    <listitem>
+      <para>List of versions and associated callbacks.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>auth_count</emphasis></term>
+    <listitem>
+      <para>The number of authentication methods supported.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>auth_names</emphasis></term>
+    <listitem>
+      <para>The list of authentication methods supported.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>auth_procs</emphasis></term>
+    <listitem>
+      <para>
+The list of authentication callbacks, one for each authentication method.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>io_error_proc</emphasis></term>
+    <listitem>
+      <para>IO error handler, or NULL.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+<function>IceRegisterForProtocolSetup</function> returns the major
+opcode reserved or -1 if an error occurred.  In order to actually activate
+the protocol, the <function>IceProtocolSetup</function>
+function needs to be called with this major opcode.  Once the protocol is
+activated, all messages for the protocol should be sent using this major
+opcode.
+</para>
+
+<para>
+A protocol library may support multiple versions of the same protocol.
+The version_recs argument specifies a list of supported versions of the
+protocol, which are prioritized in decreasing order of preference.
+Each version record consists of a major and minor version of the protocol
+as well as a callback to be used for processing incoming messages.
+</para>
+
+
+<literallayout remap='Ds'>
+typedef struct {
+       int major_version;
+       int minor_version;
+       IcePoProcessMsgProc process_msg_proc;
+} IcePoVersionRec;
+</literallayout>
+
+<para>The
+<function>IcePoProcessMsgProc</function>
+callback is responsible for processing the set of messages that can be
+received by the client that initiated the
+<function>ProtocolSetup</function>
+For further information,
+see
+<link linkend="callbacks_for_processing_messages">
+<xref linkend="callbacks_for_processing_messages"></xref></link>.</para>
+
+<para>Authentication may be required before the protocol can become active.
+The protocol library must register the authentication methods that it
+supports with the ICE library.
+The auth_names and auth_procs arguments are a list of authentication names
+and callbacks that are  prioritized in decreasing order of preference.
+For information on the
+<function>IcePoAuthProc</function>
+callback, see
+<link linkend="authentication_methods">
+<xref linkend="authentication_methods"></xref></link>
+</para>
+
+<para>The
+<function>IceIOErrorProc</function>
+callback is invoked if the ICE connection unexpectedly breaks.
+You should pass NULL for io_error_proc if not interested in being notified.
+For further information,
+<link linkend="error_handling">
+<xref linkend="error_handling"></xref></link>
+</para>
+
+
+<para>The
+<function>IceRegisterForProtocolReply</function>
+function should be called for the client that responds to a
+<function>ProtocolSetup</function>
+with a
+<function>ProtocolReply</function></para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Bool <function>IceRegisterForProtocolReply</function></funcdef>
+    <paramdef>char<parameter> *host_name</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>protocol_name</emphasis></term>
+    <listitem><para>A string specifying the name of the protocol to register.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>vendor</emphasis></term>
+  <listitem>
+<para>A vendor string with semantics specified by the protocol.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>release</emphasis></term>
+  <listitem>
+<para>A release string with semantics specified by the protocol.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>version_count</emphasis></term>
+  <listitem>
+<para>The number of different versions of the protocol supported.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>version_recs</emphasis></term>
+  <listitem>
+<para>List of versions and associated callbacks.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>auth_count</emphasis></term>
+  <listitem>
+<para>The number of authentication methods supported.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>auth_names</emphasis></term>
+  <listitem>
+<para>The list of authentication methods supported.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>auth_procs</emphasis></term>
+  <listitem>
+<para>The list of authentication callbacks, one for each authentication method.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>host_based_auth_proc</emphasis></term>
+  <listitem>
+<para>Host based authentication callback.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>protocol_setup_proc</emphasis></term>
+  <listitem>
+<para>A callback to be invoked when authentication has succeeded for a
+<function>ProtocolSetup</function>
+but before the
+<function>ProtocolReply</function>
+is sent.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>protocol_activate_proc</emphasis></term>
+  <listitem>
+<para>A callback to be invoked after the
+<function>ProtocolReply</function>
+is sent.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>io_error_proc</emphasis></term>
+  <listitem>
+<para>IO error handler, or NULL.</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para><function>IceRegisterForProtocolReply</function>
+returns the major opcode reserved or -1 if an error occurred.  The major
+opcode should be used in all subsequent messages sent for this protocol.</para>
+
+<para>A protocol library may support multiple versions of the same protocol.
+The version_recs argument specifies a list of supported versions of the protocol,
+which are prioritized in decreasing order of preference.
+Each version record consists of a major and minor version of the protocol
+as well as a callback to be used for processing incoming messages.</para>
+
+
+<literallayout remap='Ds'>
+typedef struct {
+       int major_version;
+       int minor_version;
+       IcePaProcessMsgProc process_msg_proc;
+} IcePaVersionRec;
+</literallayout>
+
+
+<para>The
+<function>IcePaProcessMsgProc</function>
+callback is responsible for processing the set of messages that can be
+received by the client that accepted the
+<function>ProtocolSetup</function>
+For further information,
+see
+<link linkend="callbacks_for_processing_messages">
+<xref linkend="callbacks_for_processing_messages"></xref></link>
+</para>
+
+<para>Authentication may be required before the protocol can become active.
+The protocol library must register the authentication methods that it
+supports with the ICE library.
+The auth_names and auth_procs arguments are a list of authentication names
+and callbacks that are prioritized in decreasing order of preference.
+For information on the
+<function>IcePaAuthProc</function>,
+See
+<link linkend="authentication_methods">
+<xref linkend="authentication_methods"></xref></link>
+
+</para>
+
+<para>If authentication fails and the client attempting to initiate
+the
+<function>ProtocolSetup</function>
+has not required authentication, the
+<function>IceHostBasedAuthProc</function>
+callback is invoked with the host name of the originating client.
+If the callback returns
+<function>True</function>
+the
+<function>ProtocolSetup</function>
+will succeed, even though the original
+authentication failed.
+Note that authentication can effectively be disabled by registering an
+<function>IceHostBasedAuthProc</function>
+which always returns
+<function>True</function>
+If no host based
+authentication is allowed, you should pass NULL for host_based_auth_proc.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Bool <function>HostBasedAuthProc</function></funcdef>
+    <paramdef>char<parameter> *host_name</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>protocol_name</emphasis></term>
+    <listitem><para>The host name of the client that sent the <function>ProtocolSetup</function></para></listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>The host_name argument is a string of the form <emphasis remap='I'>protocol</emphasis>/<emphasis remap='I'>hostname</emphasis>,
+where <emphasis remap='I'>protocol</emphasis> is one of {tcp, decnet, local}.</para>
+
+<para>Because
+<function>ProtocolSetup</function>
+messages and authentication happen behind the scenes
+via callbacks, the protocol library needs some way of being notified when the
+<function>ProtocolSetup</function>
+has completed.
+This occurs in two phases.
+In the first phase, the
+<function>IceProtocolSetupProc</function>
+callback is invoked after authentication has
+successfully completed but before the ICE library sends a
+<function>ProtocolReply</function>
+Any resources required for this protocol should be allocated at this time.
+If the
+<function>IceProtocolSetupProc</function>
+returns a successful status, the ICE library will
+send the
+<function>ProtocolReply</function>
+and then invoke the
+<function>IceProtocolActivateProc</function>
+callback.  Otherwise, an error will be sent to the
+other client in response to the
+<function>ProtocolSetup</function></para>
+
+<para>The
+<function>IceProtocolActivateProc</function>
+is an optional callback and should be registered only if the protocol
+library intends to generate a message immediately following the
+<function>ProtocolReply</function>
+You should pass NULL for protocol_activate_proc if not interested
+in this callback.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Status <function>ProtocolSetupProc</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> major_version</parameter></paramdef>
+    <paramdef>int<parameter> minor_version</parameter></paramdef>
+    <paramdef>char<parameter> *vendor</parameter></paramdef>
+    <paramdef>char<parameter> *release</parameter></paramdef>
+    <paramdef>IcePointer<parameter> *client_data_ret</parameter></paramdef>
+    <paramdef>char<parameter> **failure_reason_ret</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>protocol_name</emphasis></term>
+    <listitem>
+<para>The ICE connection object.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>major_version</emphasis></term>
+  <listitem>
+<para>The major version of the protocol.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>minor_version</emphasis></term>
+  <listitem>
+<para>The minor version of the protocol.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>vendor</emphasis></term>
+  <listitem>
+<para>The vendor string registered by the protocol originator.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>release</emphasis></term>
+  <listitem>
+<para>The release string registered by the protocol originator.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>client_data_ret</emphasis></term>
+  <listitem>
+<para>Client data to be set by callback.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>failure_reason_ret</emphasis></term>
+  <listitem>
+<para>Failure reason returned.</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>The pointer stored in the client_data_ret argument will be passed
+to the
+<function>IcePaProcessMsgProc</function>
+callback whenever a message has arrived for this protocol on the
+ICE connection.</para>
+
+<para>The vendor and release strings should be freed with
+<function>free</function>
+when they are no longer needed.</para>
+
+<para>If a failure occurs, the
+<function>IceProtocolSetupProc</function>
+should return a zero status as well as allocate and return a failure
+reason string in failure_reason_ret.
+The ICE library will be responsible for freeing this memory.</para>
+
+<para>The
+<function>IceProtocolActivateProc</function>
+callback is defined as follows:</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void <function>ProtocolActivateProc</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>IcePointer<parameter> client_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem><para>The ICE connection object.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>client_data</emphasis></term>
+    <listitem>
+    <para>
+The client data set in the <function>IceProtocolSetupProc</function> callback.
+    </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>The
+<function>IceIOErrorProc</function>
+callback is invoked if the ICE connection unexpectedly breaks.
+You should pass NULL for io_error_proc if not interested in being notified.
+For further information,
+see
+<link linkend="error_handling">
+<xref linkend="error_handling"></xref></link>
+</para>
+
+<sect1 id='callbacks_for_processing_messages'>
+<title>Callbacks for Processing Messages</title>
+
+<para>When an application detects that there is new data to read on an ICE
+connection (via
+<function>select</function>
+it calls the
+<function>IceProcessMessages</function>
+function
+<link linkend="processing_messages">
+<xref linkend="processing_messages"></xref></link>.
+
+When
+<function>IceProcessMessages</function>
+reads an ICE message header with a major opcode other than
+zero (reserved for the ICE protocol), it needs to call a function that will
+read the rest of the message, unpack it, and process it accordingly.</para>
+
+<para>If the message arrives at the client that initiated the
+<function>ProtocolSetup</function>
+the
+<function>IcePoProcessMsgProc</function>
+callback is invoked.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void <function>PoProcessMsgProc</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>IcePointer<parameter> client_data</parameter></paramdef>
+    <paramdef>int<parameter> opcode</parameter></paramdef>
+    <paramdef>unsigned long<parameter> length</parameter></paramdef>
+    <paramdef>Bool<parameter> swap</parameter></paramdef>
+    <paramdef>IceReplyWaitInfo<parameter> *reply_wait</parameter></paramdef>
+    <paramdef>Bool<parameter> *reply_ready_ret</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem><para>The ICE connection object.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>client_data</emphasis></term>
+  <listitem>
+<para>Client data associated with this protocol on the ICE connection.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>opcode</emphasis></term>
+  <listitem>
+<para>The minor opcode of the message.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>length</emphasis></term>
+  <listitem>
+<para>The length (in 8-byte units) of the message beyond the ICE header.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>swap</emphasis></term>
+  <listitem>
+<para>A flag that indicates if byte swapping is necessary.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>reply_wait</emphasis></term>
+  <listitem>
+<para>Indicates if the invoking client is waiting for a reply.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>reply_ready_ret</emphasis></term>
+  <listitem>
+<para>If set to
+<function>True</function>
+a reply is ready.</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>If the message arrives at the client that accepted the
+<function>ProtocolSetup</function>
+the
+<function>IcePaProcessMsgProc</function>
+callback is invoked.</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void <function>IcePaProcessMsgProc</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>IcePointer<parameter> client_data</parameter></paramdef>
+    <paramdef>int<parameter> opcode</parameter></paramdef>
+    <paramdef>unsigned long<parameter> length</parameter></paramdef>
+    <paramdef>Bool<parameter> swap</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem><para>The ICE connection object.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>client_data</emphasis></term>
+  <listitem>
+<para>Client data associated with this protocol on the ICE connection.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>opcode</emphasis></term>
+  <listitem>
+<para>The minor opcode of the message.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>length</emphasis></term>
+  <listitem>
+<para>The length (in 8-byte units) of the message beyond the ICE header.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>swap</emphasis></term>
+  <listitem>
+<para>A flag that indicates if byte swapping is necessary.</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>In order to read the message, both of these callbacks should use the
+macros defined for this purpose (see
+<link linkend="reading_ice_messages">
+<xref linkend="reading_ice_messages"></xref></link>.).
+Note that byte swapping may be necessary.
+As a convenience, the length field in the ICE header will be swapped by ICElib
+if necessary.</para>
+
+<para>In both of these callbacks, the client_data argument is a pointer to client
+data that was registered at
+<function>ProtocolSetup</function>
+time.
+In the case of
+<function>IcePoProcessMsgProc</function>
+the client data was set in the call to
+<function>IceProtocolSetup</function>
+In the case of
+<function>IcePaProcessMsgProc</function>
+the client data was set in the
+<function>IceProtocolSetupProc</function>
+callback.</para>
+
+<para>The
+<function>IcePoProcessMsgProc</function>
+callback needs to check the reply_wait argument.
+If reply_wait is NULL ,
+the ICE library expects the function to
+pass the message to the client via a callback.
+For example, if this is a Session Management "Save Yourself" message,
+this function should notify the client of the "Save Yourself" via a callback.
+The details of how such a callback would be defined
+are implementation-dependent.</para>
+
+<para>However, if reply_wait is not NULL ,
+then the client is waiting for
+a reply or an error for a message it previously sent.
+The reply_wait is of type
+<function>IceReplyWaitInfo</function></para>
+
+
+<literallayout remap='Ds'>
+typedef struct {
+       unsigned long sequence_of_request;
+       int major_opcode_of_request;
+       int minor_opcode_of_request;
+       IcePointer reply;
+} IceReplyWaitInfo;
+</literallayout>
+
+<para><function>IceReplyWaitInfo</function>
+contains the major/minor opcodes and sequence number of
+the message for which a reply is being awaited.
+It also contains a pointer to the reply message to be filled in
+(the protocol library should cast this
+<function>IcePointer</function>
+to the appropriate reply type).
+In most cases, the reply will have some fixed-size part, and the client waiting
+for the reply will have provided a pointer to a structure to hold
+this fixed-size data.  If there is variable-length data, it would be
+expected that the
+<function>IcePoProcessMsgProc</function>
+callback will have to allocate additional
+memory and store pointer(s) to that memory in the fixed-size
+structure.  If the entire data is variable length (for example., a single
+variable-length string), then the client waiting for the reply would probably
+just pass a pointer to fixed-size space to hold a pointer, and the
+<function>IcePoProcessMsgProc</function>
+callback would allocate the storage and store the pointer.
+It is the responsibility of the client receiving the reply to
+free any memory allocated on its behalf.</para>
+
+<para>If reply_wait is not NULL and
+<function>IcePoProcessMsgProc</function>
+has a reply or error to return in response to this reply_wait
+(that is, no callback was generated), then the reply_ready_ret argument
+should be set to
+<function>True</function>
+Note that an error should only be returned
+if it corresponds to the reply being waited for.  Otherwise, the
+<function>IcePoProcessMsgProc</function>
+should either handle the error internally or invoke an error handler
+for its library.</para>
+
+<para>If reply_wait is NULL,
+then care must be taken not to store any value in reply_ready_ret,
+because this pointer may also be NULL.</para>
+
+<para>The
+<function>IcePaProcessMsgProc</function>
+callback, on the other hand, should always pass
+the message to the client via a callback.  For example, if this is a Session
+Management "Interact Request" message, this function should notify the
+client of the "Interact Request" via a callback.</para>
+
+<para>The reason the
+<function>IcePaProcessMsgProc</function>
+callback does not have a reply_wait, like
+<function>IcePoProcessMsgProc</function>
+does, is because a process that is acting as
+a server should never block for a reply (infinite blocking can
+occur if the connecting client does not act properly, denying access
+to other clients).</para>
+</sect1>
+
+<sect1 id='authentication_methods'>
+<title>Authentication Methods</title>
+
+<para>As already stated, a protocol library must register the authentication
+methods that it supports with the ICE library.  For each authentication
+method, there are two callbacks that may be registered:</para>
+<itemizedlist>
+  <listitem>
+    <para>
+One to handle the side that initiates a <function>ProtocolSetup</function>
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+One to handle the side that accepts or rejects this request
+    </para>
+  </listitem>
+</itemizedlist>
+
+<para><function>IcePoAuthProc</function>
+is the callback invoked for the client that initiated the
+<function>ProtocolSetup</function>
+This callback must be able to respond
+to the initial "Authentication Required" message or subsequent
+"Authentication Next Phase" messages sent by the other client.</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>IcePoAuthStatus <function>IcePoAuthStatus </function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>IcePointer<parameter> client_data</parameter></paramdef>
+    <paramdef>int<parameter> opcode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem><para>The ICE connection object.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>auth_state_ptr</emphasis></term>
+  <listitem>
+<para>A pointer to state for use by the authentication callback procedure.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>clean_up</emphasis></term>
+  <listitem>
+<para>If
+<function>True</function>
+authentication is over, and the function
+should clean up any state it was maintaining.  The
+last 6 arguments should be ignored.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>swap</emphasis></term>
+  <listitem>
+<para>If
+<function>True</function>
+the auth_data may have to be byte swapped
+(depending on its contents).</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>auth_datalen</emphasis></term>
+  <listitem>
+<para>The length (in bytes) of the authenticator data.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>auth_data</emphasis></term>
+  <listitem>
+<para>The data from the authenticator.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>reply_datalen_ret</emphasis></term>
+  <listitem>
+<para>The length (in bytes) of the reply data returned.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>reply_data_ret</emphasis></term>
+  <listitem>
+<para>The reply data returned.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>error_string_ret</emphasis></term>
+  <listitem>
+<para>If the authentication procedure encounters an error during
+authentication, it should allocate and return
+an error string.</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>Authentication may require several phases, depending on the authentication
+method.  As a result, the
+<function>IcePoAuthProc</function>
+may be called more than once when authenticating a client, and
+some state will have to be maintained between each invocation.
+At the start of each
+<function>ProtocolSetup</function>
+*auth_state_ptr is NULL,
+and the function should initialize its state and set
+this pointer.  In subsequent invocations of the callback, the pointer
+should be used to get at any state previously stored by the callback.</para>
+
+<para>If needed, the network ID of the client accepting the
+<function>ProtocolSetup</function>
+can be obtained by calling the
+<function>IceConnectionString</function>
+function.</para>
+
+<para>ICElib will be responsible for freeing the reply_data_ret and
+error_string_ret pointers with
+<function>free</function></para>
+
+<para>The auth_data pointer may point to a volatile block of memory.
+If the data must be kept beyond this invocation of the callback, be sure
+to make a copy of it.</para>
+
+<para>The
+<function>IcePoAuthProc</function>
+should return one of four values:</para>
+<itemizedlist>
+  <listitem>
+<para><function>IcePoAuthHaveReply</function>
+- a reply is available.</para>
+  </listitem>
+  <listitem>
+<para><function>IcePoAuthRejected</function>
+- authentication rejected.</para>
+  </listitem>
+  <listitem>
+<para><function>IcePoAuthFailed</function>
+- authentication failed.</para>
+  </listitem>
+  <listitem>
+<para><function>IcePoAuthDoneCleanup</function>
+- done cleaning up.</para>
+  </listitem>
+</itemizedlist>
+
+<para><function>IcePaAuthProc</function>
+is the callback invoked for the client that received the
+<function>ProtocolSetup</function></para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>IcePoAuthStatus <function>PoAuthStatus </function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>IcePointer<parameter> *auth_state_ptr</parameter></paramdef>
+    <paramdef>Bool<parameter> swap</parameter></paramdef>
+    <paramdef>int<parameter> auth_datalen</parameter></paramdef>
+    <paramdef>IcePointer<parameter> auth_data</parameter></paramdef>
+    <paramdef>int<parameter> *reply_datalen_ret</parameter></paramdef>
+    <paramdef>IcePointer<parameter> *reply_data_ret</parameter></paramdef>
+    <paramdef>char<parameter> **error_string_ret</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem><para>The ICE connection object.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>auth_state_ptr</emphasis></term>
+    <listitem>
+<para>A pointer to state for use by the authentication callback procedure.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>swap</emphasis></term>
+    <listitem>
+<para>If
+<function>True</function>
+auth_data may have to be byte swapped
+(depending on its contents).</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>auth_datalen</emphasis></term>
+    <listitem>
+<para>The length (in bytes) of the protocol originator authentication data.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>auth_data</emphasis></term>
+    <listitem>
+<para>The authentication data from the protocol originator.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>reply_datalen_ret</emphasis></term>
+    <listitem>
+<para>The length of the authentication data returned.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>reply_data_ret</emphasis></term>
+    <listitem>
+<para>The authentication data returned.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>error_string_ret</emphasis></term>
+    <listitem>
+<para>If authentication is rejected or fails, an error
+string is returned.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>Authentication may require several phases, depending on the authentication
+method.  As a result, the
+<function>IcePaAuthProc</function>
+may be called more than once when authenticating a client, and
+some state will have to be maintained between each invocation.
+At the start of each
+<function>ProtocolSetup</function>
+auth_datalen is zero,
+*auth_state_ptr is NULL,
+and the function should initialize its state and set
+this pointer.  In subsequent invocations of the callback, the pointer
+should be used to get at any state previously stored by the callback.</para>
+
+<para>If needed, the network ID of the client accepting the
+<function>ProtocolSetup</function>
+can be obtained by calling the
+<function>IceConnectionString</function>
+function.</para>
+
+<para>The auth_data pointer may point to a volatile block of memory.
+If the data must be kept beyond this invocation of the callback, be sure
+to make a copy of it.</para>
+
+<para>ICElib will be responsible for transmitting and freeing the reply_data_ret and
+error_string_ret pointers with
+<function>free</function></para>
+
+<para>
+The <function>IcePaAuthProc</function> should return one of four values:
+</para>
+
+
+<itemizedlist>
+  <listitem>
+    <para>
+<function>IcePaAuthContinue</function> - continue (or start) authentication.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+<function>IcePaAuthAccepted</function> - authentication accepted.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+<function>IcePaAuthRejected</function> - authentication rejected.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+<function>IcePaAuthFailed</function> - authentication failed.
+    </para>
+  </listitem>
+</itemizedlist>
+</sect1>
+
+</chapter>
+
+<chapter id='ice_connections'>
+<title>ICE Connections</title>
+
+<para>
+In order for two clients to establish an ICE connection, one client has to be
+waiting for connections, and the other client has to initiate the connection.
+Most clients will initiate connections, so we discuss that first.
+</para>
+
+<sect1 id='opening_an_ice_connection'>
+<title>Opening an ICE Connection</title>
+
+
+<para>
+To open an ICE connection with another client (that is, waiting
+for connections), use <function>IceOpenConnection</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>IceConn <function>IceOpenConnection</function></funcdef>
+    <paramdef>char<parameter> *network_ids_list</parameter></paramdef>
+    <paramdef>IcePointer<parameter> context</parameter></paramdef>
+    <paramdef>Bool<parameter> must_authenticate</parameter></paramdef>
+    <paramdef>int<parameter> major_opcode_check</parameter></paramdef>
+    <paramdef>int<parameter> error_length</parameter></paramdef>
+    <paramdef>char<parameter> *error_string_ret</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>network_ids_list</emphasis></term>
+    <listitem>
+      <para>
+Specifies the network ID(s) of the other client.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>context</emphasis></term>
+    <listitem>
+      <para>
+A pointer to an opaque object or NULL.  Used to determine if an
+ICE connection can be shared (see below).
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>must_authenticate</emphasis></term>
+    <listitem>
+      <para>
+If <function>True</function> the other client may not bypass authentication.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>major_opcode_check</emphasis></term>
+    <listitem>
+      <para>
+Used to force a new ICE connection to be created (see below).
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>error_length</emphasis></term>
+    <listitem>
+      <para>Length of the error_string_ret argument passed in.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>error_string_ret</emphasis></term>
+    <listitem>
+      <para>
+Returns a null-terminated error message, if any.  The error_string_ret
+argument points to user supplied memory.  No more than error_length bytes
+are used.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+<function>IceOpenConnection</function>
+returns an opaque ICE connection object if it succeeds;
+otherwise, it returns NULL.
+</para>
+
+<para>
+The network_ids_list argument contains a list of network IDs separated
+by commas.  An attempt will be made to use the first network ID.  If
+that fails, an attempt will be made using the second network ID, and so on.
+Each network ID has the following format:
+</para>
+
+<informaltable pgwide='0' frame='none'>
+  <tgroup cols='3' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <colspec colname='c3'/>
+    <tbody>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>tcp/&lt;hostname&gt;:&lt;portnumber&gt;</entry>
+        <entry align='left'>or</entry>
+      </row>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>decnet/&lt;hostname&gt;::&lt;objname&gt;</entry>
+        <entry align='left'>or</entry>
+      </row>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>local/&lt;hostname&gt;:&lt;path&gt;</entry>
+        <entry align='left'></entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+
+<para>Most protocol libraries will have some sort of open function that should
+internally make a call into
+<function>IceOpenConnection</function>
+When
+<function>IceOpenConnection</function>
+is called, it may be possible to use a previously opened ICE connection (if
+the target client is the same).  However, there are cases in which shared
+ICE connections are not desired.</para>
+
+<para>The context argument is used to determine if an ICE connection can
+be shared.
+If context is NULL,
+then the caller is always willing to share the connection.
+If context is not NULL,
+then the caller is not willing to use a previously opened ICE connection
+that has a different non-NULL context associated with it.</para>
+
+<para>In addition, if major_opcode_check contains a nonzero major opcode value,
+a previously created ICE connection will be used only if the major opcode
+is not active on the connection.  This can be used to force multiple ICE
+connections between two clients for the same protocol.</para>
+
+<para>Any authentication requirements are handled internally by the ICE library.
+The method by which the authentication data is obtained
+is implementation-dependent.
+  <footnote remap='FS'>
+<para>The X Consortium's ICElib implementation uses an .ICEauthority file (see
+Appendix A).
+  </para></footnote> </para>
+
+<para>After
+<function>IceOpenConnection</function>
+is called, the client is ready to send a
+<function>ProtocolSetup</function>
+(provided that
+<function>IceRegisterForProtocolSetup</function>
+was called) or receive a
+<function>ProtocolSetup</function>
+(provided that
+<function>IceRegisterForProtocolReply</function>
+was called).</para>
+</sect1>
+
+<sect1 id='listening_for_ice_connections'>
+<title>Listening for ICE Connections</title>
+
+<para>Clients wishing to accept ICE connections must first call
+<function>IceListenForConnections</function>
+or
+<function>IceListenForWellKnownConnections</function>
+so that they can listen for connections.  A list of opaque "listen" objects are
+returned, one for each type of transport method that is available
+(for example, Unix Domain, TCP, DECnet, and so on).</para>
+
+<para>Normally clients will let ICElib allocate an available name in each
+transport and return listen objects.  Such a client will then use
+<function>IceComposeNetworkIdList</function>
+to extract the chosen names and make them
+available to other clients for opening the connection.  In certain
+cases it may be necessary for a client to listen for connections
+on pre-arranged transport object names.  Such a client may use
+<function>IceListenForWellKnownConnections</function>
+to specify the names for the listen objects.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Status <function>IceListenForConnections</function></funcdef>
+    <paramdef>int<parameter> *count_ret</parameter></paramdef>
+    <paramdef>IceListenObj<parameter> **listen_objs_ret</parameter></paramdef>
+    <paramdef>int<parameter> error_length</parameter></paramdef>
+    <paramdef>char<parameter> *error_string_ret</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>count_ret</emphasis></term>
+    <listitem><para>Returns the number of listen objects created.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>listen_objs_ret</emphasis></term>
+    <listitem><para>Returns a list of pointers to opaque listen objects.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>error_length</emphasis></term>
+  <listitem>
+<para>The length of the error_string_ret argument passed in.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>error_string_ret</emphasis></term>
+  <listitem>
+<para>Returns a null-terminated error message, if any.
+The error_string_ret points to user supplied memory.
+No more than error_length bytes are used.</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>The return value of
+<function>IceListenForConnections</function>
+is zero for failure and a positive value for success.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Status <function>IceListenForWellKnownConnections</function></funcdef>
+    <paramdef>char<parameter> *port_id</parameter></paramdef>
+    <paramdef>int<parameter> *count_ret</parameter></paramdef>
+    <paramdef>IceListenObj<parameter> **listen_objs_ret</parameter></paramdef>
+    <paramdef>int<parameter> error_length</parameter></paramdef>
+    <paramdef>char<parameter> *error_string_ret</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>port_id</emphasis></term>
+    <listitem>
+      <para>
+Specifies the port identification for the address(es) to be opened.  The
+value must not contain the slash ("/"> or comma (".") character; thse are
+reserved for future use.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>count_ret</emphasis></term>
+    <listitem>
+      <para>Returns the number of listen objects created.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>listen_objs_ret</emphasis></term>
+    <listitem>
+      <para>
+Returns a list of pointers to opaque listen objects.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>listen_objs_ret</emphasis></term>
+    <listitem>
+      <para>
+Returns a list of pointers to opaque listen objects.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>error_length</emphasis></term>
+    <listitem>
+      <para>
+The length of the error_string_ret argument passed in.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>error_string_ret</emphasis></term>
+    <listitem>
+      <para>
+Returns a null-terminated error message, if any.  The error_string_ret
+points to user supplied memory.  No more than error_length bytes are used.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+<function>IceListenForWellKnownConnections</function> constructs a list
+of network IDs by prepending each known transport to port_id and then
+attempts to create listen objects for the result.  Port_id is the portnumber,
+objname, or path portion of the ICE network ID. If a listen object for
+a particular network ID cannot be created the network ID is ignored.
+If no listen objects are created
+<function>IceListenForWellKnownConnections</function>
+returns failure.
+</para>
+
+<para>
+The return value of <function>IceListenForWellKnownConnections</function>
+is zero for failure and a positive value for success.
+</para>
+
+<para>
+To close and free the listen objects, use
+<function>IceFreeListenObjs</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void <function>IceFreeListenObjs</function></funcdef>
+    <paramdef>int<parameter> count</parameter></paramdef>
+    <paramdef>IceListenObj<parameter> *listen_objs</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>count</emphasis></term>
+    <listitem>
+      <para>The number of listen objects.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>listen_objs</emphasis></term>
+    <listitem>
+      <para>The listen objects.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+To detect a new connection on a listen object, use
+<function>select</function> on the descriptor associated with
+the listen object.
+</para>
+
+<para>
+To obtain the descriptor, use
+<function>IceGetListenConnectionNumber</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>int <function>IceGetListenConnectionNumber</function></funcdef>
+    <paramdef>IceListenObj<parameter> *listen_objs</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+  <term><emphasis remap='I'>listen_obj</emphasis></term>
+    <listitem>
+      <para>The listen objects.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+To obtain the network ID string associated with a listen object, use
+<function>IceGetListenConnectionString</function>
+</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>char <function>IceGetListenConnectionString</function></funcdef>
+    <paramdef>IceListenObj<parameter> listen_obj</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>listen_obj</emphasis></term>
+    <listitem>
+      <para>The listen objects.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>A network ID has the following format:</para>
+
+<informaltable pgwide='0' frame='none'>
+  <tgroup cols='3' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <colspec colname='c3'/>
+    <tbody>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>tcp/&lt;hostname&gt;:&lt;portnumber&gt;</entry>
+        <entry align='left'>or</entry>
+      </row>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>decnet/&lt;hostname&gt;::&lt;objname&gt;</entry>
+        <entry align='left'>or</entry>
+      </row>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>local/&lt;hostname&gt;:&lt;path&gt;</entry>
+        <entry align='left'></entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+<para>
+To compose a string containing a list of network IDs separated by commas
+(the format recognized by <function>IceOpenConnection</function>
+use <function>IceComposeNetworkIdList</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>char <function>IceComposeNetworkIdList</function></funcdef>
+    <paramdef>int<parameter> count</parameter></paramdef>
+    <paramdef>IceListenObj<parameter> *listen_objs</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>count</emphasis></term>
+    <listitem>
+      <para>The number of listen objects.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>listen_objs</emphasis></term>
+    <listitem>
+      <para>The listen objects.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+</sect1>
+
+<sect1 id='host_based_authentication_for_ice_connec'>
+<title>Host Based Authentication for ICE Connections</title>
+
+<para>
+If authentication fails when a client attempts to open an
+ICE connection and the initiating client has not required authentication,
+a host based authentication procedure may be invoked to provide
+a last chance for the client to connect.  Each listen object has such a
+callback associated with it, and this callback is set using the
+<function>IceSetHostBasedAuthProc</function>
+function.
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void <function>IceSetHostBasedAuthProc</function></funcdef>
+    <paramdef>IceListenObj<parameter> listen_obj</parameter></paramdef>
+    <paramdef>IceHostBasedAuthProc<parameter> host_based_auth_proc</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>IceListenObj</emphasis></term>
+    <listitem>
+      <para>The listen object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>host_based_auth_proc</emphasis></term>
+    <listitem>
+      <para>The host based authentication procedure.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+By default, each listen object has no host based authentication procedure
+associated with it.  Passing NULL for host_based_auth_proc turns off
+host based authentication if it was previously set.
+</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Bool <function>HostBasedAuthProc</function></funcdef>
+    <paramdef>char<parameter> *host_name</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>host_name</emphasis></term>
+    <listitem>
+      <para>
+The host name of the client that tried to open an ICE connection.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+The host_name argument is a string in the form
+<emphasis remap='I'>protocol</emphasis>/
+<emphasis remap='I'>hostname</emphasis>,
+where <emphasis remap='I'>protocol</emphasis> is one of
+{tcp, decnet, local}.
+</para>
+
+<para>
+If <function>IceHostBasedAuthProc</function> returns
+<function>True</function>
+access will be granted, even though the original authentication failed.
+Note that authentication can effectively be disabled by registering an
+<function>IceHostBasedAuthProc</function>
+which always returns <function>True</function>
+</para>
+
+<para>
+Host based authentication is also allowed at
+<function>ProtocolSetup</function> time.
+The callback is specified in the
+<function>IceRegisterForProtocolReply</function>
+function (see
+<link linkend="protocol_registration">
+<xref linkend="protocol_registration"></xref></link>).
+</para>
+</sect1>
+
+<sect1 id='accepting_ice_connections'>
+<title>Accepting ICE Connections</title>
+
+
+<para>
+After a connection attempt is detected on a listen object returned by
+<function>IceListenForConnections</function>
+you should call <function>IceAcceptConnection</function>
+This returns a new opaque ICE connection object.
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>IceConn <function>IceAcceptConnection</function></funcdef>
+    <paramdef>IceListenObj<parameter> listen_obj</parameter></paramdef>
+    <paramdef>IceAcceptStatus<parameter> *status_ret</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+
+<variablelist remap='IP'>
+  <varlistentry>
+  <term><emphasis remap='I'>listen_obj</emphasis></term>
+  <listitem>
+<para>The listen object on which a new connection was detected.</para>
+  </listitem>
+  </varlistentry>
+  </variablelist>
+  <variablelist remap='IP'>
+  <varlistentry>
+  <term><emphasis remap='I'>status_ret</emphasis></term>
+  <listitem>
+<para>Return status information.</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>The status_ret argument is set to one of the following values:</para>
+<itemizedlist>
+  <listitem>
+<para><function>IceAcceptSuccess</function>
+- the accept operation succeeded,
+and the function returns a new connection object.</para>
+  </listitem>
+  <listitem>
+<para><function>IceAcceptFailure</function>
+- the accept operation failed, and the function returns NULL.</para>
+  </listitem>
+  <listitem>
+<para><function>IceAcceptBadMalloc</function>
+- a memory allocation failed, and the function returns NULL.</para>
+  </listitem>
+</itemizedlist>
+
+<para>In general, to detect new connections, you should call
+<function>select</function>
+on the file descriptors associated with the listen objects.
+When a new connection is detected, the
+<function>IceAcceptConnection</function>
+function should be called.
+<function>IceAcceptConnection</function>
+may return a new ICE connection that is in a pending state.  This is because
+before the connection can become valid, authentication may be necessary.
+Because the ICE library cannot block and wait for the connection to
+become valid (infinite blocking can occur if the connecting client
+does not act properly), the application must wait for the connection status
+to become valid.</para>
+
+<para>The following pseudo-code demonstrates how connections are accepted:</para>
+
+<literallayout class="monospaced">
+new_ice_conn = IceAcceptConnection (listen_obj, &amp;accept_status);
+if (accept_status != IceAcceptSuccess)
+{
+     close the file descriptor and return
+}
+
+status = IceConnectionStatus (new_ice_conn);
+time_start = time_now;
+
+while (status == IceConnectPending)
+{
+     select() on {new_ice_conn, all open connections}
+
+     for (each ice_conn in the list of open connections)
+          if (data ready on ice_conn)
+          {
+               status = IceProcessMessages (ice_conn, NULL, NULL);
+               if (status == IceProcessMessagesIOError)
+                    IceCloseConnection(ice_conn);
+          }
+     if data ready on new_ice_conn
+     {
+          /*
+          * IceProcessMessages is called until the connection
+          * is non-pending.  Doing so handles the connection
+          * setup request and any authentication requirements.
+          */
+
+          IceProcessMessages ( new_ice_conn, NULL, NULL);
+          status = IceConnectionStatus (new_ice_conn);
+     }
+     else
+     {
+          if (time_now - time_start &gt; MAX_WAIT_TIME)
+               status = IceConnectRejected;
+     }
+}
+
+if (status == IceConnectAccepted)
+{
+     Add new_ice_conn to the list of open connections
+}
+else
+{
+     IceCloseConnection
+     new_ice_conn
+}
+</literallayout>
+
+<para>After
+<function>IceAcceptConnection</function>
+is called and the connection has been
+validated, the client is ready to receive a
+<function>ProtocolSetup</function>
+(provided
+that
+<function>IceRegisterForProtocolReply</function>
+was called) or send a
+<function>ProtocolSetup</function>
+(provided that
+<function>IceRegisterForProtocolSetup</function>
+was called).</para>
+</sect1>
+
+<sect1 id='closing_ice_connections'>
+<title>Closing ICE Connections</title>
+
+<para>To close an ICE connection created with
+<function>IceOpenConnection</function>
+or
+<function>IceAcceptConnection</function>
+use
+<function>IceCloseConnection</function></para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>IceCloseStatus <function>IceCloseConnection</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+  <term><emphasis remap='I'>ice_conn</emphasis></term>
+  <listitem>
+  <para>The ICE connection to close.</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>To actually close an ICE connection, the following conditions
+must be met:</para>
+
+<itemizedlist>
+  <listitem>
+<para>The <emphasis remap='I'>open reference count</emphasis> must have reached zero on this ICE connection.
+When
+<function>IceOpenConnection</function>
+is called, it tries to use a previously opened
+ICE connection.  If it is able to use an existing connection, it increments
+the open reference count on the connection by one.
+So, to close an ICE connection, each call to
+<function>IceOpenConnection</function>
+must be matched with a call to
+<function>IceCloseConnection</function>
+The connection can be closed only
+on the last call to
+<function>IceCloseConnection</function></para>
+  </listitem>
+  <listitem>
+<para>The <emphasis remap='I'>active protocol count</emphasis> must have reached zero.  Each time a
+<function>ProtocolSetup</function>
+succeeds on the connection, the active protocol count
+is incremented by one.  When the client no longer expects to use the
+protocol on the connection, the
+<function>IceProtocolShutdown</function>
+function should be called, which decrements the active protocol count
+by one (see
+<link linkend="protocol_setup_and_shutdown">
+<xref linkend="protocol_setup_and_shutdown"></xref></link>).
+</para>
+  </listitem>
+  <listitem>
+<para>If shutdown negotiation is enabled on the connection, the client on the other
+side of the ICE connection must agree to have the connection closed.</para>
+
+<para><function>IceCloseConnection</function>
+returns one of the following values:</para>
+  </listitem>
+  <listitem>
+<para><function>IceClosedNow</function>
+- the ICE connection was closed at this time.  The watch procedures were
+invoked and the connection was freed.</para>
+  </listitem>
+  <listitem>
+<para><function>IceClosedASAP</function>
+- an IO error had occurred on the connection, but
+<function>IceCloseConnection</function>
+is being called within a nested
+<function>IceProcessMessages</function>
+The watch procedures have been invoked at this time, but the connection
+will be freed as soon as possible (when the nesting level reaches zero and
+<function>IceProcessMessages</function>
+returns a status of
+<function>IceProcessMessagesConnectionClosed</function></para>
+  </listitem>
+  <listitem>
+<para><function>IceConnectionInUse</function>
+- the connection was not closed at this time, because it is being used by
+other active protocols.</para>
+  </listitem>
+  <listitem>
+<para><function>IceStartedShutdownNegotiation</function>
+- the connection was not closed at this time and shutdown negotiation started
+with the client on the other side of the ICE connection.  When the connection
+is actually closed,
+<function>IceProcessMessages</function>
+will return a status of
+<function>IceProcessMessagesConnectionClosed</function></para>
+  </listitem>
+</itemizedlist>
+
+<para>When it is known that the client on the other side of the ICE connection
+has terminated the connection without initiating shutdown negotiation, the
+<function>IceSetShutdownNegotiation</function>
+function should be called to turn off shutdown negotiation.  This will prevent
+<function>IceCloseConnection</function>
+from writing to a broken connection.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void <function>IceSetShutdownNegotiation</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>Bool<parameter> negotiate</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+  <term><emphasis remap='I'>ice_conn</emphasis></term>
+  <listitem>
+  <para>A valid ICE connection object.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>negotiate</emphasis></term>
+  <listitem>
+<para>If
+<function>False</function>
+shutdown negotiating will be turned off.</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>To check the shutdown negotiation status of an ICE connection, use
+<function>IceCheckShutdownNegotiation</function></para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Bool <function>IceCheckShutdownNegotiation</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+  <term><emphasis remap='I'>ice_conn</emphasis></term>
+  <listitem>
+  <para>A valid ICE connection object.</para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para><function>IceCheckShutdownNegotiation</function>
+returns
+<function>True</function>
+if shutdown negotiation will take place on the connection;
+otherwise, it returns
+<function>False</function>
+Negotiation is on by default for a connection.  It
+can only be changed with the
+<function>IceSetShutdownNegotiation</function>
+function.</para>
+</sect1>
+
+<sect1 id='connection_watch_procedures'>
+<title>Connection Watch Procedures</title>
+
+<para>To add a watch procedure that will be called
+each time ICElib opens a new connection via
+<function>IceOpenConnection</function>
+or
+<function>IceAcceptConnection</function>
+or closes a connection via
+<function>IceCloseConnection</function>
+use
+<function>IceAddConnectionWatch</function></para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Status <function>IceAddConnectionWatch</function></funcdef>
+    <paramdef>IceWatchProc<parameter> watch_proc</parameter></paramdef>
+    <paramdef>IcePointer<parameter> client_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>watch_proc</emphasis></term>
+    <listitem>
+      <para>
+The watch procedure to invoke when ICElib opens or closes a connection.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>client_data</emphasis></term>
+    <listitem>
+      <para>This pointer will be passed to the watch procedure.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+The return value of <function>IceAddConnectionWatch</function>
+is zero for failure, and a positive value for success.
+</para>
+
+<para>
+Note that several calls to <function>IceOpenConnection</function>
+might share the same ICE connection.  In such a case, the watch procedure
+is only invoked when the connection is first created (after authentication
+succeeds).  Similarly, because connections might be shared, the
+watch procedure is called only if <function>IceCloseConnection</function>
+actually closes the connection (right before the IceConn is freed).
+</para>
+
+<para>
+The watch procedures are very useful for applications that
+need to add a file descriptor to a select mask when a new connection
+is created and remove the file descriptor when the connection is destroyed.
+Because connections are shared, knowing when to add and remove the file
+descriptor from the select mask would be difficult without the watch
+procedures.
+</para>
+
+<para>
+Multiple watch procedures may be registered with the ICE library.
+No assumptions should be made about their order of invocation.
+</para>
+
+<para>
+If one or more ICE connections were already created by the ICE library at the
+time the watch procedure is registered, the watch procedure will instantly
+be invoked for each of these ICE connections (with the opening argument
+set to <function>True</function>
+</para>
+
+<para>
+The watch procedure is of type <function>IceWatchProc</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void <function>WatchProc</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>IcePointer<parameter> client_data</parameter></paramdef>
+    <paramdef>Bool<parameter> opening</parameter></paramdef>
+    <paramdef>IcePointer<parameter> *watch_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>
+The opened or closed ICE connection.  Call
+<function>IceConnectionNumber</function>
+to get the file descriptor associated with this connection.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>client_data</emphasis></term>
+    <listitem>
+      <para>
+Client data specified in the call to
+<function>IceAddConnectionWatch</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>opening</emphasis></term>
+    <listitem>
+      <para>
+If <function>True</function> the connection is being opened.  If
+<function>False</function> the connection is being closed.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>watch_data</emphasis></term>
+    <listitem>
+      <para>Can be used to save a pointer to client data.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+If opening is <function>True</function> the client should set the
+*watch_data pointer to any data it may need to save until the connection
+is closed and the watch procedure is invoked again with opening set to
+<function>False</function>
+</para>
+
+<para>
+To remove a watch procedure, use
+<function>IceRemoveConnectionWatch</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void <function>IceRemoveConnectionWatch</function></funcdef>
+    <paramdef>IceWatchProc<parameter> watch_proc</parameter></paramdef>
+    <paramdef>IcePointer<parameter> client_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>watch_proc</emphasis></term>
+    <listitem>
+      <para>
+The watch procedure that was passed to
+<function>IceAddConnectionWatch</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>client_data</emphasis></term>
+    <listitem>
+      <para>
+The client_data pointer that was passed to
+<function>IceAddConnectionWatch</function>
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+</sect1>
+</chapter>
+
+<chapter id='protocol_setup_and_shutdown'>
+<title>Protocol Setup and Shutdown</title>
+
+<para>
+To activate a protocol on a given ICE connection, use
+<function>IceProtocolSetup</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>IceProtocolSetupStatus <function>IceProtocolSetup</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> my_opcode</parameter></paramdef>
+    <paramdef>IcePointer<parameter> client_data</parameter></paramdef>
+    <paramdef>Bool<parameter> must_authenticate</parameter></paramdef>
+    <paramdef>int<parameter> *major_version_ret</parameter></paramdef>
+    <paramdef>int<parameter> *minor_version_ret</parameter></paramdef>
+    <paramdef>char<parameter> **vendor_ret</parameter></paramdef>
+    <paramdef>char<parameter> **release_ret</parameter></paramdef>
+    <paramdef>int<parameter> error_length</parameter></paramdef>
+    <paramdef>char<parameter> *error_string_ret</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>my_opcode</emphasis></term>
+    <listitem>
+      <para>
+The major opcode of the protocol to be set up, as returned by
+<function>IceRegisterForProtocolSetup</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>client_data</emphasis></term>
+    <listitem>
+      <para>
+The client data stored in this pointer will be passed to the
+<function>IcePoProcessMsgProc</function> callback.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>must_authenticate</emphasis></term>
+    <listitem>
+      <para>
+If <function>True</function> the other client may
+not bypass authentication.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>major_version_ret</emphasis></term>
+    <listitem>
+      <para>The major version of the protocol to be used is returned.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>minor_version_ret</emphasis></term>
+    <listitem>
+      <para>The minor version of the protocol to be used is returned.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>vendor_ret</emphasis></term>
+    <listitem>
+      <para>The vendor string specified by the protocol acceptor.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>release_ret</emphasis></term>
+    <listitem>
+      <para>The release string specified by the protocol acceptor.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>error_length</emphasis></term>
+    <listitem>
+      <para>
+Specifies the length of the error_string_ret argument passed in.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>error_string_ret</emphasis></term>
+    <listitem>
+      <para>
+Returns a null-terminated error message, if any.
+The error_string_ret argument points to user supplied memory.
+No more than error_length bytes are used.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+The vendor_ret and release_ret strings should be freed with
+<function>free</function> when no longer needed.
+</para>
+
+<para>
+<function>IceProtocolSetup</function> returns one of the following values:
+</para>
+
+<itemizedlist>
+  <listitem>
+    <para>
+<function>IceProtocolSetupSuccess</function> - the major_version_ret,
+minor_version_ret, vendor_ret, release_ret are set.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+<function>IceProtocolSetupFailure</function> or
+<function>IceProtocolSetupIOError</function>
+- check error_string_ret for failure reason.  The major_version_ret,
+minor_version_ret, vendor_ret, release_ret are not set.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+<function>IceProtocolAlreadyActive</function>
+- this protocol is already active on this connection.
+The major_version_ret, minor_version_ret, vendor_ret, release_ret
+are not set.
+    </para>
+  </listitem>
+</itemizedlist>
+
+<para>
+To notify the ICE library when a given protocol will no longer be used
+on an ICE connection, use <function>IceProtocolShutdown</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Status <function>IceProtocolShutdown</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> major_opcode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+  <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>major_opcode</emphasis></term>
+    <listitem>
+      <para>The major opcode of the protocol to shut down.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+The return value of <function>IceProtocolShutdown</function>
+is zero for failure and a positive value for success.
+</para>
+
+<para>
+Failure will occur if the major opcode was never registered OR the protocol
+of the major opcode was never activated on the connection.  By activated,
+we mean that a <function>ProtocolSetup</function> succeeded on the connection.
+Note that ICE does not define how each sub-protocol triggers a
+protocol shutdown.
+</para>
+</chapter>
+
+<chapter id='processing_messages'>
+<title>Processing Messages</title>
+
+
+<para>To process incoming messages on an ICE connection, use
+<function>IceProcessMessages</function></para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>IceProcessMessagesStatus <function>IceProcessMessages</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>IceReplyWaitInfo<parameter> *reply_wait</parameter></paramdef>
+    <paramdef>Bool<parameter> *reply_ready_ret</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>reply_wait</emphasis></term>
+    <listitem>
+      <para>Indicates if a reply is being waited for.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>reply_ready_ret</emphasis></term>
+    <listitem>
+      <para>
+If set to <function>True</function> on return, a reply is ready.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+<function>IceProcessMessages</function> is used in two ways:
+</para>
+
+<itemizedlist>
+  <listitem>
+    <para>
+In the first, a client may generate a message and block by calling
+<function>IceProcessMessages</function> repeatedly until it gets its reply.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+In the second, a client calls <function>IceProcessMessages</function>
+with reply_wait set to NULL in response to <function>select</function>
+showing that there is data to read on the ICE connection.
+The ICE library may process zero or more complete messages.
+Note that messages that are not blocked for are always processed by
+invoking callbacks.
+    </para>
+  </listitem>
+</itemizedlist>
+
+<para>
+<function>IceReplyWaitInfo</function> contains the major/minor opcodes
+and sequence number of the message for which a reply is being awaited.
+It also contains a pointer to the reply message to be filled in (the
+protocol library should cast this <function>IcePointer</function>
+to the appropriate reply type).  In most
+cases, the reply will have some fixed-size part, and the client waiting
+for the reply will have provided a pointer to a structure to hold
+this fixed-size data.  If there is variable-length data, it would be
+expected that the
+<function>IcePoProcessMsgProc</function>
+callback will have to allocate additional
+memory and store pointer(s) to that memory in the fixed-size
+structure.  If the entire data is variable length (for example, a single
+variable-length string), then the client waiting for the reply would probably
+just pass a pointer to fixed-size space to hold a pointer, and the
+<function>IcePoProcessMsgProc</function>
+callback would allocate the storage and store the pointer.
+It is the responsibility of the client receiving the reply to
+free up any memory allocated on its behalf.
+</para>
+
+<literallayout class="monospaced">
+typedef struct {
+     unsigned long sequence_of_request;
+     int major_opcode_of_request;
+     int minor_opcode_of_request;
+     IcePointer reply;
+} IceReplyWaitInfo;
+</literallayout>
+
+<para>
+If reply_wait is not NULL and
+<function>IceProcessMessages</function>
+has a reply or error to return in response to this reply_wait
+(that is, no callback was generated), then the reply_ready_ret argument
+will be set to <function>True</function>
+</para>
+
+<para>
+If reply_wait is NULL, then the caller may also pass NULL for
+reply_ready_ret and be guaranteed that no value will be stored in
+this pointer.
+</para>
+
+<para>
+<function>IceProcessMessages</function> returns one of the following values:
+</para>
+
+<itemizedlist>
+  <listitem>
+    <para>
+<function>IceProcessMessagesSuccess</function> - no error occurred.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+<function>IceProcessMessagesIOError</function> - an IO error occurred,
+and the caller must explicitly close the connection by calling
+<function>IceCloseConnection</function>
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+<function>IceProcessMessagesConnectionClosed</function>
+- the ICE connection has been closed (closing of the connection was deferred
+because of shutdown negotiation, or because the
+<function>IceProcessMessages</function>
+nesting level was not zero).  Do not attempt
+to access the ICE connection at this point, since it has been freed.
+    </para>
+  </listitem>
+</itemizedlist>
+
+</chapter>
+
+<chapter id='ping'>
+<title>Ping</title>
+
+<para>
+To send a "Ping" message to the client on the other side of the
+ICE connection, use <function>IcePing</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Status <function>IcePing</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>IcePingReplyProc<parameter> ping_reply_proc</parameter></paramdef>
+    <paramdef>IcePointer<parameter> client_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>ping_reply_proc</emphasis></term>
+    <listitem>
+      <para>The callback to invoke when the Ping reply arrives.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>client_data</emphasis></term>
+    <listitem>
+      <para>
+This pointer will be passed to the <function>IcePingReplyProc</function>
+callback.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para><function>IcePing</function>
+returns zero for failure and a positive value for success.</para>
+
+<para>When
+<function>IceProcessMessages</function>
+processes the Ping reply, it will invoke the
+<function>IcePingReplyProc</function>
+callback.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void <function>PingReplyProc</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>IcePointer<parameter> client_data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+  <term><emphasis remap='I'>ice_conn</emphasis></term>
+  <listitem>
+<para>A valid ICE connection object.</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>client_data</emphasis></term>
+  <listitem>
+<para>The client data specified in the call to
+<function>IcePing</function></para>
+  </listitem>
+  </varlistentry>
+</variablelist>
+
+</chapter>
+
+<chapter id='using_icelib_informational_functions'>
+<title>Using ICElib Informational Functions</title>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>IceConnectStatus <function>IceConnectionStatus</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para><function>IceConnectionStatus</function>
+returns the status of an ICE connection.  The possible return values are:</para>
+
+<itemizedlist>
+  <listitem>
+<para><function>IceConnectPending</function>
+- the connection is not valid yet (that is, authentication is taking place).
+This is only relevant to connections created by
+<function>IceAcceptConnection</function></para>
+  </listitem>
+  <listitem>
+<para><function>IceConnectAccepted</function>
+- the connection has been accepted.
+This is only relevant to connections created by
+<function>IceAcceptConnection</function></para>
+  </listitem>
+  <listitem>
+<para><function>IceConnectRejected</function>
+- the connection had been rejected  (that is, authentication failed).
+This is only relevant to connections created by
+<function>IceAcceptConnection</function></para>
+  </listitem>
+  <listitem>
+<para><function>IceConnectIOError</function>
+- an IO error has occurred on the connection.</para>
+  </listitem>
+</itemizedlist>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>char <function> *IceVendor</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para><function>IceVendor</function>
+returns the ICE library vendor identification
+for the other side of the connection.
+The string should be freed with a call to
+<function>free</function>
+when no longer needed.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>char <function> *IceRelease</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para><function>IceRelease</function>
+returns the release identification of the ICE library
+on the other side of the connection.
+The string should be freed with a call to
+<function>free</function>
+when no longer needed.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>int <function> IceProtocolVersion</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para><function>IceProtocolVersion</function>
+returns the major version of the ICE protocol on this connection.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>int <function> IceProtocolRevision</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+
+<para><function>IceProtocolRevision</function>
+returns the minor version of the ICE protocol on this connection.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>int <function> IceConnectionNumber</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+
+<para><function>IceConnectionNumber</function>
+returns the file descriptor of this ICE connection.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>char <function> *IceConnectionString</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para><function>IceConnectionString</function>
+returns the network ID of the client that
+accepted this connection.  The string should be freed with a call to
+<function>free</function>
+when no longer needed.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>unsigned long <function> IceLastSentSequenceNumber</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+
+<para><function>IceLastSentSequenceNumber</function>
+returns the sequence number of the last message sent on this ICE connection.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>unsigned long <function> IceLastReceivedSequenceNumber</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para><function>IceLastReceivedSequenceNumber</function>
+returns the sequence number of the last message received on this
+ICE connection.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Bool <function> IceSwapping</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+
+<para><function>IceSwapping</function>
+returns
+<function>True</function>
+if byte swapping is necessary when reading messages on the ICE connection.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>IcePointer <function> IceGetContext</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<para><function>IceGetContext</function>
+returns the context associated with a connection created by
+<function>IceOpenConnection</function></para>
+</chapter>
+
+<chapter id='ice_messages'>
+<title>ICE Messages</title>
+
+<para>
+All ICE messages have a standard 8-byte header.  The ICElib macros that
+read and write messages rely on the following naming convention for message
+headers:
+</para>
+
+<literallayout class='monospaced'>
+     CARD8     major_opcode;
+     CARD8     minor_opcode;
+     CARD8     data[2];
+     CARD32    length B32;
+</literallayout>
+
+<para>
+The 3rd and 4th bytes of the message header can be used as needed.
+The length field is specified in units of 8 bytes.
+</para>
+
+<sect1 id='sending_ice_messages'>
+<title>Sending ICE Messages</title>
+
+<para>
+The ICE library maintains an output buffer used for generating messages.
+Protocol libraries layered on top of ICE may choose to batch messages
+together and flush the output buffer at appropriate times.
+</para>
+
+<para>
+If an IO error has occurred on an ICE connection, all write operations
+will be ignored.  For further information, see
+<link linkend="error_handling">
+<xref linkend="error_handling"></xref></link>.
+</para>
+
+
+<para>
+To get the size of the ICE output buffer, use
+<function>IceGetOutBufSize</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>int <function> IceGetOutBufSize</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+To flush the ICE output buffer, use <function>IceFlush</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>int <function> IceFlush</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+Note that the output buffer may be implicitly flushed if there is
+insufficient space to generate a message.
+</para>
+
+<para>The following macros can be used to generate ICE messages:</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceGetHeader</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> major_opcode</parameter></paramdef>
+    <paramdef>int<parameter> minor_opcode</parameter></paramdef>
+    <paramdef>int<parameter> header_size</parameter></paramdef>
+    <paramdef>&lt;C_data_type&gt;<parameter> *pmsg</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>major_opcode</emphasis></term>
+    <listitem>
+      <para>The major opcode of the message.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>minor_opcode</emphasis></term>
+    <listitem>
+      <para>The minor opcode of the message.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>header_size</emphasis></term>
+    <listitem>
+      <para>The size of the message header (in bytes).</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>&lt;C_data_type&gt;</emphasis></term>
+    <listitem>
+      <para>The actual C data type of the message header.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>pmsg</emphasis></term>
+    <listitem>
+      <para>
+The message header pointer.  After this macro is called, the
+library can store data in the message header.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+<function>IceGetHeader</function>
+is used to set up a message header on an ICE connection.
+It sets the major and minor opcodes of the message, and initializes
+the message's length to the length of the header.  If additional
+variable length data follows, the message's length field should be
+updated.
+</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceGetHeaderExtra</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> major_opcode</parameter></paramdef>
+    <paramdef>int<parameter> minor_opcode</parameter></paramdef>
+    <paramdef>int<parameter> header_size</parameter></paramdef>
+    <paramdef>int<parameter> extra</parameter></paramdef>
+    <paramdef>&lt;C_data_type&gt;<parameter> *pmsg</parameter></paramdef>
+    <paramdef>char<parameter> *pdata</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>major_opcode</emphasis></term>
+    <listitem>
+      <para>The major opcode of the message.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>minor_opcode</emphasis></term>
+    <listitem>
+      <para>The minor opcode of the message.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>header_size</emphasis></term>
+    <listitem>
+      <para>The size of the message header (in bytes).</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>extra</emphasis></term>
+    <listitem>
+      <para>
+The size of the extra data beyond the header (in 8-byte units).
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>&lt;C_data_type&gt;</emphasis></term>
+    <listitem>
+      <para>The actual C data type of the message header.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>pmsg</emphasis></term>
+    <listitem>
+      <para>
+The message header pointer.  After this macro is called, the
+library can store data in the message header.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>pdata</emphasis></term>
+    <listitem>
+      <para>
+Returns a pointer to the ICE output buffer that points
+immediately after the message header.  The variable length
+data should be stored here.  If there was not enough room
+in the ICE output buffer, pdata is set to NULL.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+<function>IceGetHeaderExtra</function>
+is used to generate a message with a fixed (and relatively small) amount
+of variable length data.  The complete message must fit in the ICE output
+buffer.
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceSimpleMessage</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> major_opcode</parameter></paramdef>
+    <paramdef>int<parameter> minor_opcode</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>major_opcode</emphasis></term>
+    <listitem>
+      <para>The major opcode of the message.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>minor_opcode</emphasis></term>
+    <listitem>
+      <para>The minor opcode of the message.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+<function>IceSimpleMessage</function>
+is used to generate a message that is identical
+in size to the ICE header message, and has no additional data.
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceErrorHeader</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> offending_major_opcode</parameter></paramdef>
+    <paramdef>int<parameter> offending_minor_opcode</parameter></paramdef>
+    <paramdef>int<parameter> offending_sequence_num</parameter></paramdef>
+    <paramdef>int<parameter> severity</parameter></paramdef>
+    <paramdef>int<parameter> error_class</parameter></paramdef>
+    <paramdef>int<parameter> data_length</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>offending_major_opcode</emphasis></term>
+    <listitem>
+      <para>
+The major opcode of the protocol in which an error was detected.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>offending_minor_opcode</emphasis></term>
+    <listitem>
+      <para>
+The minor opcode of the protocol in which an error was detected.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>offending_sequence_num</emphasis></term>
+    <listitem>
+      <para>The sequence number of the message that caused the error.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis></term>
+    <listitem>
+      <para>
+<function>IceCanContinue</function>
+<function>IceFatalToProtocol</function>
+or
+<function>IceFatalToConnection</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>error_class</emphasis></term>
+    <listitem>
+      <para>The error class.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>data_length</emphasis></term>
+    <listitem>
+      <para>
+Length of data (in 8-byte units) to be written after the header.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+<function>IceErrorHeader</function> sets up an error message header.
+</para>
+
+<para>
+Note that the two clients connected by ICE may be using different
+major opcodes for a given protocol.  The offending_major_opcode passed
+to this macro is the major opcode of the protocol for the client
+sending the error message.
+</para>
+
+<para>
+Generic errors, which are common to all protocols, have classes
+in the range 0x8000..0xFFFF.
+See the <emphasis remap='I'>Inter-Client Exchange Protocol</emphasis>
+standard for more details.
+</para>
+
+<informaltable pgwide='0' frame='none'>
+  <tgroup cols='2' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <tbody>
+      <row>
+        <entry align='left'>IceBadMinor</entry>
+        <entry align='left'>0x8000</entry>
+      </row>
+      <row>
+        <entry align='left'>IceBadState</entry>
+        <entry align='left'>0x8001</entry>
+      </row>
+      <row>
+        <entry align='left'>IceBadLength</entry>
+        <entry align='left'>0x8002</entry>
+      </row>
+      <row>
+        <entry align='left'>IceBadValue</entry>
+        <entry align='left'>0x8003</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+<para>Per-protocol errors have classes in the range 0x0000-0x7fff.</para>
+
+<para>
+To write data to an ICE connection, use the
+<function>IceWriteData</function> macro.  If the data fits into the
+ICE output buffer, it is copied there.  Otherwise, the ICE output buffer
+is flushed and the data is directly sent.
+</para>
+
+<para>
+This macro is used in conjunction with
+<function>IceGetHeader</function> and
+<function>IceErrorHeader</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceWriteData</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> bytes</parameter></paramdef>
+    <paramdef>char<parameter> *data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>bytes</emphasis></term>
+    <listitem>
+      <para>The number of bytes to write.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>data</emphasis></term>
+    <listitem>
+      <para>The data to write.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+To write data as 16-bit quantities, use <function>IceWriteData16</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceWriteData16</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> bytes</parameter></paramdef>
+    <paramdef>char<parameter> *data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>bytes</emphasis></term>
+    <listitem>
+      <para>The number of bytes to write.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>data</emphasis></term>
+    <listitem>
+      <para>The data to write.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+To write data as 32-bit quantities, use <function>IceWriteData32</function>
+</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceWriteData32</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> bytes</parameter></paramdef>
+    <paramdef>char<parameter> *data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>bytes</emphasis></term>
+    <listitem>
+      <para>The number of bytes to write.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>data</emphasis></term>
+    <listitem>
+      <para>The data to write.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+To write data as 32-bit quantities, use <function>IceWriteData32</function>
+</para>
+
+<para>
+To bypass copying data to the ICE output buffer, use
+<function>IceSendData</function> to directly send data over the network
+connection.  If necessary, the ICE output buffer is first flushed.
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceSendData</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> bytes</parameter></paramdef>
+    <paramdef>char<parameter> *data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>bytes</emphasis></term>
+    <listitem>
+      <para>The number of bytes to send.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>data</emphasis></term>
+    <listitem>
+      <para>The data to send.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+To force 32-bit or 64-bit alignment, use <function>IceWritePad</function>
+A maximum of 7 pad bytes can be specified.
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceWritePad</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> bytes</parameter></paramdef>
+    <paramdef>char<parameter> *data</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>bytes</emphasis></term>
+    <listitem>
+      <para>The number of bytes to write.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>data</emphasis></term>
+    <listitem>
+      <para>The number of pad bytes to write.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+</sect1>
+
+<sect1 id='reading_ice_messages'>
+<title>Reading ICE Messages</title>
+
+
+<para>
+The ICE library maintains an input buffer used for reading messages.
+If the ICE library chooses to perform nonblocking reads (this is
+implementation-dependent), then for every read operation that it makes,
+zero or more complete messages may be read into the input buffer.  As
+a result, for all of the macros described in this section that read
+messages, an actual read operation will occur on the connection only if
+the data is not already present in the input buffer.
+</para>
+
+
+<para>
+To get the size of the ICE input buffer, use
+<function>IceGetInBufSize</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>int<function> IceGetInBufSize</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+When reading messages, care must be taken to check for IO errors.  If
+any IO error occurs in reading any part of a message, the message should
+be thrown out.  After using any of the macros described below for reading
+messages, the <function>IceValidIO</function>
+macro can be used to check if an IO error occurred on the
+connection.  After an IO error has occurred on an ICE connection, all
+read operations will be ignored.  For further information, see
+<link linkend="error_handling">
+<xref linkend="error_handling"></xref></link>.
+</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Bool<function> IceValidIO</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>The following macros can be used to read ICE messages.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceReadSimpleMessage</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>&lt;C_data_type&gt;<parameter> *pmsg</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>&lt;C_data_type&gt;</emphasis></term>
+    <listitem>
+      <para>The actual C data type of the message header.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>pmsg</emphasis></term>
+    <listitem>
+      <para>This pointer is set to the message header.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+<function>IceReadSimpleMessage</function>
+is used for messages that are identical in size to the 8-byte ICE header, but
+use the spare 2 bytes in the header to encode additional data.  Note that the
+ICE library always reads in these first 8 bytes, so it can obtain the major
+opcode of the message.  <function>IceReadSimpleMessage</function>
+simply returns a pointer to these 8 bytes; it does not actually read any data
+into the input buffer.
+</para>
+
+<para>
+For a message with variable length data, there are two ways of reading
+the message.  One method involves reading the complete message in one
+pass using <function>IceReadCompleteMessage</function>
+The second method involves reading the message header (note that this may
+be larger than the 8-byte ICE header), then reading
+the variable length data in chunks (see
+<function>IceReadMessageHeader</function> and
+<function>IceReadData</function>
+</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceReadCompleteMessage</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> header_size</parameter></paramdef>
+    <paramdef>&lt;C_data_type&gt;<parameter> *pmsg</parameter></paramdef>
+    <paramdef>char<parameter> *pdata</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>header_size</emphasis></term>
+    <listitem>
+      <para>The size of the message header (in bytes).</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>&lt;C_data_type&gt;</emphasis></term>
+    <listitem>
+      <para>The actual C data type of the message header.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>pmsg</emphasis></term>
+    <listitem>
+      <para>This pointer is set to the message header.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>pdata</emphasis></term>
+    <listitem>
+      <para>
+This pointer is set to the variable length data of the message.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+If the ICE input buffer has sufficient space,
+<function>IceReadCompleteMessage</function>
+will read the complete message into the
+ICE input buffer.  Otherwise, a buffer will be allocated to hold the
+variable length data.  After the call, the pdata argument should
+be checked against NULL to make sure that there was sufficient memory
+to allocate the buffer.
+</para>
+
+<para>
+After calling <function>IceReadCompleteMessage</function>
+and processing the message, <function>IceDisposeCompleteMessage</function>
+should be called.
+</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceDisposeCompleteMessage</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>char<parameter> *pdata</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>pdata</emphasis></term>
+    <listitem>
+      <para>
+The pointer to the variable length data returned in
+<function>IceReadCompleteMessage</function>
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+If a buffer had to be allocated to hold the variable length data (because
+it did not fit in the ICE input buffer), it is freed here by ICElib.
+</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceReadMessageHeader</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> header_size</parameter></paramdef>
+    <paramdef>&lt;C_data_type&gt;<parameter> *pmsg</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>header_size</emphasis></term>
+    <listitem>
+      <para>The size of the message header (in bytes).</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>&lt;C_data_type&gt;</emphasis></term>
+    <listitem>
+      <para>The actual C data type of the message header.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>pmsg</emphasis></term>
+    <listitem>
+      <para>This pointer is set to the message header.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+<function>IceReadMessageHeader</function> reads just the message header.
+The rest of the data should be read with the
+<function>IceReadData</function>
+family of macros.  This method of reading a message should be used when the
+variable length data must be read in chunks.
+</para>
+
+
+<para>
+To read data directly into a user supplied buffer, use
+<function>IceReadData</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceReadData</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> bytes</parameter></paramdef>
+    <paramdef>char<parameter> *pdata</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>bytes</emphasis></term>
+    <listitem>
+      <para>The number of bytes to read.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>pdata</emphasis></term>
+    <listitem>
+      <para>The data is read into this user supplied buffer.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+To read data as 16-bit quantities, use <function>IceReadData16</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceReadData16</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>Bool<parameter> swap</parameter></paramdef>
+    <paramdef>int<parameter> bytes</parameter></paramdef>
+    <paramdef>char<parameter> *pdata</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>swap</emphasis></term>
+    <listitem>
+      <para>
+If <function>True,</function> the values will be byte swapped.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>bytes</emphasis></term>
+    <listitem>
+      <para>The number of bytes to read.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>pdata</emphasis></term>
+    <listitem>
+      <para>The data is read into this user supplied buffer.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+To read data as 32-bit quantities, use <function>IceReadData32</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceReadData32</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>Bool<parameter> swap</parameter></paramdef>
+    <paramdef>int<parameter> bytes</parameter></paramdef>
+    <paramdef>char<parameter> *pdata</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>swap</emphasis></term>
+    <listitem>
+      <para>
+If <function>True,</function> the values will be byte swapped.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>bytes</emphasis></term>
+    <listitem>
+      <para>The number of bytes to read.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>pdata</emphasis></term>
+    <listitem>
+      <para>The data is read into this user supplied buffer.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>To force 32-bit or 64-bit alignment, use
+<function>IceReadPad</function>
+A maximum of 7 pad bytes can be specified.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceReadPad</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> bytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem>
+      <para>A valid ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>bytes</emphasis></term>
+    <listitem>
+      <para>The number of pad bytes.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+</sect1>
+</chapter>
+
+<chapter id='error_handling'>
+<title>Error Handling</title>
+
+
+<para>There are two default error handlers in ICElib:</para>
+
+<itemizedlist>
+  <listitem>
+    <para>
+One to handle typically fatal conditions (for example,
+a connection dying because a machine crashed)
+    </para>
+  </listitem>
+  <listitem>
+    <para>One to handle ICE-specific protocol errors</para>
+  </listitem>
+</itemizedlist>
+
+<para>
+These error handlers can be changed to user-supplied routines if you
+prefer your own error handling and can be changed as often as you like.
+</para>
+
+
+<para>
+To set the ICE error handler, use <function>IceSetErrorHandler</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef><function> IceSetErrorHandler</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>int<parameter> bytes</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>handler</emphasis></term>
+    <listitem>
+      <para>
+The ICE error handler.  You should pass NULL to restore the default handler.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+<function>IceSetErrorHandler</function> returns the previous error handler.
+</para>
+
+<para>
+The ICE error handler is invoked when an unexpected ICE protocol
+error (major opcode 0) is encountered.  The action of the default
+handler is to print an explanatory message to
+<function>stderr</function>
+and if the severity is fatal, call
+<function>exit</function>
+with a nonzero value.  If exiting
+is undesirable, the application should register its own error handler.
+</para>
+
+<para>
+Note that errors in other protocol
+domains should be handled by their respective libraries (these libraries
+should have their own error handlers).
+</para>
+
+<para>
+An ICE error handler has the type of <function>IceErrorHandler</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void<function> IceErrorHandler</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>Bool<parameter> swap</parameter></paramdef>
+    <paramdef>int<parameter> offending_minor_opcode</parameter></paramdef>
+    <paramdef>unsigned long<parameter> offending_sequence_num</parameter></paramdef>
+    <paramdef>int<parameter> error_class</parameter></paramdef>
+    <paramdef>int<parameter> severity</parameter></paramdef>
+    <paramdef>IcePointer<parameter> values</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>handler</emphasis></term>
+    <listitem>
+      <para>The ICE connection object.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>swap</emphasis></term>
+    <listitem>
+      <para>A flag that indicates if the values need byte swapping.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>offending_minor_opcode</emphasis></term>
+    <listitem>
+      <para>The ICE minor opcode of the offending message.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>offending_sequence_num</emphasis></term>
+    <listitem>
+      <para>The sequence number of the offending message.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>error_class</emphasis></term>
+    <listitem>
+      <para>The error class of the offending message.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis></term>
+    <listitem>
+      <para>
+<function>IceCanContinue</function>
+<function>IceFatalToProtocol</function>
+or
+<function>IceFatalToConnection</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis></term>
+    <listitem>
+      <para>
+Any additional error values specific to the minor opcode and class.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>The following error classes are defined at the ICE level:</para>
+
+<literallayout remap='Ds'>
+<function>IceBadMinor</function>
+<function>IceBadState</function>
+<function>IceBadLength</function>
+<function>IceBadValue</function>
+<function>IceBadMajor</function>
+<function>IceNoAuth</function>
+<function>IceNoVersion</function>
+<function>IceSetupFailed</function>
+<function>IceAuthRejected</function>
+<function>IceAuthFailed</function>
+<function>IceProtocolDuplicate</function>
+<function>IceMajorOpcodeDuplicate</function>
+<function>IceUnknownProtocol</function>
+</literallayout>
+
+<para>
+For further information, see
+the <emphasis remap='I'>Inter-Client Exchange Protocol</emphasis> standard.
+</para>
+
+
+<para>
+To handle fatal I/O errors, use <function>IceSetIOErrorHandler</function>
+</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>IceIOErrorHandler<function> IceSetIOErrorHandler</function></funcdef>
+    <paramdef>IceIOErrorHandler<parameter> handler</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>handler</emphasis></term>
+    <listitem>
+      <para>
+The I/O error handler.  You should pass NULL to restore the default handler.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+<function>IceSetIOErrorHandler</function> returns the previous
+IO error handler.
+</para>
+
+<para>
+An ICE I/O error handler has the type of
+<function>IceIOErrorHandler</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void<function> IceIOErrorHandler</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem><para>The ICE connection object.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para> There are two ways of handling IO errors in ICElib:</para>
+
+<itemizedlist>
+  <listitem>
+    <para>
+In the first, the IO error handler does whatever is necessary
+to respond to the IO error and then returns, but it does not call
+<function>IceCloseConnection</function>
+The ICE connection is given a "bad IO" status, and all future reads
+and writes to the connection are ignored.  The next time
+<function>IceProcessMessages</function>
+is called it will return a status of
+<function>IceProcessMessagesIOError</function>
+At that time, the application should call
+<function>IceCloseConnection</function>
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+In the second, the IO error handler does call
+<function>IceCloseConnection</function>
+and then uses the <function>longjmp</function>
+call to get back to the application's main event loop.  The
+<function>setjmp</function> and
+<function>longjmp</function>
+calls may not work properly on all platforms,
+and special care must be taken to avoid memory leaks.
+Therefore, this second model is less desirable.
+    </para>
+  </listitem>
+</itemizedlist>
+
+<para>
+Before the application I/O error handler is invoked, protocol libraries
+that were interested in being notified of I/O errors will have their
+<function>IceIOErrorProc</function>
+handlers invoked.  This handler is set up in the protocol registration
+functions (see <function>IceRegisterForProtocolSetup</function> and
+<function>IceRegisterForProtocolReply</function>
+and could be used to clean up state specific to the protocol.
+</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void<function> IceIOErrorProc</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem><para>The ICE connection object.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+Note that every <function>IceIOErrorProc</function>
+callback must return.  This is required
+because each active protocol must be notified of the broken connection,
+and the application IO error handler must be invoked afterwards.
+</para>
+</chapter>
+
+<chapter id='multithreading_support'>
+<title>Multi-Threading Support</title>
+
+
+<para>To declare that multiple threads in an application will be using the ICE
+library, use
+<function>IceInitThreads</function></para>
+
+<literallayout remap='FD'>
+Status IceInitThreads()
+</literallayout>
+
+
+<para>The
+<function>IceInitThreads</function>
+function must be the first ICElib function a
+multi-threaded program calls.  It must complete before any other ICElib
+call is made.
+<function>IceInitThreads</function>
+returns a nonzero status if and only if it was able
+to initialize the threads package successfully.
+It is safe to call
+<function>IceInitThreads</function>
+more than once, although the threads package will only be initialized once.</para>
+
+<para>Protocol libraries layered on top of ICElib will have to lock critical
+sections of code that access an ICE connection (for example, when
+generating messages).  Two calls, which are generally implemented as
+macros, are provided:</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void<function> IceLockConn</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void<function> IceUnlockConn</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem><para>The ICE connection object.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+<para>To keep an ICE connection locked across several ICElib calls, applications use
+<function>IceAppLockConn</function>
+and
+<function>IceAppUnlockConn</function></para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void<function> IceAppLockConn</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem><para>The ICE connection object.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>The
+<function>IceAppLockConn</function>
+function completely locks out other threads using the connection
+until
+<function>IceAppUnlockConn</function>
+is called.  Other threads attempting to use ICElib
+calls on the connection will block.
+If the program has not previously called
+<function>IceInitThreads</function>
+<function>IceAppLockConn</function>
+has no effect.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void<function> IceAppUnlockConn</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem><para>The ICE connection object.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+<para>The
+<function>IceAppUnlockConn</function>
+function allows other threads to complete ICElib
+calls on the connection that were blocked by a previous call to
+<function>IceAppLockConn</function>
+from this thread.  If the program has not previously called
+<function>IceInitThreads</function>
+<function>IceAppUnlockConn</function>
+has no effect.</para>
+</chapter>
+
+<chapter id='miscellaneous_functions'>
+<title>Miscellaneous Functions</title>
+
+
+
+
+<para>To allocate scratch space (for example, when generating
+messages with variable data), use
+<function>IceAllocScratch</function>
+Each ICE connection has one scratch space associated with it.
+The scratch space starts off as empty and grows as needed.
+The contents of the scratch space is not guaranteed to be preserved
+after any ICElib function is called.</para>
+
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>char<function> *IceAllocScratch</function></funcdef>
+    <paramdef>IceConn<parameter> ice_conn</parameter></paramdef>
+    <paramdef>unsigned long<parameter> size</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>ice_conn</emphasis></term>
+    <listitem><para>The ICE connection object.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>size</emphasis></term>
+    <listitem><para>The number of bytes required.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+<para>Note that the memory returned by
+<function>IceAllocScratch</function>
+should not be freed by the caller.
+The ICE library will free the memory when the ICE connection is closed.</para>
+</chapter>
+
+<chapter id='acknowledgements'>
+<title>Acknowledgements</title>
+
+
+<para>
+Thanks to Bob Scheifler for his thoughtful input on the design
+of the ICE library.  Thanks also to Jordan Brown, Larry Cable, Donna Converse,
+Clive Feather, Stephen Gildea, Vania Joloboff, Kaleb Keithley,
+Stuart Marks, Hiro Miyamoto, Ralph Swick, Jim VanGilder, and Mike Wexler.
+</para>
+</chapter>
+
+<appendix id="authentication_utility_functions">
+<title>Authentication Utility Functions</title>
+
+
+<para>
+As discussed in this document, the means by which authentication data
+is obtained by the ICE library (for
+<function>ConnectionSetup</function>
+messages or
+<function>ProtocolSetup</function>
+messages) is implementation-dependent.&dagger;
+<footnote remap='FS'>
+<para>The X Consortium's ICElib implementation assumes the presence of an
+ICE authority file.
+</para></footnote>
+</para>
+
+<para>
+This appendix describes some utility functions that manipulate an
+ICE authority file.  The authority file can be used to pass authentication
+data between clients.
+</para>
+
+<para>The basic operations on the .ICEauthority file are:</para>
+
+<itemizedlist>
+  <listitem>
+    <para>Get file name</para>
+  </listitem>
+  <listitem>
+    <para>Lock</para>
+  </listitem>
+  <listitem>
+    <para>Unlock</para>
+  </listitem>
+  <listitem>
+    <para>Read entry</para>
+  </listitem>
+  <listitem>
+    <para>Write entry</para>
+  </listitem>
+  <listitem>
+    <para>Search for entry</para>
+  </listitem>
+</itemizedlist>
+
+<para>
+These are fairly low-level operations, and it is expected that a program,
+like "iceauth", would exist to add, remove, and display entries in the file.
+</para>
+
+<para>
+In order to use these utility functions, the
+&lt;<symbol role='Pn'>X11/ICE/ICEutil.h</symbol>&gt;
+header file must be included.
+</para>
+
+<para>
+An entry in the .ICEauthority file is defined by the following data structure:
+</para>
+
+
+<literallayout class="monospaced">
+typedef struct {
+     char *protocol_name;
+     unsigned short protocol_data_length;
+     char *protocol_data;
+     char *network_id;
+     char *auth_name;
+     unsigned short auth_data_length;
+     char *auth_data;
+} IceAuthFileEntry;
+</literallayout>
+
+
+<para>
+The protocol_name member is either "ICE" for connection setup authentication
+or the subprotocol name, such as "XSMP".  For each entry, protocol specific
+data can be specified in the protocol_data member.  This can be used
+to search for old entries that need to be removed from the file.
+</para>
+
+<para>
+The network_id member is the network ID of the client accepting
+authentication (for example, the network ID of a session manager).
+A network ID has the following form:
+</para>
+
+<informaltable pgwide='0' frame='none'>
+  <tgroup cols='3' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <colspec colname='c3'/>
+    <tbody>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>tcp/&lt;hostname&gt;:&lt;portnumber&gt;</entry>
+        <entry align='left'>or</entry>
+      </row>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>decnet/&lt;hostname&gt;::&lt;objname&gt;</entry>
+        <entry align='left'>or</entry>
+      </row>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>local/&lt;hostname&gt;:&lt;path&gt;</entry>
+        <entry align='left'></entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+<para>
+The auth_name member is the name of the authentication method.
+The auth_data member is the actual authentication data,
+and the auth_data_length member is the number of bytes in the data.
+</para>
+
+<para>
+To obtain the default authorization file name, use
+<function>IceAuthFileName</function>
+</para>
+
+<literallayout remap='FD'>
+char *IceAuthFileName()
+</literallayout>
+
+<para>
+If the ICEAUTHORITY environment variable if set, this value is returned.
+Otherwise, the default authorization file name is $HOME/.ICEauthority.
+This name is statically allocated and should not be freed.
+</para>
+
+<para>
+To synchronously update the authorization file, the file must
+be locked with a call to
+<function>IceLockAuthFile</function>
+This function takes advantage of the fact that the
+<function>link</function>
+system call will fail if the name of the new link already exists.
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>int<function> IceLockAuthFile</function></funcdef>
+    <paramdef>char<parameter> *file_name</parameter></paramdef>
+    <paramdef>int<parameter> retries</parameter></paramdef>
+    <paramdef>int<parameter> timeout</parameter></paramdef>
+    <paramdef>long<parameter> dead</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>file_name</emphasis></term>
+    <listitem><para>The authorization file to lock.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>retries</emphasis></term>
+    <listitem>
+      <para>The number of retries.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>timeout</emphasis></term>
+    <listitem>
+      <para>The number of seconds before each retry.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>dead</emphasis></term>
+    <listitem>
+      <para>
+If a lock already exists that is the specified dead seconds old,
+it is broken.
+A value of zero is used to unconditionally break an old lock.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>One of three values is returned:</para>
+
+<itemizedlist>
+  <listitem>
+    <para>
+<function>IceAuthLockSuccess</function> - the lock succeeded.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+<function>IceAuthLockError</function> - a system error occurred, and
+<function>errno</function> may prove useful.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+<function>IceAuthLockTimeout</function> - the specified number of
+retries failed.
+    </para>
+  </listitem>
+</itemizedlist>
+
+<para>
+To unlock an authorization file, use <function>IceUnlockAuthFile</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>int<function> IceUnlockAuthFile</function></funcdef>
+    <paramdef>char<parameter> *file_name</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>file_name</emphasis></term>
+    <listitem><para>The authorization file to unlock.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+To read the next entry in an authorization file, use
+<function>IceReadAuthFileEntry</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>IceAuthFileEntry<function> *IceReadAuthFileEntry</function></funcdef>
+    <paramdef>FILE<parameter> *auth_file</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>auth_file</emphasis></term>
+    <listitem><para>The authorization file.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+Note that it is the responsibility of the application to open the file
+for reading before calling this function.  If an error is encountered,
+or there are no more entries to read, NULL is returned.
+</para>
+
+<para>
+Entries should be free with a call to
+<function>IceFreeAuthFileEntry</function>
+</para>
+
+<para>
+To write an entry in an authorization file, use
+<function>IceWriteAuthFileEntry</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>Status<function> IceWriteAuthFileEntry</function></funcdef>
+    <paramdef>FILE<parameter> *auth_file</parameter></paramdef>
+    <paramdef>IceAuthFileEntry<parameter> *entry</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>auth_file</emphasis></term>
+    <listitem><para>The authorization file.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>entry</emphasis></term>
+    <listitem><para>The entry to write.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+Note that it is the responsibility of the application to open the file
+for writing before calling this function.  The function returns a nonzero
+status if the operation was successful.
+</para>
+
+
+<para>
+To search the default authorization file for an entry that matches a given
+protocol_name/network_id/auth_name tuple, use
+<function>IceGetAuthFileEntry</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>IceAuthFileEntry<function> *IceGetAuthFileEntry</function></funcdef>
+    <paramdef>char<parameter> *protocol_name</parameter></paramdef>
+    <paramdef>char<parameter> *network_id</parameter></paramdef>
+    <paramdef>char<parameter> *auth_name</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>auth_file</emphasis></term>
+    <listitem><para>The name of the protocol to search on.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>network_id</emphasis></term>
+    <listitem>
+      <para>The network ID to search on.</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>auth_name</emphasis></term>
+    <listitem>
+      <para>The authentication method to search on.</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+If <function>IceGetAuthFileEntry</function>
+fails to find such an entry, NULL is returned.
+</para>
+
+
+<para>
+To free an entry returned by
+<function>IceReadAuthFileEntry</function> or
+<function>IceGetAuthFileEntry</function> use
+<function>IceFreeAuthFileEntry</function>
+</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void<function> IceFreeAuthFileEntry</function></funcdef>
+    <paramdef>IceAuthFileEntry<parameter> *entry</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>entry</emphasis></term>
+    <listitem><para>The entry to free.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+</appendix>
+
+<appendix id="mit_magic_cookie_1_authentication">
+<title>MIT-MAGIC-COOKIE-1 Authentication</title>
+
+
+<para>The X Consortium's ICElib implementation supports a simple
+MIT-MAGIC-COOKIE-1 authentication scheme using the authority file utilities
+described in Appendix A.</para>
+
+<para>In this model, an application, such as a session manager, obtains a
+magic cookie by calling
+<function>IceGenerateMagicCookie</function>
+and then stores it in the user's local .ICEauthority file
+so that local clients can connect.  In order to allow remote clients to
+connect, some remote execution mechanism should be used to store the
+magic cookie in the user's .ICEauthority file on a remote machine.</para>
+
+<para>In addition to storing the magic cookie in the .ICEauthority file, the
+application needs to call the
+<function>IceSetPaAuthData</function>
+function in order to store the magic cookie in memory.  When it comes time
+for the MIT-MAGIC-COOKIE-1 authentication procedure to accept or reject the
+connection, it will compare the magic cookie presented by the requestor to
+the magic cookie in memory.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>char<function> *IceGenerateMagicCookie</function></funcdef>
+    <paramdef>int<parameter> length</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>length</emphasis></term>
+    <listitem><para>The desired length of the magic cookie.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>The magic cookie returned will be null-terminated.  If memory can not be
+allocated for the magic cookie, the function will return NULL.
+Otherwise, the magic cookie should be freed with a call to
+<function>free</function></para>
+
+
+<para>To store the authentication data in memory, use
+<function>IceSetPaAuthData</function>
+Currently, this function is only used for MIT-MAGIC-COOKIE-1
+authentication, but it may be used for additional authentication
+methods in the future.</para>
+
+<funcsynopsis>
+<funcprototype>
+  <funcdef>void<function> IceSetPaAuthData</function></funcdef>
+    <paramdef>int<parameter> num_entries</parameter></paramdef>
+    <paramdef>IceAuthDataEntry<parameter> *entries</parameter></paramdef>
+</funcprototype>
+</funcsynopsis>
+
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>num_entries</emphasis></term>
+    <listitem><para>The number of authentication data entries.</para></listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>entries</emphasis></term>
+    <listitem><para>The list of authentication data entries.</para></listitem>
+  </varlistentry>
+</variablelist>
+
+<para>Each entry has associated with it a protocol name
+(for example, "ICE" for ICE connection setup authentication,
+"XSMP" for session management authentication), a network ID for the
+"accepting" client, an authentication name (for example, MIT-MAGIC-COOKIE-1),
+and authentication data.  The ICE library
+will merge these entries with previously set entries, based on the
+(protocol_name, network_id, auth_name) tuple.</para>
+
+
+
+<literallayout class="monospaced">
+typedef struct {
+       char *protocol_name;
+       char *network_id;
+       char *auth_name;
+       unsigned short auth_data_length;
+       char *auth_data;
+} IceAuthDataEntry;
+</literallayout>
+
+</appendix>
+</book>
+
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100755 (executable)
index 0000000..23ed84a
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+
+if ENABLE_DOCS
+doc_sources = ICElib.xml
+dist_doc_DATA = $(doc_sources)
+
+if HAVE_XMLTO
+doc_DATA = $(doc_sources:.xml=.html)
+
+if HAVE_FOP
+doc_DATA += $(doc_sources:.xml=.ps) $(doc_sources:.xml=.pdf)
+endif
+
+if HAVE_XMLTO_TEXT
+doc_DATA += $(doc_sources:.xml=.txt)
+endif
+
+if HAVE_STYLESHEETS
+XMLTO_FLAGS = -m $(XSL_STYLESHEET)
+
+doc_DATA += xorg.css
+xorg.css: $(STYLESHEET_SRCDIR)/xorg.css
+       $(AM_V_GEN)cp -pf $(STYLESHEET_SRCDIR)/xorg.css $@
+endif
+
+CLEANFILES = $(doc_DATA)
+
+SUFFIXES = .xml .ps .pdf .txt .html
+
+.xml.txt:
+       $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) txt $<
+
+.xml.html:
+       $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) xhtml-nochunks $<
+
+.xml.pdf:
+       $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) --with-fop pdf $<
+
+.xml.ps:
+       $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) --with-fop ps $<
+
+endif HAVE_XMLTO
+endif ENABLE_DOCS
diff --git a/ice.pc.in b/ice.pc.in
new file mode 100644 (file)
index 0000000..b96c9f8
--- /dev/null
+++ b/ice.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: ICE
+Description: X Inter Client Exchange Library
+Version: @PACKAGE_VERSION@
+Requires: xproto
+Cflags: -I${includedir}
+Libs: -L${libdir} -lICE
diff --git a/include/X11/ICE/ICE.h b/include/X11/ICE/ICE.h
new file mode 100755 (executable)
index 0000000..7560647
--- /dev/null
@@ -0,0 +1,101 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+
+******************************************************************************/
+
+#ifndef _ICE_H_
+#define _ICE_H_
+
+/*
+ * Protocol Version
+ */
+
+#define IceProtoMajor 1
+#define IceProtoMinor 0
+
+
+/*
+ * Byte Order
+ */
+
+#define IceLSBfirst            0
+#define IceMSBfirst            1
+
+
+/*
+ * ICE minor opcodes
+ */
+
+#define ICE_Error              0
+#define ICE_ByteOrder          1
+#define ICE_ConnectionSetup    2
+#define ICE_AuthRequired       3
+#define ICE_AuthReply          4
+#define ICE_AuthNextPhase      5
+#define ICE_ConnectionReply    6
+#define ICE_ProtocolSetup      7
+#define ICE_ProtocolReply      8
+#define ICE_Ping               9
+#define ICE_PingReply          10
+#define ICE_WantToClose                11
+#define ICE_NoClose            12
+
+
+/*
+ * Error severity
+ */
+
+#define IceCanContinue         0
+#define IceFatalToProtocol     1
+#define IceFatalToConnection   2
+
+
+/*
+ * ICE error classes that are common to all protocols
+ */
+
+#define IceBadMinor    0x8000
+#define IceBadState    0x8001
+#define IceBadLength   0x8002
+#define IceBadValue    0x8003
+
+
+/*
+ * ICE error classes that are specific to the ICE protocol
+ */
+
+#define IceBadMajor                    0
+#define IceNoAuth                      1
+#define IceNoVersion                   2
+#define IceSetupFailed                 3
+#define IceAuthRejected                        4
+#define IceAuthFailed                  5
+#define IceProtocolDuplicate           6
+#define IceMajorOpcodeDuplicate                7
+#define IceUnknownProtocol             8
+
+#endif /* _ICE_H_ */
diff --git a/include/X11/ICE/ICEconn.h b/include/X11/ICE/ICEconn.h
new file mode 100755 (executable)
index 0000000..f169b6c
--- /dev/null
@@ -0,0 +1,250 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifndef _ICECONN_H_
+#define _ICECONN_H_
+
+#include <X11/ICE/ICElib.h>
+
+/*
+ * Data structures for ICE connection object 
+ */
+
+typedef struct _IceSavedReplyWait {
+    IceReplyWaitInfo           *reply_wait;
+    Bool                       reply_ready;
+    struct _IceSavedReplyWait  *next;
+} _IceSavedReplyWait;
+
+typedef struct _IcePingWait {
+    IcePingReplyProc           ping_reply_proc;
+    IcePointer                 client_data;
+    struct _IcePingWait        *next;
+} _IcePingWait;
+
+typedef struct {
+    char               *vendor;
+    char               *release;
+    int                        version_count;
+    IcePoVersionRec    *version_recs;
+    int                        auth_count;
+    char               **auth_names;
+    IcePoAuthProc      *auth_procs;
+    IceIOErrorProc     io_error_proc;
+} _IcePoProtocol;
+
+typedef struct {
+    char                       *vendor;
+    char                       *release;
+    int                                version_count;
+    IcePaVersionRec            *version_recs;
+    IceProtocolSetupProc       protocol_setup_proc;
+    IceProtocolActivateProc    protocol_activate_proc;
+    int                                auth_count;
+    char                       **auth_names;
+    IcePaAuthProc              *auth_procs;
+    IceHostBasedAuthProc       host_based_auth_proc;
+    IceIOErrorProc             io_error_proc;
+} _IcePaProtocol;
+
+typedef struct {
+    char               *protocol_name;
+    _IcePoProtocol     *orig_client;
+    _IcePaProtocol     *accept_client;
+} _IceProtocol;
+
+typedef struct {
+    Bool                       in_use;
+    int                                my_opcode;
+    _IceProtocol               *protocol;
+    IcePointer                 client_data;
+    Bool                       accept_flag;
+    union {
+       IcePaProcessMsgProc     accept_client;
+       IcePoProcessMsgProc     orig_client;
+    } process_msg_proc;
+} _IceProcessMsgInfo;
+
+typedef struct {
+    int                his_version_index;
+    int                my_version_index;
+    char       *his_vendor;
+    char       *his_release;
+    char       my_auth_index;
+    IcePointer         my_auth_state;
+    Bool       must_authenticate;
+} _IceConnectToMeInfo;
+
+typedef struct {
+    int                his_opcode;
+    int                my_opcode;
+    int                his_version_index;
+    int                my_version_index;
+    char       *his_vendor;
+    char       *his_release;
+    char       my_auth_index;
+    IcePointer         my_auth_state;
+    Bool       must_authenticate;
+} _IceProtoSetupToMeInfo;
+
+typedef struct {
+    Bool       auth_active;
+    char       my_auth_index;
+    IcePointer         my_auth_state;
+} _IceConnectToYouInfo;
+
+typedef struct {
+    int                my_opcode;
+    int                my_auth_count;
+    int                *my_auth_indices;
+    Bool       auth_active;
+    char       my_auth_index;
+    IcePointer my_auth_state;
+} _IceProtoSetupToYouInfo;
+
+
+struct _IceConn {
+
+    unsigned int io_ok : 1;                 /* did an IO error occur? */
+    unsigned int swap : 1;                  /* do we need to swap on reads? */
+    unsigned int waiting_for_byteorder : 1;  /* waiting for a ByteOrder msg? */
+    unsigned int skip_want_to_close : 1;     /* avoid shutdown negotiation? */
+    unsigned int want_to_close : 1;         /* did we send a WantToClose? */
+    unsigned int free_asap : 1;                     /* free as soon as possible */
+    unsigned int unused1 : 2;               /* future use */
+    unsigned int unused2 : 8;               /* future use */
+
+    IceConnectStatus connection_status; /* pending, accepted, rejected */
+
+    unsigned char my_ice_version_index; /* which version are we using? */
+
+    struct _XtransConnInfo *trans_conn; /* transport connection object */
+    unsigned long send_sequence;       /* Sequence # of last msg sent */
+    unsigned long receive_sequence;            /* Sequence # of last msg received */
+
+    char *connection_string;           /* network connection string */
+    char *vendor;                      /* other client's vendor */
+    char *release;                     /* other client's release */
+
+    char *inbuf;                       /* Input buffer starting address */
+    char *inbufptr;                    /* Input buffer index pointer */
+    char *inbufmax;                    /* Input buffer maximum+1 address */
+
+    char *outbuf;                      /* Output buffer starting address */
+    char *outbufptr;                   /* Output buffer index pointer */
+    char *outbufmax;                   /* Output buffer maximum+1 address */
+
+    char *scratch;                     /* scratch buffer */
+    unsigned long scratch_size;                /* scratch size */
+
+    int dispatch_level;                        /* IceProcessMessages dispatch level */
+
+    IcePointer context;                        /* context associated with caller
+                                          of IceOpenConnection */
+
+    /*
+     * Before we read a message, the major opcode of the message must be
+     * mapped to our corresponding major opcode (the two clients can use
+     * different opcodes for the same protocol).  In order to save space,
+     * we keep track of the mininum and maximum major opcodes used by the
+     * other client.  To get the information on how to process this message,
+     * we do the following...
+     *
+     * processMsgInfo = iceConn->process_msg_info[
+     *     message->majorOpcode - iceConn->his_min_opcode]
+     *
+     * Note that the number of elements in the iceConn->process_msg_info
+     * array is always (iceConn->his_max_opcode - iceConn->his_min_opcode + 1).
+     * We check process_msg_info->in_use to see if the opcode is being used.
+     */
+
+    _IceProcessMsgInfo         *process_msg_info;
+    char                       his_min_opcode;   /* [1..255] */
+    char                       his_max_opcode;   /* [1..255] */
+
+
+    /*
+     * Number of times this iceConn was returned in IceOpenConnection
+     * or IceAcceptConnection.
+     */
+
+    unsigned char              open_ref_count;
+
+
+    /*
+     * Number of active protocols.
+     */
+
+    unsigned char              proto_ref_count;
+
+
+    /*
+     * If this ICE connection was created with IceAcceptConnection,
+     * the listen_obj field is set to the listen object.  Otherwise,
+     * the listen_obj field is NULL.
+     */
+
+    IceListenObj               listen_obj;
+
+
+
+
+    /*
+     * We need to keep track of all the replies we're waiting for.
+     * Check the comments in process.c for how this works.
+     */
+
+    _IceSavedReplyWait         *saved_reply_waits;
+
+
+    /*
+     * We keep track of all Pings sent from the client.  When the Ping reply
+     * arrives, we remove it from the list.
+     */
+
+    _IcePingWait               *ping_waits;
+
+
+    /*
+     * Some state for a client doing a Connection/Protocol Setup
+     */
+
+    _IceConnectToYouInfo       *connect_to_you;
+    _IceProtoSetupToYouInfo    *protosetup_to_you;
+
+
+    /*
+     * Some state for a client receiving a Connection/Protocol Setup
+     */
+
+    _IceConnectToMeInfo                *connect_to_me;
+    _IceProtoSetupToMeInfo     *protosetup_to_me;
+
+};
+
+#endif /* _ICECONN_H_ */
diff --git a/include/X11/ICE/ICElib.h b/include/X11/ICE/ICElib.h
new file mode 100755 (executable)
index 0000000..ba42119
--- /dev/null
@@ -0,0 +1,431 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifndef _ICELIB_H_
+#define _ICELIB_H_
+
+#include <X11/ICE/ICE.h>
+#include <X11/Xfuncproto.h>
+
+#define Bool int
+#define Status int
+#define True 1
+#define False 0
+
+typedef void *IcePointer;
+
+typedef enum {
+    IcePoAuthHaveReply,
+    IcePoAuthRejected,
+    IcePoAuthFailed,
+    IcePoAuthDoneCleanup
+} IcePoAuthStatus;
+
+typedef enum {
+    IcePaAuthContinue,
+    IcePaAuthAccepted,
+    IcePaAuthRejected,
+    IcePaAuthFailed
+} IcePaAuthStatus;
+
+typedef enum {
+    IceConnectPending,
+    IceConnectAccepted,
+    IceConnectRejected,
+    IceConnectIOError
+} IceConnectStatus;
+
+typedef enum {
+    IceProtocolSetupSuccess,
+    IceProtocolSetupFailure,
+    IceProtocolSetupIOError,
+    IceProtocolAlreadyActive
+} IceProtocolSetupStatus;
+
+typedef enum {
+    IceAcceptSuccess,
+    IceAcceptFailure,
+    IceAcceptBadMalloc
+} IceAcceptStatus;
+
+typedef enum {
+    IceClosedNow,
+    IceClosedASAP,
+    IceConnectionInUse,
+    IceStartedShutdownNegotiation
+} IceCloseStatus;
+
+typedef enum {
+    IceProcessMessagesSuccess,
+    IceProcessMessagesIOError,
+    IceProcessMessagesConnectionClosed
+} IceProcessMessagesStatus;
+
+typedef struct {
+    unsigned long      sequence_of_request;
+    int                        major_opcode_of_request;
+    int                        minor_opcode_of_request;
+    IcePointer         reply;
+} IceReplyWaitInfo;
+
+typedef struct _IceConn *IceConn;
+typedef struct _IceListenObj *IceListenObj;
+
+typedef void (*IceWatchProc) (
+    IceConn            /* iceConn */,
+    IcePointer         /* clientData */,
+    Bool               /* opening */,
+    IcePointer *       /* watchData */
+);
+
+typedef void (*IcePoProcessMsgProc) (
+    IceConn            /* iceConn */,
+    IcePointer         /* clientData */,
+    int                        /* opcode */,
+    unsigned long      /* length */,
+    Bool               /* swap */,
+    IceReplyWaitInfo *  /* replyWait */,
+    Bool *             /* replyReadyRet */
+);
+
+typedef void (*IcePaProcessMsgProc) (
+    IceConn            /* iceConn */,
+    IcePointer         /* clientData */,
+    int                        /* opcode */,
+    unsigned long      /* length */,
+    Bool               /* swap */
+);
+
+typedef struct {
+    int                         major_version;
+    int                         minor_version;
+    IcePoProcessMsgProc  process_msg_proc;
+} IcePoVersionRec;
+
+typedef struct {
+    int                         major_version;
+    int                         minor_version;
+    IcePaProcessMsgProc  process_msg_proc;
+} IcePaVersionRec;
+
+typedef IcePoAuthStatus (*IcePoAuthProc) (
+    IceConn            /* iceConn */,
+    IcePointer *       /* authStatePtr */,
+    Bool               /* cleanUp */,
+    Bool               /* swap */,
+    int                        /* authDataLen */,
+    IcePointer         /* authData */,
+    int *              /* replyDataLenRet */,
+    IcePointer *       /* replyDataRet */,
+    char **            /* errorStringRet */
+);
+
+typedef IcePaAuthStatus (*IcePaAuthProc) (
+    IceConn            /* iceConn */,
+    IcePointer *       /* authStatePtr */,
+    Bool               /* swap */,
+    int                        /* authDataLen */,
+    IcePointer         /* authData */,
+    int *              /* replyDataLenRet */,
+    IcePointer *       /* replyDataRet */,
+    char **            /* errorStringRet */
+);
+
+typedef Bool (*IceHostBasedAuthProc) (
+    char *             /* hostName */
+);
+
+typedef Status (*IceProtocolSetupProc) (
+    IceConn            /* iceConn */,
+    int                        /* majorVersion */,
+    int                        /* minorVersion */,
+    char *             /* vendor */,
+    char *             /* release */,
+    IcePointer *       /* clientDataRet */,
+    char **            /* failureReasonRet */
+);
+
+typedef void (*IceProtocolActivateProc) (
+    IceConn            /* iceConn */,
+    IcePointer         /* clientData */
+);
+
+typedef void (*IceIOErrorProc) (
+    IceConn            /* iceConn */
+);
+
+typedef void (*IcePingReplyProc) (
+    IceConn            /* iceConn */,
+    IcePointer         /* clientData */
+);
+
+typedef void (*IceErrorHandler) (
+    IceConn            /* iceConn */,
+    Bool               /* swap */,
+    int                        /* offendingMinorOpcode */,
+    unsigned long      /* offendingSequence */,
+    int                /* errorClass */,
+    int                        /* severity */,
+    IcePointer         /* values */
+);
+
+typedef void (*IceIOErrorHandler) (
+    IceConn            /* iceConn */
+);
+
+
+/*
+ * Function prototypes
+ */
+
+_XFUNCPROTOBEGIN
+
+extern int IceRegisterForProtocolSetup (
+    char *                     /* protocolName */,
+    char *                     /* vendor */,
+    char *                     /* release */,
+    int                                /* versionCount */,
+    IcePoVersionRec *          /* versionRecs */,
+    int                                /* authCount */,
+    const char **              /* authNames */,
+    IcePoAuthProc *            /* authProcs */,
+    IceIOErrorProc             /* IOErrorProc */
+);
+
+extern int IceRegisterForProtocolReply (
+    char *                     /* protocolName */,
+    char *                     /* vendor */,
+    char *                     /* release */,
+    int                                /* versionCount */,
+    IcePaVersionRec *          /* versionRecs */,
+    int                                /* authCount */,
+    const char **              /* authNames */,
+    IcePaAuthProc *            /* authProcs */,
+    IceHostBasedAuthProc       /* hostBasedAuthProc */,
+    IceProtocolSetupProc       /* protocolSetupProc */,
+    IceProtocolActivateProc    /* protocolActivateProc */,
+    IceIOErrorProc             /* IOErrorProc */
+);
+
+extern IceConn IceOpenConnection (
+    char *             /* networkIdsList */,
+    IcePointer         /* context */,
+    Bool               /* mustAuthenticate */,
+    int                        /* majorOpcodeCheck */,
+    int                        /* errorLength */,
+    char *             /* errorStringRet */
+);
+
+extern IcePointer IceGetConnectionContext (
+    IceConn            /* iceConn */
+);
+
+extern Status IceListenForConnections (
+    int *              /* countRet */,
+    IceListenObj **    /* listenObjsRet */,
+    int                        /* errorLength */,
+    char *             /* errorStringRet */
+);
+
+extern Status IceListenForWellKnownConnections (
+    char *             /* port */,
+    int *              /* countRet */,
+    IceListenObj **    /* listenObjsRet */,
+    int                        /* errorLength */,
+    char *             /* errorStringRet */
+);
+
+extern int IceGetListenConnectionNumber (
+    IceListenObj       /* listenObj */
+);
+
+extern char *IceGetListenConnectionString (
+    IceListenObj       /* listenObj */
+);
+
+extern char *IceComposeNetworkIdList (
+    int                        /* count */,
+    IceListenObj *     /* listenObjs */
+);
+
+extern void IceFreeListenObjs (
+    int                        /* count */,
+    IceListenObj *     /* listenObjs */
+);
+
+extern void IceSetHostBasedAuthProc (
+    IceListenObj               /* listenObj */,
+    IceHostBasedAuthProc       /* hostBasedAuthProc */
+);
+
+extern IceConn IceAcceptConnection (
+    IceListenObj       /* listenObj */,
+    IceAcceptStatus *  /* statusRet */
+);
+
+extern void IceSetShutdownNegotiation (
+    IceConn            /* iceConn */,
+    Bool               /* negotiate */
+);
+
+extern Bool IceCheckShutdownNegotiation (
+    IceConn            /* iceConn */
+);
+
+extern IceCloseStatus IceCloseConnection (
+    IceConn            /* iceConn */
+);
+
+extern Status IceAddConnectionWatch (
+    IceWatchProc               /* watchProc */,
+    IcePointer                 /* clientData */
+);
+
+extern void IceRemoveConnectionWatch (
+    IceWatchProc               /* watchProc */,
+    IcePointer                 /* clientData */
+);
+
+extern IceProtocolSetupStatus IceProtocolSetup (
+    IceConn            /* iceConn */,
+    int                /* myOpcode */,
+    IcePointer         /* clientData */,
+    Bool               /* mustAuthenticate */,
+    int        *               /* majorVersionRet */,
+    int        *               /* minorVersionRet */,
+    char **            /* vendorRet */,
+    char **            /* releaseRet */,
+    int                        /* errorLength */,
+    char *             /* errorStringRet */
+);
+
+extern Status IceProtocolShutdown (
+    IceConn            /* iceConn */,
+    int                        /* majorOpcode */
+);
+
+extern IceProcessMessagesStatus IceProcessMessages (
+    IceConn            /* iceConn */,
+    IceReplyWaitInfo * /* replyWait */,
+    Bool *             /* replyReadyRet */
+);
+
+extern Status IcePing (
+   IceConn             /* iceConn */,
+   IcePingReplyProc    /* pingReplyProc */,
+   IcePointer          /* clientData */
+);
+
+extern char *IceAllocScratch (
+   IceConn             /* iceConn */,
+   unsigned long       /* size */
+);
+
+extern int IceFlush (
+   IceConn             /* iceConn */
+);
+
+extern int IceGetOutBufSize (
+   IceConn             /* iceConn */
+);
+
+extern int IceGetInBufSize (
+   IceConn             /* iceConn */
+);
+
+extern IceConnectStatus IceConnectionStatus (
+    IceConn            /* iceConn */
+);
+
+extern char *IceVendor (
+    IceConn            /* iceConn */
+);
+
+extern char *IceRelease (
+    IceConn            /* iceConn */
+);
+
+extern int IceProtocolVersion (
+    IceConn            /* iceConn */
+);
+
+extern int IceProtocolRevision (
+    IceConn            /* iceConn */
+);
+
+extern int IceConnectionNumber (
+    IceConn            /* iceConn */
+);
+
+extern char *IceConnectionString (
+    IceConn            /* iceConn */
+);
+
+extern unsigned long IceLastSentSequenceNumber (
+    IceConn            /* iceConn */
+);
+
+extern unsigned long IceLastReceivedSequenceNumber (
+    IceConn            /* iceConn */
+);
+
+extern Bool IceSwapping (
+    IceConn            /* iceConn */
+);
+
+extern IceErrorHandler IceSetErrorHandler (
+    IceErrorHandler    /* handler */
+);
+
+extern IceIOErrorHandler IceSetIOErrorHandler (
+    IceIOErrorHandler  /* handler */
+);
+
+extern char *IceGetPeerName (
+    IceConn            /* iceConn */
+);
+
+/*
+ * Multithread Routines
+ */
+
+extern Status IceInitThreads (
+    void
+);
+
+extern void IceAppLockConn (
+    IceConn            /* iceConn */
+);
+
+extern void IceAppUnlockConn (
+    IceConn            /* iceConn */
+);
+
+_XFUNCPROTOEND
+
+#endif /* _ICELIB_H_ */
diff --git a/include/X11/ICE/ICEmsg.h b/include/X11/ICE/ICEmsg.h
new file mode 100755 (executable)
index 0000000..6a60f1c
--- /dev/null
@@ -0,0 +1,316 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifndef _ICEMSG_H_
+#define _ICEMSG_H_
+
+#include <X11/Xfuncproto.h>
+
+#include <X11/ICE/ICEconn.h>
+
+_XFUNCPROTOBEGIN
+
+/*
+ * Function prototypes for internal ICElib functions
+ */
+
+extern Status _IceRead (
+    IceConn            /* iceConn */,
+    unsigned long      /* nbytes */,
+    char *             /* ptr */
+);
+
+extern void _IceReadSkip (
+    IceConn            /* iceConn */,
+    unsigned long      /* nbytes */
+);
+
+extern void _IceWrite (
+    IceConn            /* iceConn */,
+    unsigned long      /* nbytes */,
+    char *             /* ptr */
+);
+
+
+extern void _IceErrorBadMinor (
+    IceConn            /* iceConn */,
+    int                        /* majorOpcode */,
+    int                        /* offendingMinor */,
+    int                        /* severity */
+);
+
+extern void _IceErrorBadState (
+    IceConn            /* iceConn */,
+    int                        /* majorOpcode */,
+    int                        /* offendingMinor */,
+    int                        /* severity */
+);
+
+extern void _IceErrorBadLength (
+    IceConn            /* iceConn */,
+    int                        /* majorOpcode */,
+    int                        /* offendingMinor */,
+    int                        /* severity */
+);
+
+extern void _IceErrorBadValue (
+    IceConn            /* iceConn */,
+    int                        /* majorOpcode */,
+    int                        /* offendingMinor */,
+    int                        /* offset */,
+    int                        /* length */,
+    IcePointer         /* value */
+);
+
+extern IcePoAuthStatus _IcePoMagicCookie1Proc (
+    IceConn            /* iceConn */,
+    IcePointer *       /* authStatePtr */,
+    Bool               /* cleanUp */,
+    Bool               /* swap */,
+    int                /* authDataLen */,
+    IcePointer         /* authData */,
+    int *              /* replyDataLenRet */,
+    IcePointer *       /* replyDataRet */,
+    char **            /* errorStringRet */
+);
+
+extern IcePaAuthStatus _IcePaMagicCookie1Proc (
+    IceConn            /* iceConn */,
+    IcePointer *       /* authStatePtr */,
+    Bool               /* swap */,
+    int                /* authDataLen */,
+    IcePointer         /* authData */,
+    int *              /* replyDataLenRet */,
+    IcePointer *       /* replyDataRet */,
+    char **            /* errorStringRet */
+);
+
+
+/*
+ * Macro to check if IO operations are valid on an ICE connection.
+ */
+
+#define IceValidIO(_iceConn) _iceConn->io_ok
+
+
+/*
+ * Macros for writing messages.
+ */
+
+#define IceGetHeader(_iceConn, _major, _minor, _headerSize, _msgType, _pMsg) \
+    if ((_iceConn->outbufptr + _headerSize) > _iceConn->outbufmax) \
+        IceFlush (_iceConn); \
+    _pMsg = (_msgType *) _iceConn->outbufptr; \
+    _pMsg->majorOpcode = _major; \
+    _pMsg->minorOpcode = _minor; \
+    _pMsg->length = (_headerSize - SIZEOF (iceMsg)) >> 3; \
+    _iceConn->outbufptr += _headerSize; \
+    _iceConn->send_sequence++
+
+#define IceGetHeaderExtra(_iceConn, _major, _minor, _headerSize, _extra, _msgType, _pMsg, _pData) \
+    if ((_iceConn->outbufptr + \
+       _headerSize + ((_extra) << 3)) > _iceConn->outbufmax) \
+        IceFlush (_iceConn); \
+    _pMsg = (_msgType *) _iceConn->outbufptr; \
+    if ((_iceConn->outbufptr + \
+       _headerSize + ((_extra) << 3)) <= _iceConn->outbufmax) \
+        _pData = (char *) _pMsg + _headerSize; \
+    else \
+        _pData = NULL; \
+    _pMsg->majorOpcode = _major; \
+    _pMsg->minorOpcode = _minor; \
+    _pMsg->length = ((_headerSize - SIZEOF (iceMsg)) >> 3) + (_extra); \
+    _iceConn->outbufptr += (_headerSize + ((_extra) << 3)); \
+    _iceConn->send_sequence++
+
+#define IceSimpleMessage(_iceConn, _major, _minor) \
+{ \
+    iceMsg *_pMsg; \
+    IceGetHeader (_iceConn, _major, _minor, SIZEOF (iceMsg), iceMsg, _pMsg); \
+}
+
+#define IceErrorHeader(_iceConn, _offendingMajorOpcode, _offendingMinorOpcode, _offendingSequenceNum, _severity, _errorClass, _dataLength) \
+{ \
+    iceErrorMsg        *_pMsg; \
+\
+    IceGetHeader (_iceConn, _offendingMajorOpcode, ICE_Error, \
+       SIZEOF (iceErrorMsg), iceErrorMsg, _pMsg); \
+    _pMsg->length += (_dataLength); \
+    _pMsg->offendingMinorOpcode = _offendingMinorOpcode; \
+    _pMsg->severity = _severity; \
+    _pMsg->offendingSequenceNum = _offendingSequenceNum; \
+    _pMsg->errorClass = _errorClass; \
+}
+
+
+/*
+ * Write data into the ICE output buffer.
+ */
+
+#define IceWriteData(_iceConn, _bytes, _data) \
+{ \
+    if ((_iceConn->outbufptr + (_bytes)) > _iceConn->outbufmax) \
+    { \
+       IceFlush (_iceConn); \
+        _IceWrite (_iceConn, (unsigned long) (_bytes), _data); \
+    } \
+    else \
+    { \
+        memcpy (_iceConn->outbufptr, _data, _bytes); \
+        _iceConn->outbufptr += (_bytes); \
+    } \
+}
+
+#ifndef WORD64
+
+#define IceWriteData16(_iceConn, _bytes, _data) \
+    IceWriteData (_iceConn, _bytes, (char *) _data)
+
+#define IceWriteData32(_iceConn, _bytes, _data) \
+    IceWriteData (_iceConn, _bytes, (char *) _data)
+
+#else /* WORD64 */
+
+/* IceWriteData16 and IceWriteData32 defined in misc.c for WORD64 */
+
+#endif /* WORD64 */
+
+
+/*
+ * The IceSendData macro bypasses copying the data to the
+ * ICE connection buffer and sends the data directly.  If necessary,
+ * the ICE connection buffer is first flushed.
+ */
+
+#define IceSendData(_iceConn, _bytes, _data) \
+{ \
+    if (_iceConn->outbufptr > _iceConn->outbuf) \
+       IceFlush (_iceConn); \
+    _IceWrite (_iceConn, (unsigned long) (_bytes), _data); \
+}
+
+
+/*
+ * Write pad bytes.  Used to force 32 or 64 bit alignment.
+ * A maxium of 7 pad bytes can be specified.
+ */
+
+#define IceWritePad(_iceConn, _bytes) \
+{ \
+    if ((_iceConn->outbufptr + (_bytes)) > _iceConn->outbufmax) \
+    { \
+        char _dummy[7]; \
+       IceFlush (_iceConn); \
+        _IceWrite (_iceConn, (unsigned long) (_bytes), _dummy); \
+    } \
+    else \
+    { \
+        _iceConn->outbufptr += (_bytes); \
+    } \
+}
+
+
+/*
+ * Macros for reading messages.
+ */
+
+#define IceReadCompleteMessage(_iceConn, _headerSize, _msgType, _pMsg, _pData)\
+{ \
+    unsigned long _bytes; \
+    IceReadMessageHeader (_iceConn, _headerSize, _msgType, _pMsg); \
+    _bytes = (_pMsg->length << 3) - (_headerSize - SIZEOF (iceMsg)); \
+    if ((_iceConn->inbufmax - _iceConn->inbufptr) >= _bytes) \
+    { \
+       _IceRead (_iceConn, _bytes, _iceConn->inbufptr); \
+       _pData = _iceConn->inbufptr; \
+       _iceConn->inbufptr += _bytes; \
+    } \
+    else \
+    { \
+       _pData = (char *) malloc ((unsigned) _bytes); \
+        if (_pData) \
+           _IceRead (_iceConn, _bytes, _pData); \
+        else \
+           _IceReadSkip (_iceConn, _bytes); \
+    } \
+}
+
+#define IceDisposeCompleteMessage(_iceConn, _pData) \
+    if ((char *) _pData < _iceConn->inbuf || \
+       (char *) _pData >= _iceConn->inbufmax) \
+        free ((char *) _pData);
+
+
+#define IceReadSimpleMessage(_iceConn, _msgType, _pMsg) \
+    _pMsg = (_msgType *) (_iceConn->inbuf);
+
+#define IceReadMessageHeader(_iceConn, _headerSize, _msgType, _pMsg) \
+{ \
+    _IceRead (_iceConn, \
+       (unsigned long) (_headerSize - SIZEOF (iceMsg)), \
+       _iceConn->inbufptr); \
+    _pMsg = (_msgType *) (_iceConn->inbuf); \
+    _iceConn->inbufptr += (_headerSize - SIZEOF (iceMsg)); \
+}
+
+#define IceReadData(_iceConn, _bytes, _pData) \
+    _IceRead (_iceConn, (unsigned long) (_bytes), (char *) _pData); \
+
+#ifndef WORD64
+
+#define IceReadData16(_iceConn, _swap, _bytes, _pData) \
+{ \
+    _IceRead (_iceConn, (unsigned long) (_bytes), (char *) _pData); \
+}
+
+#define IceReadData32(_iceConn, _swap, _bytes, _pData) \
+{ \
+    _IceRead (_iceConn, (unsigned long) (_bytes), (char *) _pData); \
+}
+
+#else /* WORD64 */
+
+/* IceReadData16 and IceReadData32 defined in misc.c for WORD64 */
+
+#endif /* WORD64 */
+
+
+/*
+ * Read pad bytes (for 32 or 64 bit alignment).
+ * A maxium of 7 pad bytes can be specified.
+ */
+
+#define IceReadPad(_iceConn, _bytes) \
+{ \
+    char _dummy[7]; \
+    _IceRead (_iceConn, (unsigned long) (_bytes), _dummy); \
+}
+
+_XFUNCPROTOEND
+
+#endif /* _ICEMSG_H_ */
diff --git a/include/X11/ICE/ICEproto.h b/include/X11/ICE/ICEproto.h
new file mode 100755 (executable)
index 0000000..1fcbe6b
--- /dev/null
@@ -0,0 +1,175 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifndef _ICEPROTO_H_
+#define _ICEPROTO_H_
+
+#include <X11/Xmd.h>
+
+typedef struct {
+    CARD8      majorOpcode;
+    CARD8      minorOpcode;
+    CARD8      data[2];
+    CARD32     length B32;
+} iceMsg;
+
+typedef struct {
+    CARD8      majorOpcode;
+    CARD8      minorOpcode;
+    CARD16     errorClass B16;
+    CARD32     length B32;
+    CARD8      offendingMinorOpcode;
+    CARD8      severity;
+    CARD16     unused B16;
+    CARD32     offendingSequenceNum B32;
+    /* n       varying values */
+    /* p       p = pad (n, 8) */
+} iceErrorMsg;
+
+typedef struct {
+    CARD8      majorOpcode;
+    CARD8      minorOpcode;
+    CARD8      byteOrder;
+    CARD8      unused;
+    CARD32     length B32;
+} iceByteOrderMsg;
+
+typedef struct {
+    CARD8      majorOpcode;
+    CARD8      minorOpcode;
+    CARD8      versionCount;
+    CARD8      authCount;
+    CARD32     length B32;
+    CARD8      mustAuthenticate;
+    CARD8      unused[7];
+    /* i       STRING          vendor */
+    /* j       STRING          release */
+    /* k       LIST of STRING  authentication-protocol-names */
+    /* m       LIST of VERSION version-list */
+    /* p       p = pad (i+j+k+m, 8) */
+} iceConnectionSetupMsg;
+
+typedef struct {
+    CARD8      majorOpcode;
+    CARD8      minorOpcode;
+    CARD8      authIndex;
+    CARD8      unused1;
+    CARD32     length B32;
+    CARD16     authDataLength B16;
+    CARD8      unused2[6];
+    /* n       varying data */
+    /* p       p = pad (n, 8) */
+} iceAuthRequiredMsg;
+
+typedef struct {
+    CARD8      majorOpcode;
+    CARD8      minorOpcode;
+    CARD8      unused1[2];
+    CARD32     length B32;
+    CARD16     authDataLength B16;
+    CARD8      unused2[6];
+    /* n       varying data */
+    /* p       p = pad (n, 8) */
+} iceAuthReplyMsg;
+
+typedef struct {
+    CARD8      majorOpcode;
+    CARD8      minorOpcode;
+    CARD8      unused1[2];
+    CARD32     length B32;
+    CARD16     authDataLength B16;
+    CARD8      unused2[6];
+    /* n       varying data */
+    /* p       p = pad (n, 8) */
+} iceAuthNextPhaseMsg;
+
+typedef struct {
+    CARD8      majorOpcode;
+    CARD8      minorOpcode;
+    CARD8      versionIndex;
+    CARD8      unused;
+    CARD32     length B32;
+    /* i       STRING          vendor */
+    /* j       STRING          release */
+    /* p       p = pad (i+j, 8) */
+} iceConnectionReplyMsg;
+
+typedef struct {
+    CARD8      majorOpcode;
+    CARD8      minorOpcode;
+    CARD8      protocolOpcode;
+    CARD8      mustAuthenticate;
+    CARD32     length B32;
+    CARD8      versionCount;
+    CARD8      authCount;
+    CARD8      unused[6];
+    /* i       STRING          protocol-name */
+    /* j       STRING          vendor */
+    /* k       STRING          release */
+    /* m       LIST of STRING  authentication-protocol-names */
+    /* n       LIST of VERSION version-list */
+    /* p        p = pad (i+j+k+m+n, 8) */
+} iceProtocolSetupMsg;
+
+typedef struct {
+    CARD8      majorOpcode;
+    CARD8      minorOpcode;
+    CARD8      versionIndex;
+    CARD8      protocolOpcode;
+    CARD32     length B32;
+    /* i       STRING          vendor */
+    /* j       STRING          release */
+    /* p       p = pad (i+j, 8) */
+} iceProtocolReplyMsg;
+
+typedef iceMsg  icePingMsg;
+typedef iceMsg  icePingReplyMsg;
+typedef iceMsg  iceWantToCloseMsg;
+typedef iceMsg  iceNoCloseMsg;
+
+
+/*
+ * SIZEOF values.  These better be multiples of 8.
+ */
+
+#define sz_iceMsg                      8
+#define sz_iceErrorMsg                 16
+#define sz_iceByteOrderMsg             8
+#define sz_iceConnectionSetupMsg        16
+#define sz_iceAuthRequiredMsg          16
+#define sz_iceAuthReplyMsg             16
+#define sz_iceAuthNextPhaseMsg         16
+#define sz_iceConnectionReplyMsg       8
+#define sz_iceProtocolSetupMsg         16
+#define sz_iceProtocolReplyMsg         8
+#define sz_icePingMsg                  8
+#define sz_icePingReplyMsg             8
+#define sz_iceWantToCloseMsg           8
+#define sz_iceNoCloseMsg               8
+
+#endif /* _ICEPROTO_H_ */
diff --git a/include/X11/ICE/ICEutil.h b/include/X11/ICE/ICEutil.h
new file mode 100755 (executable)
index 0000000..2852931
--- /dev/null
@@ -0,0 +1,124 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifndef _ICEUTIL_H_
+#define _ICEUTIL_H_
+
+#include <X11/Xfuncproto.h>
+
+#include <stdio.h>
+
+_XFUNCPROTOBEGIN
+
+/*
+ * Data structure for entry in ICE authority file
+ */
+
+typedef struct {
+    char           *protocol_name;
+    unsigned short  protocol_data_length;
+    char           *protocol_data;
+    char           *network_id;
+    char           *auth_name;
+    unsigned short  auth_data_length;
+    char           *auth_data;
+} IceAuthFileEntry;
+
+
+/*
+ * Authentication data maintained in memory.
+ */
+
+typedef struct {
+    char           *protocol_name;
+    char           *network_id;
+    char           *auth_name;
+    unsigned short  auth_data_length;
+    char           *auth_data;
+} IceAuthDataEntry;
+
+
+/*
+ * Return values from IceLockAuthFile
+ */
+
+#define IceAuthLockSuccess     0   /* lock succeeded */
+#define IceAuthLockError       1   /* lock unexpectely failed, check errno */
+#define IceAuthLockTimeout     2   /* lock failed, timeouts expired */
+
+
+/*
+ * Function Prototypes
+ */
+
+extern char *IceAuthFileName (
+    void
+);
+
+extern int IceLockAuthFile (
+    char *             /* file_name */,
+    int                        /* retries */,
+    int                        /* timeout */,
+    long               /* dead */
+);
+
+extern void IceUnlockAuthFile (
+    char *             /* file_name */
+);
+
+extern IceAuthFileEntry *IceReadAuthFileEntry (
+    FILE *             /* auth_file */
+);
+
+extern void IceFreeAuthFileEntry (
+    IceAuthFileEntry * /* auth */
+);
+
+extern Status IceWriteAuthFileEntry (
+    FILE *             /* auth_file */,
+    IceAuthFileEntry * /* auth */
+);
+
+extern IceAuthFileEntry *IceGetAuthFileEntry (
+    char *             /* protocol_name */,
+    char *             /* network_id */,
+    char *             /* auth_name */
+);
+
+extern char *IceGenerateMagicCookie (
+    int                        /* len */
+);
+
+extern void IceSetPaAuthData (
+    int                        /* numEntries */,
+    IceAuthDataEntry * /* entries */
+);
+
+_XFUNCPROTOEND
+
+#endif /* _ICEUTIL_H_ */
diff --git a/packaging/libICE.spec b/packaging/libICE.spec
new file mode 100644 (file)
index 0000000..0ba3f86
--- /dev/null
@@ -0,0 +1,73 @@
+
+Name:       libICE
+Summary:    X.Org X11 libICE runtime library
+Version:    1.0.7
+Release:    0
+Group:      System/Libraries
+License:    MIT/X11
+URL:        http://www.x.org
+Source0:    http://xorg.freedesktop.org/releases/individual/lib/%{name}-%{version}.tar.gz
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+BuildRequires:  pkgconfig(xproto)
+BuildRequires:  pkgconfig(xtrans)
+BuildRequires:  pkgconfig(xorg-macros)
+
+
+%description
+The X.Org X11 ICE (Inter-Client Exchange) runtime library.
+
+
+%package devel
+Summary:    X.Org X11 libICE development package
+Group:      System/Libraries
+Requires:   %{name} = %{version}-%{release}
+Requires:   xorg-x11-filesystem
+
+%description devel
+The X.Org X11 ICE (Inter-Client Exchange) development package.
+
+
+%prep
+%setup -q -n %{name}-%{version}
+
+
+%build
+
+%reconfigure --disable-static
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+
+
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+
+
+
+
+
+
+%files
+%defattr(-,root,root,-)
+%doc AUTHORS COPYING README ChangeLog
+%{_libdir}/libICE.so.6
+%{_libdir}/libICE.so.6.3.0
+%exclude /usr/share/doc/libICE/ICElib.xml
+%exclude /usr/share/doc/libICE/ice.xml
+
+
+%files devel
+%defattr(-,root,root,-)
+%dir %{_includedir}/X11
+%dir %{_includedir}/X11/ICE
+%{_includedir}/X11/ICE/*.h
+%{_libdir}/libICE.so
+%{_libdir}/pkgconfig/ice.pc
+
diff --git a/specs/Makefile.am b/specs/Makefile.am
new file mode 100755 (executable)
index 0000000..4b7bef5
--- /dev/null
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+# DEALINGS IN THE SOFTWARE.
+#
+
+if ENABLE_SPECS
+doc_sources = ice.xml
+dist_doc_DATA = $(doc_sources)
+
+if HAVE_XMLTO
+doc_DATA = $(doc_sources:.xml=.html)
+
+if HAVE_FOP
+doc_DATA += $(doc_sources:.xml=.ps) $(doc_sources:.xml=.pdf)
+endif
+
+if HAVE_XMLTO_TEXT
+doc_DATA += $(doc_sources:.xml=.txt)
+endif
+
+if HAVE_STYLESHEETS
+XMLTO_FLAGS = -m $(XSL_STYLESHEET)
+
+doc_DATA += xorg.css
+xorg.css: $(STYLESHEET_SRCDIR)/xorg.css
+       $(AM_V_GEN)cp -pf $(STYLESHEET_SRCDIR)/xorg.css $@
+endif
+
+CLEANFILES = $(doc_DATA)
+
+SUFFIXES = .xml .ps .pdf .txt .html
+
+.xml.txt:
+       $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) txt $<
+
+.xml.html:
+       $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) xhtml-nochunks $<
+
+.xml.pdf:
+       $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) --with-fop pdf $<
+
+.xml.ps:
+       $(AM_V_GEN)$(XMLTO) $(XMLTO_FLAGS) --with-fop ps $<
+
+endif HAVE_XMLTO
+endif ENABLE_SPECS
diff --git a/specs/ice.xml b/specs/ice.xml
new file mode 100755 (executable)
index 0000000..64e24ca
--- /dev/null
@@ -0,0 +1,2593 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+                   "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+
+<!-- lifted from troff+ms+XMan by doclifter -->
+<book id="ice">
+
+<bookinfo>
+   <title>Inter-Client Exchange (ICE) Protocol</title>
+   <subtitle>X Consortium Standard</subtitle>
+   <releaseinfo>X Version 11, Release 6.4</releaseinfo>
+   <authorgroup>
+      <author>
+         <firstname>Robert</firstname><surname>Scheifler</surname>
+      </author>
+      <othercredit>
+         <firstname>Jordan</firstname><surname>Brown</surname>
+         <affiliation><orgname>Quarterdeck Office Systems</orgname></affiliation>
+      </othercredit>
+   </authorgroup>
+   <corpname>X Consortium Standard</corpname>
+   <copyright><year>1993</year><holder>X Consortium</holder></copyright>
+   <copyright><year>1994</year><holder>X Consortium</holder></copyright>
+   <releaseinfo>Version 1.0</releaseinfo>
+   <affiliation><orgname>X Consortium</orgname></affiliation>
+   <productnumber>X Version 11, Release 7</productnumber>
+
+<legalnotice>
+<para>Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the &ldquo;Software&rdquo;), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</para>
+
+<para>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</para>
+
+<para>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</para>
+
+<para>Except as contained in this notice, the name of the X Consortium shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the X Consortium.</para>
+
+<para>X Window System is a trademark of X Consortium, Inc.</para>
+</legalnotice>
+
+<abstract>
+<para>
+There are numerous possible protocols that can be used for communication
+among clients.  They have many similarities and common needs, including
+authentication, version negotiation, data typing, and connection management.  The <emphasis remap='I'> Inter-Client Exchange</emphasis> (ICE) protocol
+is intended to provide a framework for building such protocols.  Using
+ICE reduces the complexity of designing new protocols and
+allows the sharing of many aspects of the implementation.
+</para>
+</abstract>
+</bookinfo>
+
+<chapter id="purpose_and_goals">
+<title>Purpose and Goals</title>
+
+<para>
+In discussing a variety of protocols -- existing, under development, and
+hypothetical -- it was noted that they have many elements in common.  Most
+protocols need mechanisms for authentication, for
+version negotiation,
+and for setting up and taking down connections.  There are also
+cases where the same two parties need to talk to each other using multiple
+protocols.  For example, an embedding relationship between two parties is
+likely to require the simultaneous use of session management, data transfer,
+focus negotiation, and command notification protocols.  While these are
+logically separate protocols, it is desirable for them to share as many
+pieces of implementation as possible.</para>
+
+<para>The
+<emphasis remap='I'>
+Inter-Client Exchange
+</emphasis>
+(ICE) protocol provides a generic framework for building protocols on top of
+reliable, byte-stream transport connections.  It provides basic mechanisms
+for setting up and shutting down connections, for performing authentication,
+for negotiating
+versions,
+and for reporting errors.  The
+protocols running within an ICE connection are referred to here as
+<emphasis remap='I'>subprotocols.</emphasis>
+ICE provides facilities for each subprotocol to do its own version
+negotiation, authentication, and error reporting.  In addition, if two
+parties are communicating using several different subprotocols, ICE will
+allow them to share the same transport layer connection.</para>
+
+</chapter>
+
+<chapter id="overview_of_the_protocol">
+<title>Overview of the Protocol</title>
+
+
+<para>Through some mechanism outside ICE, two parties make themselves known to
+each other and agree that they would like to communicate using an ICE
+subprotocol.  ICE assumes that this negotation includes some notion by which
+the parties will decide which is the \*Qoriginating\*U party and which is
+the \*Qanswering\*U party.  The negotiation will also need to provide the
+originating party with a name or address of the answering party.  Examples
+of mechanisms by which parties can make themselves known to each other are
+the X selection mechanism, environment
+variables, and shared files.</para>
+
+<para>The originating party first determines whether there is an existing ICE
+connection between the two parties.  If there is, it can re-use the existing
+connection and move directly to the setup of the subprotocol.  If no ICE
+connection exists, the originating party will open a transport connection to
+the answering party and will start ICE connection setup.</para>
+
+<para>The ICE connection setup dialog consists of three major parts: byte order
+exchange, authentication, and connection information exchange.  The first
+message in each direction is a
+<function>ByteOrder</function>
+message telling which byte order will be used by the sending party in
+messages that it sends.  After that, the originating party sends a
+<function>ConnectionSetup</function>
+message giving information about itself (vendor name and release number) and
+giving a list of ICE version numbers it is capable of supporting and a list
+of authentication schemes it is willing to accept.  Authentication is
+optional.  If no authentication is required, the answering party responds
+with a
+<function>ConnectionReply</function>
+message giving information about itself, and the connection setup is complete.</para>
+
+<para>If the connection setup is to be authenticated, the answering party will
+respond with an
+<function>AuthenticationRequired</function>
+message instead of a
+<function>ConnectionReply</function>
+message.  The parties then exchange
+<function>AuthenticationReply</function>
+and
+<function>AuthenticationNextPhase</function>
+messages until authentication is complete, at which time the answering party
+finally sends its
+<function>ConnectionReply</function>
+message.</para>
+
+<para>Once an ICE connection is established (or an existing connection reused),
+the originating party starts subprotocol negotiation by sending a
+<function>ProtocolSetup</function>
+message.  This message gives the name of the subprotocol that the parties
+have agreed to use, along with the ICE major opcode that the originating
+party has assigned to that subprotocol.  Authentication can also occur for
+the subprotocol, independently of authentication for the connection.
+Subprotocol authentication is optional.  If there is no subprotocol
+authentication, the answering party responds with a
+<function>ProtocolReply</function>
+message, giving the ICE major opcode that it has assigned
+for the subprotocol.</para>
+
+<para>Subprotocols are authenticated independently of each other, because they may
+have differing security requirements.  If there is authentication for this
+particular subprotocol, it takes place before the answering party emits the
+<function>ProtocolReply</function>
+message, and it uses the
+<function>AuthenticationRequired</function>
+<function>AuthenticationReply</function>
+and
+<function>AuthenticationNextPhase</function>
+messages, just as for the connection authentication.  Only when subprotocol
+authentication is complete does the answering party send its
+<function>ProtocolReply</function>
+message.</para>
+
+<para>When a subprotocol has been set up and authenticated, the two parties can
+communicate using messages defined by the subprotocol.  Each message has two
+opcodes: a major opcode and a minor opcode.  Each party will send messages
+using the major opcode it has assigned in its
+<function>ProtocolSetup</function>
+or
+<function>ProtocolReply</function>
+message.  These opcodes will, in general, not be the same.  For a particular
+subprotocol, each party will need to keep track of two major opcodes: the
+major opcode it uses when it sends messages, and the major opcode it expects
+to see in messages it receives.  The minor opcode values and semantics are
+defined by each individual subprotocol.</para>
+
+<para>Each subprotocol will have one or more messages whose semantics are that the
+subprotocol is to be shut down.  Whether this is done unilaterally or is
+performed through negotiation is defined by each subprotocol.  Once a
+subprotocol is shut down, its major opcodes are removed from
+use; no further messages on this subprotocol should be sent until the
+opcode is reestablished with
+<function>ProtocolSetup</function>
+</para>
+
+<para>ICE has a facility to negotiate the closing of the connection when there are
+no longer any active subprotocols.  When either party decides that no
+subprotocols are active, it can send a
+<function>WantToClose</function>
+message.  If the other party agrees to close the connection, it can simply
+do so.  If the other party wants to keep the connection open, it can
+indicate its desire by replying with a
+<function>NoClose</function>
+message.</para>
+<!--  XXX \- Note that it's likely that both parties will WantToClose at once. -->
+
+<para>It should be noted that the party that initiates the connection isn't
+necessarily the same as the one that initiates setting up a subprotocol.
+For example, suppose party A connects to party B.  Party A will issue the
+<function>ConnectionSetup</function>
+message and party B will respond with a
+<function>ConnectionReply</function>
+message.  (The authentication steps are omitted here for brevity.)
+Typically, party A will also issue the
+<function>ProtocolSetup</function>
+message and expect a
+<function>ProtocolReply</function>
+from party B.  Once the connection is established, however, either party may
+initiate the negotiation of a subprotocol.  Continuing this example, party B
+may decide that it needs to set up a subprotocol for communication with
+party A.  Party B would issue the
+<function>ProtocolSetup</function>
+message and expect a
+<function>ProtocolReply</function>
+from party A.</para>
+<!--  .nH 1 "Data Types" -->
+</chapter>
+
+<chapter id="data_types">
+<title>Data Types</title>
+
+<para>ICE messages contain several types of data.  Byte order is negotiated in
+the initial connection messages; in general data is sent in the sender's
+byte order and the receiver is required to swap it appropriately.
+In order to support 64-bit machines, ICE messages
+are padded to multiples of 8 bytes.  All messages are designed so that
+fields are \*Qnaturally\*U aligned on 16-, 32-, and 64-bit boundaries.
+The following formula gives the number of bytes necessary
+to pad <emphasis remap='I'>E</emphasis> bytes to the next multiple of
+<emphasis remap='I'>b</emphasis>:</para>
+<literallayout remap='DS'>
+
+pad(<emphasis remap='I'>E</emphasis>, <emphasis remap='I'>b</emphasis>) = (<emphasis remap='I'>b</emphasis> - (<emphasis remap='I'>E</emphasis> mod <emphasis remap='I'>b</emphasis>)) mod <emphasis remap='I'>b</emphasis>
+</literallayout>
+
+<sect1 id="primitive_types">
+<title>Primitive Types</title>
+
+<informaltable pgwide='1' frame='none'>
+  <tgroup cols='2' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <thead>
+      <row>
+        <entry align='left'>Type Name</entry>
+        <entry align='left'>Description</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>CARD8</entry>
+        <entry align='left'>8-bit unsigned integer</entry>
+      </row>
+      <row>
+        <entry align='left'>CARD16</entry>
+        <entry align='left'>16-bit unsigned integer</entry>
+      </row>
+      <row>
+        <entry align='left'>CARD32</entry>
+        <entry align='left'>32-bit unsigned integer</entry>
+      </row>
+      <row>
+        <entry align='left'>BOOL</entry>
+        <entry align='left'><para><function>False</function>
+or
+<function>True</function></para></entry>
+      </row>
+      <row>
+        <entry align='left'>LPCE</entry>
+        <entry align='left'>A character from the X Portable Character Set in Latin Portable Character
+Encoding</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+</sect1>
+
+<sect1 id="complex_types">
+<title>Complex Types</title>
+
+<informaltable pgwide='1' frame='none'>
+  <tgroup cols='2' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <thead>
+      <row>
+        <entry align='left'>Type Name</entry>
+        <entry align='left'>Type</entry>
+      </row>
+      <row>
+        <entry align='left'>.TH</entry>
+        <entry align='left'></entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>VERSION</entry>
+        <entry align='left'>[Major, minor: CARD16]</entry>
+      </row>
+      <row>
+        <entry align='left'>STRING</entry>
+        <entry align='left'>LISTofLPCE</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+
+<para>LISTof&lt;type&gt; denotes a counted collection of &lt;type&gt;.  The exact encoding
+varies depending on the context; see the encoding section.</para>
+<!--  .nH 1 "Message Format" -->
+</sect1>
+
+<sect1 id="message_format">
+<title>Message Format</title>
+
+<para>All ICE messages include the following information:</para>
+
+<informaltable pgwide='1' frame='none'>
+  <tgroup cols='2' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <thead>
+      <row>
+        <entry>Field Type</entry>
+        <entry>Description</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>CARD8</entry>
+        <entry align='left'>protocol major opcode</entry>
+      </row>
+      <row>
+        <entry align='left'>CARD8</entry>
+        <entry align='left'>protocol minor opcode</entry>
+      </row>
+      <row>
+        <entry align='left'>CARD32</entry>
+        <entry align='left'>length of remaining data in 8-byte units</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+
+<para>The fields are as follows:</para>
+
+<variablelist>
+  <varlistentry>
+    <term>Protocol major opcode</term>
+    <listitem>
+      <para>
+This specifies what subprotocol the message is intended for.  Major opcode
+0 is reserved for ICE control messages.  The major opcodes of other
+subprotocols are dynamically assigned and exchanged at protocol
+negotiation time.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term>Protocol minor opcode</term>
+    <listitem>
+      <para>
+This specifies what protocol-specific operation is to be performed.
+Minor opcode 0 is reserved for Errors; other values are protocol-specific.
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term>Length of data in 8-byte units</term>
+    <listitem>
+      <para>
+This specifies the length of the information following the first 8 bytes.
+Each message-type has a different format, and will need to be separately
+length-checked against this value.  As every data item has either an
+explicit length, or an implicit length, this can be easily accomplished.
+Messages that have too little or too much data indicate a serious
+protocol failure, and should result in a <function>BadLength</function>
+error.
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+</sect1>
+
+</chapter>
+
+<chapter id="overall_protocol_description">
+<title>Overall Protocol Description</title>
+
+<para>
+Every message sent in a given direction has an implicit sequence number,
+starting with 1.  Sequence numbers are global to the connection; independent
+sequence numbers are <emphasis remap='I'>not</emphasis> maintained for each protocol.</para>
+
+<para>Messages of a given major-opcode (i.e., of a given protocol) must be
+responded to (if a response is called for) in order by the receiving party.
+Messages from different protocols can be responded to in arbitrary order.</para>
+
+<para>Minor opcode 0 in every protocol is for reporting errors.  At most one error
+is generated per request.  If more than one error condition is encountered
+in processing a request, the choice of which error is returned is
+implementation-dependent.
+</para>
+
+<para><function>Error</function></para>
+<variablelist remap='IP'>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para>CARD8</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para>
+{<symbol role='Pn'>CanContinue</symbol>,
+<function>FatalToProtocol</function>
+<function>FatalToConnection</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>sequence-number</emphasis>:</term>
+    <listitem>
+      <para>CARD32</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>class</emphasis>:</term>
+    <listitem>
+      <para>CARD16</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>value(s)</emphasis>:</term>
+    <listitem>
+      <para>&lt;dependent on major/minor opcode and class&gt;</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+This message is sent to report an error in response to a message
+from any protocol.  The <function>Error</function> message
+exists in all protocol major-opcode spaces; it
+is minor-opcode zero in every protocol.  The minor opcode of the
+message that caused the error is reported, as well as the sequence
+number of that message.
+The severity indicates the sender's behavior following
+the identification of the error.  <function>CanContinue</function>
+indicates the sender is willing to accept additional messages for this
+protocol.  <function>FatalToProcotol</function>
+indicates the sender is unwilling to accept further messages for this
+protocol but that messages for other protocols may be accepted.
+<function>FatalToConnection</function>
+indicates the sender is unwilling to accept any further
+messages for any protocols on the connection.  The sender
+is required to conform to specified severity conditions
+for generic and ICE (major opcode 0) errors; see
+<link linkend="generic_error_classes">
+<xref linkend="generic_error_classes"></xref></link> and
+<link linkend="ice_error_classes">
+<xref linkend="ice_error_classes"></xref></link>.
+.
+The class defines the generic class of
+error.  Classes are specified separately for each protocol (numeric
+values can mean different things in different protocols).  The error
+values, if any, and their types vary with the specific error class
+for the protocol.
+</para>
+</chapter>
+
+<chapter id="ice_control_subprotocol__major_opcode_0">
+<title>ICE Control Subprotocol -- Major Opcode 0</title>
+
+<para>
+Each of the ICE control opcodes is described below.
+Most of the messages have additional information included beyond the
+description above.  The additional information is appended to the message
+header and the length field is computed accordingly.
+</para>
+
+<para>
+In the following message descriptions, \*QExpected errors\*U indicates
+errors that may occur in the normal course of events.  Other errors
+(in particular
+<function>BadMajor</function>
+<function>BadMinor</function>
+<function>BadState</function>
+<function>BadLength</function>
+<function>BadValue</function>
+<function>ProtocolDuplicate</function> and
+<function>MajorOpcodeDuplicate</function>
+might occur, but generally indicate a serious implementation failure on
+the part of the errant peer.
+</para>
+<para><function>ByteOrder</function></para>
+
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>byte-order</emphasis>:</term>
+    <listitem>
+      <para>
+{<symbol role='Pn'>MSBfirst</symbol>,
+<function>LSBfirst</function>
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+Both parties must send this message before sending any other,
+including errors.  This message specifies the byte order that
+will be used on subsequent messages sent by this party.
+</para>
+
+<note>
+<para>
+Note:  If the receiver detects an error in this message,
+it must be sure to send its own
+<function>ByteOrder</function> message before sending the
+<function>Error</function>.
+</para>
+</note>
+
+<para><function>ConnectionSetup</function></para>
+
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>versions</emphasis>:</term>
+    <listitem>
+      <para>LISTofVERSION</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>must-authenticate</emphasis>:</term>
+    <listitem>
+      <para>BOOL</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>authentication-protocol-names</emphasis>:</term>
+    <listitem>
+      <para>LISTofSTRING</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>vendor</emphasis>:</term>
+    <listitem>
+      <para>STRING</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>release</emphasis>:</term>
+    <listitem>
+      <para>STRING</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term>Responses:</term>
+    <listitem>
+      <para>
+<function>ConnectionReply</function>,
+<function>AuthenticationRequired</function> (See note)
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term>Expected errors:</term>
+    <listitem>
+      <para>
+<function>NoVersion</function>,
+<function>SetupFailed</function>,
+<function>NoAuthentication</function>,
+<function>AuthenticationRejected</function>,
+<function>AuthenticationFailed</function>
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+The party that initiates the connection (the one that does the
+"connect()") must send this message as the second message (after
+<function>ByteOrder</function> on startup.
+</para>
+
+<para>
+Versions gives a list, in decreasing order of preference, of the
+protocol versions this party is capable of speaking.  This document
+specifies major version 1, minor version 0.
+</para>
+
+<para>
+If must-authenticate is <function>True</function> the initiating
+party demands authentication; the accepting party
+<emphasis remap='I'>must</emphasis> pick an authentication scheme
+and use it.  In this case, the only valid response is
+<function>AuthenticationRequired</function>
+</para>
+
+<para>
+If must-authenticate is <function>False</function> the accepting
+party may choose an authentication mechanism, use a host-address-based
+authentication scheme, or skip authentication.  When must-authenticate
+is <function>False</function> <function>ConnectionReply</function> and
+<function>AuthenticationRequired</function> are both valid responses.
+If a host-address-based authentication scheme is used,
+<function>AuthenticationRejected</function> and
+<function>AuthenticationFailed</function> errors are possible.
+</para>
+
+<para>
+Authentication-protocol-names specifies a (possibly null, if
+must-authenticate is <function>False</function>
+list of authentication protocols the party is willing to perform.  If
+must-authenticate is <function>True</function>
+presumably the party will offer only authentication mechanisms
+allowing mutual authentication.
+</para>
+
+<para>
+Vendor gives the name of the vendor of this ICE implementation.
+</para>
+
+<para>
+Release gives the release identifier of this ICE implementation.
+</para>
+
+<para><function>AuthenticationRequired</function></para>
+
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>authentication-protocol-index</emphasis>:</term>
+    <listitem>
+      <para>CARD8</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>data</emphasis>:</term>
+    <listitem>
+      <para>&lt;specific to authentication protocol&gt;</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term>Response:</term>
+    <listitem>
+      <para><function>AuthenticationReply</function></para>
+    </listitem>
+  </varlistentry>
+    <varlistentry>
+    <term>Expected errors:</term>
+    <listitem>
+      <para>
+<function>AuthenticationRejected</function>,
+<function>AuthenticationFailed</function>
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+This message is sent in response to a <function>ConnectionSetup</function>
+or <function>ProtocolSetup</function>
+message to specify that authentication is to be done and what
+authentication mechanism is to be used.
+</para>
+
+<para>
+The authentication protocol is specified by a 0-based index into the list
+of names given in the <function>ConnectionSetup</function> or
+<function>ProtocolSetup</function>
+Any protocol-specific data that might be required is also sent.
+</para>
+
+
+<para><function>AuthenticationReply</function></para>
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>data</emphasis>:</term>
+    <listitem>
+      <para>&lt;specific to authentication protocol&gt;</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term>Responses:</term>
+    <listitem>
+      <para>
+<function>AuthenticationNextPhase</function>,
+<function>ConnectionReply</function>,
+<function>ProtocolReply</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term>Expected errors:</term>
+    <listitem>
+      <para>
+<function>AuthenticationRejected</function>,
+<function>AuthenticationFailed</function>,
+<function>SetupFailed</function>
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+This message is sent in response to an
+<function>AuthenticationRequired</function> or
+<function>AuthenticationNextPhase</function> message, to
+supply authentication data as defined by the authentication protocol
+being used.
+</para>
+
+<para>
+Note that this message is sent by the party that initiated the current
+negotiation -- the party that sent the
+<function>ConnectionSetup</function> or
+<function>ProtocolSetup</function> message.
+</para>
+
+<para>
+<function>AuthenticationNextPhase</function>
+indicates that more is to be done to complete the authentication.
+If the authentication is complete,
+<function>ConnectionReply</function>
+is appropriate if the current authentication handshake is the result of a
+<function>ConnectionSetup</function> and a
+<function>ProtocolReply</function>
+is appropriate if it is the result of a
+<function>ProtocolSetup</function>.
+</para>
+
+<para><function>AuthenticationNextPhase</function></para>
+
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>data</emphasis>:</term>
+    <listitem>
+      <para>&lt;specific to authentication protocol&gt;</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term>Response:</term>
+    <listitem>
+      <para><function>AuthenticationReply</function></para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term>Expected errors:</term>
+    <listitem>
+      <para>
+<function>AuthenticationRejected</function>,
+<function>AuthenticationFailed</function>
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+This message is sent in response to an
+<function>AuthenticationReply</function>
+message, to supply authentication data as defined by the authentication
+protocol being used.
+</para>
+
+<para><function>ConnectionReply</function></para>
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>version-index</emphasis>:</term>
+    <listitem>
+      <para>CARD8</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>vendor</emphasis>:</term>
+    <listitem>
+      <para>STRING</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>release</emphasis>:</term>
+    <listitem>
+      <para>STRING</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+This message is sent in response to a
+<function>ConnectionSetup</function> or
+<function>AuthenticationReply</function>
+message to indicate that the authentication handshake is complete.
+</para>
+
+<para>
+Version-index gives a 0-based index into the list of versions offered in
+the <function>ConnectionSetup</function> message; it specifies the
+version of the ICE protocol that both parties
+should speak for the duration of the connection.
+</para>
+
+<para>Vendor gives the name of the vendor of this ICE implementation.</para>
+
+<para>
+Release gives the release identifier of this ICE implementation.
+</para>
+
+<para><function>ProtocolSetup</function></para>
+
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>protocol-name</emphasis>:</term>
+    <listitem>
+      <para>STRING</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>major-opcode</emphasis>:</term>
+    <listitem>
+      <para>CARD8</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>versions</emphasis>:</term>
+    <listitem>
+      <para>LISTofVERSION</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>vendor</emphasis>:</term>
+    <listitem>
+      <para>STRING</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>release</emphasis>:</term>
+    <listitem>
+      <para>STRING</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>must-authenticate</emphasis>:</term>
+    <listitem>
+      <para>BOOL</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+  <term><emphasis remap='I'>authentication-protocol-names</emphasis>:</term>
+    <listitem>
+      <para>LISTofSTRING</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term>Responses:</term>
+    <listitem>
+      <para>
+<function>AuthenticationRequired</function>,
+<function>ProtocolReply</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term>Expected errors:</term>
+    <listitem>
+      <para>
+<function>UnknownProtocol</function>,
+<function>NoVersion</function>,
+<function>SetupFailed</function>,
+<function>NoAuthentication</function>,
+<function>AuthenticationRejected</function>,
+<function>AuthenticationFailed</function>
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+This message is used to initiate negotiation of a protocol and
+establish any authentication specific to it.
+</para>
+
+<para>
+Protocol-name gives the name of the protocol the party wishes
+to speak.
+</para>
+
+<para>
+Major-opcode gives the opcode that the party will use in messages
+it sends.
+</para>
+
+<para>
+Versions gives a list of version numbers, in decreasing order of
+preference, that the party is willing to speak.
+</para>
+
+<para>
+Vendor and release are identification strings with semantics defined
+by the specific protocol being negotiated.
+</para>
+
+<para>
+If must-authenticate is <function>True</function>,
+the initiating party demands authentication; the accepting party
+<emphasis remap='I'>must</emphasis> pick an authentication scheme
+and use it.  In this case, the only valid response is
+<function>AuthenticationRequired</function>
+</para>
+
+<para>
+If must-authenticate is <function>False</function>,
+the accepting party may choose an authentication mechanism, use a
+host-address-based authentication scheme, or skip authentication.
+When must-authenticate is <function>False</function>,
+<function>ProtocolReply</function> and
+<function>AuthenticationRequired</function>
+are both valid responses.  If a host-address-based authentication
+scheme is used, <function>AuthenticationRejected</function> and
+<function>AuthenticationFailed</function> errors are possible.
+</para>
+
+<para>
+Authentication-protocol-names  specifies a (possibly null, if
+must-authenticate is <function>False</function>
+list of authentication protocols the party is willing to perform.  If
+must-authenticate is <function>True</function>
+presumably the party will offer only authentication mechanisms
+allowing mutual authentication.
+</para>
+
+<para><function>ProtocolReply</function></para>
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>major-opcode</emphasis>:</term>
+    <listitem>
+      <para>CARD8</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>version-index</emphasis>:</term>
+    <listitem>
+      <para>CARD8</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>vendor</emphasis>:</term>
+    <listitem>
+      <para>STRING</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>release</emphasis>:</term>
+    <listitem>
+      <para>STRING</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+This message is sent in response to a <function>ProtocolSetup</function>
+or <function>AuthenticationReply</function>
+message to indicate that the authentication handshake is complete.
+</para>
+
+<para>
+Major-opcode gives the opcode that this party will use in
+messages that it sends.
+</para>
+
+<para>
+Version-index gives a 0-based index into the list of versions offered in the
+<function>ProtocolSetup</function> message; it specifies the version
+of the protocol that both parties should speak for the duration of
+the connection.
+</para>
+
+<para>
+Vendor and release are identification strings with semantics defined
+by the specific protocol being negotiated.
+</para>
+
+<para><function>Ping</function></para>
+<variablelist>
+  <varlistentry>
+    <term>Response:</term>
+    <listitem>
+      <para><function>PingReply</function></para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+This message is used to test if the connection is still functioning.
+</para>
+
+<para><function>PingReply</function></para>
+
+<para>
+This message is sent in response to a <function>Ping</function>
+message, indicating that the connection is still functioning.
+</para>
+
+<para><function>WantToClose</function></para>
+<variablelist>
+  <varlistentry>
+    <term>Responses:</term>
+    <listitem>
+      <para>
+<function>WantToClose</function>,
+<function>NoClose</function>,
+<function>ProtocolSetup</function>
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+
+<para>
+This message is used to initiate a possible close of the connection.
+The sending party has noticed that, as a result of mechanisms specific
+to each protocol, there are no active protocols left.
+There are four possible scenarios arising from this request:
+</para>
+
+<orderedlist>
+  <listitem>
+    <para>
+The receiving side noticed too, and has already sent a
+<function>WantToClose</function> On receiving a
+<function>WantToClose</function> while already attempting to
+shut down, each party should simply close the connection.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+The receiving side hasn't noticed, but agrees.  It closes the connection.
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+The receiving side has a <function>ProtocolSetup</function>
+"in flight," in which case it is to ignore
+<function>WantToClose</function> and the party sending
+<function>WantToClose</function> is to abandon the shutdown attempt
+when it receives the <function>ProtocolSetup</function>
+    </para>
+  </listitem>
+  <listitem>
+    <para>
+The receiving side wants the connection kept open for some
+reason not specified by the ICE protocol, in which case it
+sends <function>NoClose</function>
+    </para>
+  </listitem>
+</orderedlist>
+
+<para>
+See the state transition diagram for additional information.
+</para>
+
+<para><function>NoClose</function></para>
+
+<para>
+This message is sent in response to a <function>WantToClose</function>
+message to indicate that the responding party does not want the
+connection closed at this time.  The receiving party should not close the
+connection.  Either party may again initiate
+<function>WantToClose</function> at some future time.
+</para>
+
+<sect1 id="generic_error_classes">
+<title>Generic Error Classes</title>
+
+<para>
+These errors should be used by all protocols, as applicable.
+For ICE (major opcode 0), <function>FatalToProtocol</function>
+should be interpreted as <function>FatalToConnection</function>.
+</para>
+
+<para><function>BadMinor</function></para>
+
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para>&lt;any&gt;</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para>
+<function>FatalToProtocol</function> or
+<function>CanContinue</function>
+(protocol's discretion)
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>(none)</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+Received a message with an unknown minor opcode.
+</para>
+
+<para><function>BadState</function></para>
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para>&lt;any&gt;</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para>
+<function>FatalToProtocol</function> or
+<function>CanContinue</function> (protocol's discretion)
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>(none)</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+Received a message with a valid minor opcode which is not appropriate
+for the current state of the protocol.
+</para>
+
+<para><function>BadLength</function></para>
+
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para>&lt;any&gt;</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para>
+<function>FatalToProtocol</function> or
+<function>CanContinue</function> (protocol's discretion)
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>(none)</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+Received a message with a bad length.  The length of the message is
+longer or shorter than required to contain the data.
+</para>
+
+<para><function>BadValue</function></para>
+
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para>&lt;any&gt;</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para><function>CanContinue</function></para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>
+CARD32 Byte offset to offending value in offending message.
+CARD32 Length of offending value.
+&lt;varies&gt; Offending value
+      </para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>Received a message with a bad value specified.</para>
+
+</sect1>
+
+<sect1 id="ice_error_classes">
+<title>ICE Error Classes</title>
+
+<para>These errors are all major opcode 0 errors.</para>
+
+<para><function>BadMajor</function></para>
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para>&lt;any&gt;</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para><function>CanContinue</function></para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>CARD8 Opcode</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>The opcode given is not one that has been registered.</para>
+
+
+<para><function>NoAuthentication</function></para>
+
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para>
+<function>ConnectionSetup</function>,
+<function>ProtocolSetup</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para>
+<function>ConnectionSetup</function> \(-&gt;
+<function>FatalToConnection</function>
+<function>ProtocolSetup</function> \(-&gt;
+<function>FatalToProtocol</function>
+       </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>(none)</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>None of the authentication protocols offered are available.</para>
+
+<para><function>NoVersion</function></para>
+
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para>
+<function>ConnectionSetup</function>,
+<function>ProtocolSetup</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para>
+<function>ConnectionSetup</function> \(-&gt;
+<function>FatalToConnection</function>
+<function>ProtocolSetup</function> \(-&gt;
+<function>FatalToProtocol</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>(none)</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>None of the protocol versions offered are available.</para>
+
+<para><function>SetupFailed</function></para>
+
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para>
+<function>ConnectionSetup</function>,
+<function>ProtocolSetup</function>,
+<function>AuthenticationReply</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para>
+<function>ConnectionSetup</function> \(-&gt;
+<function>FatalToConnection</function>
+<function>ProtocolSetup</function> \(-&gt;
+<function>FatalToProtocol</function>
+<function>AuthenticationReply</function> \(-&gt;
+<function>FatalToConnection</function> if authenticating a connection,
+otherwise <function>FatalToProtocol</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>STRING reason</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+The sending side is unable to accept the
+new connection or new protocol for a reason other than authentication
+failure.  Typically this error will be a result of inability to allocate
+additional resources on the sending side.  The reason field will give a
+human-interpretable message providing further detail on the type of failure.
+</para>
+
+<para><function>AuthenticationRejected</function></para>
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para>
+<function>AuthenticationReply</function>,
+<function>AuthenticationRequired</function>,
+<function>AuthenticationNextPhase</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para><function>FatalToProtocol</function></para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>STRING reason</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+Authentication rejected.  The peer has failed to properly
+authenticate itself.  The reason field will give a human-interpretable
+message providing further detail.
+</para>
+
+<para><function>AuthenticationFailed</function></para>
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para>
+<function>AuthenticationReply</function>,
+<function>AuthenticationRequired</function>,
+<function>AuthenticationNextPhase</function>
+      </para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para><function>FatalToProtocol</function></para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>STRING reason</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+Authentication failed.  <function>AuthenticationFailed</function>
+does not imply that the authentication was rejected, as
+<function>AuthenticationRejected</function>
+does.  Instead it means that the sender was unable to complete
+the authentication for some other reason.  (For instance, it
+may have been unable to contact an authentication server.)
+The reason field will give a human-interpretable message
+providing further detail.
+</para>
+
+<para><function>ProtocolDuplicate</function></para>
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para><function>ProtocolSetup</function></para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para><function>FatalToProtocol</function> (but see note)</para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>STRING protocol name</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+The protocol name was already registered.  This is fatal to
+the "new" protocol being set up by <function>ProtocolSetup</function>
+but it does not affect the existing registration.
+</para>
+
+<para><function>MajorOpcodeDuplicate</function></para>
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para><function>ProtocolSetup</function></para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para><function>FatalToProtocol</function> (but see note)</para>
+  </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>CARD8 opcode</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>
+The major opcode specified was already registered.  This is
+fatal to the \*Qnew\*U protocol being set up by
+<function>ProtocolSetup</function> but it does not affect the
+existing registration.
+</para>
+
+<para><function>UnknownProtocol</function></para>
+<variablelist>
+  <varlistentry>
+    <term><emphasis remap='I'>offending-minor-opcode</emphasis>:</term>
+    <listitem>
+      <para><function>ProtocolSetup</function></para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>severity</emphasis>:</term>
+    <listitem>
+      <para><function>FatalToProtocol</function></para>
+    </listitem>
+  </varlistentry>
+  <varlistentry>
+    <term><emphasis remap='I'>values</emphasis>:</term>
+    <listitem>
+      <para>STRING protocol name</para>
+    </listitem>
+  </varlistentry>
+</variablelist>
+
+<para>The protocol specified is not supported.</para>
+
+</sect1>
+</chapter>
+
+<chapter id="state_diagrams">
+<title>State Diagrams</title>
+
+<para>
+Here are the state diagrams for the party that initiates the connection:
+</para>
+
+<literallayout>
+<emphasis remap='C'>start</emphasis>:
+     connect to other end, send <function>ByteOrder</function> <function>ConnectionSetup</function> -&gt; <emphasis remap='C'>conn_wait</emphasis>
+
+<emphasis remap='C'>conn_wait</emphasis>:
+     receive <function>ConnectionReply</function> -&gt; <emphasis remap='C'>stasis</emphasis>
+     receive <function>AuthenticationRequired</function> -&gt; <emphasis remap='C'>conn_auth1</emphasis>
+     receive <function>Error</function> -&gt; <emphasis remap='C'>quit</emphasis>
+     receive &lt;other&gt;, send <function>Error</function> -&gt; <emphasis remap='C'>quit</emphasis>
+
+<emphasis remap='C'>conn_auth1</emphasis>:
+     if good auth data, send <function>AuthenticationReply</function> -&gt; <emphasis remap='C'>conn_auth2</emphasis>
+     if bad auth data, send <function>Error</function> -&gt; <emphasis remap='C'>quit</emphasis>
+
+<emphasis remap='C'>conn_auth2</emphasis>:
+     receive <function>ConnectionReply</function> -&gt; <emphasis remap='C'>stasis</emphasis>
+     receive <function>AuthenticationNextPhase</function> -&gt; <emphasis remap='C'>conn_auth1</emphasis>
+     receive <function>Error</function> -&gt; <emphasis remap='C'>quit</emphasis>
+     receive &lt;other&gt;, send <function>Error</function> -&gt; <emphasis remap='C'>quit</emphasis>
+</literallayout>
+
+<para>
+Here are top-level state transitions for the party
+that accepts connections.
+</para>
+
+<literallayout>
+<emphasis remap='C'>listener</emphasis>:
+     accept connection -&gt; <emphasis remap='C'>init_wait</emphasis>
+
+<emphasis remap='C'>init_wait</emphasis>:
+     receive <function>ByteOrder</function> <function>ConnectionSetup</function> -&gt; <emphasis remap='C'>auth_ask</emphasis>
+     receive &lt;other&gt;, send <function>Error</function> -&gt; <emphasis remap='C'>quit</emphasis>
+
+<emphasis remap='C'>auth_ask</emphasis>:
+     send <function>ByteOrder</function> <function>ConnectionReply</function>
+-&gt; <emphasis remap='C'>stasis</emphasis>
+
+     send <function>AuthenticationRequired</function> -&gt; <emphasis remap='C'>auth_wait</emphasis>
+
+     send <function>Error</function> -&gt; <emphasis remap='C'>quit</emphasis>
+
+<emphasis remap='C'>auth_wait</emphasis>:
+     receive <function>AuthenticationReply</function> -&gt; <emphasis remap='C'>auth_check</emphasis>
+
+     receive &lt;other&gt;, send <function>Error</function> -&gt; <emphasis remap='C'>quit</emphasis>
+
+<emphasis remap='C'>auth_check</emphasis>:
+     if no more auth needed, send <function>ConnectionReply</function> -&gt; <emphasis remap='C'>stasis</emphasis>
+     if good auth data, send <function>AuthenticationNextPhase</function> -&gt; <emphasis remap='C'>auth_wait</emphasis>
+     if bad auth data, send <function>Error</function> -&gt; <emphasis remap='C'>quit</emphasis>
+</literallayout>
+
+<para>
+Here are the top-level state transitions for all parties after the initial
+connection establishment subprotocol.
+</para>
+
+<note>
+<para>
+Note:  this is not quite the truth for branches out from stasis, in
+that multiple conversations can be interleaved on the connection.
+</para>
+</note>
+
+<literallayout>
+<emphasis remap='C'>stasis</emphasis>:
+     send <function>ProtocolSetup</function> -&gt; <emphasis remap='C'>proto_wait</emphasis>
+     receive <function>ProtocolSetup</function> -&gt; <emphasis remap='C'>proto_reply</emphasis>
+     send <function>Ping</function> -&gt; <emphasis remap='C'>ping_wait</emphasis>
+     receive <function>Ping</function> send <function>PingReply</function> -&gt; <emphasis remap='C'>stasis</emphasis>
+     receive <function>WantToClose</function> -&gt; <emphasis remap='C'>shutdown_attempt</emphasis>
+     receive &lt;other&gt;, send <function>Error</function> -&gt; <emphasis remap='C'>stasis</emphasis>
+     all protocols shut down, send <function>WantToClose</function> -&gt; <emphasis remap='C'>close_wait</emphasis>
+
+<emphasis remap='C'>proto_wait</emphasis>:
+     receive <function>ProtocolReply</function> -&gt; <emphasis remap='C'>stasis</emphasis>
+     receive <function>AuthenticationRequired</function> -&gt; <emphasis remap='C'>give_auth1</emphasis>
+     receive <function>Error</function> give up on this protocol -&gt; <emphasis remap='C'>stasis</emphasis>
+     receive <function>WantToClose</function> -&gt; <emphasis remap='C'>proto_wait</emphasis>
+
+<emphasis remap='C'>give_auth1</emphasis>:
+     if good auth data, send <function>AuthenticationReply</function> -&gt; <emphasis remap='C'>give_auth2</emphasis>
+     if bad auth data, send <function>Error</function> give up on this protocol -&gt; <emphasis remap='C'>stasis</emphasis>
+     receive <function>WantToClose</function> -&gt; <emphasis remap='C'>give_auth1</emphasis>
+
+<emphasis remap='C'>give_auth2</emphasis>:
+     receive <function>ProtocolReply</function> -&gt; <emphasis remap='C'>stasis</emphasis>
+     receive <function>AuthenticationNextPhase</function> -&gt; <emphasis remap='C'>give_auth1</emphasis>
+     receive <function>Error</function> give up on this protocol -&gt; <emphasis remap='C'>stasis</emphasis>
+     receive <function>WantToClose</function> -&gt; <emphasis remap='C'>give_auth2</emphasis>
+
+<emphasis remap='C'>proto_reply</emphasis>:
+     send <function>ProtocolReply</function> -&gt; <emphasis remap='C'>stasis</emphasis>
+     send <function>AuthenticationRequired</function> -&gt; <emphasis remap='C'>take_auth1</emphasis>
+     send <function>Error</function> give up on this protocol -&gt; <emphasis remap='C'>stasis</emphasis>
+
+<emphasis remap='C'>take_auth1</emphasis>:
+     receive <function>AuthenticationReply</function> -&gt; <emphasis remap='C'>take_auth2</emphasis>
+     receive <function>Error</function> give up on this protocol -&gt; <emphasis remap='C'>stasis</emphasis>
+
+<emphasis remap='C'>take_auth2</emphasis>:
+     if good auth data \(-&gt; <emphasis remap='C'>take_auth3</emphasis>
+     if bad auth data, send <function>Error</function> give up on this protocol -&gt; <emphasis remap='C'>stasis</emphasis>
+
+<emphasis remap='C'>take_auth3</emphasis>:
+     if no more auth needed, send <function>ProtocolReply</function> -&gt; <emphasis remap='C'>stasis</emphasis>
+     if good auth data, send <function>AuthenticationNextPhase</function> -&gt; <emphasis remap='C'>take_auth1</emphasis>
+     if bad auth data, send <function>Error</function> give up on this protocol -&gt; <emphasis remap='C'>stasis</emphasis>
+
+<emphasis remap='C'>ping_wait</emphasis>:
+     receive <function>PingReply</function> -&gt; <emphasis remap='C'>stasis</emphasis>
+
+<emphasis remap='C'>quit</emphasis>:
+     -&gt; close connection
+</literallayout>
+
+<para>
+Here are the state transitions for shutting down the connection:
+</para>
+
+<literallayout>
+<emphasis remap='C'>shutdown_attempt</emphasis>:
+     if want to stay alive anyway, send <function>NoClose</function> -&gt; <emphasis remap='C'>stasis</emphasis>
+     else -&gt; <emphasis remap='C'>quit</emphasis>
+
+<emphasis remap='C'>close_wait</emphasis>:
+     receive <function>ProtocolSetup</function> -&gt; <emphasis remap='C'>proto_reply</emphasis>
+     receive <function>NoClose</function> -&gt; <emphasis remap='C'>stasis</emphasis>
+     receive <function>WantToClose</function> -&gt; <emphasis remap='C'>quit</emphasis>
+     connection close -&gt; <emphasis remap='C'>quit</emphasis>
+</literallayout>
+</chapter>
+<chapter id="protocol_encoding">
+<title>Protocol Encoding</title>
+
+<para>
+In the encodings below, the first column is the number of bytes occupied.
+The second column is either the type (if the value is variable) or the
+actual value.  The third column is the description of the value (e.g.,
+the parameter name).  Receivers must ignore bytes that are designated
+as unused or pad bytes.
+</para>
+
+<para>
+This document describes major version 1, minor version 0
+of the ICE protocol.
+</para>
+
+<para>
+LISTof&lt;type&gt; indicates some number of repetitions of
+&lt;type&gt;, with no
+additional padding.  The number of repetitions must be specified elsewhere
+in the message.
+</para>
+
+<sect1 id="primitives">
+<title>Primitives</title>
+
+<informaltable pgwide='1' frame='none'>
+  <tgroup cols='3' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <colspec colname='c3'/>
+    <thead>
+      <row>
+        <entry align='left'>Type Name</entry>
+        <entry align='left'>Length (bytes)</entry>
+        <entry align='left'>Description</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>CARD8</entry>
+        <entry align='left'>1</entry>
+        <entry align='left'>8-bit unsigned integer</entry>
+      </row>
+      <row>
+        <entry align='left'>CARD16</entry>
+        <entry align='left'>2</entry>
+        <entry align='left'>16-bit unsigned integer</entry>
+      </row>
+      <row>
+        <entry align='left'>CARD32</entry>
+        <entry align='left'>4</entry>
+        <entry align='left'>32-bit unsigned integer</entry>
+      </row>
+      <row>
+        <entry align='left'>LPCE</entry>
+        <entry align='left'>1</entry>
+        <entry align='left'><para>A character from the X Portable Character Set in Latin Portable Character
+Encoding</para></entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+</sect1>
+
+<sect1 id="enumerations">
+<title>Enumerations</title>
+
+
+<informaltable pgwide='1' frame='none'>
+  <tgroup cols='3' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <colspec colname='c3'/>
+    <thead>
+      <row>
+        <entry align='left'>Type Name</entry>
+        <entry align='left'>Value</entry>
+        <entry align='left'>Description</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>BOOL</entry>
+        <entry align='left'>0</entry>
+        <entry align='left'>False</entry>
+      </row>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>1</entry>
+        <entry align='left'>True</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+</sect1>
+
+<sect1 id="compound_types">
+<title>Compound Types</title>
+
+<informaltable pgwide='1' frame='none'>
+  <tgroup cols='4' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <colspec colname='c3'/>
+    <colspec colname='c4'/>
+    <thead>
+      <row>
+        <entry align='left'>Type Name</entry>
+        <entry align='left'>Length (bytes)</entry>
+        <entry align='left'>Type</entry>
+        <entry align='left'>Description</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>VERSION</entry>
+        <entry align='left'></entry>
+        <entry align='left'></entry>
+        <entry align='left'></entry>
+      </row>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>2</entry>
+        <entry align='left'>CARD16</entry>
+        <entry align='left'>Major version number</entry>
+      </row>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>2</entry>
+        <entry align='left'>CARD16</entry>
+        <entry align='left'>Minor version number</entry>
+      </row>
+      <row>
+        <entry align='left'>STRING</entry>
+        <entry align='left'></entry>
+        <entry align='left'></entry>
+        <entry align='left'></entry>
+      </row>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>2</entry>
+        <entry align='left'>CARD16</entry>
+        <entry align='left'>length of string in bytes</entry>
+      </row>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>n</entry>
+        <entry align='left'>LISTofLPCE</entry>
+        <entry align='left'>string</entry>
+      </row>
+      <row>
+        <entry align='left'></entry>
+        <entry align='left'>p</entry>
+        <entry align='left'></entry>
+        <entry align='left'>unused, p = pad(n+2, 4)</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+</sect1>
+
+<sect1 id="ice_minor_opcodes">
+<title>ICE Minor opcodes</title>
+
+<informaltable pgwide='0' frame='none'>
+  <tgroup cols='2' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <thead>
+      <row>
+        <entry align='left'>Message Name</entry>
+        <entry align='right'>Encoding</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>Error</entry>
+        <entry align='right'>0</entry>
+      </row>
+      <row>
+        <entry align='left'>ByteOrder</entry>
+        <entry align='right'>1</entry>
+      </row>
+      <row>
+        <entry align='left'>ConnectionSetup</entry>
+        <entry align='right'>2</entry>
+      </row>
+      <row>
+        <entry align='left'>AuthenticationRequired</entry>
+        <entry align='right'>3</entry>
+      </row>
+      <row>
+        <entry align='left'>AuthenticationReply</entry>
+        <entry align='right'>4</entry>
+      </row>
+      <row>
+        <entry align='left'>AuthenticationNextPhase</entry>
+        <entry align='right'>5</entry>
+      </row>
+      <row>
+        <entry align='left'>ConnectionReply</entry>
+        <entry align='right'>6</entry>
+      </row>
+      <row>
+        <entry align='left'>ProtocolSetup</entry>
+        <entry align='right'>7</entry>
+      </row>
+      <row>
+        <entry align='left'>ProtocolReply</entry>
+        <entry align='right'>8</entry>
+      </row>
+      <row>
+        <entry align='left'>Ping</entry>
+        <entry align='right'>9</entry>
+      </row>
+      <row>
+        <entry align='left'>PingReply</entry>
+        <entry align='right'>10</entry>
+      </row>
+      <row>
+        <entry align='left'>WantToClose</entry>
+        <entry align='right'>11</entry>
+      </row>
+      <row>
+        <entry align='left'>NoClose</entry>
+        <entry align='right'>12</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+</sect1>
+
+<sect1 id="message_encoding">
+<title>Message Encoding</title>
+
+<literallayout class="monospaced">
+<function>Error</function>
+     1     CARD8         major-opcode
+     1     0             Error
+     2     CARD16        class
+     4     (n+p)/8+1     length
+     1     CARD8         offending-minor-opcode
+     1                   severity:
+           0               CanContinue
+           1               FatalToProtocol
+           2               FatalToConnection
+     2                   unused
+     4     CARD32        sequence number of erroneous message
+     n     &lt;varies&gt;     value(s)
+     p                   pad, p = pad(n,8)
+</literallayout>
+
+
+<literallayout class="monospaced">
+<function>ByteOrder</function>
+     1     0     ICE
+     1     1     ByteOrder
+     1           byte-order:
+           0        LSBfirst
+           1        MSBfirst
+     1           unused
+     4     0     length
+</literallayout>
+
+<literallayout class="monospaced">
+<function>ConnectionSetup</function>
+     1     0                   ICE
+     1     2                   ConnectionSetup
+     1     CARD8               Number of versions offered
+     1     CARD8               Number of authentication protocol names offered
+     4     (i+j+k+m+p)/8+1     length
+     1     BOOL                must-authenticate
+     7                         unused
+     i     STRING              vendor
+     j     STRING              release
+     k     LISTofSTRING        authentication-protocol-names
+     m     LISTofVERSION       version-list
+     p                         unused, p = pad(i+j+k+m,8)
+</literallayout>
+
+<literallayout class="monospaced">
+<function>AuthenticationRequired</function>
+     1     0             ICE
+     1     3             AuthenticationRequired
+     1     CARD8         authentication-protocol-index
+     1                   unused
+     4     (n+p)/8+1     length
+     2     n             length of authentication data
+     6          unused
+     n     &lt;varies&gt;     data
+     p                   unused, p = pad(n,8)
+</literallayout>
+
+<literallayout class="monospaced">
+<function>AuthenticationReply</function>
+     1     0             ICE
+     1     4             AuthenticationReply
+     2                   unused
+     4     (n+p)/8+1     length
+     2     n             length of authentication data
+     6                   unused
+     n     &lt;varies&gt;     data
+     p                   unused, p = pad(n,8)
+</literallayout>
+
+<literallayout class="monospaced">
+<function>AuthenticationNextPhase</function>
+     1     0             ICE
+     1     5             AuthenticationNextPhase
+     2                   unused
+     4     (n+p)/8+1     length
+     2     n             length of authentication data
+     6                   unused
+     n     &lt;varies&gt;     data
+     p                   unused, p = pad(n,8)
+</literallayout>
+
+<literallayout class="monospaced">
+<function>ConnectionReply</function>
+     1     0             ICE
+     1     6             ConnectionReply
+     1     CARD8         version-index
+     1                   unused
+     4     (i+j+p)/8     length
+     i     STRING        vendor
+     j     STRING        release
+     p                   unused, p = pad(i+j,8)
+</literallayout>
+
+<literallayout class="monospaced">
+<function>ProtocolSetup</function>
+     1     0                     ICE
+     1     7                     ProtocolSetup
+     1     CARD8                 major-opcode
+     1     BOOL                  must-authenticate
+     4     (i+j+k+m+n+p)/8+1     length
+     1     CARD8                 Number of versions offered
+     1     CARD8                 Number of authentication protocol names offered
+     6                           unused
+     i     STRING                protocol-name
+     j     STRING                vendor
+     k     STRING                release
+     m     LISTofSTRING          authentication-protocol-names
+     n     LISTofVERSION         version-list
+     p                           unused, p = pad(i+j+k+m+n,8)
+</literallayout>
+
+<literallayout class="monospaced">
+<function>ProtocolReply</function>
+     1     0             ICE
+     1     8             ProtocolReply
+     1     CARD8         version-index
+     1     CARD8         major-opcode
+     4     (i+j+p)/8     length
+     i     STRING        vendor
+     j     STRING        release
+     p                   unused, p = pad(i+j, 8)
+</literallayout>
+
+<literallayout class="monospaced">
+<function>Ping</function>
+     1     0     ICE
+     1     9     Ping
+     2     0     unused
+     4     0     length
+</literallayout>
+
+<literallayout class="monospaced">
+<function>PingReply</function>
+     1     0     ICE
+     1     10    PingReply
+     2     0     unused
+     4     0     length
+</literallayout>
+
+<literallayout class="monospaced">
+<function>WantToClose</function>
+     1     0     ICE
+     1     11    WantToClose
+     2     0     unused
+     4     0     length
+</literallayout>
+
+<literallayout class="monospaced">
+<function>NoClose</function>
+     1     0     ICE
+     1     12    NoClose
+     2     0     unused
+     4     0     length
+</literallayout>
+
+</sect1>
+
+<sect1 id="error_class_encoding">
+<title>Error Class Encoding</title>
+
+<para>
+Generic errors have classes in the range 0x8000-0xFFFF, and
+subprotocol-specific errors are in the range 0x0000-0x7FFF.
+</para>
+
+<sect2 id="generic_error_class_encoding">
+<title>Generic Error Class Encoding</title>
+
+<informaltable pgwide='0' frame='none'>
+  <tgroup cols='2' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <thead>
+      <row>
+        <entry align='left'>Class</entry>
+        <entry align='center'>Encoding</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>BadMinor</entry>
+        <entry align='right'>0x8000</entry>
+      </row>
+      <row>
+        <entry align='left'>BadState</entry>
+        <entry align='right'>0x8001</entry>
+      </row>
+      <row>
+        <entry align='left'>BadLength</entry>
+        <entry align='right'>0x8002</entry>
+      </row>
+      <row>
+        <entry align='left'>BadValue</entry>
+        <entry align='right'>0x8003</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+</sect2>
+<sect2 id="ice_specific_error_class_encoding">
+<title>ICE-specific Error Class Encoding</title>
+
+<informaltable pgwide='0' frame='none'>
+  <tgroup cols='2' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <thead>
+      <row>
+        <entry align='left'>Class</entry>
+        <entry align='center'>Encoding</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>BadMajor</entry>
+        <entry align='right'>0</entry>
+      </row>
+      <row>
+        <entry align='left'>NoAuthentication</entry>
+        <entry align='right'>1</entry>
+      </row>
+      <row>
+        <entry align='left'>NoVersion</entry>
+        <entry align='right'>2</entry>
+      </row>
+      <row>
+        <entry align='left'>SetupFailed</entry>
+        <entry align='right'>3</entry>
+      </row>
+      <row>
+        <entry align='left'>AuthenticationRejected</entry>
+        <entry align='right'>4</entry>
+      </row>
+      <row>
+        <entry align='left'>AuthenticationFailed</entry>
+        <entry align='right'>5</entry>
+      </row>
+      <row>
+        <entry align='left'>ProtocolDuplicate</entry>
+        <entry align='right'>6</entry>
+      </row>
+      <row>
+        <entry align='left'>MajorOpcodeDuplicate</entry>
+        <entry align='right'>7</entry>
+      </row>
+      <row>
+        <entry align='left'>UnknownProtocol</entry>
+        <entry align='right'>8</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+</sect2>
+</sect1>
+</chapter>
+
+<appendix id="modification_history">
+
+<title>Modification History</title>
+
+<sect1 id="release_6_to_release_6_1">
+<title>Release 6 to Release 6.1</title>
+<para>
+Release 6.1 added the ICE X rendezvous protocol (Appendix B) and
+updated the document version to 1.1.
+</para>
+</sect1>
+
+<sect1 id="release_6_1_to_release_6_3">
+<title>Release 6.1 to Release 6.3</title>
+<para>Release 6.3 added the listen on well known ports feature.</para>
+</sect1>
+
+</appendix>
+
+<appendix id="ice_x_rendezvous_protocol">
+<title>ICE X Rendezvous Protocol</title>
+
+<sect1 id="introduction">
+<title>Introduction</title>
+<para>
+The ICE X rendezvous protocol is designed to answer the need posed
+in Section 2 for one mechanism by which two clients interested in
+communicating via ICE are able to exchange the necessary information.
+This protocol is appropriate for any two ICE clients who also have X
+connections to the same X server.
+</para>
+</sect1>
+
+<sect1 id="overview_of_ice_x_rendezvous">
+<title>Overview of ICE X Rendezvous</title>
+
+<para>
+The ICE X Rendezvous Mechanism requires clients willing to act as ICE
+originating parties to pre-register the ICE subprotocols they support in an
+ICE_PROTOCOLS property on their top-level window.  Clients willing to
+act as ICE answering parties then send an ICE_PROTOCOLS X
+<function>ClientMessage</function>
+event to the ICE originating parties.  This
+<function>ClientMessage</function>
+event identifies
+the ICE network IDs of the ICE answering party as well as the ICE
+subprotocol it wishes to speak.  Upon receipt of this message the ICE
+originating party uses the information to establish an ICE connection
+with the ICE answering party.
+</para>
+</sect1>
+
+<sect1 id="registering_known_protocols">
+<title>Registering Known Protocols</title>
+
+<para>
+Clients willing to act as ICE originating parties preregister
+the ICE subprotocols they support in a list of atoms held by an
+ICE_PROTOCOLS property on their top-level window.  The name of each
+atom listed in ICE_PROTOCOLS must be of the form
+ICE_INITIATE_<emphasis remap='I'>pname</emphasis> where
+<emphasis remap='I'>pname</emphasis> is the name of the ICE
+subprotocol the ICE originating party is willing to speak, as would be
+specified in an ICE
+<function>ProtocolSetup</function>
+message.
+</para>
+
+<para>
+Clients with an ICE_INITIATE_<emphasis remap='I'>pname</emphasis> atom
+in the ICE_PROTOCOLS property on their top-level windows must respond to
+<function>ClientMessage</function> events of
+type ICE_PROTOCOLS specifying ICE_INITIATE_
+<emphasis remap='I'>pname</emphasis>.  If a client does not
+want to respond to these client message events, it should
+remove the ICE_INITIATE_<emphasis remap='I'>pname</emphasis>
+atom from its ICE_PROTOCOLS property
+or remove the ICE_PROTOCOLS property entirely.
+</para>
+</sect1>
+
+<sect1 id="initiating_the_rendezvoud">
+<title>Initiating the Rendezvous</title>
+
+<para>
+To initiate the rendezvous a client acting as an ICE answering
+party sends an X
+<function>ClientMessage</function>
+event of type ICE_PROTOCOLS to an ICE
+originating party.  This ICE_PROTOCOLS client message contains the
+information the ICE originating party needs to identify the ICE
+subprotocol the two parties will use as well as the ICE network
+identification string of the ICE answering party.
+</para>
+
+<para>
+Before the ICE answering party sends the client message event it must
+define a text property on one of its windows.  This text property
+contains the ICE answering party's ICE network identification string
+and will be used by ICE originating parties to determine the ICE
+answering party's list of ICE network IDs.
+</para>
+
+<para>
+The property name will normally be ICE_NETWORK_IDS, but may be any
+name of the ICE answering party's choosing.  The format for this text
+property is as follows:
+</para>
+
+<informaltable pgwide='0' frame='none'>
+  <tgroup cols='2' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <thead>
+      <row>
+        <entry align='left'>Field</entry>
+        <entry align='left'>Value</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>type</entry>
+        <entry align='left'>XA_STRING</entry>
+      </row>
+      <row>
+        <entry align='left'>format</entry>
+        <entry align='left'>8</entry>
+      </row>
+      <row>
+        <entry align='left'>value</entry>
+        <entry align='left'>comma-separated list of ICE network IDs</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+
+
+<para>
+Once the ICE answering party has established this text property on one
+of its windows, it initiates the rendezvous by sending an
+ICE_PROTOCOLS
+<function>ClientMessage</function>
+event to an ICE originating party's
+top-level window.  This event has the following format
+and must only be sent to windows that have pre-registered the ICE
+subprotocol in an ICE_PROTOCOLS property on their top-level window.
+</para>
+
+<informaltable pgwide='0' frame='none'>
+  <tgroup cols='2' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <thead>
+      <row>
+        <entry align='left'>Field</entry>
+        <entry align='left'>Value</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>message_type</entry>
+        <entry align='left'>Atom = "ICE_PROTOCOLS"</entry>
+      </row>
+      <row>
+        <entry align='left'>format</entry>
+        <entry align='left'>32</entry>
+      </row>
+      <row>
+        <entry align='left'>data.l[0]</entry>
+        <entry align='left'>Atom identifying the ICE subprotocol to speak</entry>
+      </row>
+      <row>
+        <entry align='left'>data.l[1]</entry>
+        <entry align='left'>Timestamp</entry>
+      </row>
+      <row>
+        <entry align='left'>data.l[2]</entry>
+        <entry align='left'><para>ICE answering party's window ID with
+ICE network IDs text property</para></entry>
+      </row>
+      <row>
+        <entry align='left'>data.l[3]</entry>
+        <entry align='left'>Atom naming text property containing the ICE
+answering party's ICE network IDs</entry>
+      </row>
+      <row>
+        <entry align='left'>data.l[4]</entry>
+        <entry align='left'>Reserved.  Must be 0.</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+
+<para>
+The name of the atom in data.l[0] must be of the form
+ICE_INITIATE_<emphasis remap='I'>pname</emphasis>, where
+<emphasis remap='I'>pname</emphasis> is the name of the ICE
+subprotocol the ICE answering party wishes to speak.
+</para>
+
+<para>
+When an ICE originating party receives a
+<function>ClientMessage</function>
+event of type
+ICE_PROTOCOLS specifying ICE_INITIATE_<emphasis remap='I'>pname</emphasis>
+it can initiate an ICE connection with the ICE answering party.
+To open this connection the client retrieves the ICE answering
+party's ICE network IDs from the window specified in data.l[2] using
+the text property specified in data.l[3].
+</para>
+
+<para>
+If the connection attempt fails for any reason, the client must
+respond to the client message event by sending a return
+<function>ClientMessage</function>
+event to the window specified in data.l[2].  This return
+event has the following format:
+</para>
+
+<informaltable pgwide='0' frame='none'>
+  <tgroup cols='2' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <thead>
+      <row>
+        <entry align='left'>Field</entry>
+        <entry align='left'>Value</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>message_type</entry>
+        <entry align='left'>Atom = "ICE_INITIATE_FAILED"</entry>
+      </row>
+      <row>
+        <entry align='left'>format</entry>
+        <entry align='left'>32</entry>
+      </row>
+      <row>
+        <entry align='left'>data.l[0]</entry>
+        <entry align='left'>Atom identifying the ICE subprotocol requested</entry>
+      </row>
+      <row>
+        <entry align='left'>data.l[1]</entry>
+        <entry align='left'>Timestamp</entry>
+      </row>
+      <row>
+        <entry align='left'>data.l[2]</entry>
+        <entry align='left'><para>Initiating party's window ID
+(holding ICE_PROTOCOLS)</para></entry>
+      </row>
+      <row>
+        <entry align='left'>data.l[3]</entry>
+        <entry align='left'>int: reason for failure</entry>
+      </row>
+      <row>
+        <entry align='left'>data.l[4]</entry>
+        <entry align='left'>Reserved, must be 0</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+
+<para>
+The values of data.l[0] and data.l[1] are copied directly from the
+client message event the client received.
+</para>
+
+<para>
+The value in data.l[2] is
+the id of the window to which the
+ICE_PROTOCOLS.ICE_INITIATE_<emphasis remap='I'>pname</emphasis>
+client message event was sent.
+</para>
+
+<para>Data.l[3] has one of the following values:</para>
+
+<!-- .ne 21 -->
+
+<informaltable pgwide='0' frame='none'>
+  <tgroup cols='3' align='center'>
+    <colspec colname='c1'/>
+    <colspec colname='c2'/>
+    <colspec colname='c3'/>
+    <thead>
+      <row>
+        <entry align='left'>Value</entry>
+        <entry align='left'>Encoding</entry>
+        <entry align='left'>Description</entry>
+      </row>
+    </thead>
+    <tbody>
+      <row>
+        <entry align='left'>OpenFailed</entry>
+        <entry align='center'>1</entry>
+        <entry align='left'>
+The client was unable to open the connection
+(e.g. a call to IceOpenConnection() failed).  If the
+client is able to distinguish authentication or
+authorization errors from general errors, then
+the preferred reply is <function>AuthenticationFailed</function>
+for authorization errors.
+          </entry>
+      </row>
+      <row>
+        <entry align='left'>AuthenticationFailed</entry>
+        <entry align='center'>2</entry>
+        <entry align='left'>Authentication or authorization of the
+connection or protocol setup was refused.
+This reply will be given only if the client is
+able to distinguish it from
+<function>OpenFailed</function>
+otherwise
+<function>OpenFailed</function>
+will be returned.</entry>
+      </row>
+      <row>
+        <entry align='left'>SetupFailed</entry>
+        <entry align='center'>3</entry>
+        <entry align='left'>The client was unable to initiate the specified
+protocol on the connection (e.g. a call to
+IceProtocolSetup() failed).</entry>
+      </row>
+      <row>
+        <entry align='left'>UnknownProtocol</entry>
+        <entry align='center'>4</entry>
+        <entry align='left'>The client does not recognize the requested
+protocol.  (This represents a semantic error
+on the part of the answering party.)</entry>
+      </row>
+      <row>
+        <entry align='left'>Refused</entry>
+        <entry align='center'>5</entry>
+        <entry align='left'>
+The client was in the process of removing
+ICE_INITIATE_<emphasis remap='I'>pname</emphasis>
+from its ICE_PROTOCOLS list
+when the client message was sent; the client no
+longer is willing to establish the specified ICE
+communication.</entry>
+      </row>
+    </tbody>
+  </tgroup>
+</informaltable>
+
+
+<note>
+<para>
+Clients willing to act as ICE originating parties must update the
+ICE_PROTOCOLS property on their top-level windows to include the
+ICE_INITIATE_<emphasis remap='I'>pname</emphasis> atom(s) identifying
+the ICE subprotocols they
+speak.  The method a client uses to update the ICE_PROTOCOLS property
+to include ICE_INITIATE_<emphasis remap='I'>pname</emphasis> atoms is
+implementation dependent, but
+the client must ensure the integrity of the list to prevent the
+accidental omission of any atoms previously in the list.
+</para>
+
+<para>
+When setting up the ICE network IDs text property on one of its
+windows, the ICE answering party can determine its comma-separated
+list of ICE network IDs by calling IceComposeNetworkIdList() after
+making a call to IceListenForConnections().  The method an ICE
+answering party uses to find the top-level windows of clients willing
+to act as ICE originating parties is dependent upon the nature of the
+answering party.  Some may wish to use the approach of requiring the
+user to click on a client's window.  Others wishing to find existing
+clients without requiring user interaction might use something similar
+to the XQueryTree() method used by several freely-available
+applications.  In order for the ICE answering party to become
+automatically aware of new clients willing to originate ICE
+connections, the ICE answering party might register for
+SubstructureNotify events on the root window of the display.  When it
+receives a SubstructureNotify event, the ICE answering party can check
+to see if it was the result of the creation of a new client top-level
+window with an ICE_PROTOCOLS property.
+</para>
+
+<para>
+In any case, before attempting to use this ICE X Rendezvous Mechanism
+ICE answering parties wishing to speak ICE subprotocol
+<emphasis remap='I'>pname</emphasis> should
+check for the ICE_INITIATE_<emphasis remap='I'>pname</emphasis> atom
+in the ICE_PROTOCOLS property on
+a client's top-level window.  A client that does not include an
+ICE_INITIATE_<emphasis remap='I'>pname</emphasis> atom in a
+ICE_PROTOCOLS property on some top-level window should be assumed to ignore
+<function>ClientMessage</function>
+events of type
+ICE_PROTOCOLS specifying ICE_INITIATE_<emphasis remap='I'>pname</emphasis>
+for ICE subprotocol <emphasis remap='I'>pname</emphasis>.
+</para>
+</note>
+</sect1>
+
+<sect1 id="ice_subprotocol_versioning">
+<title>ICE Subprotocol Versioning</title>
+
+<para>
+Although the version of the ICE subprotocol could be passed in the
+client message event, ICE provides more a flexible version negotiation
+mechanism than will fit within a single
+<function>ClientMessage</function>
+event.  Because
+of this, ICE subprotocol versioning is handled within the ICE protocol
+setup phase.</para>
+<note remap='NT'>
+<para>Clients wish to communicate with each other via an ICE subprotocol
+known as "RAP V1.0".  In RAP terminology one party, the "agent",
+communicates with other RAP-enabled applications on demand.  The
+user may direct the agent to establish communication with a specific
+application by clicking on the application's window, or the agent may
+watch for new application windows to be created and automatically
+establish communication.
+</para>
+
+<para>
+During startup the ICE answering party (the agent) first calls
+IceRegisterForProtocolReply() with a list of
+the versions (i.e., 1.0) of RAP the agent can speak.  The answering
+party then calls IceListenForConnections() followed by
+IceComposeNetworkIdList() and stores the resulting ICE network IDs
+string in a text property on one of its windows.
+</para>
+
+<para>
+When the answering party (agent) finds a client with which it wishes to
+speak, it checks to see if the ICE_INITIATE_RAP atom is in the ICE_PROTOCOLS
+property on the client's top-level window.  If it is present the agent
+sends the client's top-level window an ICE_PROTOCOLS client
+message event as described above.  When the client receives the client
+message event and is willing to originate an ICE connection using RAP,
+it performs an IceRegisterForProtocolSetup() with a list of the
+versions of RAP the client can speak.  The client then retrieves
+the agent's ICE network ID from the property and window specified by
+the agent in the client message event and calls IceOpenConnection().
+After this call succeeds the client calls IceProtocolSetup() specifying
+the RAP protocol.  During this
+process, ICE calls the RAP protocol routines that handle the version
+negotiation.
+</para>
+
+<para>
+Note that it is not necessary for purposes of this rendezvous that
+the client application call any ICElib functions prior to receipt
+of the client message event.
+</para>
+</note>
+</sect1>
+</appendix>
+</book>
diff --git a/src/ICElibint.h b/src/ICElibint.h
new file mode 100755 (executable)
index 0000000..3df59d6
--- /dev/null
@@ -0,0 +1,541 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifndef _ICELIBINT_H_
+#define _ICELIBINT_H_
+
+#include <X11/Xos.h>
+#include <X11/Xfuncs.h>
+#include <X11/Xmd.h>
+#include <X11/ICE/ICEproto.h>
+#include <X11/ICE/ICEconn.h>
+#include <X11/ICE/ICEmsg.h>
+#include <X11/ICE/ICEutil.h>
+#ifdef WIN32
+#include <X11/Xwindows.h>
+#endif
+
+#include <stdlib.h>
+#include <stddef.h>
+
+
+/*
+ * Vendor & Release
+ */
+
+#define IceVendorString  "MIT"
+#define IceReleaseString "1.0"
+
+
+/*
+ * Pad to a 64 bit boundary
+ */
+
+#define PAD64(_bytes) ((8 - ((unsigned int) (_bytes) % 8)) % 8)
+
+#define PADDED_BYTES64(_bytes) (_bytes + PAD64 (_bytes))
+
+
+/*
+ * Pad to 32 bit boundary
+ */
+
+#define PAD32(_bytes) ((4 - ((unsigned int) (_bytes) % 4)) % 4)
+
+#define PADDED_BYTES32(_bytes) (_bytes + PAD32 (_bytes))
+
+
+/*
+ * Number of 8 byte units in _bytes.
+ */
+
+#define WORD64COUNT(_bytes) (((unsigned int) ((_bytes) + 7)) >> 3)
+
+
+/*
+ * Number of 4 byte units in _bytes.
+ */
+
+#define WORD32COUNT(_bytes) (((unsigned int) ((_bytes) + 3)) >> 2)
+
+
+/*
+ * Given a string, compute the number of bytes for the STRING representation
+ */
+
+#define STRING_BYTES(_string) \
+    (2 + strlen (_string) + PAD32 (2 + strlen (_string)))
+
+
+/*
+ * Size of ICE input/output buffers
+ */
+
+#define ICE_INBUFSIZE 1024
+
+#define ICE_OUTBUFSIZE 1024
+
+
+/*
+ * Maxium number of ICE authentication methods allowed, and maxiumum
+ * number of authentication data entries allowed to be set in the
+ * IceSetPaAuthData function.
+ *
+ * We should use linked lists, but this is easier and should suffice.
+ */
+
+#define MAX_ICE_AUTH_NAMES 32
+#define ICE_MAX_AUTH_DATA_ENTRIES 100
+
+
+/*
+ * ICE listen object
+ */
+
+struct _IceListenObj {
+    struct _XtransConnInfo     *trans_conn; /* transport connection object */
+    char                       *network_id;
+    IceHostBasedAuthProc       host_based_auth_proc;
+};
+
+
+/*
+ * Some internal data structures for processing ICE messages.
+ */
+
+typedef void (*_IceProcessCoreMsgProc) (
+    IceConn            /* iceConn */,
+    int                        /* opcode */,
+    unsigned long      /* length */,
+    Bool               /* swap */,
+    IceReplyWaitInfo *  /* replyWait */,
+    Bool *             /* replyReadyRet */,
+    Bool *             /* connectionClosedRet */
+);
+
+typedef struct {
+    int                        major_version;
+    int                        minor_version;
+    _IceProcessCoreMsgProc     process_core_msg_proc;
+} _IceVersion;
+
+
+/*
+ * STORE FOO
+ */
+
+#define STORE_CARD8(_pBuf, _val) \
+{ \
+    *((CARD8 *) _pBuf) = _val; \
+    _pBuf += 1; \
+}
+
+#ifndef WORD64
+
+#define STORE_CARD16(_pBuf, _val) \
+{ \
+    *((CARD16 *) _pBuf) = _val; \
+    _pBuf += 2; \
+}
+
+#define STORE_CARD32(_pBuf, _val) \
+{ \
+    *((CARD32 *) _pBuf) = _val; \
+    _pBuf += 4; \
+}
+
+#else /* WORD64 */
+
+#define STORE_CARD16(_pBuf, _val) \
+{ \
+    struct { \
+        int value   :16; \
+        int pad     :16; \
+    } _d; \
+    _d.value = _val; \
+    memcpy (_pBuf, &_d, 2); \
+    _pBuf += 2; \
+}
+
+#define STORE_CARD32(_pBuf, _val) \
+{ \
+    struct { \
+        int value   :32; \
+    } _d; \
+    _d.value = _val; \
+    memcpy (_pBuf, &_d, 4); \
+    _pBuf += 4; \
+}
+
+#endif /* WORD64 */
+
+#define STORE_STRING(_pBuf, _string) \
+{ \
+    CARD16 _len = strlen (_string); \
+    STORE_CARD16 (_pBuf, _len); \
+    memcpy (_pBuf, _string, _len); \
+    _pBuf += _len; \
+    if (PAD32 (2 + _len)) \
+        _pBuf += PAD32 (2 + _len); \
+}
+
+
+/*
+ * EXTRACT FOO
+ */
+
+#define EXTRACT_CARD8(_pBuf, _val) \
+{ \
+    _val = *((CARD8 *) _pBuf); \
+    _pBuf += 1; \
+}
+
+#ifndef WORD64
+
+#define EXTRACT_CARD16(_pBuf, _swap, _val) \
+{ \
+    _val = *((CARD16 *) _pBuf); \
+    _pBuf += 2; \
+    if (_swap) \
+        _val = lswaps (_val); \
+}
+
+#define EXTRACT_CARD32(_pBuf, _swap, _val) \
+{ \
+    _val = *((CARD32 *) _pBuf); \
+    _pBuf += 4; \
+    if (_swap) \
+        _val = lswapl (_val); \
+}
+
+#else /* WORD64 */
+
+#define EXTRACT_CARD16(_pBuf, _swap, _val) \
+{ \
+    _val = *(_pBuf + 0) & 0xff;        /* 0xff incase _pBuf is signed */ \
+    _val <<= 8; \
+    _val |= *(_pBuf + 1) & 0xff;\
+    _pBuf += 2; \
+    if (_swap) \
+        _val = lswaps (_val); \
+}
+
+#define EXTRACT_CARD32(_pBuf, _swap, _val) \
+{ \
+    _val = *(_pBuf + 0) & 0xff;        /* 0xff incase _pBuf is signed */ \
+    _val <<= 8; \
+    _val |= *(_pBuf + 1) & 0xff;\
+    _val <<= 8; \
+    _val |= *(_pBuf + 2) & 0xff;\
+    _val <<= 8; \
+    _val |= *(_pBuf + 3) & 0xff;\
+    _pBuf += 4; \
+    if (_swap) \
+        _val = lswapl (_val); \
+}
+
+#endif /* WORD64 */
+
+#define EXTRACT_STRING(_pBuf, _swap, _string) \
+{ \
+    CARD16 _len; \
+    EXTRACT_CARD16 (_pBuf, _swap, _len); \
+    _string = (char *) malloc (_len + 1); \
+    memcpy (_string, _pBuf, _len); \
+    _pBuf += _len; \
+    _string[_len] = '\0'; \
+    if (PAD32 (2 + _len)) \
+        _pBuf += PAD32 (2 + _len); \
+}
+
+#define EXTRACT_LISTOF_STRING(_pBuf, _swap, _count, _strings) \
+{ \
+    int _i; \
+    for (_i = 0; _i < _count; _i++) \
+        EXTRACT_STRING (_pBuf, _swap, _strings[_i]); \
+}
+
+
+#define SKIP_STRING(_pBuf, _swap, _end, _bail) \
+{ \
+    CARD16 _len; \
+    EXTRACT_CARD16 (_pBuf, _swap, _len); \
+    _pBuf += _len + PAD32(2+_len); \
+    if (_pBuf > _end) { \
+       _bail; \
+    } \
+} 
+
+#define SKIP_LISTOF_STRING(_pBuf, _swap, _count, _end, _bail) \
+{ \
+    int _i; \
+    for (_i = 0; _i < _count; _i++) \
+        SKIP_STRING (_pBuf, _swap, _end, _bail); \
+}
+
+
+\f
+/*
+ * Byte swapping
+ */
+
+/* byte swap a long literal */
+#define lswapl(_val) ((((_val) & 0xff) << 24) |\
+                  (((_val) & 0xff00) << 8) |\
+                  (((_val) & 0xff0000) >> 8) |\
+                  (((_val) >> 24) & 0xff))
+
+/* byte swap a short literal */
+#define lswaps(_val) ((((_val) & 0xff) << 8) | (((_val) >> 8) & 0xff))
+
+
+\f
+/*
+ * ICE replies (not processed via callbacks because we block)
+ */
+
+#define ICE_CONNECTION_REPLY   1
+#define ICE_CONNECTION_ERROR   2
+#define ICE_PROTOCOL_REPLY     3
+#define ICE_PROTOCOL_ERROR     4
+
+typedef struct {
+    int                  type;
+    int          version_index;
+    char         *vendor;
+    char          *release;
+} _IceConnectionReply;
+
+typedef struct {
+    int                  type;
+    char         *error_message;
+} _IceConnectionError;
+
+typedef struct {
+    int                  type;
+    int          major_opcode;
+    int                  version_index;
+    char         *vendor;
+    char         *release;
+} _IceProtocolReply;
+
+typedef struct {
+    int                  type;
+    char         *error_message;
+} _IceProtocolError;
+
+
+typedef union {
+    int                        type;
+    _IceConnectionReply        connection_reply;
+    _IceConnectionError        connection_error;
+    _IceProtocolReply  protocol_reply;
+    _IceProtocolError  protocol_error;
+} _IceReply;
+
+
+/*
+ * Watch for ICE connection create/destroy.
+ */
+
+typedef struct _IceWatchedConnection {
+    IceConn                            iceConn;
+    IcePointer                         watch_data;
+    struct _IceWatchedConnection       *next;
+} _IceWatchedConnection;
+
+typedef struct _IceWatchProc {
+    IceWatchProc               watch_proc;
+    IcePointer                 client_data;
+    _IceWatchedConnection      *watched_connections;
+    struct _IceWatchProc       *next;
+} _IceWatchProc;
+
+
+/*
+ * Locking
+ */
+
+#define IceLockConn(_iceConn)
+#define IceUnlockConn(_iceConn)
+
+
+/*
+ * Extern declarations
+ */
+
+extern IceConn         _IceConnectionObjs[];
+extern char            *_IceConnectionStrings[];
+extern int                     _IceConnectionCount;
+
+extern _IceProtocol    _IceProtocols[];
+extern int             _IceLastMajorOpcode;
+
+extern int             _IceAuthCount;
+extern char            *_IceAuthNames[];
+extern IcePoAuthProc   _IcePoAuthProcs[];
+extern IcePaAuthProc   _IcePaAuthProcs[];
+
+extern int             _IceVersionCount;
+extern _IceVersion     _IceVersions[];
+
+extern _IceWatchProc   *_IceWatchProcs;
+
+extern IceErrorHandler   _IceErrorHandler;
+extern IceIOErrorHandler _IceIOErrorHandler;
+
+extern IceAuthDataEntry         _IcePaAuthDataEntries[];
+extern int              _IcePaAuthDataEntryCount;
+
+extern void _IceErrorBadMajor (
+    IceConn            /* iceConn */,
+    int                        /* offendingMajor */,
+    int                        /* offendingMinor */,
+    int                        /* severity */
+);
+
+extern void _IceErrorNoAuthentication (
+    IceConn            /* iceConn */,
+    int                        /* offendingMinor */
+);
+
+extern void _IceErrorNoVersion (
+    IceConn            /* iceConn */,
+    int                        /* offendingMinor */
+);
+
+extern void _IceErrorSetupFailed (
+    IceConn            /* iceConn */,
+    int                        /* offendingMinor */,
+    char *             /* reason */
+);
+
+extern void _IceErrorAuthenticationRejected (
+    IceConn            /* iceConn */,
+    int                        /* offendingMinor */,
+    char *             /* reason */
+);
+
+extern void _IceErrorAuthenticationFailed (
+    IceConn            /* iceConn */,
+    int                        /* offendingMinor */,
+    char *             /* reason */
+);
+
+extern void _IceErrorProtocolDuplicate (
+    IceConn            /* iceConn */,
+    char *             /* protocolName */
+);
+
+extern void _IceErrorMajorOpcodeDuplicate (
+    IceConn            /* iceConn */,
+    int                        /* majorOpcode */
+);
+
+extern void _IceErrorUnknownProtocol (
+    IceConn            /* iceConn */,
+    char *             /* protocolName */
+);
+
+extern void _IceAddOpcodeMapping (
+    IceConn            /* iceConn */,
+    int                        /* hisOpcode */,
+    int                        /* myOpcode */
+);
+
+extern char *_IceGetPeerName (
+    IceConn            /* iceConn */
+);
+
+extern void _IceFreeConnection (
+    IceConn            /* iceConn */
+);
+
+extern void _IceAddReplyWait (
+    IceConn            /* iceConn */,
+    IceReplyWaitInfo * /* replyWait */
+);
+
+extern IceReplyWaitInfo *_IceSearchReplyWaits (
+    IceConn            /* iceConn */,
+    int                        /* majorOpcode */
+);
+
+extern void _IceSetReplyReady (
+    IceConn            /* iceConn */,
+    IceReplyWaitInfo * /* replyWait */
+);
+
+extern Bool _IceCheckReplyReady (
+    IceConn            /* iceConn */,
+    IceReplyWaitInfo * /* replyWait */
+);
+
+extern void _IceConnectionOpened (
+    IceConn            /* iceConn */
+);
+
+extern void _IceConnectionClosed (
+    IceConn            /* iceConn */
+);
+
+extern void _IceGetPoAuthData (
+    char *             /* protocol_name */,
+    char *             /* address */,
+    char *             /* auth_name */,
+    unsigned short *   /* auth_data_length_ret */,
+    char **            /* auth_data_ret */
+);
+
+extern void _IceGetPaAuthData (
+    char *             /* protocol_name */,
+    char *             /* address */,
+    char *             /* auth_name */,
+    unsigned short *   /* auth_data_length_ret */,
+    char **            /* auth_data_ret */
+);
+
+extern void _IceGetPoValidAuthIndices (
+    char *             /* protocol_name */,
+    char *             /* address */,
+    int                        /* num_auth_names */,
+    char **            /* auth_names */,
+    int        *               /* num_indices_ret */,
+    int        *               /* indices_ret */
+);
+
+extern void _IceGetPaValidAuthIndices (
+    char *             /* protocol_name */,
+    char *             /* address */,
+    int                        /* num_auth_names */,
+    char **            /* auth_names */,
+    int        *               /* num_indices_ret */,
+    int        *               /* indices_ret */
+);
+
+#endif /* _ICELIBINT_H_ */
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100755 (executable)
index 0000000..a5dd7d4
--- /dev/null
@@ -0,0 +1,53 @@
+lib_LTLIBRARIES=libICE.la
+
+AM_CPPFLAGS = -I${top_srcdir}/include
+
+AM_CFLAGS = \
+       $(ICE_CFLAGS) \
+       $(XTRANS_CFLAGS) \
+       $(CWARNFLAGS) \
+       -DICE_t -DTRANS_CLIENT -DTRANS_SERVER
+
+libICE_la_LDFLAGS = -version-number 6:3:0 -no-undefined
+
+libICE_la_LIBADD = $(ICE_LIBS) $(XTRANS_LIBS)
+
+libICE_la_SOURCES = \
+       ICElibint.h \
+       accept.c \
+       authutil.c \
+       connect.c \
+       error.c \
+       getauth.c \
+       globals.h \
+       iceauth.c \
+       icetrans.c \
+       listen.c \
+       listenwk.c \
+       locking.c \
+       misc.c \
+       ping.c \
+       process.c \
+       protosetup.c \
+       register.c \
+       replywait.c \
+       setauth.c \
+       shutdown.c \
+       watch.c
+
+iceincludedir=$(includedir)/X11/ICE
+iceinclude_HEADERS=\
+       $(top_srcdir)/include/X11/ICE/ICE.h \
+       $(top_srcdir)/include/X11/ICE/ICEconn.h \
+       $(top_srcdir)/include/X11/ICE/ICElib.h \
+       $(top_srcdir)/include/X11/ICE/ICEmsg.h \
+       $(top_srcdir)/include/X11/ICE/ICEproto.h \
+       $(top_srcdir)/include/X11/ICE/ICEutil.h
+
+if LINT
+ALL_LINT_FLAGS=$(LINT_FLAGS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+               $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS)
+
+lint:
+       $(LINT) $(ALL_LINT_FLAGS) $(libICE_la_SOURCES) $(XINERAMA_LIBS)
+endif LINT
diff --git a/src/accept.c b/src/accept.c
new file mode 100755 (executable)
index 0000000..6bc40ad
--- /dev/null
@@ -0,0 +1,183 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+#include <X11/Xtrans/Xtrans.h>
+
+
+IceConn
+IceAcceptConnection (
+       IceListenObj    listenObj,
+       IceAcceptStatus *statusRet
+)
+{
+    IceConn                    iceConn;
+    XtransConnInfo     newconn;
+    iceByteOrderMsg    *pMsg;
+    int                endian, status;
+
+    /*
+     * Accept the connection.
+     */
+
+    if ((newconn = _IceTransAccept (listenObj->trans_conn, &status)) == NULL)
+    {
+       if (status == TRANS_ACCEPT_BAD_MALLOC)
+           *statusRet = IceAcceptBadMalloc;
+       else
+           *statusRet = IceAcceptFailure;
+       return (NULL);
+    }
+
+
+    /*
+     * Set close-on-exec so that programs that fork() don't get confused.
+     */
+
+    _IceTransSetOption (newconn, TRANS_CLOSEONEXEC, 1);
+
+
+    /*
+     * Create an ICE object for this connection.
+     */
+
+    if ((iceConn = (IceConn) malloc (sizeof (struct _IceConn))) == NULL)
+    {
+       _IceTransClose (newconn);
+       *statusRet = IceAcceptBadMalloc;
+       return (NULL);
+    }
+
+    iceConn->listen_obj = listenObj;
+
+    iceConn->waiting_for_byteorder = True;
+    iceConn->connection_status = IceConnectPending;
+    iceConn->io_ok = True;
+    iceConn->dispatch_level = 0;
+    iceConn->context = NULL;
+    iceConn->my_ice_version_index = 0;
+
+    iceConn->trans_conn = newconn;
+    iceConn->send_sequence = 0;
+    iceConn->receive_sequence = 0;
+
+    iceConn->connection_string = strdup(listenObj->network_id);
+
+    if (iceConn->connection_string == NULL)
+    {
+       _IceTransClose (newconn);
+       free ((char *) iceConn);
+       *statusRet = IceAcceptBadMalloc;
+       return (NULL);
+    }
+
+    iceConn->vendor = NULL;
+    iceConn->release = NULL;
+
+    if ((iceConn->inbuf = iceConn->inbufptr =
+       (char *) malloc (ICE_INBUFSIZE)) != NULL)
+    {
+       iceConn->inbufmax = iceConn->inbuf + ICE_INBUFSIZE;
+    }
+    else
+    {
+       _IceTransClose (newconn);
+       free ((char *) iceConn);
+       *statusRet = IceAcceptBadMalloc;
+       return (NULL);
+    }
+
+    if ((iceConn->outbuf = iceConn->outbufptr =
+       (char *) malloc (ICE_OUTBUFSIZE)) != NULL)
+    {
+       iceConn->outbufmax = iceConn->outbuf + ICE_OUTBUFSIZE;
+    }
+    else
+    {
+       _IceTransClose (newconn);
+       free (iceConn->inbuf);
+       free ((char *) iceConn);
+       *statusRet = IceAcceptBadMalloc;
+       return (NULL);
+    }
+
+    iceConn->scratch = NULL;
+    iceConn->scratch_size = 0;
+
+    iceConn->open_ref_count = 1;
+    iceConn->proto_ref_count = 0;
+
+    iceConn->skip_want_to_close = False;
+    iceConn->want_to_close = False;
+    iceConn->free_asap = False;
+
+    iceConn->saved_reply_waits = NULL;
+    iceConn->ping_waits = NULL;
+
+    iceConn->process_msg_info = NULL;
+
+    iceConn->connect_to_you = NULL;
+    iceConn->protosetup_to_you = NULL;
+
+    iceConn->connect_to_me = NULL;
+    iceConn->protosetup_to_me = NULL;
+
+
+    /*
+     * Send our byte order.
+     */
+
+    IceGetHeader (iceConn, 0, ICE_ByteOrder,
+       SIZEOF (iceByteOrderMsg), iceByteOrderMsg, pMsg);
+
+    endian = 1;
+    if (*(char *) &endian)
+       pMsg->byteOrder = IceLSBfirst;
+    else
+       pMsg->byteOrder = IceMSBfirst;
+
+    IceFlush (iceConn);
+
+
+    if (_IceWatchProcs)
+    {
+       /*
+        * Notify the watch procedures that an iceConn was opened.
+        */
+
+       _IceConnectionOpened (iceConn);
+    }
+
+    *statusRet = IceAcceptSuccess;
+
+    return (iceConn);
+}
diff --git a/src/authutil.c b/src/authutil.c
new file mode 100755 (executable)
index 0000000..fd0a77d
--- /dev/null
@@ -0,0 +1,504 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+#include <X11/ICE/ICEutil.h>
+#include <X11/Xos.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#include <time.h>
+#define Time_t time_t
+#ifdef __UNIXOS2__
+extern char* getenv(const char*);
+#define link rename
+#endif
+#ifndef X_NOT_POSIX
+#include <unistd.h>
+#else
+#ifndef WIN32
+extern unsigned        sleep ();
+#else
+#define link rename
+#endif
+#endif
+
+static Status read_short (FILE *file, unsigned short *shortp);
+static Status read_string (FILE *file, char **stringp);
+static Status read_counted_string (FILE *file, unsigned short *countp, char **stringp);
+static Status write_short (FILE *file, unsigned short s);
+static Status write_string (FILE *file, char *string);
+static Status write_counted_string (FILE *file, unsigned short count, char *string);
+
+
+\f
+/*
+ * The following routines are for manipulating the .ICEauthority file
+ * These are utility functions - they are not part of the standard
+ * ICE library specification.
+ */
+
+char *
+IceAuthFileName (void)
+{
+    static char slashDotICEauthority[] = "/.ICEauthority";
+    char       *name;
+    static char        *buf;
+    static int bsize;
+    int                size;
+#if defined(WIN32) || defined(__UNIXOS2__)
+#ifndef PATH_MAX
+#define PATH_MAX 512
+#endif
+    char       dir[PATH_MAX];
+#endif
+
+    if ((name = getenv ("ICEAUTHORITY")))
+       return (name);
+
+    name = getenv ("HOME");
+
+    if (!name)
+    {
+#ifdef WIN32
+    register char *ptr1;
+    register char *ptr2;
+    int len1 = 0, len2 = 0;
+
+    if ((ptr1 = getenv("HOMEDRIVE")) && (ptr2 = getenv("HOMEDIR"))) {
+       len1 = strlen (ptr1);
+       len2 = strlen (ptr2);
+    } else if ((ptr2 = getenv("USERNAME"))) {
+       len1 = strlen (ptr1 = "/users/");
+       len2 = strlen (ptr2);
+    }
+    if ((len1 + len2 + 1) < PATH_MAX) {
+       sprintf (dir, "%s%s", ptr1, (ptr2) ? ptr2 : "");
+       name = dir;
+    }
+    if (!name)
+#endif
+#ifdef __UNIXOS2__
+       strcpy (dir,"c:");
+       name = dir;
+       if (!name)
+#endif
+       return (NULL);
+    }
+
+    size = strlen (name) + strlen (&slashDotICEauthority[1]) + 2;
+
+    if (size > bsize)
+    {
+       if (buf)
+           free (buf);
+       buf = malloc ((unsigned) size);
+       if (!buf)
+           return (NULL);
+       bsize = size;
+    }
+
+    strcpy (buf, name);
+    strcat (buf, slashDotICEauthority + (name[1] == '\0' ? 1 : 0));
+
+    return (buf);
+}
+
+
+\f
+int
+IceLockAuthFile (
+       char    *file_name,
+       int     retries,
+       int     timeout,
+       long    dead
+)
+{
+    char       creat_name[1025], link_name[1025];
+    struct stat        statb;
+    Time_t     now;
+    int                creat_fd = -1;
+
+    if ((int) strlen (file_name) > 1022)
+       return (IceAuthLockError);
+
+    strcpy (creat_name, file_name);
+    strcat (creat_name, "-c");
+    strcpy (link_name, file_name);
+    strcat (link_name, "-l");
+
+    if (stat (creat_name, &statb) != -1)
+    {
+       now = time ((Time_t *) 0);
+
+       /*
+        * NFS may cause ctime to be before now, special
+        * case a 0 deadtime to force lock removal
+        */
+
+       if (dead == 0 || now - statb.st_ctime > dead)
+       {
+           unlink (creat_name);
+           unlink (link_name);
+       }
+    }
+    
+    while (retries > 0)
+    {
+       if (creat_fd == -1)
+       {
+           creat_fd = creat (creat_name, 0666);
+
+           if (creat_fd == -1)
+           {
+               if (errno != EACCES)
+                   return (IceAuthLockError);
+           }
+           else
+               close (creat_fd);
+       }
+
+       if (creat_fd != -1)
+       {
+           if (link (creat_name, link_name) != -1)
+               return (IceAuthLockSuccess);
+
+           if (errno == ENOENT)
+           {
+               creat_fd = -1;  /* force re-creat next time around */
+               continue;
+           }
+
+           if (errno != EEXIST)
+               return (IceAuthLockError);
+       }
+
+       sleep ((unsigned) timeout);
+       --retries;
+    }
+
+    return (IceAuthLockTimeout);
+}
+
+
+\f
+void
+IceUnlockAuthFile (
+       char    *file_name
+)
+{
+#ifndef WIN32
+    char       creat_name[1025];
+#endif
+    char       link_name[1025];
+
+    if ((int) strlen (file_name) > 1022)
+       return;
+
+#ifndef WIN32
+    strcpy (creat_name, file_name);
+    strcat (creat_name, "-c");
+#endif
+    strcpy (link_name, file_name);
+    strcat (link_name, "-l");
+
+#ifndef WIN32
+    unlink (creat_name);
+#endif
+    unlink (link_name);
+}
+
+
+\f
+IceAuthFileEntry *
+IceReadAuthFileEntry (
+       FILE    *auth_file
+)
+{
+    IceAuthFileEntry           local;
+    IceAuthFileEntry           *ret;
+
+    local.protocol_name = NULL;
+    local.protocol_data = NULL;
+    local.network_id = NULL;
+    local.auth_name = NULL;
+    local.auth_data = NULL;
+
+    if (!read_string (auth_file, &local.protocol_name))
+       return (NULL);
+
+    if (!read_counted_string (auth_file,
+       &local.protocol_data_length, &local.protocol_data))
+       goto bad;
+
+    if (!read_string (auth_file, &local.network_id))
+       goto bad;
+
+    if (!read_string (auth_file, &local.auth_name))
+       goto bad;
+
+    if (!read_counted_string (auth_file,
+       &local.auth_data_length, &local.auth_data))
+       goto bad;
+
+    if (!(ret = (IceAuthFileEntry *) malloc (sizeof (IceAuthFileEntry))))
+       goto bad;
+
+    *ret = local;
+
+    return (ret);
+
+ bad:
+
+    if (local.protocol_name) free (local.protocol_name);
+    if (local.protocol_data) free (local.protocol_data);
+    if (local.network_id) free (local.network_id);
+    if (local.auth_name) free (local.auth_name);
+    if (local.auth_data) free (local.auth_data);
+
+    return (NULL);
+}
+
+
+\f
+void
+IceFreeAuthFileEntry (
+       IceAuthFileEntry        *auth
+)
+{
+    if (auth)
+    {
+       if (auth->protocol_name) free (auth->protocol_name);
+       if (auth->protocol_data) free (auth->protocol_data);
+       if (auth->network_id) free (auth->network_id);
+       if (auth->auth_name) free (auth->auth_name);
+       if (auth->auth_data) free (auth->auth_data);
+       free ((char *) auth);
+    }
+}
+
+
+\f
+Status
+IceWriteAuthFileEntry (
+       FILE                    *auth_file,
+       IceAuthFileEntry        *auth
+)
+{
+    if (!write_string (auth_file, auth->protocol_name))
+       return (0);
+
+    if (!write_counted_string (auth_file,
+       auth->protocol_data_length, auth->protocol_data))
+       return (0);
+
+    if (!write_string (auth_file, auth->network_id))
+       return (0);
+
+    if (!write_string (auth_file, auth->auth_name))
+       return (0);
+
+    if (!write_counted_string (auth_file,
+       auth->auth_data_length, auth->auth_data))
+       return (0);
+
+    return (1);
+}
+
+
+\f
+IceAuthFileEntry *
+IceGetAuthFileEntry (
+       char    *protocol_name,
+       char    *network_id,
+       char    *auth_name
+)
+{
+    FILE               *auth_file;
+    char               *filename;
+    IceAuthFileEntry    *entry;
+
+    if (!(filename = IceAuthFileName ()))
+       return (NULL);
+
+    if (access (filename, R_OK) != 0)          /* checks REAL id */
+       return (NULL);
+
+    if (!(auth_file = fopen (filename, "rb")))
+       return (NULL);
+
+    for (;;)
+    {
+       if (!(entry = IceReadAuthFileEntry (auth_file)))
+           break;
+
+       if (strcmp (protocol_name, entry->protocol_name) == 0 &&
+           strcmp (network_id, entry->network_id) == 0 &&
+            strcmp (auth_name, entry->auth_name) == 0)
+       {
+           break;
+       }
+
+       IceFreeAuthFileEntry (entry);
+    }
+
+    fclose (auth_file);
+
+    return (entry);
+}
+
+
+\f
+/*
+ * local routines
+ */
+
+static Status
+read_short (FILE *file, unsigned short *shortp)
+{
+    unsigned char   file_short[2];
+
+    if (fread ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
+       return (0);
+
+    *shortp = file_short[0] * 256 + file_short[1];
+    return (1);
+}
+
+
+static Status
+read_string (FILE *file, char **stringp)
+
+{
+    unsigned short  len;
+    char           *data;
+
+    if (!read_short (file, &len))
+       return (0);
+
+    data = malloc ((unsigned) len + 1);
+    
+    if (!data)
+           return (0);
+    
+    if (len != 0) 
+    {
+       if (fread (data, (int) sizeof (char), (int) len, file) != len)
+       {
+           free (data);
+           return (0);
+       }
+       
+    }
+    data[len] = '\0';
+
+    *stringp = data;
+
+    return (1);
+}
+
+
+static Status
+read_counted_string (FILE *file, unsigned short        *countp, char **stringp)
+{
+    unsigned short  len;
+    char           *data;
+
+    if (!read_short (file, &len))
+       return (0);
+
+    if (len == 0)
+    {
+       data = NULL;
+    }
+    else
+    {
+       data = malloc ((unsigned) len);
+
+       if (!data)
+           return (0);
+
+       if (fread (data, (int) sizeof (char), (int) len, file) != len)
+       {
+           free (data);
+           return (0);
+       }
+    }
+
+    *stringp = data;
+    *countp = len;
+
+    return (1);
+}
+
+
+static Status
+write_short (FILE *file, unsigned short s)
+{
+    unsigned char   file_short[2];
+
+    file_short[0] = (s & (unsigned) 0xff00) >> 8;
+    file_short[1] = s & 0xff;
+
+    if (fwrite ((char *) file_short, (int) sizeof (file_short), 1, file) != 1)
+       return (0);
+
+    return (1);
+}
+
+
+static Status
+write_string (FILE *file, char *string)
+{
+    unsigned short count = strlen (string);
+
+    if (!write_short (file, count))
+       return (0);
+
+    if (fwrite (string, (int) sizeof (char), (int) count, file) != count)
+       return (0);
+
+    return (1);
+}
+
+
+static Status
+write_counted_string (FILE *file, unsigned short count, char *string)
+{
+    if (!write_short (file, count))
+       return (0);
+
+    if (fwrite (string, (int) sizeof (char), (int) count, file) != count)
+       return (0);
+
+    return (1);
+}
diff --git a/src/connect.c b/src/connect.c
new file mode 100755 (executable)
index 0000000..2542a0c
--- /dev/null
@@ -0,0 +1,533 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+#include <X11/Xtrans/Xtrans.h>
+#include "globals.h"
+
+static XtransConnInfo ConnectToPeer(char *networkIdsList,
+                                   char **actualConnectionRet);
+
+#define Strstr strstr
+\f
+IceConn
+IceOpenConnection (
+       char       *networkIdsList,
+       IcePointer context,
+       Bool       mustAuthenticate,
+       int        majorOpcodeCheck,
+       int        errorLength,
+       char       *errorStringRet
+)
+{
+    IceConn                    iceConn;
+    int                                extra, i, j;
+    int                                endian;
+    Bool                       gotReply, ioErrorOccured;
+    unsigned long              setup_sequence;
+    iceByteOrderMsg            *pByteOrderMsg;
+    iceConnectionSetupMsg      *pSetupMsg;
+    char                       *pData;
+    IceReplyWaitInfo           replyWait;
+    _IceReply                  reply;
+    int                                authUsableCount;
+    int                                authUsableFlags[MAX_ICE_AUTH_NAMES];
+    int                                authIndices[MAX_ICE_AUTH_NAMES];
+
+    if (errorStringRet && errorLength > 0)
+       *errorStringRet = '\0';
+
+    if (networkIdsList == NULL || *networkIdsList == '\0')
+    {
+       strncpy (errorStringRet,
+           "networkIdsList argument is NULL", errorLength);
+       return (NULL);
+    }
+
+    /*
+     * Check to see if we can use a previously created ICE connection.
+     *
+     * If iceConn->want_to_close is True, or iceConn->free_asap is True,
+     * we can not use the iceConn.
+     *
+     * If 'context' is non-NULL, we will only use a previously opened ICE
+     * connection if the specified 'context' is equal to the context
+     * associated with the ICE connection, or if the context associated
+     * with the ICE connection is NULL.
+     * 
+     * If 'majorOpcodeCheck' is non-zero, it will contain a protocol major
+     * opcode that we should make sure is not already active on the ICE
+     * connection.  Some clients will want two seperate connections for the
+     * same protocol to the same destination client.
+     */
+
+    for (i = 0; i < _IceConnectionCount; i++)
+    {
+       char *strptr;
+       if ((strptr = (char *) Strstr (
+           networkIdsList, _IceConnectionStrings[i])) != NULL)
+       {
+           char ch = *(strptr + strlen (_IceConnectionStrings[i]));
+           if (ch == ',' || ch == '\0')
+           {
+               /*
+                * OK, we found a connection.  Make sure we can reuse it.
+                */
+
+               IceConn iceConn = _IceConnectionObjs[i];
+
+               if (iceConn->want_to_close || iceConn->free_asap ||
+                   (context && iceConn->context &&
+                    iceConn->context != context))
+               {
+                   /* force a new connection to be created */
+                   break;
+               }
+
+               if (majorOpcodeCheck)
+               {
+                   for (j = iceConn->his_min_opcode;
+                       j <= iceConn->his_max_opcode; j++)
+                   {
+                       if (iceConn->process_msg_info[
+                           j - iceConn->his_min_opcode].in_use &&
+                           iceConn->process_msg_info[
+                           j - iceConn->his_min_opcode].my_opcode ==
+                           majorOpcodeCheck)
+                           break;
+                   }
+
+                   if (j <= iceConn->his_max_opcode ||
+                       (iceConn->protosetup_to_you &&
+                       iceConn->protosetup_to_you->my_opcode ==
+                       majorOpcodeCheck))
+                   {
+                       /* force a new connection to be created */
+                       break;
+                   }
+               }
+
+               iceConn->open_ref_count++;
+               if (context && !iceConn->context)
+                   iceConn->context = context;
+               return (iceConn);
+           }
+       }
+    }
+
+    if ((iceConn = (IceConn) malloc (sizeof (struct _IceConn))) == NULL)
+    {
+       strncpy (errorStringRet, "Can't malloc", errorLength);
+       return (NULL);
+    }
+
+
+    /*
+     * Open a network connection with the peer client.
+     */
+
+    if ((iceConn->trans_conn = ConnectToPeer (networkIdsList,
+       &iceConn->connection_string)) == NULL)
+    {
+       free ((char *) iceConn);
+       strncpy (errorStringRet, "Could not open network socket", errorLength);
+       return (NULL);
+    }
+
+    /*
+     * Set close-on-exec so that programs that fork() don't get confused.
+     */
+
+    _IceTransSetOption (iceConn->trans_conn, TRANS_CLOSEONEXEC, 1);
+
+    iceConn->listen_obj = NULL;
+
+    iceConn->connection_status = IceConnectPending;
+    iceConn->io_ok = True;
+    iceConn->dispatch_level = 0;
+    iceConn->context = context;
+    iceConn->my_ice_version_index = 0;
+    iceConn->send_sequence = 0;
+    iceConn->receive_sequence = 0;
+
+    iceConn->vendor = NULL;
+    iceConn->release = NULL;
+    iceConn->outbuf = NULL;
+
+    iceConn->scratch = NULL;
+    iceConn->scratch_size = 0;
+
+    iceConn->process_msg_info = NULL;
+
+    iceConn->connect_to_you = NULL;
+    iceConn->protosetup_to_you = NULL;
+
+    iceConn->connect_to_me = NULL;
+    iceConn->protosetup_to_me = NULL;
+
+    if ((iceConn->inbuf = iceConn->inbufptr =
+       (char *) malloc (ICE_INBUFSIZE)) == NULL)
+    {
+       _IceFreeConnection (iceConn);
+       strncpy (errorStringRet, "Can't malloc", errorLength);
+       return (NULL);
+    }
+
+    iceConn->inbufmax = iceConn->inbuf + ICE_INBUFSIZE;
+
+    if ((iceConn->outbuf = iceConn->outbufptr =
+       (char *) calloc (1, ICE_OUTBUFSIZE)) == NULL)
+    {
+       _IceFreeConnection (iceConn);
+       strncpy (errorStringRet, "Can't malloc", errorLength);
+       return (NULL);
+    }
+
+    iceConn->outbufmax = iceConn->outbuf + ICE_OUTBUFSIZE;
+
+    iceConn->open_ref_count = 1;
+    iceConn->proto_ref_count = 0;
+
+    iceConn->skip_want_to_close = False;
+    iceConn->want_to_close = False;
+    iceConn->free_asap = False;
+
+    iceConn->saved_reply_waits = NULL;
+    iceConn->ping_waits = NULL;
+
+    iceConn->connect_to_you = (_IceConnectToYouInfo *) malloc (
+       sizeof (_IceConnectToYouInfo));
+    iceConn->connect_to_you->auth_active = 0;
+
+    /*
+     * Send our byte order.
+     */
+
+    IceGetHeader (iceConn, 0, ICE_ByteOrder,
+       SIZEOF (iceByteOrderMsg), iceByteOrderMsg, pByteOrderMsg);
+
+    endian = 1;
+    if (*(char *) &endian)
+       pByteOrderMsg->byteOrder = IceLSBfirst;
+    else
+       pByteOrderMsg->byteOrder = IceMSBfirst;
+
+    IceFlush (iceConn);
+
+
+    /*
+     * Now read the ByteOrder message from the other client.
+     * iceConn->swap should be set to the appropriate boolean
+     * value after the call to IceProcessMessages.
+     */
+
+    iceConn->waiting_for_byteorder = True;
+
+    ioErrorOccured = False;
+    while (iceConn->waiting_for_byteorder == True && !ioErrorOccured)
+    {
+       ioErrorOccured = (IceProcessMessages (
+           iceConn, NULL, NULL) == IceProcessMessagesIOError);
+    }
+
+    if (ioErrorOccured)
+    {
+       _IceFreeConnection (iceConn);
+       strncpy (errorStringRet, "IO error occured opening connection",
+            errorLength);
+       return (NULL);
+    }
+
+    if (iceConn->connection_status == IceConnectRejected)
+    {
+       /*
+        * We failed to get the required ByteOrder message.
+        */
+
+       _IceFreeConnection (iceConn);
+       strncpy (errorStringRet,
+           "Internal error - did not receive the expected ByteOrder message",
+            errorLength);
+       return (NULL);
+    }
+
+
+    /*
+     * Determine which authentication methods are available for
+     * the Connection Setup authentication.
+     */
+
+    _IceGetPoValidAuthIndices (
+       "ICE", iceConn->connection_string,
+       _IceAuthCount, _IceAuthNames, &authUsableCount, authIndices);
+
+    for (i = 0; i < _IceAuthCount; i++)
+    {
+       authUsableFlags[i] = 0;
+       for (j = 0; j < authUsableCount && !authUsableFlags[i]; j++)
+           authUsableFlags[i] = (authIndices[j] == i);
+    }
+
+
+    /*
+     * Now send a Connection Setup message.
+     */
+
+    extra = STRING_BYTES (IceVendorString) + STRING_BYTES (IceReleaseString);
+
+    for (i = 0; i < _IceAuthCount; i++)
+       if (authUsableFlags[i])
+       {
+           extra += STRING_BYTES (_IceAuthNames[i]);
+       }
+
+    extra += (_IceVersionCount * 4);
+
+    IceGetHeaderExtra (iceConn, 0, ICE_ConnectionSetup,
+       SIZEOF (iceConnectionSetupMsg), WORD64COUNT (extra),
+       iceConnectionSetupMsg, pSetupMsg, pData);
+
+    setup_sequence = iceConn->send_sequence;
+
+    pSetupMsg->versionCount = _IceVersionCount;
+    pSetupMsg->authCount = authUsableCount;
+    pSetupMsg->mustAuthenticate = mustAuthenticate;
+
+    STORE_STRING (pData, IceVendorString);
+    STORE_STRING (pData, IceReleaseString);
+
+    for (i = 0; i < _IceAuthCount; i++)
+       if (authUsableFlags[i])
+       {
+           STORE_STRING (pData, _IceAuthNames[i]);
+       }
+
+    for (i = 0; i < _IceVersionCount; i++)
+    {
+       STORE_CARD16 (pData, _IceVersions[i].major_version);
+       STORE_CARD16 (pData, _IceVersions[i].minor_version);
+    }
+
+    IceFlush (iceConn);
+
+
+    /*
+     * Process messages until we get a Connection Reply or an Error Message.
+     * Authentication will take place behind the scenes.
+     */
+
+    replyWait.sequence_of_request = setup_sequence;
+    replyWait.major_opcode_of_request = 0;
+    replyWait.minor_opcode_of_request = ICE_ConnectionSetup;
+    replyWait.reply = (IcePointer) &reply;
+
+    gotReply = False;
+    ioErrorOccured = False;
+
+    while (!gotReply && !ioErrorOccured)
+    {
+       ioErrorOccured = (IceProcessMessages (
+           iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError);
+
+       if (ioErrorOccured)
+       {
+           strncpy (errorStringRet, "IO error occured opening connection",
+               errorLength);
+           _IceFreeConnection (iceConn);
+           iceConn = NULL;
+       }
+       else if (gotReply)
+       {
+           if (reply.type == ICE_CONNECTION_REPLY)
+           {
+               if (reply.connection_reply.version_index >= _IceVersionCount)
+               {
+                   strncpy (errorStringRet,
+                       "Got a bad version index in the Connection Reply",
+                       errorLength);
+
+                   free (reply.connection_reply.vendor);
+                   free (reply.connection_reply.release);
+                   _IceFreeConnection (iceConn);
+                   iceConn = NULL;
+               }
+               else
+               {
+                   iceConn->my_ice_version_index =
+                       reply.connection_reply.version_index;
+                   iceConn->vendor = reply.connection_reply.vendor;
+                   iceConn->release = reply.connection_reply.release;
+
+                   _IceConnectionObjs[_IceConnectionCount] = iceConn;
+                   _IceConnectionStrings[_IceConnectionCount] =
+                       iceConn->connection_string;
+                   _IceConnectionCount++;
+
+                   free ((char *) iceConn->connect_to_you);
+                   iceConn->connect_to_you = NULL;
+
+                   iceConn->connection_status = IceConnectAccepted;
+               }
+           }
+           else /* reply.type == ICE_CONNECTION_ERROR */
+           {
+               /* Connection failed */
+
+               strncpy (errorStringRet, reply.connection_error.error_message,
+                   errorLength);
+
+               free (reply.connection_error.error_message);
+
+               _IceFreeConnection (iceConn);
+               iceConn = NULL;
+           }
+       }
+    }
+
+    if (iceConn && _IceWatchProcs)
+    {
+       /*
+        * Notify the watch procedures that an iceConn was opened.
+        */
+
+       _IceConnectionOpened (iceConn);
+    }
+
+    return (iceConn);
+}
+
+
+\f
+IcePointer
+IceGetConnectionContext (
+       IceConn    iceConn
+)
+{
+    return (iceConn->context);
+}
+
+
+\f
+/* ------------------------------------------------------------------------- *
+ *                            local routines                                 *
+ * ------------------------------------------------------------------------- */
+
+#define ICE_CONNECTION_RETRIES 5
+
+
+static XtransConnInfo
+ConnectToPeer (char *networkIdsList, char **actualConnectionRet)
+{
+    char addrbuf[256];
+    char* address;
+    char *ptr, *endptr, *delim;
+    int  madeConnection = 0;
+    int  len, retry;
+    int  connect_stat;
+    int  address_size;
+    XtransConnInfo trans_conn = NULL;
+
+    *actualConnectionRet = NULL;
+
+    ptr = networkIdsList;
+    len = strlen (networkIdsList);
+    endptr = networkIdsList + len;
+
+    if (len < sizeof addrbuf)
+    {
+       address = addrbuf;
+       address_size = 256;
+    }
+    else
+    {
+       address = malloc (len + 1);
+       address_size = len;
+    }    
+
+    while (ptr < endptr && !madeConnection)
+    {
+       if ((delim = (char *) strchr (ptr, ',')) == NULL)
+           delim = endptr;
+
+       len = delim - ptr;
+       if (len > address_size - 1)
+           len = address_size - 1;
+       strncpy (address, ptr, len);
+       address[len] = '\0';
+
+       ptr = delim + 1;
+
+       for (retry = ICE_CONNECTION_RETRIES; retry >= 0; retry--)
+       {
+           if ((trans_conn = _IceTransOpenCOTSClient (address)) == NULL)
+           {
+               break;
+           }
+
+           if ((connect_stat = _IceTransConnect (trans_conn, address)) < 0)
+           {
+               _IceTransClose (trans_conn);
+
+               if (connect_stat == TRANS_TRY_CONNECT_AGAIN)
+               {
+                   sleep(1);
+                   continue;
+               }
+               else
+                   break;
+           }
+           else
+           {
+               madeConnection = 1;
+               break;
+           }
+       }
+    }
+
+    if (madeConnection) 
+    {
+       /*
+        * We need to return the actual network connection string
+        */
+
+       *actualConnectionRet = strdup(address);
+       
+       /*
+        * Return the file descriptor
+        */
+    } 
+    else trans_conn = NULL;
+
+    if (address != addrbuf) free (address);
+
+    return trans_conn;
+}
diff --git a/src/error.c b/src/error.c
new file mode 100755 (executable)
index 0000000..5c9aa51
--- /dev/null
@@ -0,0 +1,628 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+#include <stdio.h>
+
+#include <errno.h>
+
+
+void
+_IceErrorBadMinor (
+       IceConn iceConn,
+       int     majorOpcode,
+       int     offendingMinor,
+       int     severity
+)
+{
+    IceErrorHeader (iceConn,
+       majorOpcode, offendingMinor,
+       iceConn->receive_sequence,
+       severity,
+       IceBadMinor,
+       0);
+
+    IceFlush (iceConn);
+}
+
+
+void
+_IceErrorBadState (
+       IceConn iceConn,
+       int     majorOpcode,
+       int     offendingMinor,
+       int     severity
+)
+{
+    IceErrorHeader (iceConn,
+       majorOpcode, offendingMinor,
+       iceConn->receive_sequence,
+       severity,
+       IceBadState,
+       0);
+
+    IceFlush (iceConn);
+}
+
+
+void
+_IceErrorBadLength (
+       IceConn iceConn,
+       int     majorOpcode,
+       int     offendingMinor,
+       int     severity
+)
+{
+    IceErrorHeader (iceConn,
+       majorOpcode, offendingMinor,
+       iceConn->receive_sequence,
+       severity,
+       IceBadLength,
+       0);
+
+    IceFlush (iceConn);
+}
+
+
+void
+_IceErrorBadValue (
+       IceConn         iceConn,
+       int             majorOpcode,
+       int             offendingMinor,
+       int             offset,
+       int             length,         /* in bytes */
+       IcePointer      value
+)
+{
+    IceErrorHeader (iceConn,
+       majorOpcode, offendingMinor,
+       iceConn->receive_sequence,
+       IceCanContinue,
+       IceBadValue,
+       WORD64COUNT (8 + length));
+
+    IceWriteData32 (iceConn, 4, &offset);
+    IceWriteData32 (iceConn, 4, &length);
+    IceWriteData (iceConn, length, (char *) value);
+
+    if (PAD64 (length))
+       IceWritePad (iceConn, PAD64 (length));
+    
+    IceFlush (iceConn);
+}
+
+
+void
+_IceErrorNoAuthentication (
+       IceConn iceConn,
+       int     offendingMinor
+)
+{
+    int severity = (offendingMinor == ICE_ConnectionSetup) ?
+       IceFatalToConnection : IceFatalToProtocol;
+
+    IceErrorHeader (iceConn,
+       0, offendingMinor,
+       iceConn->receive_sequence,
+       severity,
+       IceNoAuth,
+       0);
+
+    IceFlush (iceConn);
+}
+
+
+void
+_IceErrorNoVersion (
+       IceConn iceConn,
+       int     offendingMinor
+)
+{
+    int severity = (offendingMinor == ICE_ConnectionSetup) ?
+       IceFatalToConnection : IceFatalToProtocol;
+
+    IceErrorHeader (iceConn,
+       0, offendingMinor,
+       iceConn->receive_sequence,
+       severity,
+       IceNoVersion,
+       0);
+
+    IceFlush (iceConn);
+}
+
+
+void
+_IceErrorSetupFailed (
+       IceConn iceConn,
+       int     offendingMinor,
+       char    *reason
+)
+{
+    char *pBuf, *pStart;
+    int bytes;
+    int severity = (offendingMinor == ICE_ConnectionSetup) ?
+       IceFatalToConnection : IceFatalToProtocol;
+
+    if (!reason)
+       reason = "";
+    bytes = STRING_BYTES (reason);
+
+    IceErrorHeader (iceConn,
+       0, offendingMinor,
+       iceConn->receive_sequence,
+       severity,
+       IceSetupFailed,
+       WORD64COUNT (bytes));
+
+    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
+    STORE_STRING (pBuf, reason);
+
+    IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
+    IceFlush (iceConn);
+}
+
+
+void
+_IceErrorAuthenticationRejected (
+       IceConn iceConn,
+       int     offendingMinor,
+       char    *reason
+)
+{
+    char *pBuf, *pStart;
+    int bytes;
+
+    if (!reason)
+       reason = "";
+    bytes = STRING_BYTES (reason);
+
+    IceErrorHeader (iceConn,
+       0, offendingMinor,
+       iceConn->receive_sequence,
+       IceFatalToProtocol,
+       IceAuthRejected,
+       WORD64COUNT (bytes));
+
+    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
+    STORE_STRING (pBuf, reason);
+
+    IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
+    IceFlush (iceConn);
+}
+
+
+void
+_IceErrorAuthenticationFailed (
+       IceConn iceConn,
+       int     offendingMinor,
+       char    *reason
+)
+{
+    char *pBuf, *pStart;
+    int bytes;
+
+    if (!reason)
+       reason = "";
+    bytes = STRING_BYTES (reason);
+
+    IceErrorHeader (iceConn,
+       0, offendingMinor,
+       iceConn->receive_sequence,
+       IceFatalToProtocol,
+       IceAuthFailed,
+       WORD64COUNT (bytes));
+
+    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
+    STORE_STRING (pBuf, reason);
+
+    IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
+    IceFlush (iceConn);
+}
+
+
+void
+_IceErrorProtocolDuplicate (
+       IceConn iceConn,
+       char    *protocolName
+)
+{
+    char *pBuf, *pStart;
+    int bytes;
+
+    if (!protocolName)
+       protocolName = "";
+    bytes = STRING_BYTES (protocolName);
+
+    IceErrorHeader (iceConn,
+       0, ICE_ProtocolSetup,
+       iceConn->receive_sequence,
+       IceFatalToProtocol,
+       IceProtocolDuplicate,
+       WORD64COUNT (bytes));
+
+    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
+    STORE_STRING (pBuf, protocolName);
+
+    IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
+    IceFlush (iceConn);
+}
+
+
+void
+_IceErrorMajorOpcodeDuplicate (
+       IceConn iceConn,
+       int     majorOpcode
+)
+{
+    char mOp = (char) majorOpcode;
+
+    IceErrorHeader (iceConn,
+       0, ICE_ProtocolSetup,
+       iceConn->receive_sequence,
+       IceFatalToProtocol,
+       IceMajorOpcodeDuplicate,
+       1 /* length */);
+
+    IceWriteData (iceConn, 8, &mOp);
+    IceFlush (iceConn);
+}
+
+
+void
+_IceErrorUnknownProtocol (
+       IceConn iceConn,
+       char    *protocolName
+)
+{
+    char *pBuf, *pStart;
+    int bytes;
+
+    if (!protocolName)
+       protocolName = "";
+    bytes = STRING_BYTES (protocolName);
+
+    IceErrorHeader (iceConn,
+       0, ICE_ProtocolSetup,
+       iceConn->receive_sequence,
+       IceFatalToProtocol,
+       IceUnknownProtocol,
+       WORD64COUNT (bytes));
+
+    pBuf = pStart = IceAllocScratch (iceConn, PADDED_BYTES64 (bytes));
+    STORE_STRING (pBuf, protocolName);
+
+    IceWriteData (iceConn, PADDED_BYTES64 (bytes), pStart);
+    IceFlush (iceConn);
+}
+
+
+void
+_IceErrorBadMajor (
+       IceConn iceConn,
+       int     offendingMajor,
+       int     offendingMinor,
+       int     severity
+)
+{
+    char maj = (char) offendingMajor;
+
+    IceErrorHeader (iceConn,
+       0, offendingMinor,
+       iceConn->receive_sequence,
+       severity,
+       IceBadMajor,
+       1 /* length */);
+
+    IceWriteData (iceConn, 8, &maj);
+    IceFlush (iceConn);
+}
+
+
+\f
+/*
+ * Default error handler.
+ */
+
+static void
+_IceDefaultErrorHandler (
+       IceConn         iceConn,
+       Bool            swap,
+       int             offendingMinorOpcode,
+       unsigned long   offendingSequence,
+       int             errorClass,
+       int             severity,
+       IcePointer      values
+)
+{
+    char *str;
+    char *pData = (char *) values;
+
+    switch (offendingMinorOpcode)
+    {
+        case ICE_ConnectionSetup:
+            str = "ConnectionSetup";
+           break;
+        case ICE_AuthRequired:
+            str = "AuthRequired";
+           break;
+        case ICE_AuthReply:
+            str = "AuthReply";
+           break;
+        case ICE_AuthNextPhase:
+            str = "AuthNextPhase";
+           break;
+        case ICE_ConnectionReply:
+            str = "ConnectionReply";
+           break;
+        case ICE_ProtocolSetup:
+            str = "ProtocolSetup";
+           break;
+        case ICE_ProtocolReply:
+            str = "ProtocolReply";
+           break;
+        case ICE_Ping:
+            str = "Ping";
+           break;
+        case ICE_PingReply:
+            str = "PingReply";
+           break;
+        case ICE_WantToClose:
+            str = "WantToClose";
+           break;
+        case ICE_NoClose:
+            str = "NoClose";
+           break;
+       default:
+           str = "";
+       }
+
+    fprintf (stderr, "\n");
+
+    fprintf (stderr, "ICE error:  Offending minor opcode    = %d (%s)\n",
+       offendingMinorOpcode, str);
+
+    fprintf (stderr, "            Offending sequence number = %lu\n",
+       offendingSequence);
+
+    switch (errorClass)
+    {
+        case IceBadMinor:
+            str = "BadMinor";
+            break;
+        case IceBadState:
+            str = "BadState";
+            break;
+        case IceBadLength:
+            str = "BadLength";
+            break;
+        case IceBadValue:
+            str = "BadValue";
+            break;
+        case IceBadMajor:
+            str = "BadMajor";
+            break;
+        case IceNoAuth:
+            str = "NoAuthentication";
+            break;
+        case IceNoVersion:
+            str = "NoVersion";
+            break;
+        case IceSetupFailed:
+            str = "SetupFailed";
+            break;
+        case IceAuthRejected:
+            str = "AuthenticationRejected";
+            break;
+        case IceAuthFailed:
+            str = "AuthenticationFailed";
+            break;
+        case IceProtocolDuplicate:
+            str = "ProtocolDuplicate";
+            break;
+        case IceMajorOpcodeDuplicate:
+            str = "MajorOpcodeDuplicate";
+            break;
+        case IceUnknownProtocol:
+            str = "UnknownProtocol";
+            break;
+       default:
+           str = "???";
+    }
+
+    fprintf (stderr, "            Error class               = %s\n", str);
+
+    if (severity == IceCanContinue)
+       str = "CanContinue";
+    else if (severity == IceFatalToProtocol)
+       str = "FatalToProtocol";
+    else if (severity == IceFatalToConnection)
+       str = "FatalToConnection";
+    else
+       str = "???";
+
+    fprintf (stderr, "            Severity                  = %s\n", str);
+
+    switch (errorClass)
+    {
+        case IceBadValue:
+        {
+           int offset, length, val;
+
+           EXTRACT_CARD32 (pData, swap, offset);
+           EXTRACT_CARD32 (pData, swap, length);
+
+           fprintf (stderr,
+               "            BadValue Offset           = %d\n", offset);
+           fprintf (stderr,
+               "            BadValue Length           = %d\n", length);
+
+           if (length <= 4)
+           {
+               if (length == 1)
+                   val = (int) *pData;
+               else if (length == 2)
+               {
+                   EXTRACT_CARD16 (pData, swap, val);
+               }
+               else
+               {
+                   EXTRACT_CARD32 (pData, swap, val);
+               }
+
+               fprintf (stderr,
+                   "            BadValue                  = %d\n", val);
+           }
+            break;
+       }
+
+        case IceBadMajor:
+
+           fprintf (stderr, "Major opcode : %d\n", (int) *pData);
+            break;
+
+        case IceSetupFailed:
+
+           EXTRACT_STRING (pData, swap, str);
+           fprintf (stderr, "Reason : %s\n", str);
+           free(str);
+            break;
+
+        case IceAuthRejected:
+
+           EXTRACT_STRING (pData, swap, str);
+           fprintf (stderr, "Reason : %s\n", str);
+           free(str);
+            break;
+
+        case IceAuthFailed:
+
+           EXTRACT_STRING (pData, swap, str);
+           fprintf (stderr, "Reason : %s\n", str);
+           free(str);
+            break;
+
+        case IceProtocolDuplicate:
+
+           EXTRACT_STRING (pData, swap, str);
+           fprintf (stderr, "Protocol name : %s\n", str);
+           free(str);
+            break;
+
+        case IceMajorOpcodeDuplicate:
+
+           fprintf (stderr, "Major opcode : %d\n", (int) *pData);
+            break;
+
+        case IceUnknownProtocol:
+
+           EXTRACT_STRING (pData, swap, str);
+           fprintf (stderr, "Protocol name : %s\n", str);
+           free(str);
+            break;
+
+       default:
+           break;
+    }
+
+    fprintf (stderr, "\n");
+
+    if (severity != IceCanContinue)
+       exit (1);
+}
+
+IceErrorHandler   _IceErrorHandler   = _IceDefaultErrorHandler;
+
+\f
+/* 
+ * This procedure sets the ICE error handler to be the specified
+ * routine.  If NULL is passed in the default error handler is restored.
+ * The function's return value is the previous error handler.
+ */
+IceErrorHandler
+IceSetErrorHandler (
+       IceErrorHandler handler
+)
+{
+    IceErrorHandler oldHandler = _IceErrorHandler;
+
+    if (handler != NULL)
+       _IceErrorHandler = handler;
+    else
+       _IceErrorHandler = _IceDefaultErrorHandler;
+
+    return (oldHandler);
+}
+
+
+\f
+/*
+ * Default IO error handler.
+ */
+
+static void
+_IceDefaultIOErrorHandler (
+       IceConn         iceConn
+)
+{
+    fprintf (stderr,
+       "ICE default IO error handler doing an exit(), pid = %ld, errno = %d\n",
+       (long)getpid(), errno);
+
+    exit (1);
+}
+
+IceIOErrorHandler _IceIOErrorHandler = _IceDefaultIOErrorHandler;
+
+\f
+/* 
+ * This procedure sets the ICE fatal I/O error handler to be the
+ * specified routine.  If NULL is passed in the default error
+ * handler is restored.   The function's return value is the
+ * previous error handler.
+ */
+IceIOErrorHandler
+IceSetIOErrorHandler (
+       IceIOErrorHandler handler
+)
+{
+    IceIOErrorHandler oldHandler = _IceIOErrorHandler;
+
+    if (handler != NULL)
+       _IceIOErrorHandler = handler;
+    else
+       _IceIOErrorHandler = _IceDefaultIOErrorHandler;
+
+    return (oldHandler);
+}
diff --git a/src/getauth.c b/src/getauth.c
new file mode 100755 (executable)
index 0000000..aa5d72d
--- /dev/null
@@ -0,0 +1,257 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+
+static Bool auth_valid (const char *auth_name, int num_auth_names,
+                       char **auth_names, int *index_ret);
+
+\f
+/*
+ * The functions in this file are not a standard part of ICElib.
+ *
+ * The sample implementation uses an .ICEauthority to manipulate
+ * authentication data.
+ *
+ * For the client that initiates a Protocol Setup, we look in the
+ * .ICEauthority file to get the data.
+ *
+ * For the client accepting the Protocol Setup, we get the data
+ * from an in-memory database of authentication data (set by the
+ * application calling IceSetPaAuthData).  We have to get the data
+ * from memory because getting it directly from the .ICEauthority
+ * file is not secure - someone can just modify the contents of the
+ * .ICEauthority file behind our back.
+ */
+
+void
+_IceGetPoAuthData (
+       char            *protocolName,
+       char            *networkId,
+       char            *authName,
+       unsigned short  *authDataLenRet,
+       char            **authDataRet
+)
+{
+    IceAuthFileEntry    *entry;
+
+    entry = IceGetAuthFileEntry (protocolName, networkId, authName);
+
+    if (entry)
+    {
+       *authDataLenRet = entry->auth_data_length;
+
+       if ((*authDataRet = (char *) malloc (entry->auth_data_length)) != NULL)
+           memcpy (*authDataRet, entry->auth_data, entry->auth_data_length);
+    }
+    else
+    {
+       *authDataLenRet = 0;
+       *authDataRet = NULL;
+    }
+
+    IceFreeAuthFileEntry (entry);
+}
+
+
+\f
+void
+_IceGetPaAuthData (
+       char            *protocolName,
+       char            *networkId,
+       char            *authName,
+       unsigned short  *authDataLenRet,
+       char            **authDataRet
+)
+{
+    IceAuthDataEntry   *entry = NULL;
+    int                        found = 0;
+    int                        i;
+
+    for (i = 0; i < _IcePaAuthDataEntryCount && !found; i++)
+    {
+       entry = &_IcePaAuthDataEntries[i];
+
+       found =
+           strcmp (protocolName, entry->protocol_name) == 0 &&
+            strcmp (networkId, entry->network_id) == 0 &&
+            strcmp (authName, entry->auth_name) == 0;
+    }
+
+    if (found)
+    {
+       *authDataLenRet = entry->auth_data_length;
+
+       if ((*authDataRet = (char *) malloc (entry->auth_data_length)) != NULL)
+           memcpy (*authDataRet, entry->auth_data, entry->auth_data_length);
+    }
+    else
+    {
+       *authDataLenRet = 0;
+       *authDataRet = NULL;
+    }
+}
+
+
+\f
+void
+_IceGetPoValidAuthIndices (
+       char    *protocol_name,
+       char    *network_id,
+       int     num_auth_names,
+       char    **auth_names,
+       int     *num_indices_ret,
+       int     *indices_ret            /* in/out arg */
+)
+{
+    FILE               *auth_file;
+    char               *filename;
+    IceAuthFileEntry    *entry;
+    int                        index_ret, i;
+
+    *num_indices_ret = 0;
+
+    if (!(filename = IceAuthFileName ()))
+       return;
+
+    if (access (filename, R_OK) != 0)          /* checks REAL id */
+       return;
+
+    if (!(auth_file = fopen (filename, "rb")))
+       return;
+
+    for (;;)
+    {
+       if (!(entry = IceReadAuthFileEntry (auth_file)))
+           break;
+
+       if (strcmp (protocol_name, entry->protocol_name) == 0 &&
+           strcmp (network_id, entry->network_id) == 0 &&
+           auth_valid (entry->auth_name, num_auth_names,
+           auth_names, &index_ret))
+       {
+           /*
+            * Make sure we didn't store this index already.
+            */
+
+           for (i = 0; i < *num_indices_ret; i++)
+               if (index_ret == indices_ret[i])
+                   break;
+
+           if (i >= *num_indices_ret)
+           {
+               indices_ret[*num_indices_ret] = index_ret;
+               *num_indices_ret += 1;
+           }
+       }
+
+       IceFreeAuthFileEntry (entry);
+    }
+
+    fclose (auth_file);
+}
+
+
+\f
+void
+_IceGetPaValidAuthIndices (
+       char    *protocol_name,
+       char    *network_id,
+       int     num_auth_names,
+       char    **auth_names,
+       int     *num_indices_ret,
+       int     *indices_ret            /* in/out arg */
+)
+{
+    int                        index_ret;
+    int                        i, j;
+    IceAuthDataEntry   *entry;
+
+    *num_indices_ret = 0;
+
+    for (i = 0;        i < _IcePaAuthDataEntryCount; i++)
+    {
+       entry = &_IcePaAuthDataEntries[i];
+
+       if (strcmp (protocol_name, entry->protocol_name) == 0 &&
+            strcmp (network_id, entry->network_id) == 0 &&
+           auth_valid (entry->auth_name, num_auth_names,
+           auth_names, &index_ret))
+       {
+           /*
+            * Make sure we didn't store this index already.
+            */
+
+           for (j = 0; j < *num_indices_ret; j++)
+               if (index_ret == indices_ret[j])
+                   break;
+
+           if (j >= *num_indices_ret)
+           {
+               indices_ret[*num_indices_ret] = index_ret;
+               *num_indices_ret += 1;
+           }
+       }
+    }
+}
+
+
+\f
+/*
+ * local routines
+ */
+
+static Bool
+auth_valid (const char *auth_name, int num_auth_names,
+           char **auth_names, int *index_ret)
+
+{
+    /*
+     * Check if auth_name is in auth_names.  Return index.
+     */
+
+    int i;
+
+    for (i = 0; i < num_auth_names; i++)
+       if (strcmp (auth_name, auth_names[i]) == 0)
+       {
+           break;
+       }
+   
+    if (i < num_auth_names)
+    {
+       *index_ret = i;
+       return (1);
+    }
+    else
+       return (0);
+}
diff --git a/src/globals.h b/src/globals.h
new file mode 100755 (executable)
index 0000000..2102384
--- /dev/null
@@ -0,0 +1,45 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifndef __UNIXOS2__
+IceConn        _IceConnectionObjs[256];
+char           *_IceConnectionStrings[256];
+_IceProtocol   _IceProtocols[255];
+#else
+IceConn        _IceConnectionObjs[256] = {0};
+char           *_IceConnectionStrings[256] = {0};
+_IceProtocol   _IceProtocols[255] = {0};
+#endif
+int            _IceConnectionCount = 0;
+
+int            _IceLastMajorOpcode = 0;
+
+int            _IceAuthCount = 1;
+char           *_IceAuthNames[] = {"MIT-MAGIC-COOKIE-1"};
+
+_IceWatchProc  *_IceWatchProcs = NULL;
diff --git a/src/iceauth.c b/src/iceauth.c
new file mode 100755 (executable)
index 0000000..7dc46da
--- /dev/null
@@ -0,0 +1,247 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+#include <X11/ICE/ICEutil.h>
+
+#include <time.h>
+#define Time_t time_t
+
+static int was_called_state;
+
+/*
+ * MIT-MAGIC-COOKIE-1 is a sample authentication method implemented by
+ * the SI.  It is not part of standard ICElib.
+ */
+
+\f
+char *
+IceGenerateMagicCookie (
+       int len
+)
+{
+    char    *auth;
+    long    ldata[2];
+    int            seed;
+    int            value;
+    int            i;
+    
+    if ((auth = (char *) malloc (len + 1)) == NULL)
+       return (NULL);
+
+#ifdef ITIMER_REAL
+    {
+       struct timeval  now;
+       X_GETTIMEOFDAY (&now);
+       ldata[0] = now.tv_sec;
+       ldata[1] = now.tv_usec;
+    }
+#else
+    {
+#ifndef __UNIXOS2__
+       long    time ();
+#endif
+       ldata[0] = time ((long *) 0);
+       ldata[1] = getpid ();
+    }
+#endif
+    seed = (ldata[0]) + (ldata[1] << 16);
+    srand (seed);
+    for (i = 0; i < len; i++)
+    {
+       value = rand ();
+       auth[i] = value & 0xff;
+    }
+    auth[len] = '\0';
+
+    return (auth);
+}
+
+
+\f
+IcePoAuthStatus
+_IcePoMagicCookie1Proc (
+       IceConn         iceConn,
+       IcePointer      *authStatePtr,
+       Bool            cleanUp,
+       Bool            swap,
+       int             authDataLen,
+       IcePointer      authData,
+       int             *replyDataLenRet,
+       IcePointer      *replyDataRet,
+       char            **errorStringRet
+)
+{
+    if (cleanUp)
+    {
+       /*
+        * We didn't allocate any state.  We're done.
+        */
+
+       return (IcePoAuthDoneCleanup);
+    }
+
+    *errorStringRet = NULL;
+
+    if (*authStatePtr == NULL)
+    {
+       /*
+        * This is the first time we're being called.  Search the
+        * authentication data for the first occurence of
+        * MIT-MAGIC-COOKIE-1 that matches iceConn->connection_string.
+        */
+
+       unsigned short  length;
+       char            *data;
+
+       _IceGetPoAuthData ("ICE", iceConn->connection_string,
+           "MIT-MAGIC-COOKIE-1", &length, &data);
+
+       if (!data)
+       {
+           const char *tempstr =
+               "Could not find correct MIT-MAGIC-COOKIE-1 authentication";
+
+           *errorStringRet = strdup(tempstr);
+
+           return (IcePoAuthFailed);
+       }
+       else
+       {
+           *authStatePtr = (IcePointer) &was_called_state;
+
+           *replyDataLenRet = length;
+           *replyDataRet = data;
+
+           return (IcePoAuthHaveReply);
+       }
+    }
+    else
+    {
+       /*
+        * We should never get here for MIT-MAGIC-COOKIE-1 since it is
+        * a single pass authentication method.
+        */
+
+       const char *tempstr =
+           "MIT-MAGIC-COOKIE-1 authentication internal error";
+
+       *errorStringRet = strdup(tempstr);
+
+       return (IcePoAuthFailed);
+    }
+}
+
+IcePoAuthProc  _IcePoAuthProcs[] = {_IcePoMagicCookie1Proc};
+
+
+IcePaAuthStatus
+_IcePaMagicCookie1Proc (
+       IceConn         iceConn,
+       IcePointer      *authStatePtr,
+       Bool            swap,
+       int             authDataLen,
+       IcePointer      authData,
+       int             *replyDataLenRet,
+       IcePointer      *replyDataRet,
+       char            **errorStringRet
+)
+{
+    *errorStringRet = NULL;
+    *replyDataLenRet = 0;
+    *replyDataRet = NULL;
+
+    if (*authStatePtr == NULL)
+    {
+       /*
+        * This is the first time we're being called.  We don't have
+        * any data to pass to the other client.
+        */
+
+       *authStatePtr = (IcePointer) &was_called_state;
+
+       return (IcePaAuthContinue);
+    }
+    else
+    {
+       /*
+        * Search the authentication data for the first occurence of
+        * MIT-MAGIC-COOKIE-1 that matches iceConn->connection_string.
+        */
+
+       unsigned short  length;
+       char            *data;
+
+       _IceGetPaAuthData ("ICE", iceConn->connection_string,
+           "MIT-MAGIC-COOKIE-1", &length, &data);
+
+       if (data)
+       {
+           IcePaAuthStatus stat;
+
+           if (authDataLen == length &&
+               memcmp (authData, data, authDataLen) == 0)
+           {
+               stat = IcePaAuthAccepted;
+           }
+           else
+           {
+               const char *tempstr
+                   = "MIT-MAGIC-COOKIE-1 authentication rejected";
+
+               *errorStringRet = strdup(tempstr);
+
+               stat = IcePaAuthRejected;
+           }
+
+           free (data);
+           return (stat);
+       }
+       else
+       {
+           /*
+            * We should never get here because in the ConnectionReply
+            * we should have passed all the valid methods.  So we should
+            * always find a valid entry.
+            */
+
+           const char *tempstr =
+               "MIT-MAGIC-COOKIE-1 authentication internal error";
+
+           *errorStringRet = strdup(tempstr);
+
+           return (IcePaAuthFailed);
+       }
+    }
+}
+
+IcePaAuthProc  _IcePaAuthProcs[] = {_IcePaMagicCookie1Proc};
diff --git a/src/icetrans.c b/src/icetrans.c
new file mode 100755 (executable)
index 0000000..52e432b
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright Â© 2003 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission.  Keith Packard makes no
+ * representations about the suitability of this software for any purpose.  It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define ICE_t 1
+#define TRANS_CLIENT 1
+#define TRANS_SERVER 1
+
+#include <X11/Xtrans/transport.c>
diff --git a/src/listen.c b/src/listen.c
new file mode 100755 (executable)
index 0000000..22602d4
--- /dev/null
@@ -0,0 +1,273 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor,  X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+#include <X11/Xtrans/Xtrans.h>
+#include <stdio.h>
+
+\f
+Status
+IceListenForConnections (
+       int             *countRet,
+       IceListenObj    **listenObjsRet,
+       int             errorLength,
+       char            *errorStringRet
+)
+{
+    struct _IceListenObj       *listenObjs;
+    char                       *networkId;
+    int                                transCount, partial, i, j;
+    Status                     status = 1;
+    XtransConnInfo             *transConns = NULL;
+
+
+    if ((_IceTransMakeAllCOTSServerListeners (NULL, &partial,
+       &transCount, &transConns) < 0) || (transCount < 1))
+    {
+       *listenObjsRet = NULL;
+       *countRet = 0;
+
+        strncpy (errorStringRet,
+           "Cannot establish any listening sockets", errorLength);
+
+       return (0);
+    }
+
+    if ((listenObjs = (struct _IceListenObj *) malloc (
+       transCount * sizeof (struct _IceListenObj))) == NULL)
+    {
+       for (i = 0; i < transCount; i++)
+           _IceTransClose (transConns[i]);
+       free ((char *) transConns);
+       return (0);
+    }
+
+    *countRet = 0;
+
+    for (i = 0; i < transCount; i++)
+    {
+       _IceTransSetOption(transConns[i], TRANS_CLOSEONEXEC, 1);
+
+       networkId = _IceTransGetMyNetworkId (transConns[i]);
+
+       if (networkId)
+       {
+           listenObjs[*countRet].trans_conn = transConns[i];
+           listenObjs[*countRet].network_id = networkId;
+               
+           (*countRet)++;
+       }
+    }
+
+    if (*countRet == 0)
+    {
+       *listenObjsRet = NULL;
+
+        strncpy (errorStringRet,
+           "Cannot establish any listening sockets", errorLength);
+
+       status = 0;
+    }
+    else
+    {
+       *listenObjsRet = (IceListenObj *) malloc (
+           *countRet * sizeof (IceListenObj));
+
+       if (*listenObjsRet == NULL)
+       {
+           strncpy (errorStringRet, "Malloc failed", errorLength);
+
+           status = 0;
+       }
+       else
+       {
+           for (i = 0; i < *countRet; i++)
+           {
+               (*listenObjsRet)[i] = (IceListenObj) malloc (
+                   sizeof (struct _IceListenObj));
+
+               if ((*listenObjsRet)[i] == NULL)
+               {
+                   strncpy (errorStringRet, "Malloc failed", errorLength);
+
+                   for (j = 0; j < i; j++)
+                       free ((char *) (*listenObjsRet)[j]);
+
+                   free ((char *) *listenObjsRet);
+                   *listenObjsRet = NULL;
+
+                   status = 0;
+                   break;
+               }
+               else
+               {
+                   *((*listenObjsRet)[i]) = listenObjs[i];
+               }
+           }
+       }
+    }
+
+    if (status == 1)
+    {
+       if (errorStringRet && errorLength > 0)
+           *errorStringRet = '\0';
+       
+       for (i = 0; i < *countRet; i++)
+       {
+           (*listenObjsRet)[i]->host_based_auth_proc = NULL;
+       }
+    }
+    else
+    {
+       for (i = 0; i < transCount; i++)
+           _IceTransClose (transConns[i]);
+    }
+
+    free ((char *) listenObjs);
+    free ((char *) transConns);
+
+    return (status);
+}
+
+
+\f
+int
+IceGetListenConnectionNumber (
+       IceListenObj listenObj
+)
+{
+    return (_IceTransGetConnectionNumber (listenObj->trans_conn));
+}
+
+
+\f
+char *
+IceGetListenConnectionString (
+       IceListenObj listenObj
+)
+{
+    return strdup(listenObj->network_id);
+}
+
+
+\f
+char *
+IceComposeNetworkIdList (
+       int             count,
+       IceListenObj    *listenObjs
+)
+{
+    char *list;
+    int len = 0;
+    int i;
+
+    if (count < 1 || listenObjs == NULL)
+       return (NULL);
+
+    for (i = 0; i < count; i++)
+       len += (strlen (listenObjs[i]->network_id) + 1);
+
+    list = (char *) malloc (len);
+
+    if (list == NULL)
+       return (NULL);
+    else
+    {
+       int doneCount = 0;
+
+       list[0] = '\0';
+
+       for (i = 0; i < count; i++)
+       {
+           if (_IceTransIsLocal (listenObjs[i]->trans_conn))
+           {
+               strcat (list, listenObjs[i]->network_id);
+               doneCount++;
+               if (doneCount < count)
+                   strcat (list, ",");
+           }
+       }
+
+       if (doneCount < count)
+       {
+           for (i = 0; i < count; i++)
+           {
+               if (!_IceTransIsLocal (listenObjs[i]->trans_conn))
+               {
+                   strcat (list, listenObjs[i]->network_id);
+                   doneCount++;
+                   if (doneCount < count)
+                       strcat (list, ",");
+               }
+           }
+       }
+
+       return (list);
+    }
+}
+
+
+\f
+void
+IceFreeListenObjs (
+       int          count,
+       IceListenObj *listenObjs
+)
+{
+    int i;
+
+    for (i = 0; i < count; i++)
+    {
+       free (listenObjs[i]->network_id);
+       _IceTransClose (listenObjs[i]->trans_conn);
+       free ((char *) listenObjs[i]);
+    }
+
+    free ((char *) listenObjs);
+}
+
+
+\f
+/*
+ * Allow host based authentication for the ICE Connection Setup.
+ * Do not confuse with the host based authentication callbacks that
+ * can be set up in IceRegisterForProtocolReply.
+ */
+
+void
+IceSetHostBasedAuthProc (
+       IceListenObj            listenObj,
+       IceHostBasedAuthProc    hostBasedAuthProc
+)
+{
+    listenObj->host_based_auth_proc = hostBasedAuthProc;
+}
diff --git a/src/listenwk.c b/src/listenwk.c
new file mode 100755 (executable)
index 0000000..7747af6
--- /dev/null
@@ -0,0 +1,159 @@
+/*
+
+Copyright 1996, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+*/
+
+
+/* Author: Ralph Mor, X Consortium */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+#include <X11/Xtrans/Xtrans.h>
+#include <stdio.h>
+
+\f
+Status
+IceListenForWellKnownConnections (
+       char            *port,
+       int             *countRet,
+       IceListenObj    **listenObjsRet,
+       int             errorLength,
+       char            *errorStringRet
+)
+{
+    struct _IceListenObj       *listenObjs;
+    char                       *networkId;
+    int                                transCount, partial, i, j;
+    Status                     status = 1;
+    XtransConnInfo             *transConns = NULL;
+
+
+    if ((_IceTransMakeAllCOTSServerListeners (port, &partial,
+       &transCount, &transConns) < 0) || (transCount < 1))
+    {
+       *listenObjsRet = NULL;
+       *countRet = 0;
+
+        strncpy (errorStringRet,
+           "Cannot establish any listening sockets", errorLength);
+
+       return (0);
+    }
+
+    if ((listenObjs = (struct _IceListenObj *) malloc (
+       transCount * sizeof (struct _IceListenObj))) == NULL)
+    {
+       for (i = 0; i < transCount; i++)
+           _IceTransClose (transConns[i]);
+       free ((char *) transConns);
+       return (0);
+    }
+
+    *countRet = 0;
+
+    for (i = 0; i < transCount; i++)
+    {
+       networkId = (char *)_IceTransGetMyNetworkId (transConns[i]);
+
+       if (networkId)
+       {
+           listenObjs[*countRet].trans_conn = transConns[i];
+           listenObjs[*countRet].network_id = networkId;
+               
+           (*countRet)++;
+       }
+    }
+
+    if (*countRet == 0)
+    {
+       *listenObjsRet = NULL;
+
+        strncpy (errorStringRet,
+           "Cannot establish any listening sockets", errorLength);
+
+       status = 0;
+    }
+    else
+    {
+       *listenObjsRet = (IceListenObj *) malloc (
+           *countRet * sizeof (IceListenObj));
+
+       if (*listenObjsRet == NULL)
+       {
+           strncpy (errorStringRet, "Malloc failed", errorLength);
+
+           status = 0;
+       }
+       else
+       {
+           for (i = 0; i < *countRet; i++)
+           {
+               (*listenObjsRet)[i] = (IceListenObj) malloc (
+                   sizeof (struct _IceListenObj));
+
+               if ((*listenObjsRet)[i] == NULL)
+               {
+                   strncpy (errorStringRet, "Malloc failed", errorLength);
+
+                   for (j = 0; j < i; j++)
+                       free ((char *) (*listenObjsRet)[j]);
+
+                   free ((char *) *listenObjsRet);
+                   *listenObjsRet = NULL;
+
+                   status = 0;
+                   break;
+               }
+               else
+               {
+                   *((*listenObjsRet)[i]) = listenObjs[i];
+               }
+           }
+       }
+    }
+
+    if (status == 1)
+    {
+       if (errorStringRet && errorLength > 0)
+           *errorStringRet = '\0';
+       
+       for (i = 0; i < *countRet; i++)
+       {
+           (*listenObjsRet)[i]->host_based_auth_proc = NULL;
+       }
+    }
+    else
+    {
+       for (i = 0; i < transCount; i++)
+           _IceTransClose (transConns[i]);
+    }
+
+    free ((char *) listenObjs);
+    free ((char *) transConns);
+
+    return (status);
+}
diff --git a/src/locking.c b/src/locking.c
new file mode 100755 (executable)
index 0000000..79a0a74
--- /dev/null
@@ -0,0 +1,65 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+
+
+/*
+ * NOT IMPLEMENTED YET
+ */
+
+
+Status
+IceInitThreads (
+       void
+)
+{
+    return (0);
+}
+
+
+void
+IceAppLockConn (
+       IceConn iceConn
+)
+{
+    IceLockConn (iceConn);
+}
+
+
+void
+IceAppUnlockConn (
+       IceConn iceConn
+)
+{
+    IceUnlockConn (iceConn);
+}
diff --git a/src/misc.c b/src/misc.c
new file mode 100755 (executable)
index 0000000..890da9a
--- /dev/null
@@ -0,0 +1,590 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef WIN32
+#define _WILLWINSOCK_
+#endif
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+#include <X11/Xtrans/Xtrans.h>
+#include <stdio.h>
+#ifdef WIN32
+#include <X11/Xwinsock.h>
+#include <X11/Xw32defs.h>
+#endif
+
+\f
+/*
+ * scratch buffer
+ */
+
+char *
+IceAllocScratch (
+       IceConn         iceConn,
+       unsigned long   size
+)
+{
+    if (!iceConn->scratch || size > iceConn->scratch_size)
+    {
+       if (iceConn->scratch)
+           free (iceConn->scratch);
+
+       iceConn->scratch = (char *) malloc ((unsigned) size);
+       iceConn->scratch_size = size;
+    }
+
+    return (iceConn->scratch);
+}
+
+
+\f
+/*
+ * Output/Input buffer functions
+ */
+
+int
+IceFlush (
+       IceConn iceConn
+)
+{
+    _IceWrite (iceConn,
+       (unsigned long) (iceConn->outbufptr - iceConn->outbuf),
+       iceConn->outbuf);
+
+    iceConn->outbufptr = iceConn->outbuf;
+    return 1;
+}
+
+
+int
+IceGetOutBufSize (
+       IceConn iceConn
+)
+{
+    return (iceConn->outbufmax - iceConn->outbuf);
+}
+
+
+int
+IceGetInBufSize (
+       IceConn iceConn
+)
+{
+    return (iceConn->inbufmax - iceConn->inbuf);
+}
+
+
+\f
+/*
+ * informational functions
+ */
+
+IceConnectStatus
+IceConnectionStatus (
+       IceConn iceConn
+)
+{
+    return (iceConn->connection_status);
+}
+
+
+char *
+IceVendor (
+       IceConn iceConn
+)
+{
+    return strdup(iceConn->vendor);
+}
+
+
+char *
+IceRelease (
+       IceConn iceConn
+)
+{
+    return strdup(iceConn->release);
+}
+
+
+int
+IceProtocolVersion (
+       IceConn iceConn
+)
+{
+    return (_IceVersions[iceConn->my_ice_version_index].major_version);
+}
+
+
+int
+IceProtocolRevision (
+       IceConn iceConn
+)
+{
+    return (_IceVersions[iceConn->my_ice_version_index].minor_version);
+}
+
+
+int
+IceConnectionNumber (
+       IceConn iceConn
+)
+{
+    return (_IceTransGetConnectionNumber (iceConn->trans_conn));
+}
+
+
+char *
+IceConnectionString (
+       IceConn iceConn
+)
+{
+    if (iceConn->connection_string)
+    {
+       return strdup(iceConn->connection_string);
+    }
+    else
+       return (NULL);
+}
+
+
+unsigned long
+IceLastSentSequenceNumber (
+       IceConn iceConn
+)
+{
+    return (iceConn->send_sequence);
+}
+
+
+unsigned long
+IceLastReceivedSequenceNumber (
+       IceConn iceConn
+)
+{
+    return (iceConn->receive_sequence);
+}
+
+
+Bool
+IceSwapping (
+       IceConn iceConn
+)
+{
+    return (iceConn->swap);
+}
+
+
+\f
+/*
+ * Read "n" bytes from a connection.
+ *
+ * Return Status 0 if we detected an EXPECTED closed connection.
+ *
+ */
+
+Status
+_IceRead (
+       register IceConn iceConn,
+       unsigned long    nbytes,
+       register char    *ptr
+)
+{
+    register unsigned long nleft;
+
+    nleft = nbytes;
+    while (nleft > 0)
+    {
+       int nread;
+
+       if (iceConn->io_ok)
+           nread = _IceTransRead (iceConn->trans_conn, ptr, (int) nleft);
+       else
+           return (1);
+
+       if (nread <= 0)
+       {
+#ifdef WIN32
+           errno = WSAGetLastError();
+#endif
+           if (iceConn->want_to_close)
+           {
+               /*
+                * We sent a WantToClose message and now we detected that
+                * the other side closed the connection.
+                */
+
+               _IceConnectionClosed (iceConn);     /* invoke watch procs */
+               _IceFreeConnection (iceConn);
+
+               return (0);
+           }
+           else 
+           {
+               /*
+                * Fatal IO error.  First notify each protocol's IceIOErrorProc
+                * callback, then invoke the application IO error handler.
+                */
+
+               iceConn->io_ok = False;
+
+               if (iceConn->connection_status == IceConnectPending)
+               {
+                   /*
+                    * Don't invoke IO error handler if we are in the
+                    * middle of a connection setup.
+                    */
+
+                   return (1);
+               }
+
+               if (iceConn->process_msg_info)
+               {
+                   int i;
+
+                   for (i = iceConn->his_min_opcode;
+                       i <= iceConn->his_max_opcode; i++)
+                   {
+                       _IceProcessMsgInfo *process;
+
+                       process = &iceConn->process_msg_info[
+                           i - iceConn->his_min_opcode];
+
+                       if ((process != NULL) && process->in_use)
+                       {
+                           IceIOErrorProc IOErrProc = process->accept_flag ?
+                             process->protocol->accept_client->io_error_proc :
+                             process->protocol->orig_client->io_error_proc;
+
+                           if (IOErrProc)
+                               (*IOErrProc) (iceConn);
+                       }
+                   }
+               }
+
+               (*_IceIOErrorHandler) (iceConn);
+               return (1);
+           }
+       }
+
+       nleft -= nread;
+       ptr   += nread;
+    }
+
+    return (1);
+}
+
+
+\f
+/*
+ * If we read a message header with a bad major or minor opcode,
+ * we need to advance to the end of the message.  This way, the next
+ * message can be processed correctly.
+ */
+
+void
+_IceReadSkip (
+       register IceConn        iceConn,
+       register unsigned long  nbytes
+)
+{
+    char temp[512];
+
+    while (nbytes > 0)
+    {
+       unsigned long rbytes = nbytes > 512 ? 512 : nbytes;
+
+       _IceRead (iceConn, rbytes, temp);
+       nbytes -= rbytes;
+    }
+}
+
+
+\f
+/*
+ * Write "n" bytes to a connection.
+ */
+
+void
+_IceWrite (
+       register IceConn iceConn,
+       unsigned long    nbytes,
+       register char    *ptr
+)
+{
+    register unsigned long nleft;
+
+    nleft = nbytes;
+    while (nleft > 0)
+    {
+       int nwritten;
+
+       if (iceConn->io_ok)
+           nwritten = _IceTransWrite (iceConn->trans_conn, ptr, (int) nleft);
+       else
+           return;
+
+       if (nwritten <= 0)
+       {
+#ifdef WIN32
+           errno = WSAGetLastError();
+#endif
+           /*
+            * Fatal IO error.  First notify each protocol's IceIOErrorProc
+            * callback, then invoke the application IO error handler.
+            */
+
+           iceConn->io_ok = False;
+
+           if (iceConn->connection_status == IceConnectPending)
+           {
+               /*
+                * Don't invoke IO error handler if we are in the
+                * middle of a connection setup.
+                */
+
+               return;
+           }
+
+           if (iceConn->process_msg_info)
+           {
+               int i;
+
+               for (i = iceConn->his_min_opcode;
+                    i <= iceConn->his_max_opcode; i++)
+               {
+                   _IceProcessMsgInfo *process;
+
+                   process = &iceConn->process_msg_info[
+                       i - iceConn->his_min_opcode];
+
+                   if (process->in_use)
+                   {
+                       IceIOErrorProc IOErrProc = process->accept_flag ?
+                           process->protocol->accept_client->io_error_proc :
+                           process->protocol->orig_client->io_error_proc;
+
+                       if (IOErrProc)
+                           (*IOErrProc) (iceConn);
+                   }
+               }
+           }
+
+           (*_IceIOErrorHandler) (iceConn);
+           return;
+       }
+
+       nleft -= nwritten;
+       ptr   += nwritten;
+    }
+}
+
+#ifdef WORD64
+
+IceWriteData16 (
+       IceConn         iceConn,
+       unsigned long   nbytes,
+       short           *data
+)
+{
+    int numShorts = nbytes / 2;
+    int index = 0;
+
+    while (index < numShorts)
+    {
+       int spaceLeft, count, i;
+       int shortsLeft = numShorts - index;
+
+       spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1;
+
+       if (spaceLeft < 2)
+       {
+           IceFlush (iceConn);
+           spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1;
+       }
+
+       count = (shortsLeft < spaceLeft / 2) ? shortsLeft : spaceLeft / 2;
+
+       for (i = 0; i < count; i++)
+           STORE_CARD16 (iceConn->outbufptr, data[index++]);
+    }
+}
+
+
+IceWriteData32 (
+       IceConn         iceConn,
+       unsigned long   nbytes,
+       int             *data
+)
+{
+    int numLongs = nbytes / 4;
+    int index = 0;
+
+    while (index < numLongs)
+    {
+       int spaceLeft, count, i;
+       int longsLeft = numLongs - index;
+
+       spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1;
+
+       if (spaceLeft < 4)
+       {
+           IceFlush (iceConn);
+           spaceLeft = iceConn->outbufmax - iceConn->outbufptr - 1;
+       }
+
+       count = (longsLeft < spaceLeft / 4) ? longsLeft : spaceLeft / 4;
+
+       for (i = 0; i < count; i++)
+           STORE_CARD32 (iceConn->outbufptr, data[index++]);
+    }
+}
+
+
+IceReadData16 (
+       IceConn         iceConn,
+       Bool            swap,
+       unsigned long   nbytes,
+       short           *data
+)
+{
+    /* NOT IMPLEMENTED YET */
+}
+
+
+IceReadData32 (
+       IceConn         iceConn,
+       Bool            swap,
+       unsigned long   nbytes,
+       int             *data
+)
+{
+    /* NOT IMPLEMENTED YET */
+}
+
+#endif  /* WORD64 */
+
+
+\f
+void
+_IceAddOpcodeMapping (
+       IceConn iceConn,
+       int     hisOpcode,
+       int     myOpcode
+)
+{
+    if (hisOpcode <= 0 || hisOpcode > 255)
+    {
+       return;
+    }
+    else if (iceConn->process_msg_info == NULL)
+    {
+       iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc (
+           sizeof (_IceProcessMsgInfo));
+       iceConn->his_min_opcode = iceConn->his_max_opcode = hisOpcode;
+    }
+    else if (hisOpcode < iceConn->his_min_opcode)
+    {
+       _IceProcessMsgInfo *oldVec = iceConn->process_msg_info;
+       int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1;
+       int newsize = iceConn->his_max_opcode - hisOpcode + 1;
+       int i;
+
+       iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc (
+           newsize * sizeof (_IceProcessMsgInfo));
+
+       memcpy (&iceConn->process_msg_info[
+           iceConn->his_min_opcode - hisOpcode], oldVec,
+           oldsize * sizeof (_IceProcessMsgInfo));
+
+       free ((char *) oldVec);
+
+       for (i = hisOpcode + 1; i < iceConn->his_min_opcode; i++)
+       {
+           iceConn->process_msg_info[i -
+               iceConn->his_min_opcode].in_use = False;
+
+           iceConn->process_msg_info[i -
+               iceConn->his_min_opcode].protocol = NULL;
+       }
+
+       iceConn->his_min_opcode = hisOpcode;
+    }
+    else if (hisOpcode > iceConn->his_max_opcode)
+    {
+       _IceProcessMsgInfo *oldVec = iceConn->process_msg_info;
+       int oldsize = iceConn->his_max_opcode - iceConn->his_min_opcode + 1;
+       int newsize = hisOpcode - iceConn->his_min_opcode + 1;
+       int i;
+
+       iceConn->process_msg_info = (_IceProcessMsgInfo *) malloc (
+           newsize * sizeof (_IceProcessMsgInfo));
+
+       memcpy (iceConn->process_msg_info, oldVec,
+           oldsize * sizeof (_IceProcessMsgInfo));
+
+       free ((char *) oldVec);
+
+       for (i = iceConn->his_max_opcode + 1; i < hisOpcode; i++)
+       {
+           iceConn->process_msg_info[i -
+               iceConn->his_min_opcode].in_use = False;
+
+           iceConn->process_msg_info[i -
+               iceConn->his_min_opcode].protocol = NULL;
+       }
+
+       iceConn->his_max_opcode = hisOpcode;
+    }
+
+    iceConn->process_msg_info[hisOpcode -
+       iceConn->his_min_opcode].in_use = True;
+
+    iceConn->process_msg_info[hisOpcode -
+       iceConn->his_min_opcode].my_opcode = myOpcode;
+
+    iceConn->process_msg_info[hisOpcode -
+       iceConn->his_min_opcode].protocol = &_IceProtocols[myOpcode - 1];
+}
+
+
+\f
+char *
+IceGetPeerName (IceConn iceConn)
+{
+    return (_IceTransGetPeerNetworkId (iceConn->trans_conn));
+}
+
+\f
+char *
+_IceGetPeerName (IceConn iceConn)
+{
+    return (IceGetPeerName(iceConn));
+}
diff --git a/src/ping.c b/src/ping.c
new file mode 100755 (executable)
index 0000000..93d82de
--- /dev/null
@@ -0,0 +1,64 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+
+Status
+IcePing (
+       IceConn          iceConn,
+       IcePingReplyProc pingReplyProc,
+       IcePointer       clientData
+)
+{
+    _IcePingWait *newping = (_IcePingWait *) malloc (sizeof (_IcePingWait));
+    _IcePingWait *ptr = iceConn->ping_waits;
+
+    if (newping == NULL)
+       return (0);
+
+    newping->ping_reply_proc = pingReplyProc;
+    newping->client_data = clientData;
+    newping->next = NULL;
+
+    while (ptr && ptr->next)
+       ptr = ptr->next;
+
+    if (ptr == NULL)
+       iceConn->ping_waits = newping;
+    else
+       ptr->next = newping;
+
+    IceSimpleMessage (iceConn, 0, ICE_Ping);
+    IceFlush (iceConn);
+
+    return (1);
+}
diff --git a/src/process.c b/src/process.c
new file mode 100755 (executable)
index 0000000..583ea1d
--- /dev/null
@@ -0,0 +1,2525 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+
+#include <stdio.h> /* sprintf */
+
+/*
+ * Check for bad length
+ */
+
+#define CHECK_SIZE_MATCH(_iceConn, _opcode, _expected_len, _actual_len, _severity, _return) \
+    if ((((_actual_len) - SIZEOF (iceMsg)) >> 3) != _expected_len) \
+    { \
+       _IceErrorBadLength (_iceConn, 0, _opcode, _severity); \
+       return (_return); \
+    }
+
+#define CHECK_AT_LEAST_SIZE(_iceConn, _opcode, _expected_len, _actual_len, _severity) \
+    if ((((_actual_len) - SIZEOF (iceMsg)) >> 3) > _expected_len) \
+    { \
+       _IceErrorBadLength (_iceConn, 0, _opcode, _severity); \
+       return (0); \
+    }
+
+#define CHECK_COMPLETE_SIZE(_iceConn, _opcode, _expected_len, _actual_len, _pStart, _severity) \
+    if (((PADDED_BYTES64((_actual_len)) - SIZEOF (iceMsg)) >> 3) \
+        != _expected_len) \
+    { \
+       _IceErrorBadLength (_iceConn, 0, _opcode, _severity); \
+       IceDisposeCompleteMessage (iceConn, _pStart); \
+       return (0); \
+    }
+
+#define BAIL_STRING(_iceConn, _opcode, _pStart) {\
+    _IceErrorBadLength (_iceConn, 0, _opcode, IceFatalToConnection);\
+    IceDisposeCompleteMessage (_iceConn, _pStart);\
+    return (0);\
+}
+\f
+/*
+ * IceProcessMessages:
+ *
+ * If replyWait == NULL, the client is not waiting for a reply.
+ *
+ * If replyWait != NULL, the client is waiting for a reply...
+ *
+ *    - replyWait->sequence_of_request is the sequence number of the
+ *      message for which the client is waiting a reply.  This is needed
+ *     to determine if an error matches a replyWait.
+ *
+ *    - replyWait->major_opcode_of_request is the major opcode of the
+ *      message for which we are waiting a reply.
+ *
+ *    - replyWait->minor_opcode_of_request is the minor opcode of the
+ *      message for which we are waiting a reply.
+ *
+ *    - replyWait->reply is a pointer to the reply message which will be
+ *     filled in when the reply is ready (the protocol library should
+ *      cast this IcePointer to the appropriate reply type).  In most cases,
+ *      the reply will have some fixed-size part, and the sender function
+ *      will have provided a pointer to a structure (e.g.) to hold this
+ *      fixed-size data.  If there is variable-length data, it would be
+ *      expected that the reply function will have to allocate additional
+ *      memory and store pointer(s) to that memory in the fixed-size
+ *      structure.  If the entire data is variable length (e.g., a single
+ *      variable-length string), then the sender function would probably
+ *      just pass a pointer to fixed-size space to hold a pointer, and the
+ *      reply function would allocate the storage and store the pointer.
+ *     It is the responsibility of the client receiving the reply to
+ *     free up any memory allocated on it's behalf.
+ *
+ * We might be waiting for several different replies (a function can wait
+ * for a reply, and while calling IceProcessMessages, a callback can be
+ * invoked which will wait for another reply).  We take advantage of the
+ * fact that for a given protocol, we are guaranteed that messages are
+ * processed in the order we sent them.  So, everytime we have a new
+ * replyWait, we add it to the END of the 'saved_reply_waits' list.  When
+ * we read a message and want to see if it matches a replyWait, we use the
+ * FIRST replyWait in the list with the major opcode of the message.  If the
+ * reply is ready, we remove that replyWait from the list.
+ *
+ * If the reply/error is ready for the replyWait passed in to
+ * IceProcessMessages, *replyReadyRet is set to True.
+ *
+ * The return value of IceProcessMessages is one of the following:
+ *
+ * IceProcessMessagesSuccess - the message was processed successfully.
+ * IceProcessMessagesIOError - an IO error occured.  The caller should
+ *                            invoked IceCloseConnection.
+ * IceProcessMessagesConnectionClosed - the connection was closed as a
+ *                                     result of shutdown negotiation.
+ */
+
+IceProcessMessagesStatus
+IceProcessMessages (
+       IceConn          iceConn,
+       IceReplyWaitInfo *replyWait,
+       Bool             *replyReadyRet
+)
+{
+    iceMsg             *header;
+    Bool               replyReady = False;
+    IceReplyWaitInfo   *useThisReplyWait = NULL;
+    IceProcessMessagesStatus retStatus = IceProcessMessagesSuccess;
+
+    if (replyWait)
+       *replyReadyRet = False;
+
+    /*
+     * Each time IceProcessMessages is entered, we increment the dispatch
+     * level.  Each time we leave it, we decrement the dispatch level.
+     */
+
+    iceConn->dispatch_level++;
+
+
+    /*
+     * Read the ICE message header.
+     */
+
+    if (!_IceRead (iceConn, (unsigned long) SIZEOF (iceMsg), iceConn->inbuf))
+    {
+       /*
+        * If we previously sent a WantToClose and now we detected
+        * that the connection was closed, _IceRead returns status 0.
+        * Since the connection was closed, we just want to return here.
+        */
+
+       return (IceProcessMessagesConnectionClosed);
+    }
+
+    if (!iceConn->io_ok)
+    {
+       /*
+        * An unexpected IO error occured.  The caller of IceProcessMessages
+        * should call IceCloseConnection which will cause the watch procedures
+        * to be invoked and the ICE connection to be freed.
+        */
+
+       iceConn->dispatch_level--;
+       iceConn->connection_status = IceConnectIOError;
+       return (IceProcessMessagesIOError);
+    }
+
+    header = (iceMsg *) iceConn->inbuf;
+    iceConn->inbufptr = iceConn->inbuf + SIZEOF (iceMsg);
+
+    iceConn->receive_sequence++;
+
+    if (iceConn->waiting_for_byteorder)
+    {
+       if (header->majorOpcode == 0 &&
+           header->minorOpcode == ICE_ByteOrder)
+       {
+           char byteOrder = ((iceByteOrderMsg *) header)->byteOrder;
+           int endian = 1;
+
+           CHECK_SIZE_MATCH (iceConn, ICE_ByteOrder,
+               header->length, SIZEOF (iceByteOrderMsg),
+               IceFatalToConnection, IceProcessMessagesIOError);
+
+           if (byteOrder != IceMSBfirst && byteOrder != IceLSBfirst)
+           {
+               _IceErrorBadValue (iceConn, 0,
+                   ICE_ByteOrder, 2, 1, &byteOrder);
+
+               iceConn->connection_status = IceConnectRejected;
+           }
+           else
+           {
+               iceConn->swap =
+                   (((*(char *) &endian) && byteOrder == IceMSBfirst) ||
+                    (!(*(char *) &endian) && byteOrder == IceLSBfirst));
+
+               iceConn->waiting_for_byteorder = 0;
+           }
+       }
+       else
+       {
+           if (header->majorOpcode != 0)
+           {
+               _IceErrorBadMajor (iceConn, header->majorOpcode,
+                   header->minorOpcode, IceFatalToConnection);
+           }
+           else
+           {
+               _IceErrorBadState (iceConn, 0,
+                   header->minorOpcode, IceFatalToConnection);
+           }
+
+           iceConn->connection_status = IceConnectRejected;
+       }
+
+       iceConn->dispatch_level--;
+       if (!iceConn->io_ok)
+       {
+           iceConn->connection_status = IceConnectIOError;
+           retStatus = IceProcessMessagesIOError;
+       }
+
+       return (retStatus);
+    }
+
+    if (iceConn->swap)
+    {
+       /* swap the length field */
+
+       header->length = lswapl (header->length);
+    }
+
+    if (replyWait)
+    {
+       /*
+        * Add to the list of replyWaits (only if it doesn't exist
+        * in the list already.
+        */
+
+       _IceAddReplyWait (iceConn, replyWait);
+
+       /*
+        * Note that there are two different replyWaits.  The first is
+        * the one passed into IceProcessMessages, and is the replyWait
+        * for the message the client is blocking on.  The second is
+        * the replyWait for the message currently being processed
+        * by IceProcessMessages.  We call it "useThisReplyWait".
+        *
+        * Also, when two hosts communicate over an ICE connection and use
+        * different major opcodes for a subprotocol, it is impossible
+        * to use message replies unless we translate opcodes before
+        * comparing them.
+        */
+       
+       {
+           int op;
+
+           if (header->majorOpcode == 0)
+           {
+               op = 0;
+           }
+           else
+           {
+               int idx = header->majorOpcode - iceConn->his_min_opcode;
+               op = iceConn->process_msg_info[idx].my_opcode;
+           }
+           useThisReplyWait = _IceSearchReplyWaits (iceConn, op);
+       }
+    }
+
+    if (header->majorOpcode == 0)
+    {
+       /*
+        * ICE protocol
+        */
+
+       Bool connectionClosed;
+
+       _IceProcessCoreMsgProc processIce =
+           _IceVersions[iceConn->my_ice_version_index].process_core_msg_proc;
+
+       (*processIce) (iceConn, header->minorOpcode,
+           header->length, iceConn->swap,
+           useThisReplyWait, &replyReady, &connectionClosed);
+
+       if (connectionClosed)
+       {
+           /*
+            * As a result of shutdown negotiation, the connection was closed.
+            */
+
+           return (IceProcessMessagesConnectionClosed);
+       }
+    }
+    else
+    {
+       /*
+        * Sub protocol
+        */
+
+       if ((int) header->majorOpcode < iceConn->his_min_opcode ||
+           (int) header->majorOpcode > iceConn->his_max_opcode ||
+           !(iceConn->process_msg_info[header->majorOpcode -
+           iceConn->his_min_opcode].in_use))
+       {
+           /*
+            * The protocol of the message we just read is not supported.
+            */
+
+           _IceErrorBadMajor (iceConn, header->majorOpcode,
+               header->minorOpcode, IceCanContinue);
+
+           _IceReadSkip (iceConn, header->length << 3);
+       }
+       else
+       {
+           _IceProcessMsgInfo *processMsgInfo = &iceConn->process_msg_info[
+               header->majorOpcode - iceConn->his_min_opcode];
+
+           if (processMsgInfo->accept_flag)
+           {
+               IcePaProcessMsgProc processProc =
+                   processMsgInfo->process_msg_proc.accept_client;
+
+               (*processProc) (iceConn, processMsgInfo->client_data,
+                   header->minorOpcode, header->length, iceConn->swap);
+           }
+           else
+           {
+               IcePoProcessMsgProc processProc =
+                   processMsgInfo->process_msg_proc.orig_client;
+
+               (*processProc) (iceConn,
+                   processMsgInfo->client_data, header->minorOpcode,
+                   header->length, iceConn->swap,
+                   useThisReplyWait, &replyReady);
+           }
+       }
+    }
+
+    if (replyReady)
+    {
+       _IceSetReplyReady (iceConn, useThisReplyWait);
+    }
+
+
+    /*
+     * Now we check if the reply is ready for the replyWait passed
+     * into IceProcessMessages.  The replyWait is removed from the
+     * replyWait list if it is ready.
+     */
+
+    if (replyWait)
+       *replyReadyRet = _IceCheckReplyReady (iceConn, replyWait);
+
+
+    /*
+     * Decrement the dispatch level.  If we reach level 0, and the
+     * free_asap bit is set, free the connection now.  Also check for
+     * possible bad IO status.
+     */
+
+    iceConn->dispatch_level--;
+
+    if (iceConn->dispatch_level == 0 && iceConn->free_asap)
+    {
+       _IceFreeConnection (iceConn);
+       retStatus = IceProcessMessagesConnectionClosed;
+    }
+    else if (!iceConn->io_ok)
+    {
+       iceConn->connection_status = IceConnectIOError;
+       retStatus = IceProcessMessagesIOError;
+    }
+
+    return (retStatus);
+}
+
+
+\f
+static void
+AuthRequired (
+       IceConn         iceConn,
+       int             authIndex,
+       int             authDataLen,
+       IcePointer      authData
+)
+{
+    iceAuthRequiredMsg *pMsg;
+
+    IceGetHeader (iceConn, 0, ICE_AuthRequired,
+       SIZEOF (iceAuthRequiredMsg), iceAuthRequiredMsg, pMsg);
+
+    pMsg->authIndex = authIndex;
+    pMsg->authDataLength = authDataLen;
+    pMsg->length += WORD64COUNT (authDataLen);
+
+    IceWriteData (iceConn, authDataLen, (char *) authData);
+
+    if (PAD64 (authDataLen))
+       IceWritePad (iceConn, PAD64 (authDataLen));
+
+    IceFlush (iceConn);
+}
+
+
+\f
+static void
+AuthReply (
+       IceConn         iceConn,
+       int             authDataLen,
+       IcePointer      authData
+)
+{
+    iceAuthReplyMsg *pMsg;
+
+    IceGetHeader (iceConn, 0, ICE_AuthReply,
+       SIZEOF (iceAuthReplyMsg), iceAuthReplyMsg, pMsg);
+
+    pMsg->authDataLength = authDataLen;
+    pMsg->length +=  WORD64COUNT (authDataLen);
+
+    IceWriteData (iceConn, authDataLen, (char *) authData);
+
+    if (PAD64 (authDataLen))
+       IceWritePad (iceConn, PAD64 (authDataLen));
+
+    IceFlush (iceConn);
+}
+
+
+\f
+static void
+AuthNextPhase (
+       IceConn         iceConn,
+       int             authDataLen,
+       IcePointer      authData
+)
+{
+    iceAuthNextPhaseMsg *pMsg;
+
+    IceGetHeader (iceConn, 0, ICE_AuthNextPhase,
+       SIZEOF (iceAuthNextPhaseMsg), iceAuthNextPhaseMsg, pMsg);
+
+    pMsg->authDataLength = authDataLen;
+    pMsg->length += WORD64COUNT (authDataLen);
+
+    IceWriteData (iceConn, authDataLen, (char *) authData);
+
+    if (PAD64 (authDataLen))
+       IceWritePad (iceConn, PAD64 (authDataLen));
+
+    IceFlush (iceConn);
+}
+
+
+\f
+static void
+AcceptConnection (
+       IceConn iceConn,
+       int     versionIndex
+)
+{
+    iceConnectionReplyMsg      *pMsg;
+    char                       *pData;
+    int                                extra;
+
+    extra = STRING_BYTES (IceVendorString) + STRING_BYTES (IceReleaseString);
+
+    IceGetHeaderExtra (iceConn, 0, ICE_ConnectionReply,
+       SIZEOF (iceConnectionReplyMsg), WORD64COUNT (extra),
+       iceConnectionReplyMsg, pMsg, pData);
+
+    pMsg->versionIndex = versionIndex;
+
+    STORE_STRING (pData, IceVendorString);
+    STORE_STRING (pData, IceReleaseString);
+
+    IceFlush (iceConn);
+
+    iceConn->connection_status = IceConnectAccepted;
+}
+
+
+\f
+static void
+AcceptProtocol (
+       IceConn iceConn,
+       int     hisOpcode,
+       int     myOpcode,
+       int     versionIndex,
+       char    *vendor,
+       char    *release
+)
+{
+    iceProtocolReplyMsg        *pMsg;
+    char               *pData;
+    int                        extra;
+
+    extra = STRING_BYTES (vendor) + STRING_BYTES (release);
+
+    IceGetHeaderExtra (iceConn, 0, ICE_ProtocolReply,
+       SIZEOF (iceProtocolReplyMsg), WORD64COUNT (extra),
+       iceProtocolReplyMsg, pMsg, pData);
+
+    pMsg->protocolOpcode = myOpcode;
+    pMsg->versionIndex = versionIndex;
+
+    STORE_STRING (pData, vendor);
+    STORE_STRING (pData, release);
+
+    IceFlush (iceConn);
+
+
+    /*
+     * We may be using a different major opcode for this protocol
+     * than the other client.  Whenever we get a message, we must
+     * map to our own major opcode.
+     */
+
+    _IceAddOpcodeMapping (iceConn, hisOpcode, myOpcode);
+}
+
+
+\f
+static void
+PingReply (
+       IceConn iceConn
+)
+{
+    IceSimpleMessage (iceConn, 0, ICE_PingReply);
+    IceFlush (iceConn);
+}
+
+
+\f
+static Bool
+ProcessError (
+       IceConn          iceConn,
+       unsigned long    length,
+       Bool             swap,
+       IceReplyWaitInfo *replyWait
+)
+{
+    int                invokeHandler = 0;
+    Bool       errorReturned = False;
+    iceErrorMsg *message;
+    char       *pData, *pStart;
+    char       severity;
+
+    CHECK_AT_LEAST_SIZE (iceConn, ICE_Error,
+       length, SIZEOF (iceErrorMsg),
+       (iceConn->connect_to_you || iceConn->connect_to_me) ?
+       IceFatalToConnection : IceFatalToProtocol);
+
+    IceReadCompleteMessage (iceConn, SIZEOF (iceErrorMsg),
+       iceErrorMsg, message, pStart);
+
+    if (!IceValidIO (iceConn))
+    {
+       IceDisposeCompleteMessage (iceConn, pStart);
+       return (0);
+    }
+
+    severity = message->severity;
+
+    if (severity != IceCanContinue && severity != IceFatalToProtocol &&
+       severity != IceFatalToConnection)
+    {
+       _IceErrorBadValue (iceConn, 0,
+           ICE_Error, 9, 1, &severity);
+       IceDisposeCompleteMessage (iceConn, pStart);
+       return (0);
+    }
+
+    pData = pStart;
+
+    if (swap)
+    {
+       message->errorClass = lswaps (message->errorClass);
+       message->offendingSequenceNum = lswapl (message->offendingSequenceNum);
+    }
+
+    if (!replyWait ||
+       message->offendingSequenceNum != replyWait->sequence_of_request)
+    {
+       invokeHandler = 1;
+    }
+    else
+    {
+       if (iceConn->connect_to_you &&
+           ((!iceConn->connect_to_you->auth_active &&
+            message->offendingMinorOpcode == ICE_ConnectionSetup) ||
+            (iceConn->connect_to_you->auth_active &&
+           message->offendingMinorOpcode == ICE_AuthReply)))
+       {
+           _IceConnectionError *errorReply =
+               &(((_IceReply *) (replyWait->reply))->connection_error);
+           char *errorStr = NULL;
+           const char *tempstr;
+           char *prefix, *temp;
+
+           invokeHandler = 0;
+           errorReturned = True;
+
+           switch (message->errorClass)
+           {
+           case IceNoVersion:
+
+               tempstr =
+                   "None of the ICE versions specified are supported";
+               errorStr = strdup(tempstr);
+               break;
+
+           case IceNoAuth:
+
+               tempstr =
+                   "None of the authentication protocols specified are supported";
+               errorStr = strdup(tempstr);
+               break;
+
+           case IceSetupFailed:
+
+               prefix = "Connection Setup Failed, reason : ";
+
+               EXTRACT_STRING (pData, swap, temp);
+               errorStr = (char *) malloc (
+                   strlen (prefix) + strlen (temp) + 1);
+               sprintf (errorStr, "%s%s", prefix, temp);
+               free (temp);
+               break;
+
+           case IceAuthRejected:
+
+               prefix = "Authentication Rejected, reason : ";
+               EXTRACT_STRING (pData, swap, temp);
+               errorStr = (char *) malloc (
+                   strlen (prefix) + strlen (temp) + 1);
+               sprintf (errorStr, "%s%s", prefix, temp);
+               free (temp);
+               break;
+
+           case IceAuthFailed:
+
+               prefix = "Authentication Failed, reason : ";
+               EXTRACT_STRING (pData, swap, temp);
+               errorStr = (char *) malloc (
+                   strlen (prefix) + strlen (temp) + 1);
+               sprintf (errorStr, "%s%s", prefix, temp);
+               free (temp);
+               break;
+
+           default:
+               invokeHandler = 1;
+           }
+
+           errorReply->type = ICE_CONNECTION_ERROR;
+           errorReply->error_message = errorStr;
+       }
+       else if (iceConn->protosetup_to_you &&
+           ((!iceConn->protosetup_to_you->auth_active &&
+            message->offendingMinorOpcode == ICE_ProtocolSetup) ||
+            (iceConn->protosetup_to_you->auth_active &&
+           message->offendingMinorOpcode == ICE_AuthReply)))
+       {
+           _IceProtocolError *errorReply =
+               &(((_IceReply *) (replyWait->reply))->protocol_error);
+           char *errorStr = "";
+           char *prefix, *temp;
+
+           invokeHandler = 0;
+           errorReturned = True;
+
+           switch (message->errorClass)
+           {
+           case IceNoVersion:
+
+               temp =
+                   "None of the protocol versions specified are supported";
+               errorStr = strdup(temp);
+               break;
+
+           case IceNoAuth:
+
+               temp =
+                   "None of the authentication protocols specified are supported";
+               errorStr = strdup(temp);
+               break;
+
+           case IceSetupFailed:
+
+               prefix = "Protocol Setup Failed, reason : ";
+
+               EXTRACT_STRING (pData, swap, temp);
+               errorStr = (char *) malloc (
+                   strlen (prefix) + strlen (temp) + 1);
+               sprintf (errorStr, "%s%s", prefix, temp);
+               free (temp);
+               break;
+
+           case IceAuthRejected:
+
+               prefix = "Authentication Rejected, reason : ";
+               EXTRACT_STRING (pData, swap, temp);
+               errorStr = (char *) malloc (
+                   strlen (prefix) + strlen (temp) + 1);
+               sprintf (errorStr, "%s%s", prefix, temp);
+               free (temp);
+               break;
+
+           case IceAuthFailed:
+
+               prefix = "Authentication Failed, reason : ";
+               EXTRACT_STRING (pData, swap, temp);
+               errorStr = (char *) malloc (
+                   strlen (prefix) + strlen (temp) + 1);
+               sprintf (errorStr, "%s%s", prefix, temp);
+               free (temp);
+               break;
+
+           case IceProtocolDuplicate:
+
+               prefix = "Protocol was already registered : ";
+               EXTRACT_STRING (pData, swap, temp);
+               errorStr = (char *) malloc (
+                   strlen (prefix) + strlen (temp) + 1);
+               sprintf (errorStr, "%s%s", prefix, temp);
+               free (temp);
+               break;
+
+           case IceMajorOpcodeDuplicate:
+
+               prefix = "The major opcode was already used : ";
+               errorStr = (char *) malloc (strlen (prefix) + 2);
+               sprintf (errorStr, "%s%d", prefix, (int) *pData);
+               break;
+
+           case IceUnknownProtocol:
+
+               prefix = "Unknown Protocol : ";
+               EXTRACT_STRING (pData, swap, temp);
+               errorStr = (char *) malloc (
+                   strlen (prefix) + strlen (temp) + 1);
+               sprintf (errorStr, "%s%s", prefix, temp);
+               free (temp);
+               break;
+
+           default:
+               invokeHandler = 1;
+           }
+
+           errorReply->type = ICE_PROTOCOL_ERROR;
+           errorReply->error_message = errorStr;
+       }
+
+       if (errorReturned == True)
+       {
+           /*
+            * If we tried to authenticate, tell the authentication
+            * procedure to clean up.
+            */
+
+           IcePoAuthProc authProc;
+
+           if (iceConn->connect_to_you &&
+               iceConn->connect_to_you->auth_active)
+           {
+               authProc = _IcePoAuthProcs[(int)
+                   (iceConn->connect_to_you->my_auth_index)];
+
+               (*authProc) (iceConn, &iceConn->connect_to_you->my_auth_state,
+                   True /* clean up */, False /* swap */,
+                   0, NULL, NULL, NULL, NULL);
+           }
+           else if (iceConn->protosetup_to_you &&
+               iceConn->protosetup_to_you->auth_active)
+           {
+               _IcePoProtocol *protocol = _IceProtocols[
+                   iceConn->protosetup_to_you->my_opcode - 1].orig_client;
+
+               authProc = protocol->auth_procs[(int)(iceConn->
+                   protosetup_to_you->my_auth_index)];
+
+               (*authProc) (iceConn,
+                   &iceConn->protosetup_to_you->my_auth_state,
+                   True /* clean up */, False /* swap */,
+                   0, NULL, NULL, NULL, NULL);
+           }
+       }
+    }
+
+    if (invokeHandler)
+    {
+       (*_IceErrorHandler) (iceConn, swap, message->offendingMinorOpcode,
+           message->offendingSequenceNum, message->errorClass,
+           message->severity, (IcePointer) pData);
+    }
+
+    IceDisposeCompleteMessage (iceConn, pStart);
+
+    return (errorReturned);
+}
+
+
+\f
+static int
+ProcessConnectionSetup (
+       IceConn         iceConn,
+       unsigned long   length,
+       Bool            swap
+)
+{
+    iceConnectionSetupMsg *message;
+    int  myVersionCount, hisVersionCount;
+    int         myVersionIndex, hisVersionIndex;
+    int  hisMajorVersion, hisMinorVersion;
+    int         myAuthCount, hisAuthCount;
+    int         found, i, j;
+    char *myAuthName, **hisAuthNames = NULL;
+    char *pData, *pStart, *pEnd;
+    char *vendor = NULL;
+    char *release = NULL;
+    int myAuthIndex = 0;
+    int hisAuthIndex = 0;
+    int accept_setup_now = 0;
+    char mustAuthenticate;
+    int        authUsableCount;
+    int        authUsableFlags[MAX_ICE_AUTH_NAMES];
+    int        authIndices[MAX_ICE_AUTH_NAMES];
+
+    CHECK_AT_LEAST_SIZE (iceConn, ICE_ConnectionSetup,
+       length, SIZEOF (iceConnectionSetupMsg), IceFatalToConnection);
+
+    IceReadCompleteMessage (iceConn, SIZEOF (iceConnectionSetupMsg),
+       iceConnectionSetupMsg, message, pStart);
+
+    if (!IceValidIO (iceConn))
+    {
+       IceDisposeCompleteMessage (iceConn, pStart);
+       return (0);
+    }
+
+    pData = pStart;
+    pEnd = pStart + (length << 3);
+    
+    SKIP_STRING (pData, swap, pEnd, 
+                BAIL_STRING(iceConn, ICE_ConnectionSetup,
+                            pStart));                         /* vendor */
+    SKIP_STRING (pData, swap, pEnd, 
+                BAIL_STRING(iceConn, ICE_ConnectionSetup,
+                           pStart));                          /* release */
+    SKIP_LISTOF_STRING (pData, swap, (int) message->authCount, pEnd, 
+                       BAIL_STRING(iceConn, ICE_ConnectionSetup,
+                                  pStart));                   /* auth names */
+    
+    pData += (message->versionCount * 4);                     /* versions */
+
+    CHECK_COMPLETE_SIZE (iceConn, ICE_ConnectionSetup,
+       length, pData - pStart + SIZEOF (iceConnectionSetupMsg),
+       pStart, IceFatalToConnection);
+
+    mustAuthenticate = message->mustAuthenticate;
+    if (mustAuthenticate != 0 && mustAuthenticate != 1)
+    {
+       _IceErrorBadValue (iceConn, 0,
+           ICE_ConnectionSetup, 8, 1, &mustAuthenticate);
+       iceConn->connection_status = IceConnectRejected;
+       IceDisposeCompleteMessage (iceConn, pStart);
+       return (0);
+    }
+
+    pData = pStart;
+
+    EXTRACT_STRING (pData, swap, vendor);
+    EXTRACT_STRING (pData, swap, release);
+
+    if ((hisAuthCount = message->authCount) > 0)
+    {
+       hisAuthNames = (char **) malloc (hisAuthCount * sizeof (char *));
+       EXTRACT_LISTOF_STRING (pData, swap, hisAuthCount, hisAuthNames);
+    }
+
+    hisVersionCount = message->versionCount;
+    myVersionCount = _IceVersionCount;
+
+    hisVersionIndex = myVersionIndex = found = 0;
+
+    for (i = 0; i < hisVersionCount && !found; i++)
+    {
+       EXTRACT_CARD16 (pData, swap, hisMajorVersion);
+       EXTRACT_CARD16 (pData, swap, hisMinorVersion);
+
+       for (j = 0; j < myVersionCount && !found; j++)
+       {
+           if (_IceVersions[j].major_version == hisMajorVersion &&
+               _IceVersions[j].minor_version == hisMinorVersion)
+           {
+               hisVersionIndex = i;
+               myVersionIndex = j;
+               found = 1;
+           }
+       }
+    }
+
+    if (!found)
+    {
+       _IceErrorNoVersion (iceConn, ICE_ConnectionSetup);
+       iceConn->connection_status = IceConnectRejected;
+
+       free (vendor);
+       free (release);
+
+       if (hisAuthCount > 0)
+       {
+           for (i = 0; i < hisAuthCount; i++)
+               free (hisAuthNames[i]);
+       
+           free ((char *) hisAuthNames);
+       }
+
+       IceDisposeCompleteMessage (iceConn, pStart);
+       return (0);
+    }
+
+    _IceGetPaValidAuthIndices ("ICE", iceConn->connection_string,
+       _IceAuthCount, _IceAuthNames, &authUsableCount, authIndices);
+
+    for (i = 0; i < _IceAuthCount; i++)
+    {
+       authUsableFlags[i] = 0;
+       for (j = 0; j < authUsableCount && !authUsableFlags[i]; j++)
+           authUsableFlags[i] = (authIndices[j] == i);
+    }
+
+    myAuthCount = _IceAuthCount;
+
+    for (i = found = 0; i < myAuthCount && !found; i++)
+    {
+       if (authUsableFlags[i])
+       {
+           myAuthName = _IceAuthNames[i];
+
+           for (j = 0; j < hisAuthCount && !found; j++)
+               if (strcmp (myAuthName, hisAuthNames[j]) == 0)
+               {
+                   myAuthIndex = i;
+                   hisAuthIndex = j;
+                   found = 1;
+               }
+       }
+    }
+
+    if (!found)
+    {
+       /*
+        * None of the authentication methods specified by the
+        * other client is supported.  If the other client requires
+        * authentication, we must reject the connection now.
+        * Otherwise, we can invoke the host-based authentication callback
+        * to see if we can accept this connection.
+        */
+
+       if (mustAuthenticate || !iceConn->listen_obj->host_based_auth_proc)
+       {
+           _IceErrorNoAuthentication (iceConn, ICE_ConnectionSetup);
+           iceConn->connection_status = IceConnectRejected;
+       }
+       else
+       {
+           char *hostname = _IceGetPeerName (iceConn);
+
+           if ((*iceConn->listen_obj->host_based_auth_proc) (hostname))
+           {
+               accept_setup_now = 1;
+           }
+           else 
+           {
+               _IceErrorAuthenticationRejected (iceConn,
+                   ICE_ConnectionSetup, "None of the authentication protocols specified are supported and host-based authentication failed");
+
+               iceConn->connection_status = IceConnectRejected;
+           }
+
+           if (hostname)
+               free (hostname);
+       }
+
+       if (iceConn->connection_status == IceConnectRejected)
+       {
+           free (vendor);
+           free (release);
+       }
+    }
+    else
+    {
+       IcePaAuthStatus status;
+       int             authDataLen;
+       IcePointer      authData = NULL;
+       IcePointer      authState;
+       char            *errorString = NULL;
+       IcePaAuthProc   authProc = _IcePaAuthProcs[myAuthIndex];
+
+       authState = NULL;
+
+       status = (*authProc) (iceConn, &authState,
+           swap, 0, NULL, &authDataLen, &authData, &errorString);
+
+       if (status == IcePaAuthContinue)
+       {
+           _IceConnectToMeInfo *setupInfo;
+
+           AuthRequired (iceConn, hisAuthIndex, authDataLen, authData);
+
+           iceConn->connect_to_me = setupInfo = (_IceConnectToMeInfo *)
+               malloc (sizeof (_IceConnectToMeInfo));
+
+           setupInfo->my_version_index = myVersionIndex;
+           setupInfo->his_version_index = hisVersionIndex;
+           setupInfo->his_vendor = vendor;
+           setupInfo->his_release = release;
+           setupInfo->my_auth_index = myAuthIndex;
+           setupInfo->my_auth_state = authState;
+           setupInfo->must_authenticate = mustAuthenticate;
+       }
+       else if (status == IcePaAuthAccepted)
+       {
+           accept_setup_now = 1;
+       }
+
+       if (authData && authDataLen > 0)
+           free ((char *) authData);
+
+       if (errorString)
+           free (errorString);
+    }
+    
+    if (accept_setup_now)
+    {
+       AcceptConnection (iceConn, hisVersionIndex);
+
+       iceConn->vendor = vendor;
+       iceConn->release = release;
+       iceConn->my_ice_version_index = myVersionIndex;
+    }
+
+    if (hisAuthCount > 0)
+    {
+       for (i = 0; i < hisAuthCount; i++)
+           free (hisAuthNames[i]);
+       
+       free ((char *) hisAuthNames);
+    }
+
+    IceDisposeCompleteMessage (iceConn, pStart);
+    return (0);
+}
+
+
+\f
+static Bool
+ProcessAuthRequired (
+       IceConn                 iceConn,
+       unsigned long           length,
+       Bool                    swap,
+       IceReplyWaitInfo        *replyWait
+)
+{
+    iceAuthRequiredMsg  *message;
+    int                        authDataLen;
+    IcePointer                 authData;
+    int                replyDataLen;
+    IcePointer                 replyData = NULL;
+    char               *errorString = NULL;
+    IcePoAuthProc      authProc;
+    IcePoAuthStatus    status;
+    IcePointer                 authState;
+    int                        realAuthIndex = 0;
+
+    CHECK_AT_LEAST_SIZE (iceConn, ICE_AuthRequired,
+       length, SIZEOF (iceAuthRequiredMsg),
+       iceConn->connect_to_you ? IceFatalToConnection : IceFatalToProtocol);
+
+    IceReadCompleteMessage (iceConn, SIZEOF (iceAuthRequiredMsg),
+       iceAuthRequiredMsg, message, authData);
+
+    if (!IceValidIO (iceConn))
+    {
+       IceDisposeCompleteMessage (iceConn, authData);
+       return (0);
+    }
+
+    if (swap)
+    {
+       message->authDataLength = lswaps (message->authDataLength);
+    }
+
+    CHECK_COMPLETE_SIZE (iceConn, ICE_AuthRequired, length,
+       message->authDataLength + SIZEOF (iceAuthRequiredMsg), authData,
+       iceConn->connect_to_you ? IceFatalToConnection : IceFatalToProtocol);
+
+    if (iceConn->connect_to_you)
+    {
+       if ((int) message->authIndex >= _IceAuthCount)
+       {
+           _IceConnectionError *errorReply =
+               &(((_IceReply *) (replyWait->reply))->connection_error);
+
+           const char *tempstr
+               = "Received bad authIndex in the AuthRequired message";
+           char errIndex = (int) message->authIndex;
+
+           errorString = strdup(tempstr);
+
+           errorReply->type = ICE_CONNECTION_ERROR;
+           errorReply->error_message = errorString;
+
+           _IceErrorBadValue (iceConn, 0,
+               ICE_AuthRequired, 2, 1, &errIndex);
+
+           IceDisposeCompleteMessage (iceConn, authData);
+           return (1);
+       }
+       else
+       {
+           authProc = _IcePoAuthProcs[message->authIndex];
+
+           iceConn->connect_to_you->auth_active = 1;
+       }
+    }
+    else if (iceConn->protosetup_to_you)
+    {
+       if ((int) message->authIndex >=
+           iceConn->protosetup_to_you->my_auth_count)
+       {
+           _IceProtocolError *errorReply =
+               &(((_IceReply *) (replyWait->reply))->protocol_error);
+
+           const char *tempstr
+               = "Received bad authIndex in the AuthRequired message";
+           char errIndex = (int) message->authIndex;
+
+           errorString = strdup(tempstr);
+
+           errorReply->type = ICE_PROTOCOL_ERROR;
+           errorReply->error_message = errorString;
+
+           _IceErrorBadValue (iceConn, 0,
+               ICE_AuthRequired, 2, 1, &errIndex);
+
+           IceDisposeCompleteMessage (iceConn, authData);
+           return (1);
+       }
+       else
+       {
+           _IcePoProtocol *myProtocol = _IceProtocols[
+               iceConn->protosetup_to_you->my_opcode - 1].orig_client;
+
+           realAuthIndex = iceConn->protosetup_to_you->
+               my_auth_indices[message->authIndex];
+
+           authProc = myProtocol->auth_procs[realAuthIndex];
+
+           iceConn->protosetup_to_you->auth_active = 1;
+       }
+    }
+    else
+    {
+       /*
+        * Unexpected message
+        */
+
+       _IceErrorBadState (iceConn, 0, ICE_AuthRequired, IceCanContinue);
+
+       IceDisposeCompleteMessage (iceConn, authData);
+       return (0);
+    }
+
+    authState = NULL;
+    authDataLen = message->authDataLength;
+
+    status = (*authProc) (iceConn, &authState, False /* don't clean up */,
+       swap, authDataLen, authData, &replyDataLen, &replyData, &errorString);
+
+    if (status == IcePoAuthHaveReply)
+    {
+       AuthReply (iceConn, replyDataLen, replyData);
+
+       replyWait->sequence_of_request = iceConn->send_sequence;
+       replyWait->minor_opcode_of_request = ICE_AuthReply;
+
+       if (iceConn->connect_to_you)
+       {
+           iceConn->connect_to_you->my_auth_state = authState;
+           iceConn->connect_to_you->my_auth_index = message->authIndex;
+       }
+       else if (iceConn->protosetup_to_you)
+       {
+           iceConn->protosetup_to_you->my_auth_state = authState;
+           iceConn->protosetup_to_you->my_auth_index = realAuthIndex;
+       }
+    }
+    else if (status == IcePoAuthRejected || status == IcePoAuthFailed)
+    {
+       char *prefix, *returnErrorString;
+
+       if (status == IcePoAuthRejected)
+       {
+           _IceErrorAuthenticationRejected (iceConn,
+               ICE_AuthRequired, errorString);
+
+           prefix = "Authentication Rejected, reason : ";
+       }
+       else
+       {
+           _IceErrorAuthenticationFailed (iceConn,
+              ICE_AuthRequired, errorString);
+
+           prefix = "Authentication Failed, reason : ";
+       }
+
+       returnErrorString = (char *) malloc (strlen (prefix) +
+           strlen (errorString) + 1);
+       sprintf (returnErrorString, "%s%s", prefix, errorString);
+       free (errorString);
+       
+       if (iceConn->connect_to_you)
+       {
+           _IceConnectionError *errorReply =
+               &(((_IceReply *) (replyWait->reply))->connection_error);
+
+           errorReply->type = ICE_CONNECTION_ERROR;
+           errorReply->error_message = returnErrorString;
+       }
+       else
+       {
+           _IceProtocolError *errorReply =
+               &(((_IceReply *) (replyWait->reply))->protocol_error);
+
+           errorReply->type = ICE_PROTOCOL_ERROR;
+           errorReply->error_message = returnErrorString;
+       }
+    }
+
+    if (replyData && replyDataLen > 0)
+       free ((char *) replyData);
+
+    IceDisposeCompleteMessage (iceConn, authData);
+
+    return (status != IcePoAuthHaveReply);
+}
+
+
+\f
+static int
+ProcessAuthReply (
+       IceConn         iceConn,
+       unsigned long   length,
+       Bool            swap
+)
+{
+    iceAuthReplyMsg    *message;
+    int                        replyDataLen;
+    IcePointer         replyData;
+    int                authDataLen;
+    IcePointer                 authData = NULL;
+    char               *errorString = NULL;
+
+    CHECK_AT_LEAST_SIZE (iceConn, ICE_AuthReply,
+       length, SIZEOF (iceAuthReplyMsg),
+       iceConn->connect_to_me ? IceFatalToConnection : IceFatalToProtocol);
+
+    IceReadCompleteMessage (iceConn, SIZEOF (iceAuthReplyMsg),
+       iceAuthReplyMsg, message, replyData);
+
+    if (!IceValidIO (iceConn))
+    {
+       IceDisposeCompleteMessage (iceConn, replyData);
+       return (0);
+    }
+
+    if (swap)
+    {
+       message->authDataLength = lswaps (message->authDataLength);
+    }
+
+    CHECK_COMPLETE_SIZE (iceConn, ICE_AuthReply, length,
+       message->authDataLength + SIZEOF (iceAuthReplyMsg), replyData,
+       iceConn->connect_to_me ? IceFatalToConnection : IceFatalToProtocol);
+
+    replyDataLen = message->authDataLength;
+
+    if (iceConn->connect_to_me)
+    {
+       IcePaAuthProc authProc = _IcePaAuthProcs[(int)
+           (iceConn->connect_to_me->my_auth_index)];
+       IcePaAuthStatus status =
+           (*authProc) (iceConn, &iceConn->connect_to_me->my_auth_state, swap,
+           replyDataLen, replyData, &authDataLen, &authData, &errorString);
+
+       if (status == IcePaAuthContinue)
+       {
+           AuthNextPhase (iceConn, authDataLen, authData);
+       }
+       else if (status == IcePaAuthRejected || status == IcePaAuthFailed)
+       {
+           /*
+            * Before we reject, invoke host-based authentication callback
+            * and give it a chance to accept the connection (only if the
+            * other client doesn't require authentication).
+            */
+
+           if (!iceConn->connect_to_me->must_authenticate &&
+               iceConn->listen_obj->host_based_auth_proc)
+           {
+               char *hostname = _IceGetPeerName (iceConn);
+
+               if ((*iceConn->listen_obj->host_based_auth_proc) (hostname))
+               {
+                   status = IcePaAuthAccepted;
+               }
+
+               if (hostname)
+                   free (hostname);
+           }
+
+           if (status != IcePaAuthAccepted)
+           {
+               free (iceConn->connect_to_me->his_vendor);
+               free (iceConn->connect_to_me->his_release);
+               free ((char *) iceConn->connect_to_me);
+               iceConn->connect_to_me = NULL;
+
+               iceConn->connection_status = IceConnectRejected;
+
+               if (status == IcePaAuthRejected)
+               {
+                   _IceErrorAuthenticationRejected (iceConn,
+                       ICE_AuthReply, errorString);
+               }
+               else
+               {
+                   _IceErrorAuthenticationFailed (iceConn,
+                       ICE_AuthReply, errorString);
+               }
+           }
+       }
+
+       if (status == IcePaAuthAccepted)
+       {
+           AcceptConnection (iceConn,
+               iceConn->connect_to_me->his_version_index);
+
+           iceConn->vendor = iceConn->connect_to_me->his_vendor;
+           iceConn->release = iceConn->connect_to_me->his_release;
+           iceConn->my_ice_version_index =
+               iceConn->connect_to_me->my_version_index;
+
+           free ((char *) iceConn->connect_to_me);
+           iceConn->connect_to_me = NULL;
+       }
+    }
+    else if (iceConn->protosetup_to_me)
+    {
+       _IcePaProtocol *myProtocol = _IceProtocols[iceConn->protosetup_to_me->
+           my_opcode - 1].accept_client;
+       IcePaAuthProc authProc = myProtocol->auth_procs[(int)
+           (iceConn->protosetup_to_me->my_auth_index)];
+       IcePaAuthStatus status =
+           (*authProc) (iceConn, &iceConn->protosetup_to_me->my_auth_state,
+           swap, replyDataLen, replyData,
+           &authDataLen, &authData, &errorString);
+       int free_setup_info = 1;
+
+       if (status == IcePaAuthContinue)
+       {
+           AuthNextPhase (iceConn, authDataLen, authData);
+           free_setup_info = 0;
+       }
+       else if (status == IcePaAuthRejected || status == IcePaAuthFailed)
+       {
+           /*
+            * Before we reject, invoke host-based authentication callback
+            * and give it a chance to accept the Protocol Setup (only if the
+            * other client doesn't require authentication).
+            */
+
+           if (!iceConn->protosetup_to_me->must_authenticate &&
+               myProtocol->host_based_auth_proc)
+           {
+               char *hostname = _IceGetPeerName (iceConn);
+
+               if ((*myProtocol->host_based_auth_proc) (hostname))
+               {
+                   status = IcePaAuthAccepted;
+               }
+
+               if (hostname)
+                   free (hostname);
+           }
+
+           if (status == IcePaAuthRejected)
+           {
+               _IceErrorAuthenticationRejected (iceConn,
+                   ICE_AuthReply, errorString);
+           }
+           else
+           {
+               _IceErrorAuthenticationFailed (iceConn,
+                   ICE_AuthReply, errorString);
+           }
+       }
+
+       if (status == IcePaAuthAccepted)
+       {
+           IcePaProcessMsgProc processMsgProc;
+           IceProtocolSetupProc protocolSetupProc;
+           IceProtocolActivateProc protocolActivateProc;
+           _IceProcessMsgInfo *process_msg_info;
+           IcePointer clientData = NULL;
+           char *failureReason = NULL;
+           Status status = 1;
+
+           protocolSetupProc = myProtocol->protocol_setup_proc;
+           protocolActivateProc = myProtocol->protocol_activate_proc;
+
+           if (protocolSetupProc)
+           {
+               /*
+                * Notify the client of the Protocol Setup.
+                */
+
+               status = (*protocolSetupProc) (iceConn,
+                   myProtocol->version_recs[iceConn->protosetup_to_me->
+                       my_version_index].major_version,
+                   myProtocol->version_recs[iceConn->protosetup_to_me->
+                       my_version_index].minor_version,
+                   iceConn->protosetup_to_me->his_vendor,
+                   iceConn->protosetup_to_me->his_release,
+                   &clientData, &failureReason);
+
+               /*
+                * Set vendor and release pointers to NULL, so it won't
+                * get freed below.  The ProtocolSetupProc should
+                * free it.
+                */
+
+               iceConn->protosetup_to_me->his_vendor = NULL;
+               iceConn->protosetup_to_me->his_release = NULL;
+           }
+
+           if (status != 0)
+           {
+               /*
+                * Send the Protocol Reply
+                */
+
+               AcceptProtocol (iceConn,
+                   iceConn->protosetup_to_me->his_opcode,
+                   iceConn->protosetup_to_me->my_opcode,
+                   iceConn->protosetup_to_me->his_version_index,
+                   myProtocol->vendor, myProtocol->release);
+
+
+               /*
+                * Set info for this protocol.
+                */
+
+               processMsgProc = myProtocol->version_recs[
+                   iceConn->protosetup_to_me->
+                   my_version_index].process_msg_proc;
+
+               process_msg_info = &iceConn->process_msg_info[
+                   iceConn->protosetup_to_me->
+                   his_opcode -iceConn->his_min_opcode];
+
+               process_msg_info->client_data = clientData;
+               process_msg_info->accept_flag = 1;
+               process_msg_info->process_msg_proc.
+                   accept_client = processMsgProc;
+
+
+               /*
+                * Increase the reference count for the number
+                * of active protocols.
+                */
+
+               iceConn->proto_ref_count++;
+
+
+               /*
+                * Notify the client that the protocol is active.  The reason
+                * we have this 2nd callback invoked is because the client
+                * may wish to immediately generate a message for this
+                * protocol, but it must wait until we send the Protocol Reply.
+                */
+
+               if (protocolActivateProc)
+               {
+                   (*protocolActivateProc) (iceConn,
+                       process_msg_info->client_data);
+               }
+           }
+           else
+           {
+               /*
+                * An error was encountered.
+                */
+
+               _IceErrorSetupFailed (iceConn, ICE_ProtocolSetup,
+                   failureReason);
+
+               if (failureReason)
+                   free (failureReason);
+           }
+       }
+
+
+       if (free_setup_info)
+       {
+           if (iceConn->protosetup_to_me->his_vendor)
+               free (iceConn->protosetup_to_me->his_vendor);
+           if (iceConn->protosetup_to_me->his_release)
+               free (iceConn->protosetup_to_me->his_release);
+           free ((char *) iceConn->protosetup_to_me);
+           iceConn->protosetup_to_me = NULL;
+       }
+    }
+    else
+    {
+       /*
+        * Unexpected message
+        */
+
+       _IceErrorBadState (iceConn, 0, ICE_AuthReply, IceCanContinue);
+    }
+
+    if (authData && authDataLen > 0)
+       free ((char *) authData);
+
+    if (errorString)
+       free (errorString);
+
+    IceDisposeCompleteMessage (iceConn, replyData);
+    return (0);
+}
+
+
+\f
+static Bool
+ProcessAuthNextPhase (
+       IceConn                 iceConn,
+       unsigned long           length,
+       Bool                    swap,
+       IceReplyWaitInfo        *replyWait
+)
+{
+    iceAuthNextPhaseMsg *message;
+    int                authDataLen;
+    IcePointer         authData;
+    int                replyDataLen;
+    IcePointer         replyData = NULL;
+    char               *errorString = NULL;
+    IcePoAuthProc      authProc;
+    IcePoAuthStatus    status;
+    IcePointer                 *authState;
+
+    CHECK_AT_LEAST_SIZE (iceConn, ICE_AuthNextPhase,
+       length, SIZEOF (iceAuthNextPhaseMsg),
+       iceConn->connect_to_you ? IceFatalToConnection : IceFatalToProtocol);
+
+    IceReadCompleteMessage (iceConn, SIZEOF (iceAuthNextPhaseMsg),
+       iceAuthNextPhaseMsg, message, authData);
+
+    if (!IceValidIO (iceConn))
+    {
+       IceDisposeCompleteMessage (iceConn, authData);
+       return (0);
+    }
+
+    if (swap)
+    {
+       message->authDataLength = lswaps (message->authDataLength);
+    }
+
+    CHECK_COMPLETE_SIZE (iceConn, ICE_AuthNextPhase, length,
+       message->authDataLength + SIZEOF (iceAuthNextPhaseMsg), authData,
+       iceConn->connect_to_you ? IceFatalToConnection : IceFatalToProtocol);
+
+    if (iceConn->connect_to_you)
+    {
+       authProc = _IcePoAuthProcs[(int)
+           (iceConn->connect_to_you->my_auth_index)];
+
+       authState = &iceConn->connect_to_you->my_auth_state;
+    }
+    else if (iceConn->protosetup_to_you)
+    {
+       _IcePoProtocol *myProtocol =
+         _IceProtocols[iceConn->protosetup_to_you->my_opcode - 1].orig_client;
+
+       authProc = myProtocol->auth_procs[(int)
+           (iceConn->protosetup_to_you->my_auth_index)];
+
+       authState = &iceConn->protosetup_to_you->my_auth_state;
+    }
+    else
+    {
+       /*
+        * Unexpected message
+        */
+
+       _IceErrorBadState (iceConn, 0, ICE_AuthNextPhase, IceCanContinue);
+
+       IceDisposeCompleteMessage (iceConn, authData);
+       return (0);
+    }
+
+    authDataLen = message->authDataLength;
+
+    status = (*authProc) (iceConn, authState, False /* don't clean up */,
+       swap, authDataLen, authData, &replyDataLen, &replyData, &errorString);
+
+    if (status == IcePoAuthHaveReply)
+    {
+       AuthReply (iceConn, replyDataLen, replyData);
+
+       replyWait->sequence_of_request = iceConn->send_sequence;
+    }
+    else if (status == IcePoAuthRejected || status == IcePoAuthFailed)
+    {
+       char *prefix = NULL, *returnErrorString;
+
+       if (status == IcePoAuthRejected)
+       {
+           _IceErrorAuthenticationRejected (iceConn,
+              ICE_AuthNextPhase, errorString);
+
+           prefix = "Authentication Rejected, reason : ";
+       }
+       else if (status == IcePoAuthFailed)
+       {
+           _IceErrorAuthenticationFailed (iceConn,
+              ICE_AuthNextPhase, errorString);
+
+           prefix = "Authentication Failed, reason : ";
+       }
+
+       returnErrorString = (char *) malloc (strlen (prefix) +
+           strlen (errorString) + 1);
+       sprintf (returnErrorString, "%s%s", prefix, errorString);
+       free (errorString);
+
+       if (iceConn->connect_to_you)
+       {
+           _IceConnectionError *errorReply =
+               &(((_IceReply *) (replyWait->reply))->connection_error);
+
+           errorReply->type = ICE_CONNECTION_ERROR;
+           errorReply->error_message = returnErrorString;
+       }
+       else
+       {
+           _IceProtocolError *errorReply =
+               &(((_IceReply *) (replyWait->reply))->protocol_error);
+
+           errorReply->type = ICE_PROTOCOL_ERROR;
+           errorReply->error_message = returnErrorString;
+       }
+    }
+
+    if (replyData && replyDataLen > 0)
+       free ((char *) replyData);
+
+    IceDisposeCompleteMessage (iceConn, authData);
+
+    return (status != IcePoAuthHaveReply);
+}
+
+
+\f
+static Bool
+ProcessConnectionReply (
+       IceConn                 iceConn,
+       unsigned long           length,
+       Bool                    swap,
+       IceReplyWaitInfo        *replyWait
+)
+{
+    iceConnectionReplyMsg      *message;
+    char                       *pData, *pStart, *pEnd;
+    Bool                       replyReady;
+
+#if 0 /* No-op */
+    CHECK_AT_LEAST_SIZE (iceConn, ICE_ConnectionReply,
+       length, SIZEOF (iceConnectionReplyMsg), IceFatalToConnection);
+#endif
+
+    IceReadCompleteMessage (iceConn, SIZEOF (iceConnectionReplyMsg),
+       iceConnectionReplyMsg, message, pStart);
+
+    if (!IceValidIO (iceConn))
+    {
+       IceDisposeCompleteMessage (iceConn, pStart);
+       return (0);
+    }
+
+    pData = pStart;
+    pEnd = pStart + (length << 3);
+
+    SKIP_STRING (pData, swap, pEnd,
+                BAIL_STRING (iceConn, ICE_ConnectionReply,
+                             pStart));                      /* vendor */
+    SKIP_STRING (pData, swap, pEnd,
+                BAIL_STRING (iceConn, ICE_ConnectionReply,
+                             pStart));                      /* release */
+
+    CHECK_COMPLETE_SIZE (iceConn, ICE_ConnectionReply,
+       length, pData - pStart + SIZEOF (iceConnectionReplyMsg),
+       pStart, IceFatalToConnection);
+
+    pData = pStart;
+
+    if (iceConn->connect_to_you)
+    {
+       if (iceConn->connect_to_you->auth_active)
+       {
+           /*
+            * Tell the authentication procedure to clean up.
+            */
+
+           IcePoAuthProc authProc = _IcePoAuthProcs[(int)
+               (iceConn->connect_to_you->my_auth_index)];
+
+           (*authProc) (iceConn, &iceConn->connect_to_you->my_auth_state,
+               True /* clean up */, False /* swap */,
+               0, NULL, NULL, NULL, NULL);
+       }
+
+       if ((int) message->versionIndex >= _IceVersionCount)
+       {
+           _IceConnectionError *errorReply =
+               &(((_IceReply *) (replyWait->reply))->connection_error);
+           char errIndex = message->versionIndex;
+
+           _IceErrorBadValue (iceConn, 0,
+               ICE_ConnectionReply, 2, 1, &errIndex);
+           
+           errorReply->type = ICE_CONNECTION_ERROR;
+           errorReply->error_message =
+               "Received bad version index in Connection Reply";
+       }
+       else
+       {
+           _IceReply *reply = (_IceReply *) (replyWait->reply);
+
+           reply->type = ICE_CONNECTION_REPLY;
+           reply->connection_reply.version_index = message->versionIndex;
+
+           EXTRACT_STRING (pData, swap, reply->connection_reply.vendor);
+           EXTRACT_STRING (pData, swap, reply->connection_reply.release);
+       }
+
+       replyReady = True;
+    }
+    else
+    {
+       /*
+        * Unexpected message
+        */
+
+       _IceErrorBadState (iceConn, 0, ICE_ConnectionReply, IceCanContinue);
+
+       replyReady = False;
+    }
+
+    IceDisposeCompleteMessage (iceConn, pStart);
+
+    return (replyReady);
+}
+
+
+\f
+static int
+ProcessProtocolSetup (
+       IceConn         iceConn,
+       unsigned long   length,
+       Bool            swap
+)
+{
+    iceProtocolSetupMsg        *message;
+    _IcePaProtocol     *myProtocol;
+    int                myVersionCount, hisVersionCount;
+    int                        myVersionIndex, hisVersionIndex;
+    int                hisMajorVersion, hisMinorVersion;
+    int                        myAuthCount, hisAuthCount;
+    int                myOpcode, hisOpcode;
+    int                        found, i, j;
+    char               *myAuthName, **hisAuthNames = NULL;
+    char               *protocolName;
+    char               *pData, *pStart, *pEnd;
+    char               *vendor = NULL;
+    char               *release = NULL;
+    int                accept_setup_now = 0;
+    int                        myAuthIndex = 0;
+    int                        hisAuthIndex = 0;
+    char               mustAuthenticate;
+    int                        authUsableCount;
+    int                        authUsableFlags[MAX_ICE_AUTH_NAMES];
+    int                        authIndices[MAX_ICE_AUTH_NAMES];
+
+    CHECK_AT_LEAST_SIZE (iceConn, ICE_ProtocolSetup,
+       length, SIZEOF (iceProtocolSetupMsg), IceFatalToProtocol);
+
+    if (iceConn->want_to_close)
+    {
+       /*
+        * If we sent a WantToClose message, but just got a ProtocolSetup,
+        * we must cancel our WantToClose.  It is the responsiblity of the
+        * other client to send a WantToClose later on.
+        */
+
+       iceConn->want_to_close = 0;
+    }
+
+    IceReadCompleteMessage (iceConn, SIZEOF (iceProtocolSetupMsg),
+       iceProtocolSetupMsg, message, pStart);
+
+    if (!IceValidIO (iceConn))
+    {
+       IceDisposeCompleteMessage (iceConn, pStart);
+       return (0);
+    }
+
+    pData = pStart;
+    pEnd = pStart + (length << 3);
+
+    SKIP_STRING (pData, swap, pEnd,
+                BAIL_STRING(iceConn, ICE_ProtocolSetup, 
+                            pStart));                         /* proto name */
+    SKIP_STRING (pData, swap, pEnd,
+                BAIL_STRING(iceConn, ICE_ProtocolSetup, 
+                            pStart));                         /* vendor */
+    SKIP_STRING (pData, swap, pEnd,
+                BAIL_STRING(iceConn, ICE_ProtocolSetup, 
+                            pStart));                         /* release */
+    SKIP_LISTOF_STRING (pData, swap, (int) message->authCount, pEnd,
+                       BAIL_STRING(iceConn, ICE_ProtocolSetup, 
+                                   pStart));                  /* auth names */
+    pData += (message->versionCount * 4);                     /* versions */
+
+    CHECK_COMPLETE_SIZE (iceConn, ICE_ProtocolSetup,
+       length, pData - pStart + SIZEOF (iceProtocolSetupMsg),
+       pStart, IceFatalToProtocol);
+
+    mustAuthenticate = message->mustAuthenticate;
+
+    if (mustAuthenticate != 0 && mustAuthenticate != 1)
+    {
+       _IceErrorBadValue (iceConn, 0,
+           ICE_ProtocolSetup, 4, 1, &mustAuthenticate);
+       IceDisposeCompleteMessage (iceConn, pStart);
+       return (0);
+    }
+
+    pData = pStart;
+
+    if (iceConn->process_msg_info &&
+       (int) message->protocolOpcode >= iceConn->his_min_opcode &&
+        (int) message->protocolOpcode <= iceConn->his_max_opcode &&
+       iceConn->process_msg_info[
+       message->protocolOpcode - iceConn->his_min_opcode].in_use)
+    {
+       _IceErrorMajorOpcodeDuplicate (iceConn, message->protocolOpcode);
+       IceDisposeCompleteMessage (iceConn, pStart);
+       return (0);
+    }
+
+    EXTRACT_STRING (pData, swap, protocolName);
+
+    if (iceConn->process_msg_info)
+    {
+       for (i = 0;
+           i <= (iceConn->his_max_opcode - iceConn->his_min_opcode); i++)
+       {
+           if (iceConn->process_msg_info[i].in_use && strcmp (protocolName,
+               iceConn->process_msg_info[i].protocol->protocol_name) == 0)
+           {
+               _IceErrorProtocolDuplicate (iceConn, protocolName);
+               free (protocolName);
+               IceDisposeCompleteMessage (iceConn, pStart);
+               return (0);
+           }
+       }
+    }
+
+    for (i = 0; i < _IceLastMajorOpcode; i++)
+       if (strcmp (protocolName, _IceProtocols[i].protocol_name) == 0)
+           break;
+
+    if (i < _IceLastMajorOpcode &&
+        (myProtocol = _IceProtocols[i].accept_client) != NULL)
+    {
+       hisOpcode = message->protocolOpcode;
+       myOpcode = i + 1;
+       free (protocolName);
+    }
+    else
+    {
+       _IceErrorUnknownProtocol (iceConn, protocolName);
+       free (protocolName);
+       IceDisposeCompleteMessage (iceConn, pStart);
+       return (0);
+    }
+
+    EXTRACT_STRING (pData, swap, vendor);
+    EXTRACT_STRING (pData, swap, release);
+
+    if ((hisAuthCount = message->authCount) > 0)
+    {
+       hisAuthNames = (char **) malloc (hisAuthCount * sizeof (char *));
+       EXTRACT_LISTOF_STRING (pData, swap, hisAuthCount, hisAuthNames);
+    }
+
+    hisVersionCount = message->versionCount;
+    myVersionCount = myProtocol->version_count;
+
+    hisVersionIndex = myVersionIndex = found = 0;
+
+    for (i = 0; i < hisVersionCount && !found; i++)
+    {
+       EXTRACT_CARD16 (pData, swap, hisMajorVersion);
+       EXTRACT_CARD16 (pData, swap, hisMinorVersion);
+
+       for (j = 0; j < myVersionCount && !found; j++)
+       {
+           if (myProtocol->version_recs[j].major_version == hisMajorVersion &&
+               myProtocol->version_recs[j].minor_version == hisMinorVersion)
+           {
+               hisVersionIndex = i;
+               myVersionIndex = j;
+               found = 1;
+           }
+       }
+    }
+
+    if (!found)
+    {
+       _IceErrorNoVersion (iceConn, ICE_ProtocolSetup);
+
+       free (vendor);
+       free (release);
+
+       if (hisAuthCount > 0)
+       {
+           for (i = 0; i < hisAuthCount; i++)
+               free (hisAuthNames[i]);
+       
+           free ((char *) hisAuthNames);
+       }
+
+       IceDisposeCompleteMessage (iceConn, pStart);
+       return (0);
+    }
+
+    myAuthCount = myProtocol->auth_count;
+
+    _IceGetPaValidAuthIndices (
+       _IceProtocols[myOpcode - 1].protocol_name,
+       iceConn->connection_string, myAuthCount, myProtocol->auth_names,
+        &authUsableCount, authIndices);
+
+    for (i = 0; i < myAuthCount; i++)
+    {
+       authUsableFlags[i] = 0;
+       for (j = 0; j < authUsableCount && !authUsableFlags[i]; j++)
+           authUsableFlags[i] = (authIndices[j] == i);
+    }
+
+    for (i = found = 0; i < myAuthCount && !found; i++)
+    {
+       if (authUsableFlags[i])
+       {
+           myAuthName = myProtocol->auth_names[i];
+
+           for (j = 0; j < hisAuthCount && !found; j++)
+               if (strcmp (myAuthName, hisAuthNames[j]) == 0)
+               {
+                   myAuthIndex = i;
+                   hisAuthIndex = j;
+                   found = 1;
+               }
+       }
+    }
+
+    if (!found)
+    {
+       /*
+        * None of the authentication methods specified by the
+        * other client is supported.  If the other client requires
+        * authentication, we must reject the Protocol Setup now.
+        * Otherwise, we can invoke the host-based authentication callback
+        * to see if we can accept this Protocol Setup.
+        */
+
+       if (mustAuthenticate || !myProtocol->host_based_auth_proc)
+       {
+           _IceErrorNoAuthentication (iceConn, ICE_ProtocolSetup);
+       }
+       else
+       {
+           char *hostname = _IceGetPeerName (iceConn);
+
+           if ((*myProtocol->host_based_auth_proc) (hostname))
+           {
+               accept_setup_now = 1;
+           }
+           else 
+           {
+               _IceErrorAuthenticationRejected (iceConn,
+                   ICE_ProtocolSetup, "None of the authentication protocols specified are supported and host-based authentication failed");
+           }
+
+           if (hostname)
+               free (hostname);
+       }
+    }
+    else
+    {
+       IcePaAuthStatus status;
+       int             authDataLen;
+       IcePointer      authData = NULL;
+       IcePointer      authState;
+       char            *errorString = NULL;
+       IcePaAuthProc   authProc =
+               myProtocol->auth_procs[myAuthIndex];
+
+       authState = NULL;
+
+       status = (*authProc) (iceConn, &authState, swap, 0, NULL,
+           &authDataLen, &authData, &errorString);
+
+       if (status == IcePaAuthContinue)
+       {
+           _IceProtoSetupToMeInfo *setupInfo;
+
+           AuthRequired (iceConn, hisAuthIndex, authDataLen, authData);
+        
+           iceConn->protosetup_to_me = setupInfo =
+               (_IceProtoSetupToMeInfo *) malloc (
+               sizeof (_IceProtoSetupToMeInfo));
+
+           setupInfo->his_opcode = hisOpcode;
+           setupInfo->my_opcode = myOpcode;
+           setupInfo->my_version_index = myVersionIndex;
+           setupInfo->his_version_index = hisVersionIndex;
+           setupInfo->his_vendor = vendor;
+           setupInfo->his_release = release;
+           vendor = release = NULL;   /* so we don't free it */
+           setupInfo->my_auth_index = myAuthIndex;
+           setupInfo->my_auth_state = authState;
+           setupInfo->must_authenticate = mustAuthenticate;
+       }
+       else if (status == IcePaAuthAccepted)
+       {
+           accept_setup_now = 1;
+       }
+
+       if (authData && authDataLen > 0)
+           free ((char *) authData);
+
+       if (errorString)
+           free (errorString);
+    }
+
+    if (accept_setup_now)
+    {
+       IcePaProcessMsgProc             processMsgProc;
+       IceProtocolSetupProc            protocolSetupProc;
+       IceProtocolActivateProc         protocolActivateProc;
+       _IceProcessMsgInfo              *process_msg_info;
+       IcePointer                      clientData = NULL;
+       char                            *failureReason = NULL;
+       Status                          status = 1;
+
+       protocolSetupProc = myProtocol->protocol_setup_proc;
+       protocolActivateProc = myProtocol->protocol_activate_proc;
+
+       if (protocolSetupProc)
+       {
+           /*
+            * Notify the client of the Protocol Setup.
+            */
+
+           status = (*protocolSetupProc) (iceConn,
+               myProtocol->version_recs[myVersionIndex].major_version,
+               myProtocol->version_recs[myVersionIndex].minor_version,
+               vendor, release, &clientData, &failureReason);
+
+           vendor = release = NULL;   /* so we don't free it */
+       }
+
+       if (status != 0)
+       {
+           /*
+            * Send the Protocol Reply
+            */
+
+           AcceptProtocol (iceConn, hisOpcode, myOpcode, hisVersionIndex,
+               myProtocol->vendor, myProtocol->release);
+
+
+           /*
+            * Set info for this protocol.
+            */
+
+           processMsgProc = myProtocol->version_recs[
+               myVersionIndex].process_msg_proc;
+
+           process_msg_info = &iceConn->process_msg_info[hisOpcode -
+               iceConn->his_min_opcode];
+
+           process_msg_info->client_data = clientData;
+           process_msg_info->accept_flag = 1;
+           process_msg_info->process_msg_proc.accept_client = processMsgProc;
+
+
+           /*
+            * Increase the reference count for the number of active protocols.
+            */
+
+           iceConn->proto_ref_count++;
+
+
+           /*
+            * Notify the client that the protocol is active.  The reason
+            * we have this 2nd callback invoked is because the client
+            * may wish to immediately generate a message for this
+            * protocol, but it must wait until we send the Protocol Reply.
+            */
+
+           if (protocolActivateProc)
+           {
+               (*protocolActivateProc) (iceConn,
+                   process_msg_info->client_data);
+           }
+       }
+       else
+       {
+           /*
+            * An error was encountered.
+            */
+
+           _IceErrorSetupFailed (iceConn, ICE_ProtocolSetup, failureReason);
+
+           if (failureReason)
+               free (failureReason);
+       }
+    }
+
+    if (vendor)
+       free (vendor);
+
+    if (release)
+       free (release);
+
+    if (hisAuthCount > 0)
+    {
+       for (i = 0; i < hisAuthCount; i++)
+           free (hisAuthNames[i]);
+
+       free ((char *) hisAuthNames);
+    }
+
+    IceDisposeCompleteMessage (iceConn, pStart);
+    return (0);
+}
+
+
+\f
+static Bool
+ProcessProtocolReply (
+       IceConn                 iceConn,
+       unsigned long           length,
+       Bool                    swap,
+       IceReplyWaitInfo        *replyWait
+)
+{
+    iceProtocolReplyMsg *message;
+    char               *pData, *pStart, *pEnd;
+    Bool               replyReady;
+
+#if 0 /* No-op */
+    CHECK_AT_LEAST_SIZE (iceConn, ICE_ProtocolReply,
+       length, SIZEOF (iceProtocolReplyMsg), IceFatalToProtocol);
+#endif
+
+    IceReadCompleteMessage (iceConn, SIZEOF (iceProtocolReplyMsg),
+       iceProtocolReplyMsg, message, pStart);
+
+    if (!IceValidIO (iceConn))
+    {
+       IceDisposeCompleteMessage (iceConn, pStart);
+       return (0);
+    }
+
+    pData = pStart;
+    pEnd = pStart + (length << 3);
+
+    SKIP_STRING (pData, swap, pEnd,
+                BAIL_STRING(iceConn, ICE_ProtocolReply,
+                            pStart));                       /* vendor */
+    SKIP_STRING (pData, swap, pEnd,
+                BAIL_STRING(iceConn, ICE_ProtocolReply,
+                            pStart));                       /* release */
+
+    CHECK_COMPLETE_SIZE (iceConn, ICE_ProtocolReply,
+       length, pData - pStart + SIZEOF (iceProtocolReplyMsg),
+       pStart, IceFatalToProtocol);
+
+    pData = pStart;
+
+    if (iceConn->protosetup_to_you)
+    {
+       if (iceConn->protosetup_to_you->auth_active)
+       {
+           /*
+            * Tell the authentication procedure to clean up.
+            */
+
+           _IcePoProtocol *myProtocol = _IceProtocols[
+               iceConn->protosetup_to_you->my_opcode - 1].orig_client;
+
+           IcePoAuthProc authProc = myProtocol->auth_procs[(int)
+               (iceConn->protosetup_to_you->my_auth_index)];
+
+#ifdef SVR4
+
+/*
+ * authProc is never NULL, but the cc compiler on UNIX System V/386
+ * Release 4.2 Version 1 screws up an optimization.  Unless there is
+ * some sort of reference to authProc before the function call, the
+ * function call will seg fault.
+ */
+           if (authProc)
+#endif
+               (*authProc) (iceConn,
+               &iceConn->protosetup_to_you->my_auth_state,
+               True /* clean up */, False /* swap */,
+               0, NULL, NULL, NULL, NULL);
+       }
+
+       if ((int) message->versionIndex >= _IceVersionCount)
+       {
+           _IceProtocolError *errorReply =
+               &(((_IceReply *) (replyWait->reply))->protocol_error);
+           char errIndex = message->versionIndex;
+
+           _IceErrorBadValue (iceConn, 0,
+               ICE_ProtocolReply, 2, 1, &errIndex);
+           
+           errorReply->type = ICE_PROTOCOL_ERROR;
+           errorReply->error_message =
+               "Received bad version index in Protocol Reply";
+       }
+       else
+       {
+           _IceProtocolReply *reply = 
+               &(((_IceReply *) (replyWait->reply))->protocol_reply);
+
+           reply->type = ICE_PROTOCOL_REPLY;
+           reply->major_opcode = message->protocolOpcode;
+           reply->version_index = message->versionIndex;
+
+           EXTRACT_STRING (pData, swap, reply->vendor);
+           EXTRACT_STRING (pData, swap, reply->release);
+       }
+
+       replyReady = True;
+    }
+    else
+    {
+       _IceErrorBadState (iceConn, 0, ICE_ProtocolReply, IceCanContinue);
+
+       replyReady = False;
+    }
+
+    IceDisposeCompleteMessage (iceConn, pStart);
+
+    return (replyReady);
+}
+
+
+\f
+static int
+ProcessPing (
+       IceConn         iceConn,
+       unsigned long   length
+)
+{
+    CHECK_SIZE_MATCH (iceConn, ICE_Ping,
+       length, SIZEOF (icePingMsg), IceFatalToConnection, 0);
+
+    PingReply (iceConn);
+
+    return (0);
+}
+
+
+\f
+static int
+ProcessPingReply (
+       IceConn         iceConn,
+       unsigned long   length
+)
+{
+    CHECK_SIZE_MATCH (iceConn, ICE_PingReply,
+       length, SIZEOF (icePingReplyMsg), IceFatalToConnection, 0);
+
+    if (iceConn->ping_waits)
+    {
+       _IcePingWait *next = iceConn->ping_waits->next;
+       
+       (*iceConn->ping_waits->ping_reply_proc) (iceConn,
+           iceConn->ping_waits->client_data);
+
+       free ((char *) iceConn->ping_waits);
+       iceConn->ping_waits = next;
+    }
+    else
+    {
+       _IceErrorBadState (iceConn, 0, ICE_PingReply, IceCanContinue);
+    }
+
+    return (0);
+}
+
+
+\f
+static int
+ProcessWantToClose (
+       IceConn         iceConn,
+       unsigned long   length,
+       Bool            *connectionClosedRet
+)
+{
+    *connectionClosedRet = False;
+
+    CHECK_SIZE_MATCH (iceConn, ICE_WantToClose,
+       length, SIZEOF (iceWantToCloseMsg), IceFatalToConnection, 0);
+
+    if (iceConn->want_to_close || iceConn->open_ref_count == 0)
+    {
+       /*
+        * We just received a WantToClose.  Either we also sent a
+        * WantToClose, so we close the connection, or the iceConn
+        * is not being used, so we close the connection.  This
+        * second case is possible if we sent a WantToClose because
+        * the iceConn->open_ref_count reached zero, but then we
+        * received a NoClose.
+        */
+
+       _IceConnectionClosed (iceConn);         /* invoke watch procs */
+       _IceFreeConnection (iceConn);
+       *connectionClosedRet = True;
+    }
+    else if (iceConn->proto_ref_count > 0)
+    {
+       /*
+        * We haven't shut down all of our protocols yet.  We send a NoClose,
+        * and it's up to us to generate a WantToClose later on.
+        */
+
+       IceSimpleMessage (iceConn, 0, ICE_NoClose);
+       IceFlush (iceConn);
+    }
+    else
+    {
+       /*
+        * The reference count on this iceConn is zero.  This means that
+        * there are no active protocols, but the client didn't explicitly
+        * close the connection yet.  If we didn't just send a Protocol Setup,
+        * we send a NoClose, and it's up to us to generate a WantToClose
+        * later on.
+        */
+
+       if (!iceConn->protosetup_to_you)
+       {
+           IceSimpleMessage (iceConn, 0, ICE_NoClose);
+           IceFlush (iceConn);
+       }
+    }
+
+    return (0);
+}
+
+
+\f
+static int
+ProcessNoClose (
+       IceConn         iceConn,
+       unsigned long   length
+)
+{
+    CHECK_SIZE_MATCH (iceConn, ICE_NoClose,
+       length, SIZEOF (iceNoCloseMsg), IceFatalToConnection, 0);
+
+    if (iceConn->want_to_close)
+    {
+       /*
+        * The other side can't close now.  We cancel our WantToClose,
+        * and we can expect a WantToClose from the other side.
+        */
+
+       iceConn->want_to_close = 0;
+    }
+    else
+    {
+       _IceErrorBadState (iceConn, 0, ICE_NoClose, IceCanContinue);
+    }
+
+    return (0);
+}
+
+
+\f
+static void
+_IceProcessCoreMessage (
+       IceConn          iceConn,
+       int              opcode,
+       unsigned long    length,
+       Bool             swap,
+       IceReplyWaitInfo *replyWait,
+       Bool             *replyReadyRet,
+       Bool             *connectionClosedRet
+)
+{
+    Bool replyReady = False;
+
+    *connectionClosedRet = False;
+
+    switch (opcode)
+    {
+    case ICE_Error:
+
+       replyReady = ProcessError (iceConn, length, swap, replyWait);
+       break;
+
+    case ICE_ConnectionSetup:
+
+       ProcessConnectionSetup (iceConn, length, swap);
+       break;
+
+    case ICE_AuthRequired:
+
+       replyReady = ProcessAuthRequired (iceConn, length, swap, replyWait);
+        break;
+
+    case ICE_AuthReply:
+
+       ProcessAuthReply (iceConn, length, swap);
+       break;
+
+    case ICE_AuthNextPhase:
+
+       replyReady = ProcessAuthNextPhase (iceConn, length, swap, replyWait);
+       break;
+
+    case ICE_ConnectionReply:
+
+       replyReady = ProcessConnectionReply (iceConn, length, swap, replyWait);
+       break;
+
+    case ICE_ProtocolSetup:
+
+       ProcessProtocolSetup (iceConn, length, swap);
+       break;
+
+    case ICE_ProtocolReply:
+
+       replyReady = ProcessProtocolReply (iceConn, length, swap, replyWait);
+       break;
+
+    case ICE_Ping:
+
+       ProcessPing (iceConn, length);
+       break;
+
+    case ICE_PingReply:
+
+       ProcessPingReply (iceConn, length);
+       break;
+
+    case ICE_WantToClose:
+
+       ProcessWantToClose (iceConn, length, connectionClosedRet);
+       break;
+
+    case ICE_NoClose:
+
+       ProcessNoClose (iceConn, length);
+       break;
+
+    default:
+
+       _IceErrorBadMinor (iceConn, 0, opcode, IceCanContinue);
+       _IceReadSkip (iceConn, length << 3);
+       break;
+    }
+
+    if (replyWait)
+       *replyReadyRet = replyReady;
+}
+
+int            _IceVersionCount = 1;
+_IceVersion    _IceVersions[] = {
+                   {IceProtoMajor, IceProtoMinor, _IceProcessCoreMessage}};
+
diff --git a/src/protosetup.c b/src/protosetup.c
new file mode 100755 (executable)
index 0000000..2aab6d9
--- /dev/null
@@ -0,0 +1,288 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+
+
+IceProtocolSetupStatus
+IceProtocolSetup (
+       IceConn    iceConn,
+       int        myOpcode,
+       IcePointer clientData,
+       Bool       mustAuthenticate,
+       int        *majorVersionRet,
+       int        *minorVersionRet,
+       char       **vendorRet,
+       char       **releaseRet,
+       int        errorLength,
+       char       *errorStringRet
+)
+{
+    iceProtocolSetupMsg        *pMsg;
+    char               *pData;
+    _IceProtocol       *myProtocol;
+    int                        extra;
+    Bool               gotReply, ioErrorOccured;
+    int                        accepted, i;
+    int                        hisOpcode;
+    unsigned long      setup_sequence;
+    IceReplyWaitInfo   replyWait;
+    _IceReply          reply;
+    IcePoVersionRec    *versionRec = NULL;
+    int                        authCount;
+    int                        *authIndices;
+
+    if (errorStringRet && errorLength > 0)
+       *errorStringRet = '\0';
+
+    *majorVersionRet = 0;
+    *minorVersionRet = 0;
+    *vendorRet = NULL;
+    *releaseRet = NULL;
+
+    if (myOpcode < 1 || myOpcode > _IceLastMajorOpcode)
+    {
+       strncpy (errorStringRet, "myOpcode out of range", errorLength);
+       return (IceProtocolSetupFailure);
+    }
+
+    myProtocol = &_IceProtocols[myOpcode - 1];
+
+    if (myProtocol->orig_client == NULL)
+    {
+       strncpy (errorStringRet,
+           "IceRegisterForProtocolSetup was not called", errorLength);
+       return (IceProtocolSetupFailure);
+    }
+
+
+    /*
+     * Make sure this protocol hasn't been activated already.
+     */
+
+    if (iceConn->process_msg_info)
+    {
+       for (i = iceConn->his_min_opcode; i <= iceConn->his_max_opcode; i++)
+       {
+           if (iceConn->process_msg_info[
+               i - iceConn->his_min_opcode].in_use &&
+                iceConn->process_msg_info[
+               i - iceConn->his_min_opcode ].my_opcode == myOpcode)
+               break;
+       }
+
+       if (i <= iceConn->his_max_opcode)
+       {
+           return (IceProtocolAlreadyActive);
+       }
+    }
+
+    /*
+     * Generate the message.
+     */
+
+    if (myProtocol->orig_client->auth_count > 0)
+    {
+       authIndices = (int *) malloc (
+           myProtocol->orig_client->auth_count * sizeof (int));
+
+       _IceGetPoValidAuthIndices (myProtocol->protocol_name,
+           iceConn->connection_string,
+           myProtocol->orig_client->auth_count,
+           myProtocol->orig_client->auth_names,
+            &authCount, authIndices);
+
+    }
+    else
+    {
+       authCount = 0;
+       authIndices = NULL;
+    }
+
+    extra = STRING_BYTES (myProtocol->protocol_name) +
+            STRING_BYTES (myProtocol->orig_client->vendor) +
+            STRING_BYTES (myProtocol->orig_client->release);
+
+    for (i = 0; i < authCount; i++)
+    {
+       extra += STRING_BYTES (myProtocol->orig_client->auth_names[
+           authIndices[i]]);
+    }
+
+    extra += (myProtocol->orig_client->version_count * 4);
+
+    IceGetHeaderExtra (iceConn, 0, ICE_ProtocolSetup,
+       SIZEOF (iceProtocolSetupMsg), WORD64COUNT (extra),
+       iceProtocolSetupMsg, pMsg, pData);
+
+    setup_sequence = iceConn->send_sequence;
+
+    pMsg->protocolOpcode = myOpcode;
+    pMsg->versionCount = myProtocol->orig_client->version_count;
+    pMsg->authCount = authCount;
+    pMsg->mustAuthenticate = mustAuthenticate;
+
+    STORE_STRING (pData, myProtocol->protocol_name);
+    STORE_STRING (pData, myProtocol->orig_client->vendor);
+    STORE_STRING (pData, myProtocol->orig_client->release);
+
+    for (i = 0; i < authCount; i++)
+    {
+       STORE_STRING (pData, myProtocol->orig_client->auth_names[
+           authIndices[i]]);
+    }
+
+    for (i = 0; i < myProtocol->orig_client->version_count; i++)
+    {
+       STORE_CARD16 (pData,
+           myProtocol->orig_client->version_recs[i].major_version);
+       STORE_CARD16 (pData,
+           myProtocol->orig_client->version_recs[i].minor_version);
+    }
+
+    IceFlush (iceConn);
+
+
+    /*
+     * Process messages until we get a Protocol Reply.
+     */
+
+    replyWait.sequence_of_request = setup_sequence;
+    replyWait.major_opcode_of_request = 0;
+    replyWait.minor_opcode_of_request = ICE_ProtocolSetup;
+    replyWait.reply = (IcePointer) &reply;
+
+    iceConn->protosetup_to_you = (_IceProtoSetupToYouInfo *) malloc (
+       sizeof (_IceProtoSetupToYouInfo));
+    iceConn->protosetup_to_you->my_opcode = myOpcode;
+    iceConn->protosetup_to_you->my_auth_count = authCount;
+    iceConn->protosetup_to_you->auth_active = 0;
+    iceConn->protosetup_to_you->my_auth_indices = authIndices;
+
+    gotReply = False;
+    ioErrorOccured = False;
+    accepted = 0;
+
+    while (!gotReply && !ioErrorOccured)
+    {
+       ioErrorOccured = (IceProcessMessages (
+           iceConn, &replyWait, &gotReply) == IceProcessMessagesIOError);
+
+       if (ioErrorOccured)
+       {
+           strncpy (errorStringRet,
+               "IO error occured doing Protocol Setup on connection",
+               errorLength);
+           return (IceProtocolSetupIOError);
+       }
+       else if (gotReply)
+       {
+           if (reply.type == ICE_PROTOCOL_REPLY)
+           {
+               if (reply.protocol_reply.version_index >=
+                   myProtocol->orig_client->version_count)
+               {
+                   strncpy (errorStringRet,
+                       "Got a bad version index in the Protocol Reply",
+                       errorLength);
+
+                   free (reply.protocol_reply.vendor);
+                   free (reply.protocol_reply.release);
+               }
+               else
+               {
+                   versionRec = &(myProtocol->orig_client->version_recs[
+                       reply.protocol_reply.version_index]);
+
+                   accepted = 1;
+               }
+           }
+           else /* reply.type == ICE_PROTOCOL_ERROR */
+           {
+               /* Protocol Setup failed */
+               
+               strncpy (errorStringRet, reply.protocol_error.error_message,
+                   errorLength);
+
+               free (reply.protocol_error.error_message);
+           }
+
+           if (iceConn->protosetup_to_you->my_auth_indices)
+               free ((char *) iceConn->protosetup_to_you->my_auth_indices);
+           free ((char *) iceConn->protosetup_to_you);
+           iceConn->protosetup_to_you = NULL;
+       }
+    }
+
+    if (accepted)
+    {
+       _IceProcessMsgInfo *process_msg_info;
+
+       *majorVersionRet = versionRec->major_version;
+       *minorVersionRet = versionRec->minor_version;
+       *vendorRet = reply.protocol_reply.vendor;
+       *releaseRet = reply.protocol_reply.release;
+       
+
+       /*
+        * Increase the reference count for the number of active protocols.
+        */
+
+       iceConn->proto_ref_count++;
+
+
+       /*
+        * We may be using a different major opcode for this protocol
+        * than the other client.  Whenever we get a message, we must
+        * map to our own major opcode.
+        */
+
+       hisOpcode = reply.protocol_reply.major_opcode;
+
+       _IceAddOpcodeMapping (iceConn, hisOpcode, myOpcode);
+
+       process_msg_info = &iceConn->process_msg_info[hisOpcode -
+           iceConn->his_min_opcode];
+
+       process_msg_info->client_data = clientData;
+       process_msg_info->accept_flag = 0;
+
+       process_msg_info->process_msg_proc.orig_client =
+               versionRec->process_msg_proc;
+
+       return (IceProtocolSetupSuccess);
+    }
+    else
+    {
+       return (IceProtocolSetupFailure);
+    }
+}
diff --git a/src/register.c b/src/register.c
new file mode 100755 (executable)
index 0000000..5b67bf2
--- /dev/null
@@ -0,0 +1,235 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+
+int
+IceRegisterForProtocolSetup (
+       char                    *protocolName,
+       char                    *vendor,
+       char                    *release,
+       int                     versionCount,
+       IcePoVersionRec         *versionRecs,
+       int                     authCount,
+       const char              **authNames,
+       IcePoAuthProc           *authProcs,
+       IceIOErrorProc          IOErrorProc
+)
+{
+    _IcePoProtocol     *p;
+    int                        opcodeRet, i;
+
+    for (i = 1; i <= _IceLastMajorOpcode; i++)
+       if (strcmp (protocolName, _IceProtocols[i - 1].protocol_name) == 0)
+       {
+           if (_IceProtocols[i - 1].orig_client != NULL)
+           {
+               /*
+                * We've already registered this protocol.
+                */
+               
+               return (i);
+           }
+           else
+           {
+               break;
+           }
+       }
+           
+    if (i <= _IceLastMajorOpcode)
+    {
+       p = _IceProtocols[i - 1].orig_client =
+           (_IcePoProtocol *) malloc (sizeof (_IcePoProtocol));
+       opcodeRet = i;
+    }
+    else if (_IceLastMajorOpcode == 255 ||
+       versionCount < 1 ||
+       strlen (protocolName) == 0)
+    {
+       return (-1);
+    }
+    else
+    {
+       char *name;
+
+       _IceProtocols[_IceLastMajorOpcode].protocol_name = name =
+           strdup(protocolName);
+
+       p = _IceProtocols[_IceLastMajorOpcode].orig_client =
+           (_IcePoProtocol *) malloc (sizeof (_IcePoProtocol));
+
+       _IceProtocols[_IceLastMajorOpcode].accept_client = NULL;
+
+       opcodeRet = ++_IceLastMajorOpcode;
+    }
+
+    p->vendor = strdup(vendor);
+    p->release = strdup(release);
+
+    p->version_count = versionCount;
+
+    p->version_recs = (IcePoVersionRec *) malloc (
+       versionCount * sizeof (IcePoVersionRec));
+    memcpy (p->version_recs, versionRecs,
+       versionCount * sizeof (IcePoVersionRec));
+
+    if ((p->auth_count = authCount) > 0)
+    {
+       p->auth_names = (char **) malloc (
+           authCount * sizeof (char *));
+
+       p->auth_procs = (IcePoAuthProc *) malloc (
+           authCount * sizeof (IcePoAuthProc));
+
+       for (i = 0; i < authCount; i++)
+       {
+           p->auth_names[i] = strdup(authNames[i]);
+           p->auth_procs[i] = authProcs[i];
+       }
+    }
+    else
+    {
+       p->auth_names = NULL;
+       p->auth_procs = NULL;
+    }
+
+    p->io_error_proc = IOErrorProc;
+
+    return (opcodeRet);
+}
+
+
+\f
+int
+IceRegisterForProtocolReply (
+       char                            *protocolName,
+       char                            *vendor,
+       char                            *release,
+       int                             versionCount,
+       IcePaVersionRec                 *versionRecs,
+       int                             authCount,
+       const char                      **authNames,
+       IcePaAuthProc                   *authProcs,
+       IceHostBasedAuthProc            hostBasedAuthProc,
+       IceProtocolSetupProc            protocolSetupProc,
+       IceProtocolActivateProc         protocolActivateProc,
+       IceIOErrorProc                  IOErrorProc
+)
+{
+    _IcePaProtocol     *p;
+    int                        opcodeRet, i;
+
+    for (i = 1; i <= _IceLastMajorOpcode; i++)
+       if (strcmp (protocolName, _IceProtocols[i - 1].protocol_name) == 0)
+       {
+           if (_IceProtocols[i - 1].accept_client != NULL)
+           {
+               /*
+                * We've already registered this protocol.
+                */
+               
+               return (i);
+           }
+           else
+           {
+               break;
+           }
+       }
+           
+
+    if (i <= _IceLastMajorOpcode)
+    {
+       p = _IceProtocols[i - 1].accept_client =
+           (_IcePaProtocol *) malloc (sizeof (_IcePaProtocol));
+       opcodeRet = i;
+    }
+    else if (_IceLastMajorOpcode == 255 ||
+       versionCount < 1 ||
+       strlen (protocolName) == 0)
+    {
+       return (-1);
+    }
+    else
+    {
+       char *name;
+
+       _IceProtocols[_IceLastMajorOpcode].protocol_name = name =
+           strdup(protocolName);
+
+       _IceProtocols[_IceLastMajorOpcode].orig_client = NULL;
+
+       p = _IceProtocols[_IceLastMajorOpcode].accept_client =
+           (_IcePaProtocol *) malloc (sizeof (_IcePaProtocol));
+
+       opcodeRet = ++_IceLastMajorOpcode;
+    }
+
+    p->vendor = strdup(vendor);
+    p->release = strdup(release);
+
+    p->version_count = versionCount;
+
+    p->version_recs = (IcePaVersionRec *) malloc (
+       versionCount * sizeof (IcePaVersionRec));
+    memcpy (p->version_recs, versionRecs,
+       versionCount * sizeof (IcePaVersionRec));
+
+    p->protocol_setup_proc = protocolSetupProc;
+    p->protocol_activate_proc = protocolActivateProc;
+
+    if ((p->auth_count = authCount) > 0)
+    {
+       p->auth_names = (char **) malloc (
+           authCount * sizeof (char *));
+
+       p->auth_procs = (IcePaAuthProc *) malloc (
+           authCount * sizeof (IcePaAuthProc));
+
+       for (i = 0; i < authCount; i++)
+       {
+           p->auth_names[i] = strdup(authNames[i]);
+           p->auth_procs[i] = authProcs[i];
+       }
+    }
+    else
+    {
+       p->auth_names = NULL;
+       p->auth_procs = NULL;
+    }
+
+    p->host_based_auth_proc = hostBasedAuthProc;
+
+    p->io_error_proc = IOErrorProc;
+
+    return (opcodeRet);
+}
+
diff --git a/src/replywait.c b/src/replywait.c
new file mode 100755 (executable)
index 0000000..e29f019
--- /dev/null
@@ -0,0 +1,156 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+
+
+void
+_IceAddReplyWait (
+       IceConn                 iceConn,
+       IceReplyWaitInfo        *replyWait
+)
+{
+    /*
+     * Add this replyWait to the end of the list (only if the
+     * replyWait is not already in the list).
+     */
+
+    _IceSavedReplyWait *savedReplyWait;
+    _IceSavedReplyWait *prev, *last;
+
+    prev = NULL;
+    last = iceConn->saved_reply_waits;
+
+    while (last)
+    {
+       if (last->reply_wait == replyWait)
+           return;
+
+       prev = last;
+       last = last->next;
+    }
+       
+    savedReplyWait = (_IceSavedReplyWait *) malloc (
+       sizeof (_IceSavedReplyWait));
+
+    savedReplyWait->reply_wait = replyWait;
+    savedReplyWait->reply_ready = False;
+    savedReplyWait->next = NULL;
+
+    if (prev == NULL)
+       iceConn->saved_reply_waits = savedReplyWait;
+    else
+       prev->next = savedReplyWait;
+}
+
+
+\f
+IceReplyWaitInfo *
+_IceSearchReplyWaits (
+       IceConn iceConn,
+       int     majorOpcode
+)
+{
+    /*
+     * Return the first replyWait in the list with the given majorOpcode
+     */
+
+    _IceSavedReplyWait *savedReplyWait = iceConn->saved_reply_waits;
+
+    while (savedReplyWait && !savedReplyWait->reply_ready &&
+       savedReplyWait->reply_wait->major_opcode_of_request != majorOpcode)
+    {
+       savedReplyWait = savedReplyWait->next;
+    }
+
+    return (savedReplyWait ? savedReplyWait->reply_wait : NULL);
+}
+
+
+\f
+void
+_IceSetReplyReady (
+       IceConn                 iceConn,
+       IceReplyWaitInfo        *replyWait
+)
+{
+    /*
+     * The replyWait specified has a reply ready.
+     */
+
+    _IceSavedReplyWait *savedReplyWait = iceConn->saved_reply_waits;
+
+    while (savedReplyWait && savedReplyWait->reply_wait != replyWait)
+       savedReplyWait = savedReplyWait->next;
+
+    if (savedReplyWait)
+       savedReplyWait->reply_ready = True;
+}
+
+
+\f
+Bool
+_IceCheckReplyReady (
+       IceConn                 iceConn,
+       IceReplyWaitInfo        *replyWait
+)
+{
+    _IceSavedReplyWait *savedReplyWait = iceConn->saved_reply_waits;
+    _IceSavedReplyWait *prev = NULL;
+    Bool               found = False;
+    Bool               ready;
+
+    while (savedReplyWait && !found)
+    {
+       if (savedReplyWait->reply_wait == replyWait)
+           found = True;
+       else
+       {
+           prev = savedReplyWait;
+           savedReplyWait = savedReplyWait->next;
+       }
+    }
+
+    ready = found && savedReplyWait->reply_ready;
+
+    if (ready)
+    {
+       if (prev == NULL)
+           iceConn->saved_reply_waits = savedReplyWait->next;
+       else
+           prev->next = savedReplyWait->next;
+       
+       free ((char *) savedReplyWait);
+    }
+
+    return (ready);
+}
diff --git a/src/setauth.c b/src/setauth.c
new file mode 100755 (executable)
index 0000000..d190de5
--- /dev/null
@@ -0,0 +1,112 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+#include <X11/ICE/ICEutil.h>
+
+\f
+/*
+ * IceSetPaAuthData is not a standard part of ICElib, it is specific
+ * to the sample implementation.
+ *
+ * For the client that initiates a Protocol Setup, we look in the
+ * .ICEauthority file to get authentication data.
+ *
+ * For the client accepting the Protocol Setup, we get the data
+ * from an in-memory database of authentication data (set by the
+ * application calling IceSetPaAuthData).  We have to get the data
+ * from memory because getting it directly from the .ICEauthority
+ * file is not secure - someone can just modify the contents of the
+ * .ICEauthority file behind our back.
+ */
+
+int             _IcePaAuthDataEntryCount = 0;
+#ifndef __UNIXOS2__
+IceAuthDataEntry _IcePaAuthDataEntries[ICE_MAX_AUTH_DATA_ENTRIES];
+#else
+IceAuthDataEntry _IcePaAuthDataEntries[ICE_MAX_AUTH_DATA_ENTRIES] = {0};
+#endif
+
+
+void
+IceSetPaAuthData (
+       int                     numEntries,
+       IceAuthDataEntry        *entries
+)
+{
+    /*
+     * _IcePaAuthDataEntries should really be a linked list.
+     * On my list of TO DO stuff.
+     */
+
+    int i, j;
+
+    for (i = 0; i < numEntries; i++)
+    {
+       for (j = 0; j < _IcePaAuthDataEntryCount; j++)
+           if (strcmp (entries[i].protocol_name,
+               _IcePaAuthDataEntries[j].protocol_name) == 0 &&
+                strcmp (entries[i].network_id,
+               _IcePaAuthDataEntries[j].network_id) == 0 &&
+                strcmp (entries[i].auth_name,
+               _IcePaAuthDataEntries[j].auth_name) == 0)
+               break;
+
+       if (j < _IcePaAuthDataEntryCount)
+       {
+           free (_IcePaAuthDataEntries[j].protocol_name);
+           free (_IcePaAuthDataEntries[j].network_id);
+           free (_IcePaAuthDataEntries[j].auth_name);
+           free (_IcePaAuthDataEntries[j].auth_data);
+       }
+       else
+       {
+           _IcePaAuthDataEntryCount++;
+       }
+
+       _IcePaAuthDataEntries[j].protocol_name
+           = strdup(entries[i].protocol_name);
+
+       _IcePaAuthDataEntries[j].network_id
+           = strdup(entries[i].network_id);
+
+       _IcePaAuthDataEntries[j].auth_name
+            = strdup(entries[i].auth_name);
+
+       _IcePaAuthDataEntries[j].auth_data_length =
+            entries[i].auth_data_length;
+       _IcePaAuthDataEntries[j].auth_data = (char *) malloc (
+            entries[i].auth_data_length);
+       memcpy (_IcePaAuthDataEntries[j].auth_data,
+            entries[i].auth_data, entries[i].auth_data_length);
+    }
+}
diff --git a/src/shutdown.c b/src/shutdown.c
new file mode 100755 (executable)
index 0000000..da80e1f
--- /dev/null
@@ -0,0 +1,323 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+#include <X11/Xtrans/Xtrans.h>
+
+
+Status
+IceProtocolShutdown (
+       IceConn iceConn,
+       int     majorOpcode
+)
+{
+    if (iceConn->proto_ref_count == 0 || iceConn->process_msg_info == NULL ||
+        majorOpcode < 1 || majorOpcode > _IceLastMajorOpcode)
+    {
+       return (0);
+    }
+    else
+    {
+       /*
+        * Make sure this majorOpcode is really being used.
+        */
+
+       int i;
+
+       for (i = iceConn->his_min_opcode; i <= iceConn->his_max_opcode; i++)
+       {
+           if (iceConn->process_msg_info[
+               i - iceConn->his_min_opcode].in_use &&
+                iceConn->process_msg_info[
+               i - iceConn->his_min_opcode].my_opcode == majorOpcode)
+               break;
+       }
+
+       if (i > iceConn->his_max_opcode)
+       {
+           return (0);
+       }
+       else
+       {
+           /*
+            * OK, we can shut down the protocol.
+            */
+
+           iceConn->process_msg_info[
+               i - iceConn->his_min_opcode].in_use = False;
+           iceConn->proto_ref_count--;
+
+           return (1);
+       }
+    }
+}
+
+
+\f
+void
+IceSetShutdownNegotiation (
+       IceConn         iceConn,
+       Bool            negotiate
+)
+{
+    iceConn->skip_want_to_close = negotiate ? False : True;
+}
+
+
+\f
+Bool
+IceCheckShutdownNegotiation (
+       IceConn     iceConn
+)
+{
+    return (iceConn->skip_want_to_close ? False : True);
+}
+
+
+\f
+IceCloseStatus
+IceCloseConnection (
+       IceConn     iceConn
+)
+{
+    int refCountReachedZero;
+    IceCloseStatus status;
+
+    /*
+     * If this connection object was never valid, we can close
+     * it right now.  This happens if IceAcceptConnection was
+     * called, but after calling IceProcessMessages several times
+     * the connection was rejected (because of authentication or
+     * some other reason).
+     */
+
+    if (iceConn->listen_obj &&
+       iceConn->connection_status != IceConnectAccepted)
+    {
+       _IceConnectionClosed (iceConn);         /* invoke watch procs */
+       _IceFreeConnection (iceConn);
+       return (IceClosedNow);
+    }
+
+
+    /*---------------------------------------------------------------
+
+    ACTIONS:
+
+    A = Invoke Watch Procedures
+    B = Set free-asap bit
+    C = Free connection
+    D = Initialize shutdown negotiation
+    N = do nothing
+
+
+    ACTION TABLE:
+
+    IO        free-      dispatch   protocol   shutdown
+    error      asap bit   level      refcount   negotiation     ACTION
+    occured    set        reached 0  reached 0
+    
+        0          0          0          0          0          N
+        0          0          0          0          1          N
+        0          0          0          1          0          AB
+        0          0          0          1          1          N
+        0          0          1          0          0          N
+        0          0          1          0          1          N
+        0          0          1          1          0          AC
+        0          0          1          1          1          D
+        0          1          0          0          0          N
+        0          1          0          0          1          N
+        0          1          0          1          0          N
+        0          1          0          1          1          N
+        0          1          1          0          0          C
+        0          1          1          0          1          D
+        0          1          1          1          0          C
+        0          1          1          1          1          D
+        1          0          0          0          0          AB
+        1          0          0          0          1          AB
+        1          0          0          1          0          AB
+        1          0          0          1          1          AB
+        1          0          1          0          0          AC
+        1          0          1          0          1          AC
+        1          0          1          1          0          AC
+        1          0          1          1          1          AC
+        1          1          0          0          0          N
+        1          1          0          0          1          N
+        1          1          0          1          0          N
+        1          1          0          1          1          N
+        1          1          1          0          0          C
+        1          1          1          0          1          C
+        1          1          1          1          0          C
+        1          1          1          1          1          C
+
+    ---------------------------------------------------------------*/
+
+    if (iceConn->open_ref_count > 0)
+       iceConn->open_ref_count--;
+
+    refCountReachedZero = iceConn->open_ref_count == 0 &&
+       iceConn->proto_ref_count == 0;
+
+    status = IceConnectionInUse;
+
+    if (!iceConn->free_asap && (!iceConn->io_ok ||
+       (iceConn->io_ok && refCountReachedZero &&
+       iceConn->skip_want_to_close)))
+    {
+       /*
+        * Invoke the watch procedures now.
+        */
+
+       _IceConnectionClosed (iceConn);
+       status = IceClosedNow;       /* may be overwritten by IceClosedASAP */
+    }
+
+    if (!iceConn->free_asap && iceConn->dispatch_level != 0 &&
+       (!iceConn->io_ok ||
+       (iceConn->io_ok && refCountReachedZero &&
+       iceConn->skip_want_to_close)))
+    {
+       /*
+        * Set flag so we free the connection as soon as possible.
+        */
+
+       iceConn->free_asap = True;
+       status = IceClosedASAP;
+    }
+
+    if (iceConn->io_ok && iceConn->dispatch_level == 0 &&
+       !iceConn->skip_want_to_close && refCountReachedZero)
+    {
+       /*
+        * Initiate shutdown negotiation.
+        */
+
+       IceSimpleMessage (iceConn, 0, ICE_WantToClose);
+       IceFlush (iceConn);
+
+       iceConn->want_to_close = 1;
+
+       status = IceStartedShutdownNegotiation;
+    }
+    else if (iceConn->dispatch_level == 0 &&
+       (!iceConn->io_ok || (iceConn->io_ok && iceConn->skip_want_to_close &&
+       (iceConn->free_asap || (!iceConn->free_asap && refCountReachedZero)))))
+    {
+       /*
+        * Free the connection.
+        */
+
+       _IceFreeConnection (iceConn);
+
+       status = IceClosedNow;
+    }
+
+    return (status);
+}
+
+
+\f
+void
+_IceFreeConnection (
+       IceConn iceConn
+)
+{
+    if (iceConn->listen_obj == NULL)
+    {
+       /*
+        * This iceConn was created with IceOpenConnection.
+        * We keep track of all open IceConn's, so we need
+        * to remove it from the list.
+        */
+
+       int i;
+
+       for (i = 0; i < _IceConnectionCount; i++)
+           if (_IceConnectionObjs[i] == iceConn)
+               break;
+
+       if (i < _IceConnectionCount)
+       {
+           if (i < _IceConnectionCount - 1)
+           {
+               _IceConnectionObjs[i] =
+                   _IceConnectionObjs[_IceConnectionCount - 1];
+               _IceConnectionStrings[i] =
+                   _IceConnectionStrings[_IceConnectionCount - 1];
+           }
+
+           _IceConnectionCount--;
+       }
+    }
+
+    if (iceConn->trans_conn)
+       _IceTransClose (iceConn->trans_conn);
+
+    if (iceConn->connection_string)
+       free (iceConn->connection_string);
+
+    if (iceConn->vendor)
+       free (iceConn->vendor);
+
+    if (iceConn->release)
+       free (iceConn->release);
+
+    if (iceConn->inbuf)
+       free (iceConn->inbuf);
+
+    if (iceConn->outbuf)
+       free (iceConn->outbuf);
+
+    if (iceConn->scratch)
+       free (iceConn->scratch);
+
+    if (iceConn->process_msg_info)
+       free ((char *) iceConn->process_msg_info);
+
+    if (iceConn->connect_to_you)
+       free ((char *) iceConn->connect_to_you);
+
+    if (iceConn->protosetup_to_you)
+       free ((char *) iceConn->protosetup_to_you);
+
+    if (iceConn->connect_to_me)
+       free ((char *) iceConn->connect_to_me);
+
+    if (iceConn->protosetup_to_me)
+       free ((char *) iceConn->protosetup_to_me);
+
+    free ((char *) iceConn);
+}
+
+
+
+
diff --git a/src/watch.c b/src/watch.c
new file mode 100755 (executable)
index 0000000..b197a50
--- /dev/null
@@ -0,0 +1,201 @@
+/******************************************************************************
+
+
+Copyright 1993, 1998  The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+Author: Ralph Mor, X Consortium
+******************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <X11/ICE/ICElib.h>
+#include "ICElibint.h"
+
+
+Status
+IceAddConnectionWatch (
+       IceWatchProc    watchProc,
+       IcePointer      clientData
+)
+{
+    /*
+     * watchProc will be called each time an ICE connection is
+     * created/destroyed by ICElib.
+     */
+
+    _IceWatchProc      *ptr = _IceWatchProcs;
+    _IceWatchProc      *newWatchProc;
+    int                        i;
+
+    if ((newWatchProc = (_IceWatchProc *) malloc (
+       sizeof (_IceWatchProc))) == NULL)
+    {
+       return (0);
+    }
+
+    newWatchProc->watch_proc = watchProc;
+    newWatchProc->client_data = clientData;
+    newWatchProc->watched_connections = NULL;
+    newWatchProc->next = NULL;
+
+    while (ptr && ptr->next)
+       ptr = ptr->next;
+
+    if (ptr == NULL)
+       _IceWatchProcs = newWatchProc;
+    else
+       ptr->next = newWatchProc;
+
+
+    /*
+     * Invoke the watch proc with any previously opened ICE connections.
+     */
+     
+    for (i = 0; i < _IceConnectionCount; i++)
+    {
+       _IceWatchedConnection *newWatchedConn = (_IceWatchedConnection *)
+           malloc (sizeof (_IceWatchedConnection));
+
+       newWatchedConn->iceConn = _IceConnectionObjs[i];
+       newWatchedConn->next = NULL;
+
+       newWatchProc->watched_connections = newWatchedConn;
+
+       (*newWatchProc->watch_proc) (_IceConnectionObjs[i],
+           newWatchProc->client_data, True, &newWatchedConn->watch_data);
+    }
+
+    return (1);
+}
+
+
+\f
+void
+IceRemoveConnectionWatch (
+       IceWatchProc    watchProc,
+       IcePointer      clientData
+)
+{
+    _IceWatchProc      *currWatchProc = _IceWatchProcs;
+    _IceWatchProc      *prevWatchProc = NULL;
+
+    while (currWatchProc && (currWatchProc->watch_proc != watchProc ||
+        currWatchProc->client_data != clientData))
+    {
+       prevWatchProc = currWatchProc;
+       currWatchProc = currWatchProc->next;
+    }
+
+    if (currWatchProc)
+    {
+       _IceWatchProc           *nextWatchProc = currWatchProc->next;
+       _IceWatchedConnection   *watchedConn;
+
+       watchedConn = currWatchProc->watched_connections;
+       while (watchedConn)
+       {
+           _IceWatchedConnection *nextWatchedConn = watchedConn->next;
+           free ((char *) watchedConn);
+           watchedConn = nextWatchedConn;
+       }
+
+       if (prevWatchProc == NULL)
+           _IceWatchProcs = nextWatchProc;
+       else
+           prevWatchProc->next = nextWatchProc;
+
+       free ((char *) currWatchProc);
+    }
+}
+
+
+\f
+void
+_IceConnectionOpened (
+       IceConn iceConn
+)
+{
+    _IceWatchProc *watchProc = _IceWatchProcs;
+
+    while (watchProc)
+    {
+       _IceWatchedConnection *newWatchedConn = (_IceWatchedConnection *)
+           malloc (sizeof (_IceWatchedConnection));
+       _IceWatchedConnection *watchedConn;
+
+       watchedConn = watchProc->watched_connections;
+       while (watchedConn && watchedConn->next)
+           watchedConn = watchedConn->next;
+
+       newWatchedConn->iceConn = iceConn;
+       newWatchedConn->next = NULL;
+
+       if (watchedConn == NULL)
+           watchProc->watched_connections = newWatchedConn;
+       else
+           watchedConn->next = newWatchedConn;
+
+       (*watchProc->watch_proc) (iceConn,
+           watchProc->client_data, True, &newWatchedConn->watch_data);
+
+       watchProc = watchProc->next;
+    }
+}
+
+
+\f
+void
+_IceConnectionClosed (
+       IceConn iceConn
+)
+{
+    _IceWatchProc *watchProc = _IceWatchProcs;
+
+    while (watchProc)
+    {
+       _IceWatchedConnection *watchedConn = watchProc->watched_connections;
+       _IceWatchedConnection *prev = NULL;
+
+       while (watchedConn && watchedConn->iceConn != iceConn)
+       {
+           prev = watchedConn;
+           watchedConn = watchedConn->next;
+       }
+
+       if (watchedConn)
+       {
+           (*watchProc->watch_proc) (iceConn,
+               watchProc->client_data, False, &watchedConn->watch_data);
+
+           if (prev == NULL)
+               watchProc->watched_connections = watchedConn->next;
+           else
+               prev->next = watchedConn->next;
+
+           free ((char *) watchedConn);
+       }
+
+       watchProc = watchProc->next;
+    }
+}