[ogdi-dfsg] 01/11: Imported Upstream version 3.2.0

Bas Couwenberg sebastic at debian.org
Tue Jul 19 14:04:49 UTC 2016


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository ogdi-dfsg.

commit 768bcc2a28b444d3938de4b5cb97b70b3e65d290
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Tue Jul 19 14:59:24 2016 +0200

    Imported Upstream version 3.2.0
---
 ChangeLog                                 |   86 +-
 HOWTO-RELEASE                             |    2 +-
 NEWS                                      |   14 +
 README                                    |   14 +-
 VERSION                                   |    1 +
 config/generic.mak.in                     |    3 +-
 config/unix.mak.rej                       |   21 -
 config/win32.mak                          |    3 +-
 configure                                 | 5156 +++++++++++++----------------
 configure.in                              |    4 +-
 contrib/ogdi_info/makefile                |    0
 contrib/ogdi_info/ogdi_info.c             |    0
 external/expat/COPYING                    |   21 +
 external/expat/README                     |   57 +
 external/expat/ascii.h                    |   86 +
 external/expat/asciitab.h                 |   37 +
 external/expat/config.h                   |   50 +
 external/expat/expat.h                    |  712 ++++
 external/expat/expat_ogdi.def             |   55 +
 external/expat/iasciitab.h                |   38 +
 external/expat/latin1tab.h                |   37 +
 external/expat/makefile                   |   53 +
 external/expat/nametab.h                  |  150 +
 external/expat/utf8tab.h                  |   38 +
 external/expat/xmlparse.c                 | 4622 ++++++++++++++++++++++++++
 external/expat/xmlrole.c                  | 1275 +++++++
 external/expat/xmlrole.h                  |  100 +
 external/expat/xmltok.c                   | 1568 +++++++++
 external/expat/xmltok.h                   |  299 ++
 external/expat/xmltok_impl.c              | 1768 ++++++++++
 external/expat/xmltok_impl.h              |   46 +
 external/expat/xmltok_ns.c                |   98 +
 makefile => external/makefile             |   34 +-
 external/rpc_win32/LIBRPC/Makefile        |   89 +
 external/rpc_win32/LIBRPC/ONCRPC.DEF      |   86 +
 external/rpc_win32/LIBRPC/auth_non.c      |  144 +
 external/rpc_win32/LIBRPC/auth_uni.c      |  357 ++
 external/rpc_win32/LIBRPC/authunix.c      |   84 +
 external/rpc_win32/LIBRPC/bcopy.c         |   64 +
 external/rpc_win32/LIBRPC/bindresv.c      |  112 +
 external/rpc_win32/LIBRPC/clnt_gen.c      |  151 +
 external/rpc_win32/LIBRPC/clnt_per.c      |  339 ++
 external/rpc_win32/LIBRPC/clnt_raw.c      |  252 ++
 external/rpc_win32/LIBRPC/clnt_sim.c      |  129 +
 external/rpc_win32/LIBRPC/clnt_tcp.c      |  554 ++++
 external/rpc_win32/LIBRPC/clnt_udp.c      |  508 +++
 external/rpc_win32/LIBRPC/get_myad.c      |  127 +
 external/rpc_win32/LIBRPC/getopt.c        |   52 +
 external/rpc_win32/LIBRPC/getopt.h        |    3 +
 external/rpc_win32/LIBRPC/getrpcen.c      |  256 ++
 external/rpc_win32/LIBRPC/getrpcpo.c      |    0
 external/rpc_win32/LIBRPC/makeportmap.mak |   41 +
 external/rpc_win32/LIBRPC/makerpcinfo.mak |   40 +
 external/rpc_win32/LIBRPC/nt.c            |   65 +
 external/rpc_win32/LIBRPC/pmap_cln.c      |  148 +
 external/rpc_win32/LIBRPC/pmap_get.c      |   98 +
 external/rpc_win32/LIBRPC/pmap_gma.c      |  107 +
 external/rpc_win32/LIBRPC/pmap_pr.c       |   72 +
 external/rpc_win32/LIBRPC/pmap_pro.c      |  130 +
 external/rpc_win32/LIBRPC/pmap_rmt.c      |  443 +++
 external/rpc_win32/LIBRPC/portmap.c       |  458 +++
 external/rpc_win32/LIBRPC/rpc.def         |   88 +
 external/rpc_win32/LIBRPC/rpc_call.c      |  201 ++
 external/rpc_win32/LIBRPC/rpc_comm.c      |   52 +
 external/rpc_win32/LIBRPC/rpc_prot.c      |  302 ++
 external/rpc_win32/LIBRPC/rpcinfo.c       |  676 ++++
 external/rpc_win32/LIBRPC/svc.c           |  575 ++++
 external/rpc_win32/LIBRPC/svc_auth.c      |  125 +
 external/rpc_win32/LIBRPC/svc_autu.c      |  152 +
 external/rpc_win32/LIBRPC/svc_raw.c       |  177 +
 external/rpc_win32/LIBRPC/svc_run.c       |   97 +
 external/rpc_win32/LIBRPC/svc_simp.c      |  187 ++
 external/rpc_win32/LIBRPC/svc_tcp.c       |  498 +++
 external/rpc_win32/LIBRPC/svc_udp.c       |  527 +++
 external/rpc_win32/LIBRPC/xdr.c           |  596 ++++
 external/rpc_win32/LIBRPC/xdr_arra.c      |  168 +
 external/rpc_win32/LIBRPC/xdr_floa.c      |  289 ++
 external/rpc_win32/LIBRPC/xdr_mem.c       |  200 ++
 external/rpc_win32/LIBRPC/xdr_rec.c       |  605 ++++
 external/rpc_win32/LIBRPC/xdr_refe.c      |  147 +
 external/rpc_win32/LIBRPC/xdr_stdi.c      |  204 ++
 external/rpc_win32/LIBRPC/xdrrefer.c      |  102 +
 external/rpc_win32/RPC/AUTH.H             |  190 ++
 external/rpc_win32/RPC/AUTH_UNI.H         |   89 +
 external/rpc_win32/RPC/BCOPY.H            |   14 +
 external/rpc_win32/RPC/CLNT.H             |  342 ++
 external/rpc_win32/RPC/NETDB.H            |   51 +
 external/rpc_win32/RPC/PMAP_CLN.H         |   76 +
 external/rpc_win32/RPC/PMAP_PRO.H         |  105 +
 external/rpc_win32/RPC/PMAP_RMT.H         |   64 +
 external/rpc_win32/RPC/RPC.H              |  108 +
 external/rpc_win32/RPC/RPC_MSG.H          |  204 ++
 external/rpc_win32/RPC/SVC.H              |  291 ++
 external/rpc_win32/RPC/SVC_AUTH.H         |   53 +
 external/rpc_win32/RPC/TYPES.H            |   87 +
 external/rpc_win32/RPC/XDR.H              |  281 ++
 external/rpc_win32/RPCGEN/makefile        |   48 +
 external/rpc_win32/RPCGEN/proto.h         |   53 +
 external/rpc_win32/RPCGEN/rpc_clntout.c   |  223 ++
 external/rpc_win32/RPCGEN/rpc_cout.c      |  716 ++++
 external/rpc_win32/RPCGEN/rpc_hout.c      |  499 +++
 external/rpc_win32/RPCGEN/rpc_main.c      | 1159 +++++++
 external/rpc_win32/RPCGEN/rpc_parse.c     |  622 ++++
 external/rpc_win32/RPCGEN/rpc_parse.h     |  168 +
 external/rpc_win32/RPCGEN/rpc_sample.c    |  253 ++
 external/rpc_win32/RPCGEN/rpc_scan.c      |  488 +++
 external/rpc_win32/RPCGEN/rpc_scan.h      |  105 +
 external/rpc_win32/RPCGEN/rpc_svcout.c    |  965 ++++++
 external/rpc_win32/RPCGEN/rpc_tblout.c    |  170 +
 external/rpc_win32/RPCGEN/rpc_util.c      |  487 +++
 external/rpc_win32/RPCGEN/rpc_util.h      |  147 +
 external/rpc_win32/SERVICE/INST_PM.C      |   91 +
 external/rpc_win32/SERVICE/Makefile       |   27 +
 external/rpc_win32/SERVICE/PORTMAP.C      |  361 ++
 external/rpc_win32/SERVICE/SERVICE.C      |  283 ++
 external/rpc_win32/TEST/COU.X             |    8 +
 external/rpc_win32/TEST/COUNT.C           |   29 +
 external/rpc_win32/TEST/DO_COU.C          |   41 +
 external/rpc_win32/TEST/Makefile          |   57 +
 external/rpc_win32/makefile               |   41 +
 external/zlib/OGDI_ZLIB.TXT               |   19 +
 external/zlib/README                      |  147 +
 external/zlib/adler32.c                   |   48 +
 external/zlib/compress.c                  |   68 +
 external/zlib/crc32.c                     |  162 +
 external/zlib/deflate.c                   | 1350 ++++++++
 external/zlib/deflate.h                   |  318 ++
 external/zlib/example.c                   |  556 ++++
 external/zlib/gzio.c                      |  875 +++++
 external/zlib/infblock.c                  |  403 +++
 external/zlib/infblock.h                  |   39 +
 external/zlib/infcodes.c                  |  251 ++
 external/zlib/infcodes.h                  |   27 +
 external/zlib/inffast.c                   |  183 +
 external/zlib/inffast.h                   |   17 +
 external/zlib/inffixed.h                  |  151 +
 external/zlib/inflate.c                   |  366 ++
 external/zlib/inftrees.c                  |  454 +++
 external/zlib/inftrees.h                  |   58 +
 external/zlib/infutil.c                   |   87 +
 external/zlib/infutil.h                   |   98 +
 external/zlib/makefile                    |   58 +
 external/zlib/minigzip.c                  |  320 ++
 external/zlib/trees.c                     | 1214 +++++++
 external/zlib/trees.h                     |  128 +
 external/zlib/uncompr.c                   |   58 +
 external/zlib/zconf.h                     |  279 ++
 external/zlib/zlib.h                      |  893 +++++
 external/zlib/zlib_ogdi.def               |   46 +
 external/zlib/zutil.c                     |  225 ++
 external/zlib/zutil.h                     |  220 ++
 lib/win32/lxlib.lib                       |  Bin 0 -> 4546 bytes
 makefile                                  |    3 +
 ogdi/c-api/client.c                       |    8 +-
 ogdi/c-api/ecs_dyna.c                     |    9 +-
 ogdi/c-api/ecsassoc.c                     |  102 +-
 ogdi/c-api/matrix.c                       |   58 +-
 ogdi/c-api/ogdi.def                       |    3 +
 ogdi/c-api/server.c                       |   47 +-
 ogdi/datum_driver/usa/dtusa.c             |    4 +
 ogdi/driver/adrg/adrg.c                   |    7 +-
 ogdi/driver/adrg/object.c                 |   25 +-
 ogdi/driver/adrg/utils.c                  |    9 +-
 ogdi/driver/dted/object.c                 |    9 +-
 ogdi/driver/dted/utils.c                  |    7 +-
 ogdi/driver/rpf/rpf.c                     |    8 +-
 ogdi/driver/rpf/utils.c                   |   34 +-
 ogdi/driver/skeleton/object.c             |    2 +
 ogdi/driver/skeleton/skeleton.c           |    2 -
 ogdi/driver/vrf/feature.c                 |  241 +-
 ogdi/driver/vrf/object.c                  |  279 +-
 ogdi/driver/vrf/utils.c                   |   67 +-
 ogdi/driver/vrf/vrf.c                     |   20 +-
 ogdi/gltpd/asyncsvr.c                     |   14 +-
 ogdi/include/ecs_util.h                   |   43 +-
 patch                                     |   52 -
 proj/aasincos.c                           |   31 +
 proj/adjlon.c                             |   25 +
 proj/bch2bps.c                            |  143 +
 proj/bchgen.c                             |   61 +
 proj/biveval.c                            |   90 +
 proj/dmstor.c                             |   78 +
 proj/emess.c                              |   44 +
 proj/emess.h                              |   32 +
 proj/gen_cheby.c                          |   73 +
 proj/geod.c                               |  238 ++
 proj/geod_forwd.c                         |  106 +
 proj/geod_invrs.c                         |   59 +
 proj/geod_setup.c                         |   72 +
 proj/geodesic.h                           |   35 +
 proj/hypot.c                              |   39 +
 proj/makefile                             |   55 +
 proj/mk_cheby.c                           |  164 +
 proj/nad2bin.c                            |   68 +
 proj/nad2nad.c                            |  321 ++
 proj/nad_cvt.c                            |   49 +
 proj/nad_init.c                           |   46 +
 proj/nad_interp.c                         |   65 +
 proj/pj_aea.c                             |  128 +
 proj/pj_aeqd.c                            |  256 ++
 proj/pj_airy.c                            |   94 +
 proj/pj_aitoff.c                          |   46 +
 proj/pj_august.c                          |   21 +
 proj/pj_auth.c                            |   33 +
 proj/pj_bacon.c                           |   42 +
 proj/pj_bipc.c                            |  134 +
 proj/pj_boggs.c                           |   35 +
 proj/pj_bonne.c                           |   87 +
 proj/pj_cass.c                            |   82 +
 proj/pj_cc.c                              |   22 +
 proj/pj_cea.c                             |   64 +
 proj/pj_chamb.c                           |  114 +
 proj/pj_collg.c                           |   32 +
 proj/pj_dense.c                           |   21 +
 proj/pj_deriv.c                           |   36 +
 proj/pj_eck1.c                            |   20 +
 proj/pj_eck2.c                            |   31 +
 proj/pj_eck3.c                            |   28 +
 proj/pj_eck4.c                            |   52 +
 proj/pj_eck5.c                            |   21 +
 proj/pj_eck6.c                            |   50 +
 proj/pj_eisen.c                           |   25 +
 proj/pj_ell_set.c                         |  109 +
 proj/pj_ellps.c                           |   51 +
 proj/pj_eqc.c                             |   25 +
 proj/pj_eqdc.c                            |   78 +
 proj/pj_errno.c                           |    8 +
 proj/pj_factors.c                         |   81 +
 proj/pj_fourn.c                           |   40 +
 proj/pj_fwd.c                             |   37 +
 proj/pj_gall.c                            |   22 +
 proj/pj_gnom.c                            |  108 +
 proj/pj_goode.c                           |   39 +
 proj/pj_hammer.c                          |   31 +
 proj/pj_hataea.c                          |   54 +
 proj/pj_init.c                            |  190 ++
 proj/pj_inv.c                             |   32 +
 proj/pj_labrd.c                           |  112 +
 proj/pj_laea.c                            |  234 ++
 proj/pj_lagrng.c                          |   38 +
 proj/pj_lcc.c                             |   90 +
 proj/pj_list.c                            |  117 +
 proj/pj_loxim.c                           |   44 +
 proj/pj_lsat.c                            |  173 +
 proj/pj_malloc.c                          |   16 +
 proj/pj_mbtfpp.c                          |   36 +
 proj/pj_mbtfpq.c                          |   51 +
 proj/pj_mbtfps.c                          |   42 +
 proj/pj_merc.c                            |   50 +
 proj/pj_mill.c                            |   18 +
 proj/pj_mlfn.c                            |   62 +
 proj/pj_mod_ster.c                        |  210 ++
 proj/pj_moll.c                            |   48 +
 proj/pj_msfn.c                            |    9 +
 proj/pj_nocol.c                           |   41 +
 proj/pj_nsper.c                           |  151 +
 proj/pj_nzmg.c                            |   77 +
 proj/pj_ob_tran.c                         |  143 +
 proj/pj_ocea.c                            |   71 +
 proj/pj_omerc.c                           |  167 +
 proj/pj_open_lib.c                        |   67 +
 proj/pj_ortho.c                           |   92 +
 proj/pj_parab.c                           |   24 +
 proj/pj_param.c                           |   89 +
 proj/pj_pconic.c                          |   39 +
 proj/pj_phi2.c                            |   28 +
 proj/pj_poly.c                            |  101 +
 proj/pj_pr_list.c                         |   38 +
 proj/pj_putp2.c                           |   47 +
 proj/pj_putp5.c                           |   21 +
 proj/pj_qsfn.c                            |   17 +
 proj/pj_quau.c                            |   27 +
 proj/pj_robin.c                           |  108 +
 proj/pj_rpoly.c                           |   37 +
 proj/pj_sinu.c                            |   64 +
 proj/pj_stere.c                           |  239 ++
 proj/pj_strerrno.c                        |   67 +
 proj/pj_tcc.c                             |   20 +
 proj/pj_tcea.c                            |   30 +
 proj/pj_tmerc.c                           |  163 +
 proj/pj_tpeqd.c                           |   78 +
 proj/pj_tsfn.c                            |   12 +
 proj/pj_units.c                           |   34 +
 proj/pj_vandg.c                           |   81 +
 proj/pj_vandg2.c                          |   47 +
 proj/pj_vandg4.c                          |   44 +
 proj/pj_wag7.c                            |   19 +
 proj/pj_wink1.c                           |   23 +
 proj/pj_zpoly1.c                          |   49 +
 proj/pr_series.c                          |   41 +
 proj/proj.c                               |  413 +++
 proj/proj.def                             |   17 +
 proj/projects.h                           |  216 ++
 proj/readme                               |   80 +
 proj/rtodms.c                             |   74 +
 proj/strtod.c                             |  149 +
 proj/vector1.c                            |   29 +
 vpflib/include/machine.h                  |    5 +-
 vpflib/makefile                           |    4 +
 vpflib/musedir.h                          |    6 +-
 vpflib/vpfdproj.c                         |    3 +
 vpflib/vpfquery.c                         |   14 +-
 vpflib/vpfread.c                          |  144 +-
 vpflib/vpfrelat.c                         |   10 +-
 vpflib/vpftable.c                         |   19 +-
 vpflib/vpftidx.c                          |   14 +-
 vpflib/xvt.h                              |    1 +
 307 files changed, 52569 insertions(+), 3140 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e609659..4f37dc0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,88 @@
-============================================================================
+2016-07-19  Even Rouault <even.rouault at spatialys.com>
+
+        * New 3.2.0 release
+
+2016-07-11  Even Rouault <even.rouault at spatialys.com>
+
+    * ogdi/c-api/ecs_dyna.c: fix ecs_OpenDynamicLib on 64 bit Windows (OGDI #72)
+    * external/rpc_win32/LIBRPC/xdr_floa.c: make it work on AMD64
+    * Make iconv dependency optional and detect it in configure
+    * makefile: if TARGET=win32, create config/common.mak from config/common.mak.in
+    * config/win32: remove FLAGS_X86DEF = /D_X86_ no longer needed
+
+2016-07-08  Even Rouault <even.rouault at spatialys.com>
+
+    Fix various compilation problems on Windows (contributed by Jerome Siot)
+
+2016-07-07  Even Rouault <even.rouault at spatialys.com>
+
+    * ogdi/driver/vrf/utils.c: fix stack buffer overflow in vrf_GetMetadata()
+    when reading the level in CAT files. Found by GCC 5.2 -faddress=sanitize
+
+2016-07-06  Even Rouault <even.rouault at spatialys.com>
+
+    * ogdi/include/ecs_util.h: upgrade OGDI_RELEASEDATE to 20160705
+    * ogdi/c-api/server.c: fix memory leaks in error code paths of svr_CreateServer()
+    * ogdi/c-api/ecsassoc.c: ecs_SetError(): display error message on stderr if memory
+    allocation fails.
+    * ogdi/driver/vrf/feature.c: add heuristics in vrf_get_ring_coords() to
+    detect cycling topology of edges that lead to endless looping and eventually
+    crashes. Be robust to memory allocation failures in various places, and
+    properly cleanup allocated structures when returning.
+    * ogdi/driver/vrf/object.c: implement ecs_SetErrorShouldStop() logic in
+    the various _getNext.... methods
+    * ogdi/driver/vrf/vrf.c: fix memory leaks in error code paths of dyn_SelectLayer()
+    * vpflib/vpfread.c: index_pos(): no longer clamp index values to [1,table.nrows] but
+    error out. read_new_row(): be robust to memory allocation failures.
+    * vpflib/vpftable.c: vpf_open_table(): be robust to wrong nrows values for
+    memory tables.
+
+2016-07-04  Even Rouault <even.rouault at spatialys.com>
+
+    * Error handling: Add a ecs_SetErrorShouldStop() function that can be
+    used internally when the code is able to recover from an error. The user
+    may decide if he wants to be resilient on errors by defining OGDI_STOP_ON_ERROR=NO 
+    as environment variable (the default being YES: stop on error).
+    Add a ecs_SetReportErrorFunction() method to install a custom callback that
+    will be called when OGDI_STOP_ON_ERROR=YES so that the user code is still
+    aware of errors that occured. If not defined, the error will be logged in stderr.
+    * VPF: Avoid a missing fcs file in a coverage to prevent opening any
+    coverage of the library (fix opening of DNC17/COA17A dataset) if
+    OGDI_STOP_ON_ERROR=NO is defined as environment variable, and otherwise
+    better report the error
+    * VPF: _getNextObject / _getObject functions: validate the value of the tile_id
+    to avoid a potential out-of-bounds read. Fix crash on dqyarea at dqy layer
+    of DNC17/H1708311.
+
+2016-06-28  Even Rouault <even.rouault at spatialys.com>
+
+    * Fix all warnings about unused variables raised by GCC 4.8
+
+2016-06-28  Even Rouault <even.rouault at spatialys.com>
+
+    * Actually fix build against proj >= 4.8 (assuming that projects.h is installed,
+    which is the case in Ubuntu 14.04 for example) (OGDI #71)
+
+2016-06-28  Even Rouault <even.rouault at spatialys.com>
+
+    * Fix memory leak in ADRG driver
+
+2016-06-27  Even Rouault <even.rouault at spatialys.com>
+
+    * Fix mat_inverse() to not use variable length arrays (OGDI #65)
+
+2016-06-27  Even Rouault <even.rouault at spatialys.com>
+
+    * Fix build against proj >= 4.9
+    * Grow some buffers in VRF driver (patch by Craig Bruce)
+    * Fix compiler warnings raised by GCC 4.4
+    * VPF: Fix off-by-one extra write in vpf_colum_name[] in
+      read_thematic_index_header(). Reported by clang
+
+2009-05-08  Frank Warmerdam  <warmerdam at pobox.com>
+
+	* ogdi/drivers/vrf/feature.c: fix count type to be int32 to avoid
+	variable corruption on 64bit systems (#2787502).
 
 2008-05-28  Balint Cristian  <rezso at rdsor.ro>
 
diff --git a/HOWTO-RELEASE b/HOWTO-RELEASE
index fb3ebfb..16bfefc 100644
--- a/HOWTO-RELEASE
+++ b/HOWTO-RELEASE
@@ -2,7 +2,7 @@
 	=========================================
 
 1) Ensure the OGDI_VERSION and OGDI_RELEASEDATE values are up to date in
-   ogdi/include/ecs_utils.h.
+   ogdi/include/ecs_util.h.
 
 2) Update OGDI_MINOR OGDI_MAJOR and OGDI_VERSION in configure.in for
    proper soname versioning of libraries. Run autoconf to regenerate
diff --git a/NEWS b/NEWS
index 0758a64..68cbbbd 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,20 @@
 View the ChangeLog file for detailed, file by file notes on changes.  The
 NEWS file is just used to sumarize major changes, and new features. 
 
+3.2.0
+=====
+
+ o  Fix Windows build issues
+
+ o  Harding of VRF driver regarding corrupted datasets
+
+ o  Extra fixes for buffer overflows and 64 bit issues.
+
+ o  Compiler warning fixes
+
+ o  PROJ >= 4.8 support
+
+
 3.2.0beta2
 ==========
 
diff --git a/README b/README
index 2cc6022..430987e 100644
--- a/README
+++ b/README
@@ -52,11 +52,15 @@ Windows works similarly, but a preset configuration is used instead of
 building one with configure.
 
 Requirements:
-  o Cygwin (build shell) from http://www.cygwin.com/
-  o Microsoft Visual C++ 6.x (make sure it works at the commandline from bash,
-    run VCVARS32.BAT if not).
-
-1) Set TOPDIR to point to the home directory of the OGDI source tree. 
+  o Cygwin (build shell) from http://www.cygwin.com/ with the GNU Make utility
+  o Microsoft Visual C++ (make sure it works at the commandline from bash,
+    run VCVARS32.BAT / VCVARSALL.BAT if not). Make sure that the link.exe command
+    that comes with Cygwin does not override the link.exe of Visual Studio. You
+    may need to alter the PATH to make sure Visual Studio binaries come first, or
+    rename the link.exe in Cygwin
+
+1) Set TOPDIR to point to the home directory of the OGDI source tree.
+   (Do not use /cygdrive/c/ syntax)
 
    eg. 
    TOPDIR=c:/ogdi-3.1.3
diff --git a/VERSION b/VERSION
new file mode 100644
index 0000000..15222c5
--- /dev/null
+++ b/VERSION
@@ -0,0 +1 @@
+3.2.0: mardi 19 juillet 2016, 14:20:47 (UTC+0200)
diff --git a/config/generic.mak.in b/config/generic.mak.in
index 1cb74f5..699166b 100644
--- a/config/generic.mak.in
+++ b/config/generic.mak.in
@@ -106,4 +106,5 @@ EXPAT_INCLUDE := -DEXPAT_DISABLED
 EXPAT_LINKLIB := 
 endif
 
-
+# Iconv
+HAVE_ICONV=@HAVE_ICONV@
diff --git a/config/unix.mak.rej b/config/unix.mak.rej
deleted file mode 100644
index a8e7fd2..0000000
--- a/config/unix.mak.rej
+++ /dev/null
@@ -1,21 +0,0 @@
-***************
-*** 93,101 ****
-  
-  $(SHRDGEN): $(OBJECTS)
-  	@echo Making shared library: $@
-- 	$(SHLIB_LD) $(SHLIB_LDFLAGS) $(COMMON_LDFLAGS) $(COMMON_CFLAGS) -Wl,-soname,$(LIB_PREFIX)$(TOBEGEN).$(SHLIB_EXT).$(OGDI_MAJOR).$(OGDI_MINOR) -o $(TOPDIR)/bin/$(TARGET)/$(LIB_PREFIX)$(TOBEGEN).$(SHLIB_EXT).$(OGDI_MAJOR).$(OGDI_MINOR) $^ $(LINK_LIBS) 
-- 	pushd $(TOPDIR)/bin/$(TARGET); ln -s $(LIB_PREFIX)$(TOBEGEN).$(SHLIB_EXT).$(OGDI_MAJOR).$(OGDI_MINOR) $(LIB_PREFIX)$(TOBEGEN).$(SHLIB_EXT).$(OGDI_MAJOR); \
-- 	ln -s $(LIB_PREFIX)$(TOBEGEN).$(SHLIB_EXT).$(OGDI_MAJOR) $(LIB_PREFIX)$(TOBEGEN).$(SHLIB_EXT); popd
-  	@echo $@ made successfully ...
-  
-  $(DYNAGEN): $(OBJECTS)
---- 93,101 ----
-  
-  $(SHRDGEN): $(OBJECTS)
-  	@echo Making shared library: $@
-+ 	$(SHLIB_LD) $(SHLIB_LDFLAGS) $(COMMON_LDFLAGS) $(COMMON_CFLAGS) -Wl,-soname,$(LIB_PREFIX)$(TOBEGEN).$(SHLIB_EXT).$(OGDI_MAJOR) -o $@ $^ $(LINK_LIBS) 
-+ 	pushd $(TOPDIR)/bin/$(TARGET); ln -s $(LIB_PREFIX)$(TOBEGEN).$(SHLIB_EXT).$(OGDI_MAJOR).$(OGDI_MINOR) $(LIB_PREFIX)$(TOBEGEN).$(SHLIB_EXT); \
-+ 	ln -s $(LIB_PREFIX)$(TOBEGEN).$(SHLIB_EXT).$(OGDI_MAJOR).$(OGDI_MINOR) $(LIB_PREFIX)$(TOBEGEN).$(SHLIB_EXT).$(OGDI_MAJOR); popd
-  	@echo $@ made successfully ...
-  
-  $(DYNAGEN): $(OBJECTS)
diff --git a/config/win32.mak b/config/win32.mak
index 945f83d..1e6018c 100644
--- a/config/win32.mak
+++ b/config/win32.mak
@@ -148,7 +148,8 @@ COMMON_CFLAGS = /D_WINDOWS /DWIN32 /D_MBCS \
 	$(OPTIMIZATION) \
 	/W3 /YX /MD /c /Fpheaders.pch
 
-FLAGS_X86DEF = /D_X86_
+# Disabled since it causes issue on 64bit build, and no longer needed
+# FLAGS_X86DEF = /D_X86_
 
 $(subst :,\:,$(ARCHGEN)): $(OBJECTS)
 	@echo Making archive file: $@
diff --git a/configure b/configure
index 9c45a47..d7acc10 100755
--- a/configure
+++ b/configure
@@ -1,60 +1,81 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61.
+# Generated by GNU Autoconf 2.69.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
 #
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
-## --------------------- ##
-## M4sh Initialization.  ##
-## --------------------- ##
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
 
 # Be more Bourne compatible
 DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
   emulate sh
   NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
 else
-  case `(set -o) 2>/dev/null` in
-  *posix*) set -o posix ;;
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
 esac
-
 fi
 
 
-
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
   else
-    PATH_SEPARATOR=:
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
   fi
-  rm -f conf$$.sh
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
 fi
 
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
-  as_unset=unset
-else
-  as_unset=false
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
 fi
 
 
@@ -63,20 +84,19 @@ fi
 # there to prevent editors from complaining about space-tab.
 # (If _AS_PATH_WALK were called with IFS unset, it would disable word
 # splitting by setting IFS to empty value.)
-as_nl='
-'
 IFS=" ""	$as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
-case $0 in
+as_myself=
+case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
 IFS=$as_save_IFS
 
      ;;
@@ -87,354 +107,366 @@ if test "x$as_myself" = x; then
   as_myself=$0
 fi
 if test ! -f "$as_myself"; then
-  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  { (exit 1); exit 1; }
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
 fi
 
-# Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
 done
 PS1='$ '
 PS2='> '
 PS4='+ '
 
 # NLS nuisances.
-for as_var in \
-  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
-  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
-  LC_TELEPHONE LC_TIME
-do
-  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
-    eval $as_var=C; export $as_var
-  else
-    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-  fi
-done
-
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
-if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
-  as_basename=basename
-else
-  as_basename=false
-fi
-
-
-# Name of the executable.
-as_me=`$as_basename -- "$0" ||
-$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X/"$0" |
-    sed '/^.*\/\([^/][^/]*\)\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\/\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
 
 # CDPATH.
-$as_unset CDPATH
-
-
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
 if test "x$CONFIG_SHELL" = x; then
-  if (eval ":") 2>/dev/null; then
-  as_have_required=yes
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
 else
-  as_have_required=no
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
 fi
-
-  if test $as_have_required = yes && 	 (eval ":
-(as_func_return () {
-  (exit \$1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
 
 exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
 
-if as_func_ret_success; then
-  :
 else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
-  :
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
 else
-  exitcode=1
-  echo positional parameters were not saved.
+  as_have_required=no
 fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
 
-test \$exitcode = 0) || { (exit 1); exit 1; }
-
-(
-  as_lineno_1=\$LINENO
-  as_lineno_2=\$LINENO
-  test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" &&
-  test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; }
-") 2> /dev/null; then
-  :
 else
-  as_candidate_shells=
-    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
 for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  case $as_dir in
+  as_found=:
+  case $as_dir in #(
 	 /*)
 	   for as_base in sh bash ksh sh5; do
-	     as_candidate_shells="$as_candidate_shells $as_dir/$as_base"
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
 	   done;;
        esac
+  as_found=false
 done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
 IFS=$as_save_IFS
 
 
-      for as_shell in $as_candidate_shells $SHELL; do
-	 # Try only shells that exist, to save several forks.
-	 if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
-		{ ("$as_shell") 2> /dev/null <<\_ASEOF
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in
-  *posix*) set -o posix ;;
-esac
-
-fi
-
-
-:
-_ASEOF
-}; then
-  CONFIG_SHELL=$as_shell
-	       as_have_required=yes
-	       if { "$as_shell" 2> /dev/null <<\_ASEOF
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
-  emulate sh
-  NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
-  # is contrary to our usage.  Disable this feature.
-  alias -g '${1+"$@"}'='"$@"'
-  setopt NO_GLOB_SUBST
-else
-  case `(set -o) 2>/dev/null` in
-  *posix*) set -o posix ;;
+      if test "x$CONFIG_SHELL" != x; then :
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
 esac
-
-fi
-
-
-:
-(as_func_return () {
-  (exit $1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
-
-exitcode=0
-if as_func_success; then
-  :
-else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
-fi
-
-if as_func_ret_success; then
-  :
-else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
-fi
-
-if ( set x; as_func_ret_success y && test x = "$1" ); then
-  :
-else
-  exitcode=1
-  echo positional parameters were not saved.
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
 fi
-
-test $exitcode = 0) || { (exit 1); exit 1; }
-
-(
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; }
-
-_ASEOF
-}; then
-  break
 fi
-
 fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
 
-      done
-
-      if test "x$CONFIG_SHELL" != x; then
-  for as_var in BASH_ENV ENV
-        do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
-        done
-        export CONFIG_SHELL
-        exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
-fi
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
 
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
 
-    if test $as_have_required = no; then
-  echo This script requires a shell more modern than all the
-      echo shells that I found on your system.  Please install a
-      echo modern shell, or manually run the script under such a
-      echo shell if you do have one.
-      { (exit 1); exit 1; }
-fi
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
 
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
 
-fi
 
-fi
+} # as_fn_mkdir_p
 
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
 
 
-(eval "as_func_return () {
-  (exit \$1)
-}
-as_func_success () {
-  as_func_return 0
-}
-as_func_failure () {
-  as_func_return 1
-}
-as_func_ret_success () {
-  return 0
-}
-as_func_ret_failure () {
-  return 1
-}
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+  fi
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
 
-exitcode=0
-if as_func_success; then
-  :
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; then
+  as_expr=expr
 else
-  exitcode=1
-  echo as_func_success failed.
-fi
-
-if as_func_failure; then
-  exitcode=1
-  echo as_func_failure succeeded.
+  as_expr=false
 fi
 
-if as_func_ret_success; then
-  :
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+  as_basename=basename
 else
-  exitcode=1
-  echo as_func_ret_success failed.
-fi
-
-if as_func_ret_failure; then
-  exitcode=1
-  echo as_func_ret_failure succeeded.
+  as_basename=false
 fi
 
-if ( set x; as_func_ret_success y && test x = \"\$1\" ); then
-  :
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
 else
-  exitcode=1
-  echo positional parameters were not saved.
+  as_dirname=false
 fi
 
-test \$exitcode = 0") || {
-  echo No shell found that supports shell functions.
-  echo Please tell autoconf at gnu.org about your system,
-  echo including any error possibly output before this
-  echo message
-}
-
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
 
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
 
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
 
-  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
-  # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line after each line using $LINENO; the second 'sed'
-  # does the real work.  The second script uses 'N' to pair each
-  # line-number line with the line containing $LINENO, and appends
-  # trailing '-' during substitution so that $LINENO is not a special
-  # case at line end.
-  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # scripts with optimization help from Paolo Bonzini.  Blame Lee
-  # E. McMahon (1931-1989) for sed's syntax.  :-)
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
   sed -n '
     p
     /[$]LINENO/=
@@ -451,9 +483,12 @@ test \$exitcode = 0") || {
       s/-\n.*//
     ' >$as_me.lineno &&
   chmod +x "$as_me.lineno" ||
-    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
-   { (exit 1); exit 1; }; }
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
 
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
   # original and so on.  Autoconf is especially sensitive to this).
@@ -462,84 +497,55 @@ test \$exitcode = 0") || {
   exit
 }
 
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
-
 ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
+case `echo -n x` in #(((((
 -n*)
-  case `echo 'x\c'` in
+  case `echo 'xy\c'` in
   *c*) ECHO_T='	';;	# ECHO_T is single tab character.
-  *)   ECHO_C='\c';;
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
   esac;;
 *)
   ECHO_N='-n';;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
 rm -f conf$$ conf$$.exe conf$$.file
 if test -d conf$$.dir; then
   rm -f conf$$.dir/conf$$.file
 else
   rm -f conf$$.dir
-  mkdir conf$$.dir
-fi
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s='ln -s'
-  # ... but there are two gotchas:
-  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-  # In both cases, we have to default to `cp -p'.
-  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-    as_ln_s='cp -p'
-elif ln conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s=ln
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
 else
-  as_ln_s='cp -p'
+  as_ln_s='cp -pR'
 fi
 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
 rmdir conf$$.dir 2>/dev/null
 
 if mkdir -p . 2>/dev/null; then
-  as_mkdir_p=:
+  as_mkdir_p='mkdir -p "$as_dir"'
 else
   test -d ./-p && rmdir ./-p
   as_mkdir_p=false
 fi
 
-if test -x / >/dev/null 2>&1; then
-  as_test_x='test -x'
-else
-  if ls -dL / >/dev/null 2>&1; then
-    as_ls_L_option=L
-  else
-    as_ls_L_option=
-  fi
-  as_test_x='
-    eval sh -c '\''
-      if test -d "$1"; then
-        test -d "$1/.";
-      else
-	case $1 in
-        -*)set "./$1";;
-	esac;
-	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
-	???[sx]*):;;*)false;;esac;fi
-    '\'' sh
-  '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -548,142 +554,158 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
 
-exec 7<&0 </dev/null 6>&1
-
-# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
-# so uname gets run too.
-ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-
-#
-# Initializations.
-#
-ac_default_prefix=/usr/local
-ac_clean_files=
-ac_config_libobj_dir=.
-LIBOBJS=
-cross_compiling=no
-subdirs=
-MFLAGS=
-MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-# Identity of this package.
-PACKAGE_NAME=
-PACKAGE_TARNAME=
-PACKAGE_VERSION=
-PACKAGE_STRING=
-PACKAGE_BUGREPORT=
-
-ac_unique_file="config/unix.mak"
-# Factoring default headers for most tests.
-ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-#  include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif"
-
-ac_subst_vars='SHELL
-PATH_SEPARATOR
-PACKAGE_NAME
-PACKAGE_TARNAME
-PACKAGE_VERSION
-PACKAGE_STRING
-PACKAGE_BUGREPORT
-exec_prefix
-prefix
-program_transform_name
-bindir
-sbindir
-libexecdir
-datarootdir
-datadir
-sysconfdir
-sharedstatedir
-localstatedir
-includedir
-oldincludedir
-docdir
-infodir
-htmldir
-dvidir
-pdfdir
-psdir
-libdir
-localedir
-mandir
-DEFS
-ECHO_C
-ECHO_N
-ECHO_T
-LIBS
-build_alias
-host_alias
-target_alias
-OGDI_VERSION
-OGDI_MAJOR
-OGDI_MINOR
-CC
-CFLAGS
-LDFLAGS
-CPPFLAGS
-ac_ct_CC
-EXEEXT
-OBJEXT
-CXX_WFLAGS
-C_WFLAGS
-CXX_PIC
-C_PIC
-LD_SHARED
-CPP
-GREP
-EGREP
-RPC_INCLUDES
-BIG_ENDIAN
-PROJ_SETTING
-PROJ_INCLUDE
-PROJ_LIB
-ZLIB_SETTING
-ZLIB_INCLUDE
-ZLIB_LIB
-EXPAT_SETTING
-EXPAT_INCLUDE
-EXPAT_LIB
-pkgconfigdir
-binconfigs
+# Name of the host.
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+PACKAGE_URL=
+
+ac_unique_file="config/unix.mak"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='LTLIBOBJS
 LIBOBJS
-LTLIBOBJS'
+binconfigs
+pkgconfigdir
+EXPAT_LIB
+EXPAT_INCLUDE
+EXPAT_SETTING
+ZLIB_LIB
+ZLIB_INCLUDE
+ZLIB_SETTING
+PROJ_LIB
+PROJ_INCLUDE
+PROJ_SETTING
+BIG_ENDIAN
+RPC_INCLUDES
+EGREP
+GREP
+CPP
+LD_SHARED
+C_PIC
+CXX_PIC
+C_WFLAGS
+CXX_WFLAGS
+HAVE_ICONV
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+OGDI_MINOR
+OGDI_MAJOR
+OGDI_VERSION
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
 ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+with_proj
+with_projlib
+with_projinc
+with_zlib
+with_zliblib
+with_zlibinc
+with_expat
+with_expatlib
+with_expatinc
+with_pkgconfigdir
+with_binconfigs
+'
       ac_precious_vars='build_alias
 host_alias
 target_alias
@@ -698,6 +720,8 @@ CPP'
 # Initialize some variables set by options.
 ac_init_help=
 ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
 # The variables have the same names as the options, with
 # dashes changed to underlines.
 cache_file=/dev/null
@@ -753,8 +777,9 @@ do
   fi
 
   case $ac_option in
-  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *)	ac_optarg=yes ;;
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
   esac
 
   # Accept the important Cygnus configure options, so we can diagnose typos.
@@ -796,13 +821,20 @@ do
     datarootdir=$ac_optarg ;;
 
   -disable-* | --disable-*)
-    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
-   { (exit 1); exit 1; }; }
-    ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
-    eval enable_$ac_feature=no ;;
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
 
   -docdir | --docdir | --docdi | --doc | --do)
     ac_prev=docdir ;;
@@ -815,13 +847,20 @@ do
     dvidir=$ac_optarg ;;
 
   -enable-* | --enable-*)
-    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
-   { (exit 1); exit 1; }; }
-    ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'`
-    eval enable_$ac_feature=\$ac_optarg ;;
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$ac_optarg ;;
 
   -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
   | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -1012,22 +1051,36 @@ do
     ac_init_version=: ;;
 
   -with-* | --with-*)
-    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid package name: $ac_package" >&2
-   { (exit 1); exit 1; }; }
-    ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
-    eval with_$ac_package=\$ac_optarg ;;
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
 
   -without-* | --without-*)
-    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid package name: $ac_package" >&2
-   { (exit 1); exit 1; }; }
-    ac_package=`echo $ac_package | sed 's/[-.]/_/g'`
-    eval with_$ac_package=no ;;
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error $? "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=no ;;
 
   --x)
     # Obsolete; use --with-x.
@@ -1047,26 +1100,26 @@ do
   | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
     x_libraries=$ac_optarg ;;
 
-  -*) { echo "$as_me: error: unrecognized option: $ac_option
-Try \`$0 --help' for more information." >&2
-   { (exit 1); exit 1; }; }
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
     ;;
 
   *=*)
     ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
     # Reject names that are not valid shell variable names.
-    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
-      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
-   { (exit 1); exit 1; }; }
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+    esac
     eval $ac_envvar=\$ac_optarg
     export $ac_envvar ;;
 
   *)
     # FIXME: should be removed in autoconf 3.0.
-    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
     expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
     ;;
 
   esac
@@ -1074,23 +1127,36 @@ done
 
 if test -n "$ac_prev"; then
   ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  { echo "$as_me: error: missing argument to $ac_option" >&2
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
 fi
 
-# Be sure to have absolute directory names.
+# Check all directory arguments for consistency.
 for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
 		datadir sysconfdir sharedstatedir localstatedir includedir \
 		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
 		libdir localedir mandir
 do
   eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
   case $ac_val in
     [\\/$]* | ?:[\\/]* )  continue;;
     NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
   esac
-  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
 done
 
 # There might be people who depend on the old broken behavior: `$host'
@@ -1104,8 +1170,6 @@ target=$target_alias
 if test "x$host_alias" != x; then
   if test "x$build_alias" = x; then
     cross_compiling=maybe
-    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
-    If a cross compiler is detected then cross compile mode will be used." >&2
   elif test "x$build_alias" != "x$host_alias"; then
     cross_compiling=yes
   fi
@@ -1120,23 +1184,21 @@ test "$silent" = yes && exec 6>/dev/null
 ac_pwd=`pwd` && test -n "$ac_pwd" &&
 ac_ls_di=`ls -di .` &&
 ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  { echo "$as_me: error: Working directory cannot be determined" >&2
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "working directory cannot be determined"
 test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  { echo "$as_me: error: pwd does not report name of working directory" >&2
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "pwd does not report name of working directory"
 
 
 # Find the source files, if location was not specified.
 if test -z "$srcdir"; then
   ac_srcdir_defaulted=yes
   # Try the directory containing this script, then the parent directory.
-  ac_confdir=`$as_dirname -- "$0" ||
-$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$0" : 'X\(//\)[^/]' \| \
-	 X"$0" : 'X\(//\)$' \| \
-	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$0" |
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -1163,13 +1225,11 @@ else
 fi
 if test ! -r "$srcdir/$ac_unique_file"; then
   test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
 fi
 ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
 ac_abs_confdir=`(
-	cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2
-   { (exit 1); exit 1; }; }
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
 	pwd)`
 # When building in place, set srcdir=.
 if test "$ac_abs_confdir" = "$ac_pwd"; then
@@ -1209,7 +1269,7 @@ Configuration:
       --help=short        display options specific to this package
       --help=recursive    display the short help of all the included packages
   -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking...' messages
+  -q, --quiet, --silent   do not print \`checking ...' messages
       --cache-file=FILE   cache test results in FILE [disabled]
   -C, --config-cache      alias for \`--cache-file=config.cache'
   -n, --no-create         do not create output files
@@ -1217,9 +1277,9 @@ Configuration:
 
 Installation directories:
   --prefix=PREFIX         install architecture-independent files in PREFIX
-			  [$ac_default_prefix]
+                          [$ac_default_prefix]
   --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
-			  [PREFIX]
+                          [PREFIX]
 
 By default, \`make install' will install all the files in
 \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
@@ -1229,25 +1289,25 @@ for instance \`--prefix=\$HOME'.
 For better control, use the options below.
 
 Fine tuning of the installation directories:
-  --bindir=DIR           user executables [EPREFIX/bin]
-  --sbindir=DIR          system admin executables [EPREFIX/sbin]
-  --libexecdir=DIR       program executables [EPREFIX/libexec]
-  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
-  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
-  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
-  --libdir=DIR           object code libraries [EPREFIX/lib]
-  --includedir=DIR       C header files [PREFIX/include]
-  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
-  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
-  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
-  --infodir=DIR          info documentation [DATAROOTDIR/info]
-  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
-  --mandir=DIR           man documentation [DATAROOTDIR/man]
-  --docdir=DIR           documentation root [DATAROOTDIR/doc/PACKAGE]
-  --htmldir=DIR          html documentation [DOCDIR]
-  --dvidir=DIR           dvi documentation [DOCDIR]
-  --pdfdir=DIR           pdf documentation [DOCDIR]
-  --psdir=DIR            ps documentation [DOCDIR]
+  --bindir=DIR            user executables [EPREFIX/bin]
+  --sbindir=DIR           system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR        program executables [EPREFIX/libexec]
+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]
+  --libdir=DIR            object code libraries [EPREFIX/lib]
+  --includedir=DIR        C header files [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/PACKAGE]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
 _ACEOF
 
   cat <<\_ACEOF
@@ -1281,13 +1341,14 @@ Some influential environment variables:
   LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
               nonstandard directory <lib dir>
   LIBS        libraries to pass to the linker, e.g. -l<library>
-  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
               you have headers in a nonstandard directory <include dir>
   CPP         C preprocessor
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
+Report bugs to the package provider.
 _ACEOF
 ac_status=$?
 fi
@@ -1295,15 +1356,17 @@ fi
 if test "$ac_init_help" = "recursive"; then
   # If there are subdirs, report their specific --help.
   for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
-    test -d "$ac_dir" || continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
     ac_builddir=.
 
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -1330,40 +1393,324 @@ case $srcdir in
 esac
 ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
 
-    cd "$ac_dir" || { ac_status=$?; continue; }
-    # Check for guested configure.
-    if test -f "$ac_srcdir/configure.gnu"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
-    elif test -f "$ac_srcdir/configure"; then
-      echo &&
-      $SHELL "$ac_srcdir/configure" --help=recursive
-    else
-      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
-    fi || ac_status=$?
-    cd "$ac_pwd" || { ac_status=$?; break; }
-  done
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested configure.
+    if test -f "$ac_srcdir/configure.gnu"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+    elif test -f "$ac_srcdir/configure"; then
+      echo &&
+      $SHELL "$ac_srcdir/configure" --help=recursive
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+configure
+generated by GNU Autoconf 2.69
+
+Copyright (C) 2012 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 test -x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if eval \${$3+:} false; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
 fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
 
-test -n "$ac_init_help" && exit $ac_status
-if $ac_init_version; then
-  cat <<\_ACEOF
-configure
-generated by GNU Autoconf 2.61
+} # ac_fn_c_try_run
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-This configure script is free software; the Free Software Foundation
-gives unlimited permission to copy, distribute and modify it.
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
 _ACEOF
-  exit
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by $as_me, which was
-generated by GNU Autoconf 2.61.  Invocation command line was
+generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
 
@@ -1399,8 +1746,8 @@ for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  echo "PATH: $as_dir"
-done
+    $as_echo "PATH: $as_dir"
+  done
 IFS=$as_save_IFS
 
 } >&5
@@ -1434,12 +1781,12 @@ do
     | -silent | --silent | --silen | --sile | --sil)
       continue ;;
     *\'*)
-      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     case $ac_pass in
-    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
     2)
-      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      as_fn_append ac_configure_args1 " '$ac_arg'"
       if test $ac_must_keep_next = true; then
 	ac_must_keep_next=false # Got value, back to normal.
       else
@@ -1455,13 +1802,13 @@ do
 	  -* ) ac_must_keep_next=true ;;
 	esac
       fi
-      ac_configure_args="$ac_configure_args '$ac_arg'"
+      as_fn_append ac_configure_args " '$ac_arg'"
       ;;
     esac
   done
 done
-$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
-$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
 
 # When interrupted or exit'd, cleanup temporary files, and complete
 # config.log.  We remove comments because anyway the quotes in there
@@ -1473,11 +1820,9 @@ trap 'exit_status=$?
   {
     echo
 
-    cat <<\_ASBOX
-## ---------------- ##
+    $as_echo "## ---------------- ##
 ## Cache variables. ##
-## ---------------- ##
-_ASBOX
+## ---------------- ##"
     echo
     # The following way of writing the cache mishandles newlines in values,
 (
@@ -1486,12 +1831,13 @@ _ASBOX
     case $ac_val in #(
     *${as_nl}*)
       case $ac_var in #(
-      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       esac
       case $ac_var in #(
       _ | IFS | as_nl) ;; #(
-      *) $as_unset $ac_var ;;
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
       esac ;;
     esac
   done
@@ -1510,128 +1856,136 @@ echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
 )
     echo
 
-    cat <<\_ASBOX
-## ----------------- ##
+    $as_echo "## ----------------- ##
 ## Output variables. ##
-## ----------------- ##
-_ASBOX
+## ----------------- ##"
     echo
     for ac_var in $ac_subst_vars
     do
       eval ac_val=\$$ac_var
       case $ac_val in
-      *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
       esac
-      echo "$ac_var='\''$ac_val'\''"
+      $as_echo "$ac_var='\''$ac_val'\''"
     done | sort
     echo
 
     if test -n "$ac_subst_files"; then
-      cat <<\_ASBOX
-## ------------------- ##
+      $as_echo "## ------------------- ##
 ## File substitutions. ##
-## ------------------- ##
-_ASBOX
+## ------------------- ##"
       echo
       for ac_var in $ac_subst_files
       do
 	eval ac_val=\$$ac_var
 	case $ac_val in
-	*\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
 	esac
-	echo "$ac_var='\''$ac_val'\''"
+	$as_echo "$ac_var='\''$ac_val'\''"
       done | sort
       echo
     fi
 
     if test -s confdefs.h; then
-      cat <<\_ASBOX
-## ----------- ##
+      $as_echo "## ----------- ##
 ## confdefs.h. ##
-## ----------- ##
-_ASBOX
+## ----------- ##"
       echo
       cat confdefs.h
       echo
     fi
     test "$ac_signal" != 0 &&
-      echo "$as_me: caught signal $ac_signal"
-    echo "$as_me: exit $exit_status"
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
   } >&5
   rm -f core *.core core.conftest.* &&
     rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
     exit $exit_status
 ' 0
 for ac_signal in 1 2 13 15; do
-  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
 done
 ac_signal=0
 
 # confdefs.h avoids OS command line length limits that DEFS can exceed.
 rm -f -r conftest* confdefs.h
 
+$as_echo "/* confdefs.h */" > confdefs.h
+
 # Predefined preprocessor variables.
 
 cat >>confdefs.h <<_ACEOF
 #define PACKAGE_NAME "$PACKAGE_NAME"
 _ACEOF
 
-
 cat >>confdefs.h <<_ACEOF
 #define PACKAGE_TARNAME "$PACKAGE_TARNAME"
 _ACEOF
 
-
 cat >>confdefs.h <<_ACEOF
 #define PACKAGE_VERSION "$PACKAGE_VERSION"
 _ACEOF
 
-
 cat >>confdefs.h <<_ACEOF
 #define PACKAGE_STRING "$PACKAGE_STRING"
 _ACEOF
 
-
 cat >>confdefs.h <<_ACEOF
 #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
 _ACEOF
 
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
 
 # Let the site file select an alternate cache file if it wants to.
-# Prefer explicitly selected file to automatically selected ones.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
 if test -n "$CONFIG_SITE"; then
-  set x "$CONFIG_SITE"
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
 elif test "x$prefix" != xNONE; then
-  set x "$prefix/share/config.site" "$prefix/etc/config.site"
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
 else
-  set x "$ac_default_prefix/share/config.site" \
-	"$ac_default_prefix/etc/config.site"
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
 fi
-shift
-for ac_site_file
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
 do
-  if test -r "$ac_site_file"; then
-    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
-echo "$as_me: loading site script $ac_site_file" >&6;}
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
     sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file"
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
   fi
 done
 
 if test -r "$cache_file"; then
-  # Some versions of bash will fail to source /dev/null (special
-  # files actually), so we avoid doing that.
-  if test -f "$cache_file"; then
-    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
-echo "$as_me: loading cache $cache_file" >&6;}
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
     case $cache_file in
       [\\/]* | ?:[\\/]* ) . "$cache_file";;
       *)                      . "./$cache_file";;
     esac
   fi
 else
-  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
-echo "$as_me: creating cache $cache_file" >&6;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
   >$cache_file
 fi
 
@@ -1645,60 +1999,56 @@ for ac_var in $ac_precious_vars; do
   eval ac_new_val=\$ac_env_${ac_var}_value
   case $ac_old_set,$ac_new_set in
     set,)
-      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
       ac_cache_corrupted=: ;;
     ,set)
-      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
       ac_cache_corrupted=: ;;
     ,);;
     *)
       if test "x$ac_old_val" != "x$ac_new_val"; then
-	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
-echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
-	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
-echo "$as_me:   former value:  $ac_old_val" >&2;}
-	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
-echo "$as_me:   current value: $ac_new_val" >&2;}
-	ac_cache_corrupted=:
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
       fi;;
   esac
   # Pass precious variables to config.status.
   if test "$ac_new_set" = set; then
     case $ac_new_val in
-    *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
     *) ac_arg=$ac_var=$ac_new_val ;;
     esac
     case " $ac_configure_args " in
       *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
-      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
     esac
   fi
 done
 if $ac_cache_corrupted; then
-  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
-echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
-echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
-   { (exit 1); exit 1; }; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
 fi
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -1708,7 +2058,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
-OGDI_VERSION=3.2.0beta2
+OGDI_VERSION=3.2.0
 OGDI_MAJOR=3
 OGDI_MINOR=2
 
@@ -1718,15 +2068,11 @@ OGDI_MINOR=2
 
 
 if test "$TOPDIR" = "" ; then
-  { { echo "$as_me:$LINENO: error: Required TOPDIR environment variable not set, see README." >&5
-echo "$as_me: error: Required TOPDIR environment variable not set, see README." >&2;}
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "Required TOPDIR environment variable not set, see README." "$LINENO" 5
 fi
 
 if test "$OS" = "Windows_NT" ; then
-  { { echo "$as_me:$LINENO: error: Please don't use configure for Windows, see README." >&5
-echo "$as_me: error: Please don't use configure for Windows, see README." >&2;}
-   { (exit 1); exit 1; }; }
+  as_fn_error $? "Please don't use configure for Windows, see README." "$LINENO" 5
 fi
 
 ac_ext=c
@@ -1737,10 +2083,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -1750,25 +2096,25 @@ for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
 IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
 
@@ -1777,10 +2123,10 @@ if test -z "$ac_cv_prog_CC"; then
   ac_ct_CC=$CC
   # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
@@ -1790,25 +2136,25 @@ for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="gcc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
 IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
   if test "x$ac_ct_CC" = x; then
@@ -1816,12 +2162,8 @@ fi
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     CC=$ac_ct_CC
@@ -1834,10 +2176,10 @@ if test -z "$CC"; then
           if test -n "$ac_tool_prefix"; then
     # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -1847,25 +2189,25 @@ for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
 IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
 
@@ -1874,10 +2216,10 @@ fi
 if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -1888,18 +2230,18 @@ for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
        ac_prog_rejected=yes
        continue
      fi
     ac_cv_prog_CC="cc"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
 IFS=$as_save_IFS
 
 if test $ac_prog_rejected = yes; then
@@ -1918,11 +2260,11 @@ fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
 
@@ -1933,10 +2275,10 @@ if test -z "$CC"; then
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -1946,25 +2288,25 @@ for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
 IFS=$as_save_IFS
 
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
 
@@ -1977,10 +2319,10 @@ if test -z "$CC"; then
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
@@ -1990,25 +2332,25 @@ for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
-done
+  done
 IFS=$as_save_IFS
 
 fi
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
 fi
 
 
@@ -2020,12 +2362,8 @@ done
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&5
-echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools
-whose name does not start with the host triplet.  If you think this
-configuration is useful to you, please write to autoconf at gnu.org." >&2;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     CC=$ac_ct_CC
@@ -2035,51 +2373,37 @@ fi
 fi
 
 
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
 
 # Provide some information about the compiler.
-echo "$as_me:$LINENO: checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (ac_try="$ac_compiler --version >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler --version >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (ac_try="$ac_compiler -v >&5"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -v >&5") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
-{ (ac_try="$ac_compiler -V >&5"
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compiler -V >&5") 2>&5
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
   ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
 
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -2091,42 +2415,38 @@ main ()
 }
 _ACEOF
 ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
 # Try to create an executable without -o first, disregard a.out.
 # It will help us diagnose broken compilers, and finding out an intuition
 # of exeext.
-{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; }
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-#
-# List of possible output files, starting from the most likely.
-# The algorithm is not robust to junk in `.', hence go to wildcards (a.*)
-# only as a last resort.  b.out is created by i960 compilers.
-ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out'
-#
-# The IRIX 6 linker writes into existing files which may not be
-# executable, retaining their permissions.  Remove them first so a
-# subsequent execution test works.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
 ac_rmfiles=
 for ac_file in $ac_files
 do
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
     * ) ac_rmfiles="$ac_rmfiles $ac_file";;
   esac
 done
 rm -f $ac_rmfiles
 
-if { (ac_try="$ac_link_default"
+if { { ac_try="$ac_link_default"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
   (eval "$ac_link_default") 2>&5
   ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
   # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
 # So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
 # in a Makefile.  We should not override ac_cv_exeext if it was cached,
@@ -2136,14 +2456,14 @@ for ac_file in $ac_files ''
 do
   test -f "$ac_file" || continue
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj )
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
 	;;
     [ab].out )
 	# We found the default executable, but exeext='' is most
 	# certainly right.
 	break;;
     *.* )
-        if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
 	then :; else
 	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
 	fi
@@ -2162,78 +2482,41 @@ test "$ac_cv_exeext" = no && ac_cv_exeext=
 else
   ac_file=''
 fi
-
-{ echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6; }
-if test -z "$ac_file"; then
-  echo "$as_me: failed program was:" >&5
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
-   { (exit 77); exit 77; }; }
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 fi
-
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
 ac_exeext=$ac_cv_exeext
 
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; }
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
-  if { ac_try='./$ac_file'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-	cross_compiling=yes
-    else
-	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
-    fi
-  fi
-fi
-{ echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
 ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; }
-{ echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6; }
-
-{ echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; }
-if { (ac_try="$ac_link"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>&5
   ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
   # If both `conftest.exe' and `conftest' are `present' (well, observable)
 # catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
 # work properly (i.e., refer to `conftest.exe'), while it won't with
@@ -2241,37 +2524,90 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
 for ac_file in conftest.exe conftest conftest.*; do
   test -f "$ac_file" || continue
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;;
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
     *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
 	  break;;
     * ) break;;
   esac
 done
 else
-  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
 fi
-
-rm -f conftest$ac_cv_exeext
-{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6; }
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
 
 rm -f conftest.$ac_ext
 EXEEXT=$ac_cv_exeext
 ac_exeext=$EXEEXT
-{ echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; }
-if test "${ac_cv_objext+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -2283,51 +2619,46 @@ main ()
 }
 _ACEOF
 rm -f conftest.o conftest.obj
-if { (ac_try="$ac_compile"
+if { { ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
   (eval "$ac_compile") 2>&5
   ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; then
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
   for ac_file in conftest.o conftest.obj conftest.*; do
   test -f "$ac_file" || continue;
   case $ac_file in
-    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;;
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
     *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
        break;;
   esac
 done
 else
-  echo "$as_me: failed program was:" >&5
+  $as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
 fi
-
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
 OBJEXT=$ac_cv_objext
 ac_objext=$OBJEXT
-{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -2341,54 +2672,34 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_compiler_gnu=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_compiler_gnu=no
+  ac_compiler_gnu=no
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; }
-GCC=`test $ac_compiler_gnu = yes && echo yes`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
 ac_test_CFLAGS=${CFLAGS+set}
 ac_save_CFLAGS=$CFLAGS
-{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_save_c_werror_flag=$ac_c_werror_flag
    ac_c_werror_flag=yes
    ac_cv_prog_cc_g=no
    CFLAGS="-g"
-   cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -2399,34 +2710,11 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_prog_cc_g=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	CFLAGS=""
-      cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -2437,35 +2725,12 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if ac_fn_c_try_compile "$LINENO"; then :
 
-	ac_c_werror_flag=$ac_save_c_werror_flag
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
 	 CFLAGS="-g"
-	 cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -2476,42 +2741,18 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_prog_cc_g=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    ac_c_werror_flag=$ac_save_c_werror_flag
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
 if test "$ac_test_CFLAGS" = set; then
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
@@ -2527,23 +2768,18 @@ else
     CFLAGS=
   fi
 fi
-{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5
-echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_cv_prog_cc_c89=no
 ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdarg.h>
 #include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
 struct buf { int x; };
 FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -2595,31 +2831,9 @@ for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
 	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
 do
   CC="$ac_save_CC $ac_arg"
-  rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+  if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_prog_cc_c89=$ac_arg
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
 fi
-
 rm -f core conftest.err conftest.$ac_objext
   test "x$ac_cv_prog_cc_c89" != "xno" && break
 done
@@ -2630,17 +2844,19 @@ fi
 # AC_CACHE_VAL
 case "x$ac_cv_prog_cc_c89" in
   x)
-    { echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6; } ;;
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
   xno)
-    { echo "$as_me:$LINENO: result: unsupported" >&5
-echo "${ECHO_T}unsupported" >&6; } ;;
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
   *)
     CC="$CC $ac_cv_prog_cc_c89"
-    { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;;
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
 esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
 
+fi
 
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
@@ -2651,19 +2867,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
-
-{ echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldl  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -2681,47 +2892,68 @@ return dlopen ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_dl_dlopen=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBDL 1
+_ACEOF
+
+  LIBS="-ldl $LIBS"
 
-	ac_cv_lib_dl_dlopen=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for iconv_open in -lc" >&5
+$as_echo_n "checking for iconv_open in -lc... " >&6; }
+if ${ac_cv_lib_c_iconv_open+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lc  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char iconv_open ();
+int
+main ()
+{
+return iconv_open ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_c_iconv_open=yes
+else
+  ac_cv_lib_c_iconv_open=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; }
-if test $ac_cv_lib_dl_dlopen = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBDL 1
-_ACEOF
-
-  LIBS="-ldl $LIBS"
-
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_iconv_open" >&5
+$as_echo "$ac_cv_lib_c_iconv_open" >&6; }
+if test "x$ac_cv_lib_c_iconv_open" = xyes; then :
+  HAVE_ICONV=yes
 fi
 
+HAVE_ICONV=$HAVE_ICONV
+
 
 
 	# Remove -g from compile flags, we will add via CFG variable if
@@ -2732,16 +2964,12 @@ fi
 	# check for GNU compiler, and use -Wall
 	if test "$GCC" = "yes"; then
 		C_WFLAGS="-Wall"
-		cat >>confdefs.h <<\_ACEOF
-#define USE_GNUCC 1
-_ACEOF
+		$as_echo "#define USE_GNUCC 1" >>confdefs.h
 
 	fi
 	if test "$GXX" = "yes"; then
 		CXX_WFLAGS="-Wall"
-		cat >>confdefs.h <<\_ACEOF
-#define USE_GNUCC 1
-_ACEOF
+		$as_echo "#define USE_GNUCC 1" >>confdefs.h
 
 	fi
 	CXX_WFLAGS=$CXX_WFLAGS
@@ -2823,15 +3051,15 @@ ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
 fi
 if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  if ${ac_cv_prog_CPP+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
       # Double quotes because CPP needs to be expanded
     for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
@@ -2845,11 +3073,7 @@ do
   # <limits.h> exists even on freestanding compilers.
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #ifdef __STDC__
 # include <limits.h>
@@ -2858,76 +3082,34 @@ cat >>conftest.$ac_ext <<_ACEOF
 #endif
 		     Syntax error
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if ac_fn_c_try_cpp "$LINENO"; then :
 
+else
   # Broken: fails on valid input.
 continue
 fi
-
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
+if ac_fn_c_try_cpp "$LINENO"; then :
   # Broken: success on invalid input.
 continue
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
   # Passes both tests.
 ac_preproc_ok=:
 break
 fi
-
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
   break
 fi
 
@@ -2939,8 +3121,8 @@ fi
 else
   ac_cv_prog_CPP=$CPP
 fi
-{ echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
 ac_preproc_ok=false
 for ac_c_preproc_warn_flag in '' yes
 do
@@ -2950,11 +3132,7 @@ do
   # <limits.h> exists even on freestanding compilers.
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #ifdef __STDC__
 # include <limits.h>
@@ -2963,83 +3141,40 @@ cat >>conftest.$ac_ext <<_ACEOF
 #endif
 		     Syntax error
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  :
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if ac_fn_c_try_cpp "$LINENO"; then :
 
+else
   # Broken: fails on valid input.
 continue
 fi
-
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
+if ac_fn_c_try_cpp "$LINENO"; then :
   # Broken: success on invalid input.
 continue
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
   # Passes both tests.
 ac_preproc_ok=:
 break
 fi
-
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
-  :
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
 else
-  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
-   { (exit 1); exit 1; }; }
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 ac_ext=c
@@ -3049,45 +3184,40 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5
-echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  # Extract the first word of "grep ggrep" to use in msg output
-if test -z "$GREP"; then
-set dummy grep ggrep; ac_prog_name=$2
-if test "${ac_cv_path_GREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
+  if test -z "$GREP"; then
   ac_path_GREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_prog in grep ggrep; do
-  for ac_exec_ext in '' $ac_executable_extensions; do
-    ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-    { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
-    # Check for GNU ac_path_GREP and select it if it is found.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
   # Check for GNU $ac_path_GREP
 case `"$ac_path_GREP" --version 2>&1` in
 *GNU*)
   ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
 *)
   ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  $as_echo_n 0123456789 >"conftest.in"
   while :
   do
     cat "conftest.in" "conftest.in" >"conftest.tmp"
     mv "conftest.tmp" "conftest.in"
     cp "conftest.in" "conftest.nl"
-    echo 'GREP' >> "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
     "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
     diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    ac_count=`expr $ac_count + 1`
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
     if test $ac_count -gt ${ac_path_GREP_max-0}; then
       # Best one so far, save it but keep looking for a better one
       ac_cv_path_GREP="$ac_path_GREP"
@@ -3099,77 +3229,61 @@ case `"$ac_path_GREP" --version 2>&1` in
   rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
 esac
 
-
-    $ac_path_GREP_found && break 3
+      $ac_path_GREP_found && break 3
+    done
+  done
   done
-done
-
-done
 IFS=$as_save_IFS
-
-
-fi
-
-GREP="$ac_cv_path_GREP"
-if test -z "$GREP"; then
-  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
 else
   ac_cv_path_GREP=$GREP
 fi
 
-
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5
-echo "${ECHO_T}$ac_cv_path_GREP" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
  GREP="$ac_cv_path_GREP"
 
 
-{ echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
    then ac_cv_path_EGREP="$GREP -E"
    else
-     # Extract the first word of "egrep" to use in msg output
-if test -z "$EGREP"; then
-set dummy egrep; ac_prog_name=$2
-if test "${ac_cv_path_EGREP+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
+     if test -z "$EGREP"; then
   ac_path_EGREP_found=false
-# Loop through the user's path and test for each of PROGNAME-LIST
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  for ac_prog in egrep; do
-  for ac_exec_ext in '' $ac_executable_extensions; do
-    ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-    { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
-    # Check for GNU ac_path_EGREP and select it if it is found.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
   # Check for GNU $ac_path_EGREP
 case `"$ac_path_EGREP" --version 2>&1` in
 *GNU*)
   ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
 *)
   ac_count=0
-  echo $ECHO_N "0123456789$ECHO_C" >"conftest.in"
+  $as_echo_n 0123456789 >"conftest.in"
   while :
   do
     cat "conftest.in" "conftest.in" >"conftest.tmp"
     mv "conftest.tmp" "conftest.in"
     cp "conftest.in" "conftest.nl"
-    echo 'EGREP' >> "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
     "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
     diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    ac_count=`expr $ac_count + 1`
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
     if test $ac_count -gt ${ac_path_EGREP_max-0}; then
       # Best one so far, save it but keep looking for a better one
       ac_cv_path_EGREP="$ac_path_EGREP"
@@ -3181,46 +3295,31 @@ case `"$ac_path_EGREP" --version 2>&1` in
   rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
 esac
 
-
-    $ac_path_EGREP_found && break 3
+      $ac_path_EGREP_found && break 3
+    done
+  done
   done
-done
-
-done
 IFS=$as_save_IFS
-
-
-fi
-
-EGREP="$ac_cv_path_EGREP"
-if test -z "$EGREP"; then
-  { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5
-echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;}
-   { (exit 1); exit 1; }; }
-fi
-
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
 else
   ac_cv_path_EGREP=$EGREP
 fi
 
-
    fi
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5
-echo "${ECHO_T}$ac_cv_path_EGREP" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
  EGREP="$ac_cv_path_EGREP"
 
 
-{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdlib.h>
 #include <stdarg.h>
@@ -3235,47 +3334,23 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_header_stdc=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_header_stdc=no
+  ac_cv_header_stdc=no
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <string.h>
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then
-  :
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
 else
   ac_cv_header_stdc=no
 fi
@@ -3285,18 +3360,14 @@ fi
 
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdlib.h>
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then
-  :
+  $EGREP "free" >/dev/null 2>&1; then :
+
 else
   ac_cv_header_stdc=no
 fi
@@ -3306,14 +3377,10 @@ fi
 
 if test $ac_cv_header_stdc = yes; then
   # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then
+  if test "$cross_compiling" = yes; then :
   :
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <ctype.h>
 #include <stdlib.h>
@@ -3340,113 +3407,35 @@ main ()
   return 0;
 }
 _ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  :
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if ac_fn_c_try_run "$LINENO"; then :
 
-( exit $ac_status )
-ac_cv_header_stdc=no
+else
+  ac_cv_header_stdc=no
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
-
 fi
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
 if test $ac_cv_header_stdc = yes; then
 
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
 
 fi
 
 # On IRIX 5.3, sys/types and inttypes.h are conflicting.
-
-
-
-
-
-
-
-
-
 for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
 		  inttypes.h stdint.h unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  eval "$as_ac_Header=yes"
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	eval "$as_ac_Header=no"
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
 fi
@@ -3454,142 +3443,13 @@ fi
 done
 
 
-
-
-
 for ac_header in rpc/pmap_clnt.h float.h dlfcn.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
 
 fi
@@ -3612,241 +3472,229 @@ if test "$ac_cv_header_dlfcn_h" = no ; then
   CFLAGS="$CFLAGS -DMISSING_DLFCN_H"
 fi
 
-{ echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
-echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6; }
-if test "${ac_cv_c_bigendian+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
-  # See if sys/param.h defines the BYTE_ORDER macro.
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+  ac_cv_c_bigendian=unknown
+    # See if we're dealing with a universal compiler.
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __APPLE_CC__
+	       not a universal capable compiler
+	     #endif
+	     typedef int dummy;
+
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+	# Check for potential -arch flags.  It is not universal unless
+	# there are at least two -arch flags with different values.
+	ac_arch=
+	ac_prev=
+	for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+	 if test -n "$ac_prev"; then
+	   case $ac_word in
+	     i?86 | x86_64 | ppc | ppc64)
+	       if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+		 ac_arch=$ac_word
+	       else
+		 ac_cv_c_bigendian=universal
+		 break
+	       fi
+	       ;;
+	   esac
+	   ac_prev=
+	 elif test "x$ac_word" = "x-arch"; then
+	   ac_prev=arch
+	 fi
+       done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if sys/param.h defines the BYTE_ORDER macro.
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <sys/types.h>
-#include <sys/param.h>
+	     #include <sys/param.h>
 
 int
 main ()
 {
-#if  ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \
-	&& BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN)
- bogus endian macros
-#endif
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+		     && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+		     && LITTLE_ENDIAN)
+	      bogus endian macros
+	     #endif
 
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_c_try_compile "$LINENO"; then :
   # It does; now see whether it defined to BIG_ENDIAN or not.
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+		#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+		 not big endian
+		#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_bigendian=yes
+else
+  ac_cv_c_bigendian=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+	      bogus endian macros
+	     #endif
+
+  ;
+  return 0;
+}
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  # It does; now see whether it defined to _BIG_ENDIAN or not.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <sys/types.h>
-#include <sys/param.h>
+#include <limits.h>
 
 int
 main ()
 {
-#if BYTE_ORDER != BIG_ENDIAN
- not big endian
-#endif
+#ifndef _BIG_ENDIAN
+		 not big endian
+		#endif
 
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
+if ac_fn_c_try_compile "$LINENO"; then :
   ac_cv_c_bigendian=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_c_bigendian=no
+  ac_cv_c_bigendian=no
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	# It does not; compile a test program.
-if test "$cross_compiling" = yes; then
-  # try to guess the endianness by grepping values into an object file
-  ac_cv_c_bigendian=unknown
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+    fi
+    if test $ac_cv_c_bigendian = unknown; then
+      # Compile a test program.
+      if test "$cross_compiling" = yes; then :
+  # Try to guess by grepping values from an object file.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
-short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
-void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
-short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
-short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
-void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+short int ascii_mm[] =
+		  { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+		short int ascii_ii[] =
+		  { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+		int use_ascii (int i) {
+		  return ascii_mm[i] + ascii_ii[i];
+		}
+		short int ebcdic_ii[] =
+		  { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+		short int ebcdic_mm[] =
+		  { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+		int use_ebcdic (int i) {
+		  return ebcdic_mm[i] + ebcdic_ii[i];
+		}
+		extern int foo;
+
 int
 main ()
 {
- _ascii (); _ebcdic ();
+return use_ascii (foo) == use_ebcdic (foo);
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
-  ac_cv_c_bigendian=yes
-fi
-if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
-  if test "$ac_cv_c_bigendian" = unknown; then
-    ac_cv_c_bigendian=no
-  else
-    # finding both strings is unlikely to happen, but who knows?
-    ac_cv_c_bigendian=unknown
-  fi
-fi
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-
+if ac_fn_c_try_compile "$LINENO"; then :
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+	      ac_cv_c_bigendian=yes
+	    fi
+	    if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+	      if test "$ac_cv_c_bigendian" = unknown; then
+		ac_cv_c_bigendian=no
+	      else
+		# finding both strings is unlikely to happen, but who knows?
+		ac_cv_c_bigendian=unknown
+	      fi
+	    fi
 fi
-
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $ac_includes_default
 int
 main ()
 {
 
-  /* Are we little or big endian?  From Harbison&Steele.  */
-  union
-  {
-    long int l;
-    char c[sizeof (long int)];
-  } u;
-  u.l = 1;
-  return u.c[sizeof (long int) - 1] == 1;
+	     /* Are we little or big endian?  From Harbison&Steele.  */
+	     union
+	     {
+	       long int l;
+	       char c[sizeof (long int)];
+	     } u;
+	     u.l = 1;
+	     return u.c[sizeof (long int) - 1] == 1;
 
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
+if ac_fn_c_try_run "$LINENO"; then :
   ac_cv_c_bigendian=no
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_c_bigendian=yes
+  ac_cv_c_bigendian=yes
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 
-
+    fi
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+   yes)
+     $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+   no)
+      ;; #(
+   universal)
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
-echo "${ECHO_T}$ac_cv_c_bigendian" >&6; }
-case $ac_cv_c_bigendian in
-  yes)
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
 
-cat >>confdefs.h <<\_ACEOF
-#define WORDS_BIGENDIAN 1
-_ACEOF
- ;;
-  no)
-     ;;
-  *)
-    { { echo "$as_me:$LINENO: error: unknown endianness
-presetting ac_cv_c_bigendian=no (or yes) will help" >&5
-echo "$as_me: error: unknown endianness
-presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
-   { (exit 1); exit 1; }; } ;;
-esac
+     ;; #(
+   *)
+     as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
 
 if test $ac_cv_c_bigendian = yes ; then
   BIG_ENDIAN=1
@@ -3864,25 +3712,21 @@ export PROJ_LIB PROJ_INCLUDE PROJ_SETTING
 
 
 # Check whether --with-proj was given.
-if test "${with_proj+set}" = set; then
+if test "${with_proj+set}" = set; then :
   withval=$with_proj;
 fi
 
 
 if test "$with_proj" = "yes" ; then
 
-  { echo "$as_me:$LINENO: checking for pj_init in -lproj" >&5
-echo $ECHO_N "checking for pj_init in -lproj... $ECHO_C" >&6; }
-if test "${ac_cv_lib_proj_pj_init+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pj_init in -lproj" >&5
+$as_echo_n "checking for pj_init in -lproj... " >&6; }
+if ${ac_cv_lib_proj_pj_init+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lproj  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -3900,178 +3744,29 @@ return pj_init ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_proj_pj_init=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_proj_pj_init=no
+  ac_cv_lib_proj_pj_init=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_proj_pj_init" >&5
-echo "${ECHO_T}$ac_cv_lib_proj_pj_init" >&6; }
-if test $ac_cv_lib_proj_pj_init = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_proj_pj_init" >&5
+$as_echo "$ac_cv_lib_proj_pj_init" >&6; }
+if test "x$ac_cv_lib_proj_pj_init" = xyes; then :
   PROJ_SETTING=external
 else
   PROJ_SETTING=missing
 fi
 
-
-for ac_header in projects.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  for ac_header in projects.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "projects.h" "ac_cv_header_projects_h" "$ac_includes_default"
+if test "x$ac_cv_header_projects_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_PROJECTS_H 1
 _ACEOF
 
 fi
@@ -4080,14 +3775,10 @@ done
 
 
   if test $PROJ_SETTING = missing ; then
-    { { echo "$as_me:$LINENO: error: Unable to find external PROJ.4 library, give path or use default internal library." >&5
-echo "$as_me: error: Unable to find external PROJ.4 library, give path or use default internal library." >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "Unable to find external PROJ.4 library, give path or use default internal library." "$LINENO" 5
   fi
   if test "$ac_cv_header_projects_h" = no ; then
-    { { echo "$as_me:$LINENO: error: Unable to find external PROJ.4 projects.h file, give path or use default internal library." >&5
-echo "$as_me: error: Unable to find external PROJ.4 projects.h file, give path or use default internal library." >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "Unable to find external PROJ.4 projects.h file, give path or use default internal library." "$LINENO" 5
   fi
 
   PROJ_SETTING=external
@@ -4099,9 +3790,7 @@ elif test "$with_proj" != "no" -a "$with_proj" != "" ; then
     echo "checking for $with_proj/include/projects.h ... found"
     PROJ_INCLUDE=-I$with_proj/include
   else
-    { { echo "$as_me:$LINENO: error: Unable to find $with_proj/include/projects.h" >&5
-echo "$as_me: error: Unable to find $with_proj/include/projects.h" >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "Unable to find $with_proj/include/projects.h" "$LINENO" 5
   fi
 
   if test -r $with_proj/lib/libproj.so ; then
@@ -4113,9 +3802,7 @@ echo "$as_me: error: Unable to find $with_proj/include/projects.h" >&2;}
     echo "checking for $PROJ_LIB ... found"
 
   else
-    { { echo "$as_me:$LINENO: error: Unable to find $with_proj/lib/libproj.{so,a}" >&5
-echo "$as_me: error: Unable to find $with_proj/lib/libproj.{so,a}" >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "Unable to find $with_proj/lib/libproj.{so,a}" "$LINENO" 5
   fi
 
   PROJ_SETTING=external
@@ -4124,7 +3811,7 @@ fi
 
 
 # Check whether --with-projlib was given.
-if test "${with_projlib+set}" = set; then
+if test "${with_projlib+set}" = set; then :
   withval=$with_projlib;
 fi
 
@@ -4137,7 +3824,7 @@ fi
 
 
 # Check whether --with-projinc was given.
-if test "${with_projinc+set}" = set; then
+if test "${with_projinc+set}" = set; then :
   withval=$with_projinc;
 fi
 
@@ -4167,25 +3854,21 @@ export ZLIB_LIB ZLIB_INCLUDE ZLIB_SETTING
 
 
 # Check whether --with-zlib was given.
-if test "${with_zlib+set}" = set; then
+if test "${with_zlib+set}" = set; then :
   withval=$with_zlib;
 fi
 
 
 if test "$with_zlib" = "yes" ; then
 
-  { echo "$as_me:$LINENO: checking for deflateInit_ in -lz" >&5
-echo $ECHO_N "checking for deflateInit_ in -lz... $ECHO_C" >&6; }
-if test "${ac_cv_lib_z_deflateInit_+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for deflateInit_ in -lz" >&5
+$as_echo_n "checking for deflateInit_ in -lz... " >&6; }
+if ${ac_cv_lib_z_deflateInit_+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lz  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -4203,178 +3886,29 @@ return deflateInit_ ();
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
+if ac_fn_c_try_link "$LINENO"; then :
   ac_cv_lib_z_deflateInit_=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_z_deflateInit_=no
+  ac_cv_lib_z_deflateInit_=no
 fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_z_deflateInit_" >&5
-echo "${ECHO_T}$ac_cv_lib_z_deflateInit_" >&6; }
-if test $ac_cv_lib_z_deflateInit_ = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_deflateInit_" >&5
+$as_echo "$ac_cv_lib_z_deflateInit_" >&6; }
+if test "x$ac_cv_lib_z_deflateInit_" = xyes; then :
   ZLIB_SETTING=external
 else
   ZLIB_SETTING=missing
 fi
 
-
-for ac_header in zlib.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  ac_header_preproc=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
-fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  eval "$as_ac_Header=\$ac_header_preproc"
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  for ac_header in zlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_ZLIB_H 1
 _ACEOF
 
 fi
@@ -4383,14 +3917,10 @@ done
 
 
   if test $ZLIB_SETTING = missing ; then
-    { { echo "$as_me:$LINENO: error: Unable to find external ZLIB library, give path or use default internal library." >&5
-echo "$as_me: error: Unable to find external ZLIB library, give path or use default internal library." >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "Unable to find external ZLIB library, give path or use default internal library." "$LINENO" 5
   fi
   if test "$ac_cv_header_zlib_h" = no ; then
-    { { echo "$as_me:$LINENO: error: Unable to find external ZLIB zlib.h file, give path or use default internal library." >&5
-echo "$as_me: error: Unable to find external ZLIB zlib.h file, give path or use default internal library." >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "Unable to find external ZLIB zlib.h file, give path or use default internal library." "$LINENO" 5
   fi
 
   ZLIB_SETTING=external
@@ -4399,43 +3929,39 @@ echo "$as_me: error: Unable to find external ZLIB zlib.h file, give path or use
 elif test "$with_zlib" != "no" -a "$with_zlib" != "" ; then
 
   if test -r $with_zlib/include/zlib.h ; then
-    { echo "$as_me:$LINENO: result: checking for $with_zlib/include/zlib.h ... found" >&5
-echo "${ECHO_T}checking for $with_zlib/include/zlib.h ... found" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: checking for $with_zlib/include/zlib.h ... found" >&5
+$as_echo "checking for $with_zlib/include/zlib.h ... found" >&6; }
     ZLIB_INCLUDE=-I$with_zlib/include
   elif test -r $with_zlib/zlib.h ; then
-    { echo "$as_me:$LINENO: result: checking for $with_zlib/zlib.h ... found" >&5
-echo "${ECHO_T}checking for $with_zlib/zlib.h ... found" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: checking for $with_zlib/zlib.h ... found" >&5
+$as_echo "checking for $with_zlib/zlib.h ... found" >&6; }
     ZLIB_INCLUDE=-I$with_zlib
   else
-    { { echo "$as_me:$LINENO: error: Unable to find $with_zlib/include/zlib.h" >&5
-echo "$as_me: error: Unable to find $with_zlib/include/zlib.h" >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "Unable to find $with_zlib/include/zlib.h" "$LINENO" 5
   fi
 
   if test -r $with_zlib/lib/libz.so ; then
     ZLIB_LIB=$with_zlib/lib/libz.so
-    { echo "$as_me:$LINENO: result: checking for $ZLIB_LIB ... found" >&5
-echo "${ECHO_T}checking for $ZLIB_LIB ... found" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: checking for $ZLIB_LIB ... found" >&5
+$as_echo "checking for $ZLIB_LIB ... found" >&6; }
 
   elif test -r $with_zlib/lib/libz.a ; then
     ZLIB_LIB=$with_zlib/lib/libz.a
-    { echo "$as_me:$LINENO: result: checking for $ZLIB_LIB ... found" >&5
-echo "${ECHO_T}checking for $ZLIB_LIB ... found" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: checking for $ZLIB_LIB ... found" >&5
+$as_echo "checking for $ZLIB_LIB ... found" >&6; }
 
   elif test -r $with_zlib/libz.so ; then
     ZLIB_LIB=$with_zlib/libz.so
-    { echo "$as_me:$LINENO: result: checking for $ZLIB_LIB ... found" >&5
-echo "${ECHO_T}checking for $ZLIB_LIB ... found" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: checking for $ZLIB_LIB ... found" >&5
+$as_echo "checking for $ZLIB_LIB ... found" >&6; }
 
   elif test -r $with_zlib/libz.a ; then
     ZLIB_LIB=$with_zlib/libz.a
-    { echo "$as_me:$LINENO: result: checking for $ZLIB_LIB ... found" >&5
-echo "${ECHO_T}checking for $ZLIB_LIB ... found" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: checking for $ZLIB_LIB ... found" >&5
+$as_echo "checking for $ZLIB_LIB ... found" >&6; }
 
   else
-    { { echo "$as_me:$LINENO: error: Unable to find $with_zlib/{lib/,}libz.{so,a}" >&5
-echo "$as_me: error: Unable to find $with_zlib/{lib/,}libz.{so,a}" >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "Unable to find $with_zlib/{lib/,}libz.{so,a}" "$LINENO" 5
   fi
 
   ZLIB_SETTING=external
@@ -4444,7 +3970,7 @@ fi
 
 
 # Check whether --with-zliblib was given.
-if test "${with_zliblib+set}" = set; then
+if test "${with_zliblib+set}" = set; then :
   withval=$with_zliblib;
 fi
 
@@ -4452,13 +3978,13 @@ fi
 if test "$with_zliblib" != "" ; then
   ZLIB_LIB=$with_zliblib
   ZLIB_SETTING=external
-  { echo "$as_me:$LINENO: result: Using ZLIB_LIB=$ZLIB_LIB for ZLIB library." >&5
-echo "${ECHO_T}Using ZLIB_LIB=$ZLIB_LIB for ZLIB library." >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using ZLIB_LIB=$ZLIB_LIB for ZLIB library." >&5
+$as_echo "Using ZLIB_LIB=$ZLIB_LIB for ZLIB library." >&6; }
 fi
 
 
 # Check whether --with-zlibinc was given.
-if test "${with_zlibinc+set}" = set; then
+if test "${with_zlibinc+set}" = set; then :
   withval=$with_zlibinc;
 fi
 
@@ -4466,13 +3992,13 @@ fi
 if test "$with_zlibinc" != "" ; then
   ZLIB_INCLUDE=-I${with_zlibinc}
   ZLIB_SETTING=external
-  { echo "$as_me:$LINENO: result: Using ZLIB_INCLUDE=$ZLIB_INCLUDE for ZLIB includes." >&5
-echo "${ECHO_T}Using ZLIB_INCLUDE=$ZLIB_INCLUDE for ZLIB includes." >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using ZLIB_INCLUDE=$ZLIB_INCLUDE for ZLIB includes." >&5
+$as_echo "Using ZLIB_INCLUDE=$ZLIB_INCLUDE for ZLIB includes." >&6; }
 fi
 
 if test "$ZLIB_SETTING" = "internal" ; then
-  { echo "$as_me:$LINENO: result: Using internal ZLIB implementation." >&5
-echo "${ECHO_T}Using internal ZLIB implementation." >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using internal ZLIB implementation." >&5
+$as_echo "Using internal ZLIB implementation." >&6; }
 fi
 
 ZLIB_SETTING=$ZLIB_SETTING
@@ -4490,25 +4016,21 @@ export EXPAT_LIB EXPAT_INCLUDE EXPAT_SETTING
 
 
 # Check whether --with-expat was given.
-if test "${with_expat+set}" = set; then
+if test "${with_expat+set}" = set; then :
   withval=$with_expat;
 fi
 
 
 if test "$with_expat" = "yes" ; then
 
-  { echo "$as_me:$LINENO: checking for XML_ParserCreate in -lexpat" >&5
-echo $ECHO_N "checking for XML_ParserCreate in -lexpat... $ECHO_C" >&6; }
-if test "${ac_cv_lib_expat_XML_ParserCreate+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML_ParserCreate in -lexpat" >&5
+$as_echo_n "checking for XML_ParserCreate in -lexpat... " >&6; }
+if ${ac_cv_lib_expat_XML_ParserCreate+:} false; then :
+  $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lexpat  $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 /* Override any GCC internal prototype to avoid an error.
@@ -4520,184 +4042,35 @@ extern "C"
 char XML_ParserCreate ();
 int
 main ()
-{
-return XML_ParserCreate ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  ac_cv_lib_expat_XML_ParserCreate=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_cv_lib_expat_XML_ParserCreate=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_expat_XML_ParserCreate" >&5
-echo "${ECHO_T}$ac_cv_lib_expat_XML_ParserCreate" >&6; }
-if test $ac_cv_lib_expat_XML_ParserCreate = yes; then
-  EXPAT_SETTING=external
-else
-  EXPAT_SETTING=missing
-fi
-
-
-for ac_header in expat.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-	 test -z "$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_header_compiler=yes
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-	ac_header_compiler=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <$ac_header>
-_ACEOF
-if { (ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } >/dev/null && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then
-  ac_header_preproc=yes
+{
+return XML_ParserCreate ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_expat_XML_ParserCreate=yes
 else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-  ac_header_preproc=no
+  ac_cv_lib_expat_XML_ParserCreate=no
 fi
-
-rm -f conftest.err conftest.$ac_ext
-{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
-  yes:no: )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
-    ac_header_preproc=yes
-    ;;
-  no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
-
-    ;;
-esac
-{ echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_expat_XML_ParserCreate" >&5
+$as_echo "$ac_cv_lib_expat_XML_ParserCreate" >&6; }
+if test "x$ac_cv_lib_expat_XML_ParserCreate" = xyes; then :
+  EXPAT_SETTING=external
 else
-  eval "$as_ac_Header=\$ac_header_preproc"
+  EXPAT_SETTING=missing
 fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-	       { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
 
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  for ac_header in expat.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "expat.h" "ac_cv_header_expat_h" "$ac_includes_default"
+if test "x$ac_cv_header_expat_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_EXPAT_H 1
 _ACEOF
 
 fi
@@ -4706,14 +4079,10 @@ done
 
 
   if test $EXPAT_SETTING = missing ; then
-    { { echo "$as_me:$LINENO: error: Unable to find external Expat library, give path or use default internal library." >&5
-echo "$as_me: error: Unable to find external Expat library, give path or use default internal library." >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "Unable to find external Expat library, give path or use default internal library." "$LINENO" 5
   fi
   if test "$ac_cv_header_expat_h" = no ; then
-    { { echo "$as_me:$LINENO: error: Unable to find external expat.h file, give path or use default internal library." >&5
-echo "$as_me: error: Unable to find external expat.h file, give path or use default internal library." >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "Unable to find external expat.h file, give path or use default internal library." "$LINENO" 5
   fi
 
   EXPAT_SETTING=external
@@ -4732,9 +4101,7 @@ elif test "$with_expat" != "" ; then
     echo "checking for $with_expat/expat.h ... found"
     EXPAT_INCLUDE=-I$with_expat
   else
-    { { echo "$as_me:$LINENO: error: Unable to find $with_expat/include/expat.h" >&5
-echo "$as_me: error: Unable to find $with_expat/include/expat.h" >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "Unable to find $with_expat/include/expat.h" "$LINENO" 5
   fi
 
   if test -r $with_expat/lib/libexpat.so ; then
@@ -4754,9 +4121,7 @@ echo "$as_me: error: Unable to find $with_expat/include/expat.h" >&2;}
     echo "checking for $EXPAT_LIB ... found"
 
   else
-    { { echo "$as_me:$LINENO: error: Unable to find $with_expat/{lib/,}libexpat.{so,a}" >&5
-echo "$as_me: error: Unable to find $with_expat/{lib/,}libexpat.{so,a}" >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "Unable to find $with_expat/{lib/,}libexpat.{so,a}" "$LINENO" 5
   fi
 
   EXPAT_SETTING=external
@@ -4764,7 +4129,7 @@ fi
 
 
 # Check whether --with-expatlib was given.
-if test "${with_expatlib+set}" = set; then
+if test "${with_expatlib+set}" = set; then :
   withval=$with_expatlib;
 fi
 
@@ -4777,7 +4142,7 @@ fi
 
 
 # Check whether --with-expatinc was given.
-if test "${with_expatinc+set}" = set; then
+if test "${with_expatinc+set}" = set; then :
   withval=$with_expatinc;
 fi
 
@@ -4802,24 +4167,24 @@ EXPAT_LIB=$EXPAT_LIB
 # Allow the pkg-config directory to be set
 
 # Check whether --with-pkgconfigdir was given.
-if test "${with_pkgconfigdir+set}" = set; then
+if test "${with_pkgconfigdir+set}" = set; then :
   withval=$with_pkgconfigdir; pkgconfigdir=${withval}
 else
   pkgconfigdir='${libdir}/pkgconfig'
 fi
 
 
-{ echo "$as_me:$LINENO: pkgconfig directory is ${pkgconfigdir}" >&5
-echo "$as_me: pkgconfig directory is ${pkgconfigdir}" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: pkgconfig directory is ${pkgconfigdir}" >&5
+$as_echo "$as_me: pkgconfig directory is ${pkgconfigdir}" >&6;}
 
 # Make the *-config binary config scripts optional
 
 # Check whether --with-binconfigs was given.
-if test "${with_binconfigs+set}" = set; then
+if test "${with_binconfigs+set}" = set; then :
   withval=$with_binconfigs; if test "${withval}" = no; then
 		binconfigs=
-		{ echo "$as_me:$LINENO: ogdi-config scripts will not be built" >&5
-echo "$as_me: ogdi-config scripts will not be built" >&6;}
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: ogdi-config scripts will not be built" >&5
+$as_echo "$as_me: ogdi-config scripts will not be built" >&6;}
 	else
 		binconfigs='${binconfigs}'
 	fi
@@ -4866,12 +4231,13 @@ _ACEOF
     case $ac_val in #(
     *${as_nl}*)
       case $ac_var in #(
-      *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5
-echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       esac
       case $ac_var in #(
       _ | IFS | as_nl) ;; #(
-      *) $as_unset $ac_var ;;
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
       esac ;;
     esac
   done
@@ -4879,8 +4245,8 @@ echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
   (set) 2>&1 |
     case $as_nl`(ac_space=' '; set) 2>&1` in #(
     *${as_nl}ac_space=\ *)
-      # `set' does not quote correctly, so add quotes (double-quote
-      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      # `set' does not quote correctly, so add quotes: double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \.
       sed -n \
 	"s/'/'\\\\''/g;
 	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
@@ -4902,13 +4268,24 @@ echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;;
      :end' >>confcache
 if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
   if test -w "$cache_file"; then
-    test "x$cache_file" != "x/dev/null" &&
-      { echo "$as_me:$LINENO: updating cache $cache_file" >&5
-echo "$as_me: updating cache $cache_file" >&6;}
-    cat confcache >$cache_file
+    if test "x$cache_file" != "x/dev/null"; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
   else
-    { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5
-echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
   fi
 fi
 rm -f confcache
@@ -4925,6 +4302,12 @@ test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
 # take arguments), then branch to the quote section.  Otherwise,
 # look for a macro that doesn't take arguments.
 ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
 t clear
 :clear
 s/^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\)/-D\1=\2/g
@@ -4951,14 +4334,15 @@ DEFS=`sed -n "$ac_script" confdefs.h`
 
 ac_libobjs=
 ac_ltlibobjs=
+U=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
-  ac_i=`echo "$ac_i" | sed "$ac_script"`
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
   # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
   #    will be set to the directory where LIBOBJS objects are built.
-  ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext"
-  ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo'
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
 done
 LIBOBJS=$ac_libobjs
 
@@ -4966,12 +4350,15 @@ LTLIBOBJS=$ac_ltlibobjs
 
 
 
-: ${CONFIG_STATUS=./config.status}
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
-echo "$as_me: creating $CONFIG_STATUS" >&6;}
-cat >$CONFIG_STATUS <<_ACEOF
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
 #! $SHELL
 # Generated by $as_me.
 # Run this file to recreate the current configuration.
@@ -4981,59 +4368,79 @@ cat >$CONFIG_STATUS <<_ACEOF
 debug=false
 ac_cs_recheck=false
 ac_cs_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
-## --------------------- ##
-## M4sh Initialization.  ##
-## --------------------- ##
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
 
 # Be more Bourne compatible
 DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
   emulate sh
   NULLCMD=:
-  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
 else
-  case `(set -o) 2>/dev/null` in
-  *posix*) set -o posix ;;
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
 esac
-
 fi
 
 
-
-
-# PATH needs CR
-# Avoid depending upon Character Ranges.
-as_cr_letters='abcdefghijklmnopqrstuvwxyz'
-as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
-as_cr_Letters=$as_cr_letters$as_cr_LETTERS
-as_cr_digits='0123456789'
-as_cr_alnum=$as_cr_Letters$as_cr_digits
-
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
-  echo "#! /bin/sh" >conf$$.sh
-  echo  "exit 0"   >>conf$$.sh
-  chmod +x conf$$.sh
-  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
-    PATH_SEPARATOR=';'
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
   else
-    PATH_SEPARATOR=:
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
   fi
-  rm -f conf$$.sh
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
 fi
 
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
-  as_unset=unset
-else
-  as_unset=false
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
 fi
 
 
@@ -5042,20 +4449,19 @@ fi
 # there to prevent editors from complaining about space-tab.
 # (If _AS_PATH_WALK were called with IFS unset, it would disable word
 # splitting by setting IFS to empty value.)
-as_nl='
-'
 IFS=" ""	$as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
-case $0 in
+as_myself=
+case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
-  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  done
 IFS=$as_save_IFS
 
      ;;
@@ -5066,32 +4472,111 @@ if test "x$as_myself" = x; then
   as_myself=$0
 fi
 if test ! -f "$as_myself"; then
-  echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
-  { (exit 1); exit 1; }
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
 fi
 
-# Work around bugs in pre-3.0 UWIN ksh.
-for as_var in ENV MAIL MAILPATH
-do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
 done
 PS1='$ '
 PS2='> '
 PS4='+ '
 
 # NLS nuisances.
-for as_var in \
-  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
-  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
-  LC_TELEPHONE LC_TIME
-do
-  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
-    eval $as_var=C; export $as_var
-  else
-    ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-done
+  $as_echo "$as_me: error: $2" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
 
-# Required to use basename.
 if expr a : '\(a\)' >/dev/null 2>&1 &&
    test "X`expr 00001 : '.*\(...\)'`" = X001; then
   as_expr=expr
@@ -5105,13 +4590,17 @@ else
   as_basename=false
 fi
 
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
 
-# Name of the executable.
 as_me=`$as_basename -- "$0" ||
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
 	 X"$0" : 'X\(//\)$' \| \
 	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-echo X/"$0" |
+$as_echo X/"$0" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
 	    s//\1/
 	    q
@@ -5126,131 +4615,118 @@ echo X/"$0" |
 	  }
 	  s/.*/./; q'`
 
-# CDPATH.
-$as_unset CDPATH
-
-
-
-  as_lineno_1=$LINENO
-  as_lineno_2=$LINENO
-  test "x$as_lineno_1" != "x$as_lineno_2" &&
-  test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || {
-
-  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
-  # uniformly replaced by the line number.  The first 'sed' inserts a
-  # line-number line after each line using $LINENO; the second 'sed'
-  # does the real work.  The second script uses 'N' to pair each
-  # line-number line with the line containing $LINENO, and appends
-  # trailing '-' during substitution so that $LINENO is not a special
-  # case at line end.
-  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
-  # scripts with optimization help from Paolo Bonzini.  Blame Lee
-  # E. McMahon (1931-1989) for sed's syntax.  :-)
-  sed -n '
-    p
-    /[$]LINENO/=
-  ' <$as_myself |
-    sed '
-      s/[$]LINENO.*/&-/
-      t lineno
-      b
-      :lineno
-      N
-      :loop
-      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
-      t loop
-      s/-\n.*//
-    ' >$as_me.lineno &&
-  chmod +x "$as_me.lineno" ||
-    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
-   { (exit 1); exit 1; }; }
-
-  # Don't try to exec as it changes $[0], causing all sort of problems
-  # (the dirname of $[0] is not the place where we might find the
-  # original and so on.  Autoconf is especially sensitive to this).
-  . "./$as_me.lineno"
-  # Exit status is that of the last command.
-  exit
-}
-
-
-if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
-  as_dirname=dirname
-else
-  as_dirname=false
-fi
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
 
 ECHO_C= ECHO_N= ECHO_T=
-case `echo -n x` in
+case `echo -n x` in #(((((
 -n*)
-  case `echo 'x\c'` in
+  case `echo 'xy\c'` in
   *c*) ECHO_T='	';;	# ECHO_T is single tab character.
-  *)   ECHO_C='\c';;
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
   esac;;
 *)
   ECHO_N='-n';;
 esac
 
-if expr a : '\(a\)' >/dev/null 2>&1 &&
-   test "X`expr 00001 : '.*\(...\)'`" = X001; then
-  as_expr=expr
-else
-  as_expr=false
-fi
-
 rm -f conf$$ conf$$.exe conf$$.file
 if test -d conf$$.dir; then
   rm -f conf$$.dir/conf$$.file
 else
   rm -f conf$$.dir
-  mkdir conf$$.dir
-fi
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s='ln -s'
-  # ... but there are two gotchas:
-  # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
-  # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-  # In both cases, we have to default to `cp -p'.
-  ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-    as_ln_s='cp -p'
-elif ln conf$$.file conf$$ 2>/dev/null; then
-  as_ln_s=ln
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -pR'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -pR'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -pR'
+  fi
 else
-  as_ln_s='cp -p'
+  as_ln_s='cp -pR'
 fi
 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
 rmdir conf$$.dir 2>/dev/null
 
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
 if mkdir -p . 2>/dev/null; then
-  as_mkdir_p=:
+  as_mkdir_p='mkdir -p "$as_dir"'
 else
   test -d ./-p && rmdir ./-p
   as_mkdir_p=false
 fi
 
-if test -x / >/dev/null 2>&1; then
-  as_test_x='test -x'
-else
-  if ls -dL / >/dev/null 2>&1; then
-    as_ls_L_option=L
-  else
-    as_ls_L_option=
-  fi
-  as_test_x='
-    eval sh -c '\''
-      if test -d "$1"; then
-        test -d "$1/.";
-      else
-	case $1 in
-        -*)set "./$1";;
-	esac;
-	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in
-	???[sx]*):;;*)false;;esac;fi
-    '\'' sh
-  '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -5260,13 +4736,19 @@ as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
 
 exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
 
-# Save the log message, to keep $[0] and so on meaningful, and to
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
 This file was extended by $as_me, which was
-generated by GNU Autoconf 2.61.  Invocation command line was
+generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -5279,59 +4761,74 @@ on `(hostname || uname -n) 2>/dev/null | sed 1q`
 
 _ACEOF
 
-cat >>$CONFIG_STATUS <<_ACEOF
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 # Files that config.status was made for.
 config_files="$ac_config_files"
 
 _ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 ac_cs_usage="\
-\`$as_me' instantiates files from templates according to the
-current configuration.
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
 
-Usage: $0 [OPTIONS] [FILE]...
+Usage: $0 [OPTION]... [TAG]...
 
   -h, --help       print this help, then exit
   -V, --version    print version number and configuration settings, then exit
-  -q, --quiet      do not print progress messages
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   do not print progress messages
   -d, --debug      don't remove temporary files
       --recheck    update $as_me by reconfiguring in the same conditions
-  --file=FILE[:TEMPLATE]
-		   instantiate the configuration file FILE
+      --file=FILE[:TEMPLATE]
+                   instantiate the configuration file FILE
 
 Configuration files:
 $config_files
 
-Report bugs to <bug-autoconf at gnu.org>."
+Report bugs to the package provider."
 
 _ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
 config.status
-configured by $0, generated by GNU Autoconf 2.61,
-  with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2006 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
 ac_pwd='$ac_pwd'
 srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
 _ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If no file are specified by the user, then we need to provide default
-# value.  By we need to know if files were specified by the user.
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
 ac_need_defaults=:
 while test $# != 0
 do
   case $1 in
-  --*=*)
+  --*=?*)
     ac_option=`expr "X$1" : 'X\([^=]*\)='`
     ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
     ac_shift=:
     ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
   *)
     ac_option=$1
     ac_optarg=$2
@@ -5344,25 +4841,30 @@ do
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
     ac_cs_recheck=: ;;
   --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
-    echo "$ac_cs_version"; exit ;;
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
   --debug | --debu | --deb | --de | --d | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
     $ac_shift
-    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
     ac_need_defaults=false;;
   --he | --h |  --help | --hel | -h )
-    echo "$ac_cs_usage"; exit ;;
+    $as_echo "$ac_cs_usage"; exit ;;
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil | --si | --s)
     ac_cs_silent=: ;;
 
   # This is an error.
-  -*) { echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2
-   { (exit 1); exit 1; }; } ;;
+  -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
 
-  *) ac_config_targets="$ac_config_targets $1"
+  *) as_fn_append ac_config_targets " $1"
      ac_need_defaults=false ;;
 
   esac
@@ -5377,30 +4879,32 @@ if $ac_cs_silent; then
 fi
 
 _ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 if \$ac_cs_recheck; then
-  echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
-  CONFIG_SHELL=$SHELL
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
   export CONFIG_SHELL
-  exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  exec "\$@"
 fi
 
 _ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 exec 5>>config.log
 {
   echo
   sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
 ## Running $as_me. ##
 _ASBOX
-  echo "$ac_log"
+  $as_echo "$ac_log"
 } >&5
 
 _ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 
 # Handling of arguments.
 for ac_config_target in $ac_config_targets
@@ -5411,9 +4915,7 @@ do
     "ogdi-config") CONFIG_FILES="$CONFIG_FILES ogdi-config:ogdi-config.in" ;;
     "config/generic.mak") CONFIG_FILES="$CONFIG_FILES config/generic.mak" ;;
 
-  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
-echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
-   { (exit 1); exit 1; }; };;
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
 done
 
@@ -5434,181 +4936,194 @@ fi
 # after its creation but before its name has been assigned to `$tmp'.
 $debug ||
 {
-  tmp=
+  tmp= ac_tmp=
   trap 'exit_status=$?
-  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
 ' 0
-  trap '{ (exit 1); exit 1; }' 1 2 13 15
+  trap 'as_fn_exit 1' 1 2 13 15
 }
 # Create a (secure) tmp directory for tmp files.
 
 {
   tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -n "$tmp" && test -d "$tmp"
+  test -d "$tmp"
 }  ||
 {
   tmp=./conf$$-$RANDOM
   (umask 077 && mkdir "$tmp")
-} ||
-{
-   echo "$me: cannot create a temporary directory in ." >&2
-   { (exit 1); exit 1; }
-}
-
-#
-# Set up the sed scripts for CONFIG_FILES section.
-#
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
 
-# No need to generate the scripts if there are no CONFIG_FILES.
-# This happens for instance when ./config.status config.h
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
 if test -n "$CONFIG_FILES"; then
 
-_ACEOF
 
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
 
 
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
-  cat >conf$$subs.sed <<_ACEOF
-SHELL!$SHELL$ac_delim
-PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim
-PACKAGE_NAME!$PACKAGE_NAME$ac_delim
-PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim
-PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim
-PACKAGE_STRING!$PACKAGE_STRING$ac_delim
-PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim
-exec_prefix!$exec_prefix$ac_delim
-prefix!$prefix$ac_delim
-program_transform_name!$program_transform_name$ac_delim
-bindir!$bindir$ac_delim
-sbindir!$sbindir$ac_delim
-libexecdir!$libexecdir$ac_delim
-datarootdir!$datarootdir$ac_delim
-datadir!$datadir$ac_delim
-sysconfdir!$sysconfdir$ac_delim
-sharedstatedir!$sharedstatedir$ac_delim
-localstatedir!$localstatedir$ac_delim
-includedir!$includedir$ac_delim
-oldincludedir!$oldincludedir$ac_delim
-docdir!$docdir$ac_delim
-infodir!$infodir$ac_delim
-htmldir!$htmldir$ac_delim
-dvidir!$dvidir$ac_delim
-pdfdir!$pdfdir$ac_delim
-psdir!$psdir$ac_delim
-libdir!$libdir$ac_delim
-localedir!$localedir$ac_delim
-mandir!$mandir$ac_delim
-DEFS!$DEFS$ac_delim
-ECHO_C!$ECHO_C$ac_delim
-ECHO_N!$ECHO_N$ac_delim
-ECHO_T!$ECHO_T$ac_delim
-LIBS!$LIBS$ac_delim
-build_alias!$build_alias$ac_delim
-host_alias!$host_alias$ac_delim
-target_alias!$target_alias$ac_delim
-OGDI_VERSION!$OGDI_VERSION$ac_delim
-OGDI_MAJOR!$OGDI_MAJOR$ac_delim
-OGDI_MINOR!$OGDI_MINOR$ac_delim
-CC!$CC$ac_delim
-CFLAGS!$CFLAGS$ac_delim
-LDFLAGS!$LDFLAGS$ac_delim
-CPPFLAGS!$CPPFLAGS$ac_delim
-ac_ct_CC!$ac_ct_CC$ac_delim
-EXEEXT!$EXEEXT$ac_delim
-OBJEXT!$OBJEXT$ac_delim
-CXX_WFLAGS!$CXX_WFLAGS$ac_delim
-C_WFLAGS!$C_WFLAGS$ac_delim
-CXX_PIC!$CXX_PIC$ac_delim
-C_PIC!$C_PIC$ac_delim
-LD_SHARED!$LD_SHARED$ac_delim
-CPP!$CPP$ac_delim
-GREP!$GREP$ac_delim
-EGREP!$EGREP$ac_delim
-RPC_INCLUDES!$RPC_INCLUDES$ac_delim
-BIG_ENDIAN!$BIG_ENDIAN$ac_delim
-PROJ_SETTING!$PROJ_SETTING$ac_delim
-PROJ_INCLUDE!$PROJ_INCLUDE$ac_delim
-PROJ_LIB!$PROJ_LIB$ac_delim
-ZLIB_SETTING!$ZLIB_SETTING$ac_delim
-ZLIB_INCLUDE!$ZLIB_INCLUDE$ac_delim
-ZLIB_LIB!$ZLIB_LIB$ac_delim
-EXPAT_SETTING!$EXPAT_SETTING$ac_delim
-EXPAT_INCLUDE!$EXPAT_INCLUDE$ac_delim
-EXPAT_LIB!$EXPAT_LIB$ac_delim
-pkgconfigdir!$pkgconfigdir$ac_delim
-binconfigs!$binconfigs$ac_delim
-LIBOBJS!$LIBOBJS$ac_delim
-LTLIBOBJS!$LTLIBOBJS$ac_delim
-_ACEOF
+  . ./conf$$subs.sh ||
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 70; then
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
     break
   elif $ac_last_try; then
-    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
-echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
-   { (exit 1); exit 1; }; }
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
   else
     ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
   fi
 done
+rm -f conf$$subs.sh
 
-ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
-if test -n "$ac_eof"; then
-  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
-  ac_eof=`expr $ac_eof + 1`
-fi
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
 
-cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof
-/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
+_ACAWK
 _ACEOF
-sed '
-s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
-s/^/s,@/; s/!/@,|#_!!_#|/
-:n
-t n
-s/'"$ac_delim"'$/,g/; t
-s/$/\\/; p
-N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
-' >>$CONFIG_STATUS <conf$$subs.sed
-rm -f conf$$subs.sed
-cat >>$CONFIG_STATUS <<_ACEOF
-:end
-s/|#_!!_#|//g
-CEOF$ac_eof
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
 _ACEOF
 
-
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
 # trailing colons and then remove the whole line if VPATH becomes empty
 # (actually we leave an empty line to preserve line numbers).
 if test "x$srcdir" = x.; then
-  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[	 ]*\):*/\1/
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
 s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
 s/^[^=]*=[	 ]*$//
 }'
 fi
 
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 fi # test -n "$CONFIG_FILES"
 
 
-for ac_tag in  :F $CONFIG_FILES
+eval set X "  :F $CONFIG_FILES      "
+shift
+for ac_tag
 do
   case $ac_tag in
   :[FHLC]) ac_mode=$ac_tag; continue;;
   esac
   case $ac_mode$ac_tag in
   :[FHL]*:*);;
-  :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5
-echo "$as_me: error: Invalid tag $ac_tag." >&2;}
-   { (exit 1); exit 1; }; };;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
   :[FH]-) ac_tag=-:-;;
   :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
   esac
@@ -5627,7 +5142,7 @@ echo "$as_me: error: Invalid tag $ac_tag." >&2;}
     for ac_f
     do
       case $ac_f in
-      -) ac_f="$tmp/stdin";;
+      -) ac_f="$ac_tmp/stdin";;
       *) # Look for the file first in the build tree, then in the source tree
 	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
 	 # because $ac_f cannot contain `:'.
@@ -5636,26 +5151,34 @@ echo "$as_me: error: Invalid tag $ac_tag." >&2;}
 	   [\\/$]*) false;;
 	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
 	   esac ||
-	   { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5
-echo "$as_me: error: cannot find input file: $ac_f" >&2;}
-   { (exit 1); exit 1; }; };;
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
       esac
-      ac_file_inputs="$ac_file_inputs $ac_f"
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
     done
 
     # Let's still pretend it is `configure' which instantiates (i.e., don't
     # use $as_me), people would be surprised to read:
     #    /* config.h.  Generated by config.status.  */
-    configure_input="Generated from "`IFS=:
-	  echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure."
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
     if test x"$ac_file" != x-; then
       configure_input="$ac_file.  $configure_input"
-      { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
     fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
 
     case $ac_tag in
-    *:-:* | *:-) cat >"$tmp/stdin";;
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
     esac
     ;;
   esac
@@ -5665,42 +5188,7 @@ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
 	 X"$ac_file" : 'X\(//\)[^/]' \| \
 	 X"$ac_file" : 'X\(//\)$' \| \
 	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$ac_file" |
-    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)[^/].*/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\/\)$/{
-	    s//\1/
-	    q
-	  }
-	  /^X\(\/\).*/{
-	    s//\1/
-	    q
-	  }
-	  s/.*/./; q'`
-  { as_dir="$ac_dir"
-  case $as_dir in #(
-  -*) as_dir=./$as_dir;;
-  esac
-  test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || {
-    as_dirs=
-    while :; do
-      case $as_dir in #(
-      *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #(
-      *) as_qdir=$as_dir;;
-      esac
-      as_dirs="'$as_qdir' $as_dirs"
-      as_dir=`$as_dirname -- "$as_dir" ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
-	 X"$as_dir" : 'X\(//\)[^/]' \| \
-	 X"$as_dir" : 'X\(//\)$' \| \
-	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-echo X"$as_dir" |
+$as_echo X"$ac_file" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -5718,20 +5206,15 @@ echo X"$as_dir" |
 	    q
 	  }
 	  s/.*/./; q'`
-      test -d "$as_dir" && break
-    done
-    test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5
-echo "$as_me: error: cannot create directory $as_dir" >&2;}
-   { (exit 1); exit 1; }; }; }
+  as_dir="$ac_dir"; as_fn_mkdir_p
   ac_builddir=.
 
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'`
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -5767,12 +5250,12 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
 
 _ACEOF
 
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # If the template does not know about datarootdir, expand it.
 # FIXME: This hack should be removed a few years after 2.60.
 ac_datarootdir_hack=; ac_datarootdir_seen=
-
-case `sed -n '/datarootdir/ {
+ac_sed_dataroot='
+/datarootdir/ {
   p
   q
 }
@@ -5780,36 +5263,37 @@ case `sed -n '/datarootdir/ {
 /@docdir@/p
 /@infodir@/p
 /@localedir@/p
-/@mandir@/p
-' $ac_file_inputs` in
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
 *datarootdir*) ac_datarootdir_seen=yes;;
 *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
-  { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
 _ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
   ac_datarootdir_hack='
   s&@datadir@&$datadir&g
   s&@docdir@&$docdir&g
   s&@infodir@&$infodir&g
   s&@localedir@&$localedir&g
   s&@mandir@&$mandir&g
-    s&\\\${datarootdir}&$datarootdir&g' ;;
+  s&\\\${datarootdir}&$datarootdir&g' ;;
 esac
 _ACEOF
 
 # Neutralize VPATH when `$srcdir' = `.'.
 # Shell code in configure.ac might set extrasub.
 # FIXME: do we really want to maintain this feature?
-cat >>$CONFIG_STATUS <<_ACEOF
-  sed "$ac_vpsub
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
 $extrasub
 _ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 :t
 /@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s&@configure_input@&$configure_input&;t t
+s|@configure_input@|$ac_sed_conf_input|;t t
 s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
 s&@srcdir@&$ac_srcdir&;t t
 s&@abs_srcdir@&$ac_abs_srcdir&;t t
 s&@top_srcdir@&$ac_top_srcdir&;t t
@@ -5818,21 +5302,25 @@ s&@builddir@&$ac_builddir&;t t
 s&@abs_builddir@&$ac_abs_builddir&;t t
 s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
 $ac_datarootdir_hack
-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
 
 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
-  { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&5
-echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&2;}
-
-  rm -f "$tmp/stdin"
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined" >&2;}
+
+  rm -f "$ac_tmp/stdin"
   case $ac_file in
-  -) cat "$tmp/out"; rm -f "$tmp/out";;
-  *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;;
-  esac
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
  ;;
 
 
@@ -5847,11 +5335,13 @@ which seems to be undefined.  Please make sure it is defined." >&2;}
 done # for ac_tag
 
 
-{ (exit 0); exit 0; }
+as_fn_exit 0
 _ACEOF
-chmod +x $CONFIG_STATUS
 ac_clean_files=$ac_clean_files_save
 
+test $ac_write_fail = 0 ||
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
 
 # configure is writing to config.log, and then calls config.status.
 # config.status does its own redirection, appending to config.log.
@@ -5871,7 +5361,11 @@ if test "$no_create" != yes; then
   exec 5>>config.log
   # Use ||, not &&, to avoid exiting from the if with $? = 1, which
   # would make configure fail if this is the last instruction.
-  $ac_cs_success || { (exit 1); exit 1; }
+  $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
 fi
 
 
diff --git a/configure.in b/configure.in
index c721551..68b1c92 100644
--- a/configure.in
+++ b/configure.in
@@ -1,7 +1,7 @@
 dnl Process this file with autoconf to produce a configure script.
 AC_INIT(config/unix.mak)
 
-OGDI_VERSION=3.2.0beta2
+OGDI_VERSION=3.2.0
 OGDI_MAJOR=3
 OGDI_MINOR=2
 
@@ -30,6 +30,8 @@ dnl CFLAGS="$CFLAGS -I/usr/local/include"
 
 dnl Checks for libraries.
 AC_CHECK_LIB(dl,dlopen,,,)
+AC_CHECK_LIB(c,iconv_open,HAVE_ICONV=yes,,,)
+AC_SUBST(HAVE_ICONV,$HAVE_ICONV)
 
 dnl check for various compiler flags.
 AC_COMPILER_WFLAGS
diff --git a/contrib/ogdi_info/makefile b/contrib/ogdi_info/makefile
old mode 100644
new mode 100755
diff --git a/contrib/ogdi_info/ogdi_info.c b/contrib/ogdi_info/ogdi_info.c
old mode 100644
new mode 100755
diff --git a/external/expat/COPYING b/external/expat/COPYING
new file mode 100644
index 0000000..fc97b02
--- /dev/null
+++ b/external/expat/COPYING
@@ -0,0 +1,21 @@
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+                               and Clark Cooper
+
+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 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.
diff --git a/external/expat/README b/external/expat/README
new file mode 100644
index 0000000..d1c6874
--- /dev/null
+++ b/external/expat/README
@@ -0,0 +1,57 @@
+
+			Expat, Release 1.95.1
+
+This is expat, the C library for parsing XML, written by James Clark. Expat
+is a stream oriented XML parser. This means that you register handlers with
+the parser prior to starting the parse. These handlers are called when
+the parser discovers the associated structures in the document being parsed.
+A start tag is an example of the kind of structures for which you may
+register handlers.
+
+Expat is free software. You may copy, distribute, and modify it under the
+terms of the License contained in the file, COPYING, distributed with this
+package. This license is the same as the MIT/X Consortium license.
+
+Versions of expat that have an odd minor version (the middle number in the
+release above), are development releases and should be considered as
+beta software. Releases with even minor version numbers are intended to be
+production grade software.
+
+To build expat, you first run the configuration shell script in the top
+level distribution directory:
+
+	./configure
+
+There are many options which you may provide to configure (which you can
+discover by running configure with the --help option.) But the one of most
+interest is the one that sets the installation directory. By default,
+the configure script will set things up to install libexpat into
+/usr/local/lib and expat.h into /usr/local/include. If, for example, you'd
+prefer to install into /home/me/mystuff/lib and /home/me/mystuff/include,
+you can tell configure about that with:
+
+	./configure --prefix=/home/me/mystuff
+
+After running the configure script, the "make" command will build things and
+"make install" will install things into their proper location. Note that
+you need to have write permission into the directories into which things
+will be installed.
+
+Alternatively, on Win32 systems with Microsoft's Developer's Studio installed,
+you can simply double-click on lib/expat.dsp from Windows Explorer and build
+and install in the usual way from with DevStudio.
+
+As a third alternative you may choose to download expat_win32bin which has
+a pre-compiled dll in it.
+
+A reference manual is available in the doc/reference.html in this
+distribution.
+
+The homepage for this project is http://expat.sourceforge.net. There are
+links there to connect you to the bug reports page. If you need to report
+a bug when you don't have access to a browser, you may also send a bug
+report by email to expat-bugs at lists.sourceforge.net.
+
+Discussion related to the direction of future expat development takes place
+on expat-discuss at lists.sourceforge.net. Archives of this list may be found
+at http://www.geocrawler.com/redir-sf.php3?list=expat-discuss.
diff --git a/external/expat/ascii.h b/external/expat/ascii.h
new file mode 100644
index 0000000..6376b1f
--- /dev/null
+++ b/external/expat/ascii.h
@@ -0,0 +1,86 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#define ASCII_A 0x41
+#define ASCII_B 0x42
+#define ASCII_C 0x43
+#define ASCII_D 0x44
+#define ASCII_E 0x45
+#define ASCII_F 0x46
+#define ASCII_G 0x47
+#define ASCII_H 0x48
+#define ASCII_I 0x49
+#define ASCII_J 0x4A
+#define ASCII_K 0x4B
+#define ASCII_L 0x4C
+#define ASCII_M 0x4D
+#define ASCII_N 0x4E
+#define ASCII_O 0x4F
+#define ASCII_P 0x50
+#define ASCII_Q 0x51
+#define ASCII_R 0x52
+#define ASCII_S 0x53
+#define ASCII_T 0x54
+#define ASCII_U 0x55
+#define ASCII_V 0x56
+#define ASCII_W 0x57
+#define ASCII_X 0x58
+#define ASCII_Y 0x59
+#define ASCII_Z 0x5A
+
+#define ASCII_a 0x61
+#define ASCII_b 0x62
+#define ASCII_c 0x63
+#define ASCII_d 0x64
+#define ASCII_e 0x65
+#define ASCII_f 0x66
+#define ASCII_g 0x67
+#define ASCII_h 0x68
+#define ASCII_i 0x69
+#define ASCII_j 0x6A
+#define ASCII_k 0x6B
+#define ASCII_l 0x6C
+#define ASCII_m 0x6D
+#define ASCII_n 0x6E
+#define ASCII_o 0x6F
+#define ASCII_p 0x70
+#define ASCII_q 0x71
+#define ASCII_r 0x72
+#define ASCII_s 0x73
+#define ASCII_t 0x74
+#define ASCII_u 0x75
+#define ASCII_v 0x76
+#define ASCII_w 0x77
+#define ASCII_x 0x78
+#define ASCII_y 0x79
+#define ASCII_z 0x7A
+
+#define ASCII_0 0x30
+#define ASCII_1 0x31
+#define ASCII_2 0x32
+#define ASCII_3 0x33
+#define ASCII_4 0x34
+#define ASCII_5 0x35
+#define ASCII_6 0x36
+#define ASCII_7 0x37
+#define ASCII_8 0x38
+#define ASCII_9 0x39
+
+#define ASCII_TAB 0x09
+#define ASCII_SPACE 0x20 
+#define ASCII_EXCL 0x21
+#define ASCII_QUOT 0x22
+#define ASCII_AMP 0x26
+#define ASCII_APOS 0x27
+#define ASCII_MINUS 0x2D
+#define ASCII_PERIOD 0x2E
+#define ASCII_COLON 0x3A
+#define ASCII_SEMI 0x3B
+#define ASCII_LT 0x3C
+#define ASCII_EQUALS 0x3D
+#define ASCII_GT 0x3E
+#define ASCII_LSQB 0x5B
+#define ASCII_RSQB 0x5D
+#define ASCII_UNDERSCORE 0x5F
diff --git a/external/expat/asciitab.h b/external/expat/asciitab.h
new file mode 100644
index 0000000..eb445cc
--- /dev/null
+++ b/external/expat/asciitab.h
@@ -0,0 +1,37 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_CR, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/external/expat/config.h b/external/expat/config.h
new file mode 100644
index 0000000..228d347
--- /dev/null
+++ b/external/expat/config.h
@@ -0,0 +1,50 @@
+/*================================================================
+** Copyright 2000, Clark Cooper
+** All rights reserved.
+**
+** This is free software. You are permitted to copy, distribute, or modify
+** it under the terms of the MIT/X license (contained in the COPYING file
+** with this distribution.)
+**
+**
+*/
+
+/*
+** This file was hand crafted for OGDI.  Currently we assume we have
+** standard C headers, and memmove().   We depend on the makefile defining
+** WORDS_BIGENDIAN on big endian platforms.
+**
+** Frank Warmerdam, April, 2001
+*/
+
+#include <string.h>
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you have the bcopy function.  */
+#define HAVE_BCOPY 1
+
+/* Define if you have the memmove function.  */
+#define HAVE_MEMMOVE 1
+
+#define XML_NS
+#define XML_DTD
+
+#ifdef WORDS_BIGENDIAN
+#define XML_BYTE_ORDER 21
+#else
+#define XML_BYTE_ORDER 12
+#endif
+
+#define XML_CONTEXT_BYTES 1024
+
+#ifndef HAVE_MEMMOVE
+#ifdef HAVE_BCOPY
+#define memmove(d,s,l) bcopy((s),(d),(l))
+#else
+#define memmove(d,s,l) ;punting on memmove;
+#endif
+
+#endif
+
diff --git a/external/expat/expat.h b/external/expat/expat.h
new file mode 100644
index 0000000..68cde08
--- /dev/null
+++ b/external/expat/expat.h
@@ -0,0 +1,712 @@
+/*
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#ifndef XmlParse_INCLUDED
+#define XmlParse_INCLUDED 1
+
+#include <stdlib.h>
+
+#ifndef XMLPARSEAPI
+#  ifdef __declspec
+#    define XMLPARSEAPI __declspec(dllimport)
+#  else
+#    define XMLPARSEAPI /* nothing */
+#  endif
+#endif  /* not defined XMLPARSEAPI */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void *XML_Parser;
+
+/* Information is UTF-8 encoded. */
+typedef char XML_Char;
+typedef char XML_LChar;
+
+enum XML_Content_Type {
+  XML_CTYPE_EMPTY = 1,
+  XML_CTYPE_ANY,
+  XML_CTYPE_MIXED,
+  XML_CTYPE_NAME,
+  XML_CTYPE_CHOICE,
+  XML_CTYPE_SEQ
+};
+
+enum XML_Content_Quant {
+  XML_CQUANT_NONE,
+  XML_CQUANT_OPT,
+  XML_CQUANT_REP,
+  XML_CQUANT_PLUS
+};
+
+/* If type == XML_CTYPE_EMPTY or XML_CTYPE_ANY, then quant will be
+   XML_CQUANT_NONE, and the other fields will be zero or NULL.
+   If type == XML_CTYPE_MIXED, then quant will be NONE or REP and
+   numchildren will contain number of elements that may be mixed in
+   and children point to an array of XML_Content cells that will be
+   all of XML_CTYPE_NAME type with no quantification.
+
+   If type == XML_CTYPE_NAME, then the name points to the name, and
+   the numchildren field will be zero and children will be NULL. The
+   quant fields indicates any quantifiers placed on the name.
+
+   CHOICE and SEQ will have name NULL, the number of children in
+   numchildren and children will point, recursively, to an array
+   of XML_Content cells.
+
+   The EMPTY, ANY, and MIXED types will only occur at top level.
+*/
+
+typedef struct XML_cp XML_Content;
+
+struct XML_cp {
+  enum XML_Content_Type		type;
+  enum XML_Content_Quant	quant;
+  const XML_Char *		name;
+  unsigned int			numchildren;
+  XML_Content *			children;
+};
+
+
+/* This is called for an element declaration. See above for
+   description of the model argument. It's the caller's responsibility
+   to free model when finished with it.
+*/
+
+typedef void (*XML_ElementDeclHandler) (void *userData,
+					const XML_Char *name,
+					XML_Content *model);
+
+void XMLPARSEAPI
+XML_SetElementDeclHandler(XML_Parser parser,
+			  XML_ElementDeclHandler eldecl);
+
+/*
+  The Attlist declaration handler is called for *each* attribute. So
+  a single Attlist declaration with multiple attributes declared will
+  generate multiple calls to this handler. The "default" parameter
+  may be NULL in the case of the "#IMPLIED" or "#REQUIRED" keyword.
+  The "isrequired" parameter will be true and the default value will
+  be NULL in the case of "#REQUIRED". If "isrequired" is true and
+  default is non-NULL, then this is a "#FIXED" default.
+ */
+
+typedef void (*XML_AttlistDeclHandler) (void		*userData,
+					const XML_Char	*elname,
+					const XML_Char	*attname,
+					const XML_Char	*att_type,
+					const XML_Char	*dflt,
+					int		isrequired);
+
+void XMLPARSEAPI
+XML_SetAttlistDeclHandler(XML_Parser parser,
+			  XML_AttlistDeclHandler attdecl);
+
+
+  /* The XML declaration handler is called for *both* XML declarations and
+     text declarations. The way to distinguish is that the version parameter
+     will be null for text declarations. The encoding parameter may be null
+     for XML declarations. The standalone parameter will be -1, 0, or 1
+     indicating respectively that there was no standalone parameter in
+     the declaration, that it was given as no, or that it was given as yes.
+  */
+
+typedef void (*XML_XmlDeclHandler) (void		*userData,
+				    const XML_Char	*version,
+				    const XML_Char	*encoding,
+				    int			standalone);
+
+void XMLPARSEAPI
+XML_SetXmlDeclHandler(XML_Parser parser,
+		      XML_XmlDeclHandler xmldecl);
+
+
+typedef struct {
+  void *(*malloc_fcn)(size_t size);
+  void *(*realloc_fcn)(void *ptr, size_t size);
+  void (*free_fcn)(void *ptr);
+} XML_Memory_Handling_Suite;
+
+/* Constructs a new parser; encoding is the encoding specified by the external
+protocol or null if there is none specified. */
+
+XML_Parser XMLPARSEAPI
+XML_ParserCreate(const XML_Char *encoding);
+
+/* Constructs a new parser and namespace processor.  Element type names
+and attribute names that belong to a namespace will be expanded;
+unprefixed attribute names are never expanded; unprefixed element type
+names are expanded only if there is a default namespace. The expanded
+name is the concatenation of the namespace URI, the namespace separator character,
+and the local part of the name.  If the namespace separator is '\0' then
+the namespace URI and the local part will be concatenated without any
+separator.  When a namespace is not declared, the name and prefix will be
+passed through without expansion. */
+
+XML_Parser XMLPARSEAPI
+XML_ParserCreateNS(const XML_Char *encoding, XML_Char namespaceSeparator);
+
+
+/* Constructs a new parser using the memory management suit referred to
+   by memsuite. If memsuite is NULL, then use the standard library memory
+   suite. If namespaceSeparator is non-NULL it creates a parser with
+   namespace processing as described above. The character pointed at
+   will serve as the namespace separator.
+
+   All further memory operations used for the created parser will come from
+   the given suite.
+*/
+
+XML_Parser XMLPARSEAPI
+XML_ParserCreate_MM(const XML_Char *encoding,
+		    const XML_Memory_Handling_Suite *memsuite,
+		    const XML_Char *namespaceSeparator);
+
+/* atts is array of name/value pairs, terminated by 0;
+   names and values are 0 terminated. */
+
+typedef void (*XML_StartElementHandler)(void *userData,
+					const XML_Char *name,
+					const XML_Char **atts);
+
+typedef void (*XML_EndElementHandler)(void *userData,
+				      const XML_Char *name);
+
+
+/* s is not 0 terminated. */
+typedef void (*XML_CharacterDataHandler)(void *userData,
+					 const XML_Char *s,
+					 int len);
+
+/* target and data are 0 terminated */
+typedef void (*XML_ProcessingInstructionHandler)(void *userData,
+						 const XML_Char *target,
+						 const XML_Char *data);
+
+/* data is 0 terminated */
+typedef void (*XML_CommentHandler)(void *userData, const XML_Char *data);
+
+typedef void (*XML_StartCdataSectionHandler)(void *userData);
+typedef void (*XML_EndCdataSectionHandler)(void *userData);
+
+/* This is called for any characters in the XML document for
+which there is no applicable handler.  This includes both
+characters that are part of markup which is of a kind that is
+not reported (comments, markup declarations), or characters
+that are part of a construct which could be reported but
+for which no handler has been supplied. The characters are passed
+exactly as they were in the XML document except that
+they will be encoded in UTF-8.  Line boundaries are not normalized.
+Note that a byte order mark character is not passed to the default handler.
+There are no guarantees about how characters are divided between calls
+to the default handler: for example, a comment might be split between
+multiple calls. */
+
+typedef void (*XML_DefaultHandler)(void *userData,
+				   const XML_Char *s,
+				   int len);
+
+/* This is called for the start of the DOCTYPE declaration, before
+   any DTD or internal subset is parsed. */
+
+typedef void (*XML_StartDoctypeDeclHandler)(void *userData,
+					    const XML_Char *doctypeName,
+					    const XML_Char *sysid,
+					    const XML_Char *pubid,
+					    int has_internal_subset
+					    );
+
+/* This is called for the start of the DOCTYPE declaration when the
+closing > is encountered, but after processing any external subset. */
+typedef void (*XML_EndDoctypeDeclHandler)(void *userData);
+
+/* This is called for entity declarations. The is_parameter_entity
+   argument will be non-zero if the entity is a parameter entity, zero
+   otherwise.
+
+   For internal entities (<!ENTITY foo "bar">), value will
+   be non-null and systemId, publicID, and notationName will be null.
+   The value string is NOT null terminated; the length is provided in
+   the value_length argument. Since it is legal to have zero-length
+   values, do not use this argument to test for internal entities.
+
+   For external entities, value will be null and systemId will be non-null.
+   The publicId argument will be null unless a public identifier was
+   provided. The notationName argument will have a non-null value only
+   for unparsed entity declarations.
+*/
+
+typedef void (*XML_EntityDeclHandler) (void *userData,
+				       const XML_Char *entityName,
+				       int is_parameter_entity,
+				       const XML_Char *value,
+				       int value_length,
+				       const XML_Char *base,
+				       const XML_Char *systemId,
+				       const XML_Char *publicId,
+				       const XML_Char *notationName);
+				       
+void XMLPARSEAPI
+XML_SetEntityDeclHandler(XML_Parser parser,
+			 XML_EntityDeclHandler handler);
+
+/* OBSOLETE -- OBSOLETE -- OBSOLETE
+   This handler has been superceded by the EntityDeclHandler above.
+   It is provided here for backward compatibility.
+This is called for a declaration of an unparsed (NDATA)
+entity.  The base argument is whatever was set by XML_SetBase.
+The entityName, systemId and notationName arguments will never be null.
+The other arguments may be. */
+
+typedef void (*XML_UnparsedEntityDeclHandler)(void *userData,
+					      const XML_Char *entityName,
+					      const XML_Char *base,
+					      const XML_Char *systemId,
+					      const XML_Char *publicId,
+					      const XML_Char *notationName);
+
+/* This is called for a declaration of notation.
+The base argument is whatever was set by XML_SetBase.
+The notationName will never be null.  The other arguments can be. */
+
+typedef void (*XML_NotationDeclHandler)(void *userData,
+					const XML_Char *notationName,
+					const XML_Char *base,
+					const XML_Char *systemId,
+					const XML_Char *publicId);
+
+/* When namespace processing is enabled, these are called once for
+each namespace declaration. The call to the start and end element
+handlers occur between the calls to the start and end namespace
+declaration handlers. For an xmlns attribute, prefix will be null.
+For an xmlns="" attribute, uri will be null. */
+
+typedef void (*XML_StartNamespaceDeclHandler)(void *userData,
+					      const XML_Char *prefix,
+					      const XML_Char *uri);
+
+typedef void (*XML_EndNamespaceDeclHandler)(void *userData,
+					    const XML_Char *prefix);
+
+/* This is called if the document is not standalone (it has an
+external subset or a reference to a parameter entity, but does not
+have standalone="yes"). If this handler returns 0, then processing
+will not continue, and the parser will return a
+XML_ERROR_NOT_STANDALONE error. */
+
+typedef int (*XML_NotStandaloneHandler)(void *userData);
+
+/* This is called for a reference to an external parsed general entity.
+The referenced entity is not automatically parsed.
+The application can parse it immediately or later using
+XML_ExternalEntityParserCreate.
+The parser argument is the parser parsing the entity containing the reference;
+it can be passed as the parser argument to XML_ExternalEntityParserCreate.
+The systemId argument is the system identifier as specified in the entity declaration;
+it will not be null.
+The base argument is the system identifier that should be used as the base for
+resolving systemId if systemId was relative; this is set by XML_SetBase;
+it may be null.
+The publicId argument is the public identifier as specified in the entity declaration,
+or null if none was specified; the whitespace in the public identifier
+will have been normalized as required by the XML spec.
+The context argument specifies the parsing context in the format
+expected by the context argument to
+XML_ExternalEntityParserCreate; context is valid only until the handler
+returns, so if the referenced entity is to be parsed later, it must be copied.
+The handler should return 0 if processing should not continue because of
+a fatal error in the handling of the external entity.
+In this case the calling parser will return an XML_ERROR_EXTERNAL_ENTITY_HANDLING
+error.
+Note that unlike other handlers the first argument is the parser, not userData. */
+
+typedef int (*XML_ExternalEntityRefHandler)(XML_Parser parser,
+					    const XML_Char *context,
+					    const XML_Char *base,
+					    const XML_Char *systemId,
+					    const XML_Char *publicId);
+
+/* This structure is filled in by the XML_UnknownEncodingHandler
+to provide information to the parser about encodings that are unknown
+to the parser.
+The map[b] member gives information about byte sequences
+whose first byte is b.
+If map[b] is c where c is >= 0, then b by itself encodes the Unicode scalar value c.
+If map[b] is -1, then the byte sequence is malformed.
+If map[b] is -n, where n >= 2, then b is the first byte of an n-byte
+sequence that encodes a single Unicode scalar value.
+The data member will be passed as the first argument to the convert function.
+The convert function is used to convert multibyte sequences;
+s will point to a n-byte sequence where map[(unsigned char)*s] == -n.
+The convert function must return the Unicode scalar value
+represented by this byte sequence or -1 if the byte sequence is malformed.
+The convert function may be null if the encoding is a single-byte encoding,
+that is if map[b] >= -1 for all bytes b.
+When the parser is finished with the encoding, then if release is not null,
+it will call release passing it the data member;
+once release has been called, the convert function will not be called again.
+
+Expat places certain restrictions on the encodings that are supported
+using this mechanism.
+
+1. Every ASCII character that can appear in a well-formed XML document,
+other than the characters
+
+  $@\^`{}~
+
+must be represented by a single byte, and that byte must be the
+same byte that represents that character in ASCII.
+
+2. No character may require more than 4 bytes to encode.
+
+3. All characters encoded must have Unicode scalar values <= 0xFFFF,
+(ie characters that would be encoded by surrogates in UTF-16
+are  not allowed).  Note that this restriction doesn't apply to
+the built-in support for UTF-8 and UTF-16.
+
+4. No Unicode character may be encoded by more than one distinct sequence
+of bytes. */
+
+typedef struct {
+  int map[256];
+  void *data;
+  int (*convert)(void *data, const char *s);
+  void (*release)(void *data);
+} XML_Encoding;
+
+/* This is called for an encoding that is unknown to the parser.
+The encodingHandlerData argument is that which was passed as the
+second argument to XML_SetUnknownEncodingHandler.
+The name argument gives the name of the encoding as specified in
+the encoding declaration.
+If the callback can provide information about the encoding,
+it must fill in the XML_Encoding structure, and return 1.
+Otherwise it must return 0.
+If info does not describe a suitable encoding,
+then the parser will return an XML_UNKNOWN_ENCODING error. */
+
+typedef int (*XML_UnknownEncodingHandler)(void *encodingHandlerData,
+					  const XML_Char *name,
+					  XML_Encoding *info);
+
+void XMLPARSEAPI
+XML_SetElementHandler(XML_Parser parser,
+		      XML_StartElementHandler start,
+		      XML_EndElementHandler end);
+
+void XMLPARSEAPI
+XML_SetStartElementHandler(XML_Parser, XML_StartElementHandler);
+
+void XMLPARSEAPI
+XML_SetEndElementHandler(XML_Parser, XML_EndElementHandler);
+
+void XMLPARSEAPI
+XML_SetCharacterDataHandler(XML_Parser parser,
+			    XML_CharacterDataHandler handler);
+
+void XMLPARSEAPI
+XML_SetProcessingInstructionHandler(XML_Parser parser,
+				    XML_ProcessingInstructionHandler handler);
+void XMLPARSEAPI
+XML_SetCommentHandler(XML_Parser parser,
+                      XML_CommentHandler handler);
+
+void XMLPARSEAPI
+XML_SetCdataSectionHandler(XML_Parser parser,
+			   XML_StartCdataSectionHandler start,
+			   XML_EndCdataSectionHandler end);
+
+void XMLPARSEAPI
+XML_SetStartCdataSectionHandler(XML_Parser parser,
+                                XML_StartCdataSectionHandler start);
+
+void XMLPARSEAPI
+XML_SetEndCdataSectionHandler(XML_Parser parser,
+                              XML_EndCdataSectionHandler end);
+
+/* This sets the default handler and also inhibits expansion of internal entities.
+The entity reference will be passed to the default handler. */
+
+void XMLPARSEAPI
+XML_SetDefaultHandler(XML_Parser parser,
+		      XML_DefaultHandler handler);
+
+/* This sets the default handler but does not inhibit expansion of internal entities.
+The entity reference will not be passed to the default handler. */
+
+void XMLPARSEAPI
+XML_SetDefaultHandlerExpand(XML_Parser parser,
+		            XML_DefaultHandler handler);
+
+void XMLPARSEAPI
+XML_SetDoctypeDeclHandler(XML_Parser parser,
+			  XML_StartDoctypeDeclHandler start,
+			  XML_EndDoctypeDeclHandler end);
+
+void XMLPARSEAPI
+XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+			       XML_StartDoctypeDeclHandler start);
+
+void XMLPARSEAPI
+XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+			     XML_EndDoctypeDeclHandler end);
+
+void XMLPARSEAPI
+XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+				 XML_UnparsedEntityDeclHandler handler);
+
+void XMLPARSEAPI
+XML_SetNotationDeclHandler(XML_Parser parser,
+			   XML_NotationDeclHandler handler);
+
+void XMLPARSEAPI
+XML_SetNamespaceDeclHandler(XML_Parser parser,
+			    XML_StartNamespaceDeclHandler start,
+			    XML_EndNamespaceDeclHandler end);
+
+void XMLPARSEAPI
+XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+				 XML_StartNamespaceDeclHandler start);
+
+void XMLPARSEAPI
+XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+			       XML_EndNamespaceDeclHandler end);
+
+void XMLPARSEAPI
+XML_SetNotStandaloneHandler(XML_Parser parser,
+			    XML_NotStandaloneHandler handler);
+
+void XMLPARSEAPI
+XML_SetExternalEntityRefHandler(XML_Parser parser,
+				XML_ExternalEntityRefHandler handler);
+
+/* If a non-null value for arg is specified here, then it will be passed
+as the first argument to the external entity ref handler instead
+of the parser object. */
+void XMLPARSEAPI
+XML_SetExternalEntityRefHandlerArg(XML_Parser, void *arg);
+
+void XMLPARSEAPI
+XML_SetUnknownEncodingHandler(XML_Parser parser,
+			      XML_UnknownEncodingHandler handler,
+			      void *encodingHandlerData);
+
+/* This can be called within a handler for a start element, end element,
+processing instruction or character data.  It causes the corresponding
+markup to be passed to the default handler. */
+void  XML_DefaultCurrent(XML_Parser parser);
+
+/* If do_nst is non-zero, and namespace processing is in effect, and
+   a name has a prefix (i.e. an explicit namespace qualifier) then
+   that name is returned as a triplet in a single
+   string separated by the separator character specified when the parser
+   was created: URI + sep + local_name + sep + prefix.
+
+   If do_nst is zero, then namespace information is returned in the
+   default manner (URI + sep + local_name) whether or not the names
+   has a prefix.
+*/
+
+void XMLPARSEAPI
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst);
+
+/* This value is passed as the userData argument to callbacks. */
+void XMLPARSEAPI
+XML_SetUserData(XML_Parser parser, void *userData);
+
+/* Returns the last value set by XML_SetUserData or null. */
+#define XML_GetUserData(parser) (*(void **)(parser))
+
+/* This is equivalent to supplying an encoding argument
+to XML_ParserCreate. It must not be called after XML_Parse
+or XML_ParseBuffer. */
+
+int XMLPARSEAPI
+XML_SetEncoding(XML_Parser parser, const XML_Char *encoding);
+
+/* If this function is called, then the parser will be passed
+as the first argument to callbacks instead of userData.
+The userData will still be accessible using XML_GetUserData. */
+
+void XMLPARSEAPI 
+XML_UseParserAsHandlerArg(XML_Parser parser);
+
+/* Sets the base to be used for resolving relative URIs in system identifiers in
+declarations.  Resolving relative identifiers is left to the application:
+this value will be passed through as the base argument to the
+XML_ExternalEntityRefHandler, XML_NotationDeclHandler
+and XML_UnparsedEntityDeclHandler. The base argument will be copied.
+Returns zero if out of memory, non-zero otherwise. */
+
+int XMLPARSEAPI
+XML_SetBase(XML_Parser parser, const XML_Char *base);
+
+const XML_Char  XMLPARSEAPI *
+XML_GetBase(XML_Parser parser);
+
+/* Returns the number of the attribute/value pairs passed in last call
+to the XML_StartElementHandler that were specified in the start-tag
+rather than defaulted. Each attribute/value pair counts as 2; thus
+this correspondds to an index into the atts array passed to the
+XML_StartElementHandler. */
+
+int XMLPARSEAPI
+XML_GetSpecifiedAttributeCount(XML_Parser parser);
+
+/* Returns the index of the ID attribute passed in the last call to
+XML_StartElementHandler, or -1 if there is no ID attribute.  Each
+attribute/value pair counts as 2; thus this correspondds to an index
+into the atts array passed to the XML_StartElementHandler. */
+
+int XMLPARSEAPI
+XML_GetIdAttributeIndex(XML_Parser parser);
+
+/* Parses some input. Returns 0 if a fatal error is detected.
+The last call to XML_Parse must have isFinal true;
+len may be zero for this call (or any other). */
+int XMLPARSEAPI
+XML_Parse(XML_Parser parser, const char *s, int len, int isFinal);
+
+void XMLPARSEAPI *
+XML_GetBuffer(XML_Parser parser, int len);
+
+int XMLPARSEAPI
+XML_ParseBuffer(XML_Parser parser, int len, int isFinal);
+
+/* Creates an XML_Parser object that can parse an external general entity;
+context is a '\0'-terminated string specifying the parse context;
+encoding is a '\0'-terminated string giving the name of the externally specified encoding,
+or null if there is no externally specified encoding.
+The context string consists of a sequence of tokens separated by formfeeds (\f);
+a token consisting of a name specifies that the general entity of the name
+is open; a token of the form prefix=uri specifies the namespace for a particular
+prefix; a token of the form =uri specifies the default namespace.
+This can be called at any point after the first call to an ExternalEntityRefHandler
+so longer as the parser has not yet been freed.
+The new parser is completely independent and may safely be used in a separate thread.
+The handlers and userData are initialized from the parser argument.
+Returns 0 if out of memory.  Otherwise returns a new XML_Parser object. */
+XML_Parser XMLPARSEAPI
+XML_ExternalEntityParserCreate(XML_Parser parser,
+			       const XML_Char *context,
+			       const XML_Char *encoding);
+
+enum XML_ParamEntityParsing {
+  XML_PARAM_ENTITY_PARSING_NEVER,
+  XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE,
+  XML_PARAM_ENTITY_PARSING_ALWAYS
+};
+
+/* Controls parsing of parameter entities (including the external DTD
+subset). If parsing of parameter entities is enabled, then references
+to external parameter entities (including the external DTD subset)
+will be passed to the handler set with
+XML_SetExternalEntityRefHandler.  The context passed will be 0.
+Unlike external general entities, external parameter entities can only
+be parsed synchronously.  If the external parameter entity is to be
+parsed, it must be parsed during the call to the external entity ref
+handler: the complete sequence of XML_ExternalEntityParserCreate,
+XML_Parse/XML_ParseBuffer and XML_ParserFree calls must be made during
+this call.  After XML_ExternalEntityParserCreate has been called to
+create the parser for the external parameter entity (context must be 0
+for this call), it is illegal to make any calls on the old parser
+until XML_ParserFree has been called on the newly created parser.  If
+the library has been compiled without support for parameter entity
+parsing (ie without XML_DTD being defined), then
+XML_SetParamEntityParsing will return 0 if parsing of parameter
+entities is requested; otherwise it will return non-zero. */
+
+int XMLPARSEAPI
+XML_SetParamEntityParsing(XML_Parser parser,
+			  enum XML_ParamEntityParsing parsing);
+
+enum XML_Error {
+  XML_ERROR_NONE,
+  XML_ERROR_NO_MEMORY,
+  XML_ERROR_SYNTAX,
+  XML_ERROR_NO_ELEMENTS,
+  XML_ERROR_INVALID_TOKEN,
+  XML_ERROR_UNCLOSED_TOKEN,
+  XML_ERROR_PARTIAL_CHAR,
+  XML_ERROR_TAG_MISMATCH,
+  XML_ERROR_DUPLICATE_ATTRIBUTE,
+  XML_ERROR_JUNK_AFTER_DOC_ELEMENT,
+  XML_ERROR_PARAM_ENTITY_REF,
+  XML_ERROR_UNDEFINED_ENTITY,
+  XML_ERROR_RECURSIVE_ENTITY_REF,
+  XML_ERROR_ASYNC_ENTITY,
+  XML_ERROR_BAD_CHAR_REF,
+  XML_ERROR_BINARY_ENTITY_REF,
+  XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF,
+  XML_ERROR_MISPLACED_XML_PI,
+  XML_ERROR_UNKNOWN_ENCODING,
+  XML_ERROR_INCORRECT_ENCODING,
+  XML_ERROR_UNCLOSED_CDATA_SECTION,
+  XML_ERROR_EXTERNAL_ENTITY_HANDLING,
+  XML_ERROR_NOT_STANDALONE,
+  XML_ERROR_UNEXPECTED_STATE
+};
+
+/* If XML_Parse or XML_ParseBuffer have returned 0, then XML_GetErrorCode
+returns information about the error. */
+
+enum XML_Error  XMLPARSEAPI
+XML_GetErrorCode(XML_Parser parser);
+
+/* These functions return information about the current parse location.
+They may be called when XML_Parse or XML_ParseBuffer return 0;
+in this case the location is the location of the character at which
+the error was detected.
+They may also be called from any other callback called to report
+some parse event; in this the location is the location of the first
+of the sequence of characters that generated the event. */
+
+int XMLPARSEAPI XML_GetCurrentLineNumber(XML_Parser parser);
+int XMLPARSEAPI XML_GetCurrentColumnNumber(XML_Parser parser);
+long XMLPARSEAPI XML_GetCurrentByteIndex(XML_Parser parser);
+
+/* Return the number of bytes in the current event.
+Returns 0 if the event is in an internal entity. */
+
+int XMLPARSEAPI
+XML_GetCurrentByteCount(XML_Parser parser);
+
+/* If XML_CONTEXT_BYTES is defined, returns the input buffer, sets
+   the integer pointed to by offset to the offset within this buffer
+   of the current parse position, and sets the integer pointed to by size
+   to the size of this buffer (the number of input bytes). Otherwise
+   returns a null pointer. Also returns a null pointer if a parse isn't active.
+
+   NOTE: The character pointer returned should not be used outside
+   the handler that makes the call. */
+
+const char XMLPARSEAPI *
+XML_GetInputContext(XML_Parser parser,
+		    int *offset,
+		    int *size);
+
+/* For backwards compatibility with previous versions. */
+#define XML_GetErrorLineNumber XML_GetCurrentLineNumber
+#define XML_GetErrorColumnNumber XML_GetCurrentColumnNumber
+#define XML_GetErrorByteIndex XML_GetCurrentByteIndex
+
+/* Frees memory used by the parser. */
+void XMLPARSEAPI
+XML_ParserFree(XML_Parser parser);
+
+/* Returns a string describing the error. */
+const XML_LChar XMLPARSEAPI *
+XML_ErrorString(int code);
+
+/* Return a string containing the version number of this expat */
+const XML_LChar XMLPARSEAPI *
+XML_ExpatVersion();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlParse_INCLUDED */
diff --git a/external/expat/expat_ogdi.def b/external/expat/expat_ogdi.def
new file mode 100644
index 0000000..7093a24
--- /dev/null
+++ b/external/expat/expat_ogdi.def
@@ -0,0 +1,55 @@
+EXETYPE WINDOWS
+
+EXPORTS
+    	XML_SetElementDeclHandler
+	XML_SetAttlistDeclHandler
+	XML_SetXmlDeclHandler
+	XML_ParserCreate
+	XML_ParserCreateNS
+	XML_ParserCreate_MM
+	XML_SetEntityDeclHandler
+	XML_SetElementHandler
+	XML_SetStartElementHandler
+	XML_SetEndElementHandler
+	XML_SetCharacterDataHandler
+	XML_SetProcessingInstructionHandler
+	XML_SetCommentHandler
+	XML_SetCdataSectionHandler
+	XML_SetStartCdataSectionHandler
+	XML_SetEndCdataSectionHandler
+	XML_SetDefaultHandler
+	XML_SetDefaultHandlerExpand
+	XML_SetDoctypeDeclHandler
+	XML_SetStartDoctypeDeclHandler
+	XML_SetEndDoctypeDeclHandler
+	XML_SetUnparsedEntityDeclHandler
+	XML_SetNotationDeclHandler
+	XML_SetNamespaceDeclHandler
+	XML_SetStartNamespaceDeclHandler
+	XML_SetEndNamespaceDeclHandler
+	XML_SetNotStandaloneHandler
+	XML_SetExternalEntityRefHandler
+	XML_SetExternalEntityRefHandlerArg
+	XML_SetUnknownEncodingHandler
+	XML_SetReturnNSTriplet
+	XML_SetUserData
+	XML_SetEncoding
+	XML_UseParserAsHandlerArg
+	XML_SetBase
+	XML_GetBase
+	XML_GetSpecifiedAttributeCount
+	XML_GetIdAttributeIndex
+	XML_Parse
+	XML_GetBuffer
+	XML_ParseBuffer
+	XML_ExternalEntityParserCreate
+	XML_SetParamEntityParsing
+	XML_GetErrorCode
+	XML_GetCurrentLineNumber
+	XML_GetCurrentColumnNumber
+	XML_GetCurrentByteIndex
+	XML_GetCurrentByteCount
+	XML_GetInputContext
+	XML_ParserFree
+	XML_ErrorString
+	XML_ExpatVersion
diff --git a/external/expat/iasciitab.h b/external/expat/iasciitab.h
new file mode 100644
index 0000000..55dbc39
--- /dev/null
+++ b/external/expat/iasciitab.h
@@ -0,0 +1,38 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+/* Like asciitab.h, except that 0xD has code BT_S rather than BT_CR */
+/* 0x00 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x04 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x08 */ BT_NONXML, BT_S, BT_LF, BT_NONXML,
+/* 0x0C */ BT_NONXML, BT_S, BT_NONXML, BT_NONXML,
+/* 0x10 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x14 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x18 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x1C */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0x20 */ BT_S, BT_EXCL, BT_QUOT, BT_NUM,
+/* 0x24 */ BT_OTHER, BT_PERCNT, BT_AMP, BT_APOS,
+/* 0x28 */ BT_LPAR, BT_RPAR, BT_AST, BT_PLUS,
+/* 0x2C */ BT_COMMA, BT_MINUS, BT_NAME, BT_SOL,
+/* 0x30 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x34 */ BT_DIGIT, BT_DIGIT, BT_DIGIT, BT_DIGIT,
+/* 0x38 */ BT_DIGIT, BT_DIGIT, BT_COLON, BT_SEMI,
+/* 0x3C */ BT_LT, BT_EQUALS, BT_GT, BT_QUEST,
+/* 0x40 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x44 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x48 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x4C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x50 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x54 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x58 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_LSQB,
+/* 0x5C */ BT_OTHER, BT_RSQB, BT_OTHER, BT_NMSTRT,
+/* 0x60 */ BT_OTHER, BT_HEX, BT_HEX, BT_HEX,
+/* 0x64 */ BT_HEX, BT_HEX, BT_HEX, BT_NMSTRT,
+/* 0x68 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x6C */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x70 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x74 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0x78 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0x7C */ BT_VERBAR, BT_OTHER, BT_OTHER, BT_OTHER,
diff --git a/external/expat/latin1tab.h b/external/expat/latin1tab.h
new file mode 100644
index 0000000..178b1d1
--- /dev/null
+++ b/external/expat/latin1tab.h
@@ -0,0 +1,37 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+/* 0x80 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x84 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x88 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x8C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x90 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x94 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x98 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0x9C */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA4 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xA8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xAC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB0 */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xB4 */ BT_OTHER, BT_NMSTRT, BT_OTHER, BT_NAME,
+/* 0xB8 */ BT_OTHER, BT_OTHER, BT_NMSTRT, BT_OTHER,
+/* 0xBC */ BT_OTHER, BT_OTHER, BT_OTHER, BT_OTHER,
+/* 0xC0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xC8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xCC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xD4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xD8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xDC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xE8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xEC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF0 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xF4 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_OTHER,
+/* 0xF8 */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
+/* 0xFC */ BT_NMSTRT, BT_NMSTRT, BT_NMSTRT, BT_NMSTRT,
diff --git a/external/expat/makefile b/external/expat/makefile
new file mode 100644
index 0000000..a6242c9
--- /dev/null
+++ b/external/expat/makefile
@@ -0,0 +1,53 @@
+#
+#  Expat XML library makefile
+#
+# Copyright (C) 2001 Information Interoperability Institute (3i)
+# Permission to use, copy, modify and distribute this software and
+# its documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies, that
+# both the copyright notice and this permission notice appear in
+# supporting documentation, and that the name of 3i not be used 
+# in advertising or publicity pertaining to distribution of the software 
+# without specific, written prior permission.  3i makes no
+# representations about the suitability of this software for any purpose.
+# It is provided "as is" without express or implied warranty.
+#
+
+#
+# The names of the targets to build
+#
+TOBEGEN		= expat_ogdi$(OGDI_VERSION)
+TARGETGEN	= $(DYNAGEN)
+
+#
+# Source files
+#
+SOURCES =	xmlrole.c \
+		xmlparse.c \
+		xmltok.c
+	    
+
+#
+# Include the common configuration
+#
+include $(TOPDIR)/config/common.mak
+
+#
+# Compilation flags
+#
+INCLUDES = $(CURRENT_INCLUDE)
+CFLAGS 	= $(INCLUDES) $(COMMON_CFLAGS) \
+	-DVERSION=\"expat_1.95.1\" -DPACKAGE="expat"
+
+ifeq ($(BIG_ENDIAN),1)
+CFLAGS 	:=    $(CFLAGS) -DWORDS_BIGENDIAN
+endif
+
+#
+# Primary target
+#
+all: MKOBJECTDIR
+	@echo "making $(TARGETGEN)"
+	$(MAKE) --directory $(OBJDIR) -f ../makefile PASS='depend' $(TARGETGEN)
+
+clean: default-clean
diff --git a/external/expat/nametab.h b/external/expat/nametab.h
new file mode 100644
index 0000000..b05e62c
--- /dev/null
+++ b/external/expat/nametab.h
@@ -0,0 +1,150 @@
+static const unsigned namingBitmap[] = {
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x00000000, 0x04000000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00000000, 0xFF7FFFFF, 0xFF7FFFFF,
+0xFFFFFFFF, 0x7FF3FFFF, 0xFFFFFDFE, 0x7FFFFFFF,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFE00F, 0xFC31FFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00000003, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFD740, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF0003, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0x0000007F, 0x00000000, 0xFFFF0000, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x000007FE, 0xFFFE0000,
+0xFFFFFFFF, 0x7CFFFFFF, 0x002F7FFF, 0x00000060,
+0xFFFFFFE0, 0x23FFFFFF, 0xFF000000, 0x00000003,
+0xFFF99FE0, 0x03C5FDFF, 0xB0000000, 0x00030003,
+0xFFF987E0, 0x036DFDFF, 0x5E000000, 0x001C0000,
+0xFFFBAFE0, 0x23EDFDFF, 0x00000000, 0x00000001,
+0xFFF99FE0, 0x23CDFDFF, 0xB0000000, 0x00000003,
+0xD63DC7E0, 0x03BFC718, 0x00000000, 0x00000000,
+0xFFFDDFE0, 0x03EFFDFF, 0x00000000, 0x00000003,
+0xFFFDDFE0, 0x03EFFDFF, 0x40000000, 0x00000003,
+0xFFFDDFE0, 0x03FFFDFF, 0x00000000, 0x00000003,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x000D7FFF, 0x0000003F, 0x00000000,
+0xFEF02596, 0x200D6CAE, 0x0000001F, 0x00000000,
+0x00000000, 0x00000000, 0xFFFFFEFF, 0x000003FF,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0xFFFFFFFF, 0xFFFF003F, 0x007FFFFF,
+0x0007DAED, 0x50000000, 0x82315001, 0x002C62AB,
+0x40000000, 0xF580C900, 0x00000007, 0x02010800,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0x0FFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x03FFFFFF,
+0x3F3FFFFF, 0xFFFFFFFF, 0xAAFF3F3F, 0x3FFFFFFF,
+0xFFFFFFFF, 0x5FDFFFFF, 0x0FCF1FDC, 0x1FDC1FFF,
+0x00000000, 0x00004C40, 0x00000000, 0x00000000,
+0x00000007, 0x00000000, 0x00000000, 0x00000000,
+0x00000080, 0x000003FE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x001FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x07FFFFFF,
+0xFFFFFFE0, 0x00001FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000003F, 0x00000000, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
+0xFFFFFFFF, 0x0000000F, 0x00000000, 0x00000000,
+0x00000000, 0x07FF6000, 0x87FFFFFE, 0x07FFFFFE,
+0x00000000, 0x00800000, 0xFF7FFFFF, 0xFF7FFFFF,
+0x00FFFFFF, 0x00000000, 0xFFFF0000, 0xFFFFFFFF,
+0xFFFFFFFF, 0xF80001FF, 0x00030003, 0x00000000,
+0xFFFFFFFF, 0xFFFFFFFF, 0x0000003F, 0x00000003,
+0xFFFFD7C0, 0xFFFFFFFB, 0x547F7FFF, 0x000FFFFD,
+0xFFFFDFFE, 0xFFFFFFFF, 0xDFFEFFFF, 0xFFFFFFFF,
+0xFFFF007B, 0xFFFFFFFF, 0xFFFF199F, 0x033FCFFF,
+0x00000000, 0xFFFE0000, 0x027FFFFF, 0xFFFFFFFE,
+0xFFFE007F, 0xBBFFFFFB, 0xFFFF0016, 0x000707FF,
+0x00000000, 0x07FFFFFE, 0x0007FFFF, 0xFFFF03FF,
+0xFFFFFFFF, 0x7CFFFFFF, 0xFFEF7FFF, 0x03FF3DFF,
+0xFFFFFFEE, 0xF3FFFFFF, 0xFF1E3FFF, 0x0000FFCF,
+0xFFF99FEE, 0xD3C5FDFF, 0xB080399F, 0x0003FFCF,
+0xFFF987E4, 0xD36DFDFF, 0x5E003987, 0x001FFFC0,
+0xFFFBAFEE, 0xF3EDFDFF, 0x00003BBF, 0x0000FFC1,
+0xFFF99FEE, 0xF3CDFDFF, 0xB0C0398F, 0x0000FFC3,
+0xD63DC7EC, 0xC3BFC718, 0x00803DC7, 0x0000FF80,
+0xFFFDDFEE, 0xC3EFFDFF, 0x00603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3EFFDFF, 0x40603DDF, 0x0000FFC3,
+0xFFFDDFEC, 0xC3FFFDFF, 0x00803DCF, 0x0000FFC3,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0xFFFFFFFE, 0x07FF7FFF, 0x03FF7FFF, 0x00000000,
+0xFEF02596, 0x3BFF6CAE, 0x03FF3F5F, 0x00000000,
+0x03000000, 0xC2A003FF, 0xFFFFFEFF, 0xFFFE03FF,
+0xFEBF0FDF, 0x02FE3FFF, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x00000000, 0x00000000,
+0x00000000, 0x00000000, 0x1FFF0000, 0x00000002,
+0x000000A0, 0x003EFFFE, 0xFFFFFFFE, 0xFFFFFFFF,
+0x661FFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x77FFFFFF,
+};
+static const unsigned char nmstrtPages[] = {
+0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x00,
+0x00, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x15, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static const unsigned char namePages[] = {
+0x19, 0x03, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x00,
+0x00, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
+0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x13,
+0x26, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x27, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x17,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
diff --git a/external/expat/utf8tab.h b/external/expat/utf8tab.h
new file mode 100644
index 0000000..9e3b6b8
--- /dev/null
+++ b/external/expat/utf8tab.h
@@ -0,0 +1,38 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+
+/* 0x80 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x84 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x88 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x8C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x90 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x94 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x98 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0x9C */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xA8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xAC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB0 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB4 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xB8 */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xBC */ BT_TRAIL, BT_TRAIL, BT_TRAIL, BT_TRAIL,
+/* 0xC0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xC8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xCC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD0 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD4 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xD8 */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xDC */ BT_LEAD2, BT_LEAD2, BT_LEAD2, BT_LEAD2,
+/* 0xE0 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE4 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xE8 */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xEC */ BT_LEAD3, BT_LEAD3, BT_LEAD3, BT_LEAD3,
+/* 0xF0 */ BT_LEAD4, BT_LEAD4, BT_LEAD4, BT_LEAD4,
+/* 0xF4 */ BT_LEAD4, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xF8 */ BT_NONXML, BT_NONXML, BT_NONXML, BT_NONXML,
+/* 0xFC */ BT_NONXML, BT_NONXML, BT_MALFORM, BT_MALFORM,
diff --git a/external/expat/xmlparse.c b/external/expat/xmlparse.c
new file mode 100644
index 0000000..7e28a18
--- /dev/null
+++ b/external/expat/xmlparse.c
@@ -0,0 +1,4622 @@
+/*
+Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#ifdef COMPILED_FROM_DSP
+#  include "winconfig.h"
+#  define XMLPARSEAPI __declspec(dllexport)
+#  include "expat.h"
+#  undef XMLPARSEAPI
+#else
+#include <config.h>
+
+#ifdef __declspec
+#  define XMLPARSEAPI __declspec(dllexport)
+#endif
+
+#include "expat.h"
+
+#ifdef __declspec
+#  undef XMLPARSEAPI
+#endif
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include <stddef.h>
+
+#ifdef XML_UNICODE
+#define XML_ENCODE_MAX XML_UTF16_ENCODE_MAX
+#define XmlConvert XmlUtf16Convert
+#define XmlGetInternalEncoding XmlGetUtf16InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf16InternalEncodingNS
+#define XmlEncode XmlUtf16Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf16 || (((unsigned long)s) & 1))
+typedef unsigned short ICHAR;
+#else
+#define XML_ENCODE_MAX XML_UTF8_ENCODE_MAX
+#define XmlConvert XmlUtf8Convert
+#define XmlGetInternalEncoding XmlGetUtf8InternalEncoding
+#define XmlGetInternalEncodingNS XmlGetUtf8InternalEncodingNS
+#define XmlEncode XmlUtf8Encode
+#define MUST_CONVERT(enc, s) (!(enc)->isUtf8)
+typedef char ICHAR;
+#endif
+
+
+#ifndef XML_NS
+
+#define XmlInitEncodingNS XmlInitEncoding
+#define XmlInitUnknownEncodingNS XmlInitUnknownEncoding
+#undef XmlGetInternalEncodingNS
+#define XmlGetInternalEncodingNS XmlGetInternalEncoding
+#define XmlParseXmlDeclNS XmlParseXmlDecl
+
+#endif
+
+#ifdef XML_UNICODE_WCHAR_T
+#define XML_T(x) L ## x
+#else
+#define XML_T(x) x
+#endif
+
+/* Round up n to be a multiple of sz, where sz is a power of 2. */
+#define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
+
+#include "xmltok.h"
+#include "xmlrole.h"
+
+typedef const XML_Char *KEY;
+
+typedef struct {
+  KEY name;
+} NAMED;
+
+typedef struct {
+  NAMED **v;
+  size_t size;
+  size_t used;
+  size_t usedLim;
+  XML_Memory_Handling_Suite *mem;
+} HASH_TABLE;
+
+typedef struct {
+  NAMED **p;
+  NAMED **end;
+} HASH_TABLE_ITER;
+
+#define INIT_TAG_BUF_SIZE 32  /* must be a multiple of sizeof(XML_Char) */
+#define INIT_DATA_BUF_SIZE 1024
+#define INIT_ATTS_SIZE 16
+#define INIT_BLOCK_SIZE 1024
+#define INIT_BUFFER_SIZE 1024
+
+#define EXPAND_SPARE 24
+
+typedef struct binding {
+  struct prefix *prefix;
+  struct binding *nextTagBinding;
+  struct binding *prevPrefixBinding;
+  const struct attribute_id *attId;
+  XML_Char *uri;
+  int uriLen;
+  int uriAlloc;
+} BINDING;
+
+typedef struct prefix {
+  const XML_Char *name;
+  BINDING *binding;
+} PREFIX;
+
+typedef struct {
+  const XML_Char *str;
+  const XML_Char *localPart;
+  int uriLen;
+} TAG_NAME;
+
+typedef struct tag {
+  struct tag *parent;
+  const char *rawName;
+  int rawNameLength;
+  TAG_NAME name;
+  char *buf;
+  char *bufEnd;
+  BINDING *bindings;
+} TAG;
+
+typedef struct {
+  const XML_Char *name;
+  const XML_Char *textPtr;
+  int textLen;
+  const XML_Char *systemId;
+  const XML_Char *base;
+  const XML_Char *publicId;
+  const XML_Char *notation;
+  char open;
+  char is_param;
+} ENTITY;
+
+typedef struct {
+  enum XML_Content_Type		type;
+  enum XML_Content_Quant	quant;
+  const XML_Char *		name;
+  int				firstchild;
+  int				lastchild;
+  int				childcnt;
+  int				nextsib;
+} CONTENT_SCAFFOLD;
+
+typedef struct block {
+  struct block *next;
+  int size;
+  XML_Char s[1];
+} BLOCK;
+
+typedef struct {
+  BLOCK *blocks;
+  BLOCK *freeBlocks;
+  const XML_Char *end;
+  XML_Char *ptr;
+  XML_Char *start;
+  XML_Memory_Handling_Suite *mem;
+} STRING_POOL;
+
+/* The XML_Char before the name is used to determine whether
+an attribute has been specified. */
+typedef struct attribute_id {
+  XML_Char *name;
+  PREFIX *prefix;
+  char maybeTokenized;
+  char xmlns;
+} ATTRIBUTE_ID;
+
+typedef struct {
+  const ATTRIBUTE_ID *id;
+  char isCdata;
+  const XML_Char *value;
+} DEFAULT_ATTRIBUTE;
+
+typedef struct {
+  const XML_Char *name;
+  PREFIX *prefix;
+  const ATTRIBUTE_ID *idAtt;
+  int nDefaultAtts;
+  int allocDefaultAtts;
+  DEFAULT_ATTRIBUTE *defaultAtts;
+} ELEMENT_TYPE;
+
+typedef struct {
+  HASH_TABLE generalEntities;
+  HASH_TABLE elementTypes;
+  HASH_TABLE attributeIds;
+  HASH_TABLE prefixes;
+  STRING_POOL pool;
+  int complete;
+  int standalone;
+#ifdef XML_DTD
+  HASH_TABLE paramEntities;
+#endif /* XML_DTD */
+  PREFIX defaultPrefix;
+  /* === scaffolding for building content model === */
+  int in_eldecl;
+  CONTENT_SCAFFOLD *scaffold;
+  unsigned contentStringLen;
+  unsigned scaffSize;
+  unsigned scaffCount;
+  int scaffLevel;
+  int *scaffIndex;
+} DTD;
+
+typedef struct open_internal_entity {
+  const char *internalEventPtr;
+  const char *internalEventEndPtr;
+  struct open_internal_entity *next;
+  ENTITY *entity;
+} OPEN_INTERNAL_ENTITY;
+
+typedef enum XML_Error Processor(XML_Parser parser,
+				 const char *start,
+				 const char *end,
+				 const char **endPtr);
+
+static Processor prologProcessor;
+static Processor prologInitProcessor;
+static Processor contentProcessor;
+static Processor cdataSectionProcessor;
+#ifdef XML_DTD
+static Processor ignoreSectionProcessor;
+#endif /* XML_DTD */
+static Processor epilogProcessor;
+static Processor errorProcessor;
+static Processor externalEntityInitProcessor;
+static Processor externalEntityInitProcessor2;
+static Processor externalEntityInitProcessor3;
+static Processor externalEntityContentProcessor;
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName);
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity, const char *, const char *);
+static enum XML_Error
+initializeEncoding(XML_Parser parser);
+static enum XML_Error
+doProlog(XML_Parser parser, const ENCODING *enc, const char *s,
+	 const char *end, int tok, const char *next, const char **nextPtr);
+static enum XML_Error
+processInternalParamEntity(XML_Parser parser, ENTITY *entity);
+static enum XML_Error
+doContent(XML_Parser parser, int startTagLevel, const ENCODING *enc,
+	  const char *start, const char *end, const char **endPtr);
+static enum XML_Error
+doCdataSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
+#ifdef XML_DTD
+static enum XML_Error
+doIgnoreSection(XML_Parser parser, const ENCODING *, const char **startPtr, const char *end, const char **nextPtr);
+#endif /* XML_DTD */
+static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *, const char *s,
+				TAG_NAME *tagNamePtr, BINDING **bindingsPtr);
+static
+int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr);
+
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *,
+		int isCdata, int isId, const XML_Char *dfltValue,
+		XML_Parser parser);
+
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
+		    STRING_POOL *);
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *, int isCdata, const char *, const char *,
+		    STRING_POOL *);
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *);
+static enum XML_Error
+storeEntityValue(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static int
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *start, const char *end);
+
+static const XML_Char *getContext(XML_Parser parser);
+static int setContext(XML_Parser parser, const XML_Char *context);
+static void normalizePublicId(XML_Char *s);
+static int dtdInit(DTD *, XML_Parser parser);
+
+static void dtdDestroy(DTD *, XML_Parser parser);
+
+static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser);
+
+static int copyEntityTable(HASH_TABLE *, STRING_POOL *, const HASH_TABLE *,
+			   XML_Parser parser);
+
+#ifdef XML_DTD
+static void dtdSwap(DTD *, DTD *);
+#endif /* XML_DTD */
+
+static NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize);
+
+static void hashTableInit(HASH_TABLE *, XML_Memory_Handling_Suite *ms);
+
+static void hashTableDestroy(HASH_TABLE *);
+static void hashTableIterInit(HASH_TABLE_ITER *, const HASH_TABLE *);
+static NAMED *hashTableIterNext(HASH_TABLE_ITER *);
+static void poolInit(STRING_POOL *, XML_Memory_Handling_Suite *ms);
+static void poolClear(STRING_POOL *);
+static void poolDestroy(STRING_POOL *);
+static XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
+			    const char *ptr, const char *end);
+static XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+				  const char *ptr, const char *end);
+
+static int poolGrow(STRING_POOL *pool);
+
+static int nextScaffoldPart(XML_Parser parser);
+static XML_Content *build_model(XML_Parser parser);
+
+static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s);
+static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n);
+static const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s);
+static ELEMENT_TYPE * getElementType(XML_Parser Paraser,
+				     const ENCODING *enc,
+				     const char *ptr,
+				     const char *end);
+
+#define poolStart(pool) ((pool)->start)
+#define poolEnd(pool) ((pool)->ptr)
+#define poolLength(pool) ((pool)->ptr - (pool)->start)
+#define poolChop(pool) ((void)--(pool->ptr))
+#define poolLastChar(pool) (((pool)->ptr)[-1])
+#define poolDiscard(pool) ((pool)->ptr = (pool)->start)
+#define poolFinish(pool) ((pool)->start = (pool)->ptr)
+#define poolAppendChar(pool, c) \
+  (((pool)->ptr == (pool)->end && !poolGrow(pool)) \
+   ? 0 \
+   : ((*((pool)->ptr)++ = c), 1))
+
+typedef struct {
+  /* The first member must be userData so that the XML_GetUserData macro works. */
+  void *m_userData;
+  void *m_handlerArg;
+  char *m_buffer;
+  XML_Memory_Handling_Suite m_mem;
+  /* first character to be parsed */
+  const char *m_bufferPtr;
+  /* past last character to be parsed */
+  char *m_bufferEnd;
+  /* allocated end of buffer */
+  const char *m_bufferLim;
+  long m_parseEndByteIndex;
+  const char *m_parseEndPtr;
+  XML_Char *m_dataBuf;
+  XML_Char *m_dataBufEnd;
+  XML_StartElementHandler m_startElementHandler;
+  XML_EndElementHandler m_endElementHandler;
+  XML_CharacterDataHandler m_characterDataHandler;
+  XML_ProcessingInstructionHandler m_processingInstructionHandler;
+  XML_CommentHandler m_commentHandler;
+  XML_StartCdataSectionHandler m_startCdataSectionHandler;
+  XML_EndCdataSectionHandler m_endCdataSectionHandler;
+  XML_DefaultHandler m_defaultHandler;
+  XML_StartDoctypeDeclHandler m_startDoctypeDeclHandler;
+  XML_EndDoctypeDeclHandler m_endDoctypeDeclHandler;
+  XML_UnparsedEntityDeclHandler m_unparsedEntityDeclHandler;
+  XML_NotationDeclHandler m_notationDeclHandler;
+  XML_StartNamespaceDeclHandler m_startNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler m_endNamespaceDeclHandler;
+  XML_NotStandaloneHandler m_notStandaloneHandler;
+  XML_ExternalEntityRefHandler m_externalEntityRefHandler;
+  void *m_externalEntityRefHandlerArg;
+  XML_UnknownEncodingHandler m_unknownEncodingHandler;
+  XML_ElementDeclHandler m_elementDeclHandler;
+  XML_AttlistDeclHandler m_attlistDeclHandler;
+  XML_EntityDeclHandler m_entityDeclHandler;
+  XML_XmlDeclHandler m_xmlDeclHandler;
+  const ENCODING *m_encoding;
+  INIT_ENCODING m_initEncoding;
+  const ENCODING *m_internalEncoding;
+  const XML_Char *m_protocolEncodingName;
+  int m_ns;
+  int m_ns_triplets;
+  void *m_unknownEncodingMem;
+  void *m_unknownEncodingData;
+  void *m_unknownEncodingHandlerData;
+  void (*m_unknownEncodingRelease)(void *);
+  PROLOG_STATE m_prologState;
+  Processor *m_processor;
+  enum XML_Error m_errorCode;
+  const char *m_eventPtr;
+  const char *m_eventEndPtr;
+  const char *m_positionPtr;
+  OPEN_INTERNAL_ENTITY *m_openInternalEntities;
+  int m_defaultExpandInternalEntities;
+  int m_tagLevel;
+  ENTITY *m_declEntity;
+  const XML_Char *m_doctypeName;
+  const XML_Char *m_doctypeSysid;
+  const XML_Char *m_doctypePubid;
+  const XML_Char *m_declAttributeType;
+  const XML_Char *m_declNotationName;
+  const XML_Char *m_declNotationPublicId;
+  ELEMENT_TYPE *m_declElementType;
+  ATTRIBUTE_ID *m_declAttributeId;
+  char m_declAttributeIsCdata;
+  char m_declAttributeIsId;
+  DTD m_dtd;
+  const XML_Char *m_curBase;
+  TAG *m_tagStack;
+  TAG *m_freeTagList;
+  BINDING *m_inheritedBindings;
+  BINDING *m_freeBindingList;
+  int m_attsSize;
+  int m_nSpecifiedAtts;
+  int m_idAttIndex;
+  ATTRIBUTE *m_atts;
+  POSITION m_position;
+  STRING_POOL m_tempPool;
+  STRING_POOL m_temp2Pool;
+  char *m_groupConnector;
+  unsigned m_groupSize;
+  int m_hadExternalDoctype;
+  XML_Char m_namespaceSeparator;
+#ifdef XML_DTD
+  enum XML_ParamEntityParsing m_paramEntityParsing;
+  XML_Parser m_parentParser;
+#endif
+} Parser;
+
+#define MALLOC(s) (((Parser *)parser)->m_mem.malloc_fcn((s)))
+#define REALLOC(p,s) (((Parser *)parser)->m_mem.realloc_fcn((p),(s)))
+#define FREE(p) (((Parser *)parser)->m_mem.free_fcn((p)))
+
+#define userData (((Parser *)parser)->m_userData)
+#define handlerArg (((Parser *)parser)->m_handlerArg)
+#define startElementHandler (((Parser *)parser)->m_startElementHandler)
+#define endElementHandler (((Parser *)parser)->m_endElementHandler)
+#define characterDataHandler (((Parser *)parser)->m_characterDataHandler)
+#define processingInstructionHandler (((Parser *)parser)->m_processingInstructionHandler)
+#define commentHandler (((Parser *)parser)->m_commentHandler)
+#define startCdataSectionHandler (((Parser *)parser)->m_startCdataSectionHandler)
+#define endCdataSectionHandler (((Parser *)parser)->m_endCdataSectionHandler)
+#define defaultHandler (((Parser *)parser)->m_defaultHandler)
+#define startDoctypeDeclHandler (((Parser *)parser)->m_startDoctypeDeclHandler)
+#define endDoctypeDeclHandler (((Parser *)parser)->m_endDoctypeDeclHandler)
+#define unparsedEntityDeclHandler (((Parser *)parser)->m_unparsedEntityDeclHandler)
+#define notationDeclHandler (((Parser *)parser)->m_notationDeclHandler)
+#define startNamespaceDeclHandler (((Parser *)parser)->m_startNamespaceDeclHandler)
+#define endNamespaceDeclHandler (((Parser *)parser)->m_endNamespaceDeclHandler)
+#define notStandaloneHandler (((Parser *)parser)->m_notStandaloneHandler)
+#define externalEntityRefHandler (((Parser *)parser)->m_externalEntityRefHandler)
+#define externalEntityRefHandlerArg (((Parser *)parser)->m_externalEntityRefHandlerArg)
+#define unknownEncodingHandler (((Parser *)parser)->m_unknownEncodingHandler)
+#define elementDeclHandler (((Parser *)parser)->m_elementDeclHandler)
+#define attlistDeclHandler (((Parser *)parser)->m_attlistDeclHandler)
+#define entityDeclHandler (((Parser *)parser)->m_entityDeclHandler)
+#define xmlDeclHandler (((Parser *)parser)->m_xmlDeclHandler)
+#define encoding (((Parser *)parser)->m_encoding)
+#define initEncoding (((Parser *)parser)->m_initEncoding)
+#define internalEncoding (((Parser *)parser)->m_internalEncoding)
+#define unknownEncodingMem (((Parser *)parser)->m_unknownEncodingMem)
+#define unknownEncodingData (((Parser *)parser)->m_unknownEncodingData)
+#define unknownEncodingHandlerData \
+  (((Parser *)parser)->m_unknownEncodingHandlerData)
+#define unknownEncodingRelease (((Parser *)parser)->m_unknownEncodingRelease)
+#define protocolEncodingName (((Parser *)parser)->m_protocolEncodingName)
+#define ns (((Parser *)parser)->m_ns)
+#define ns_triplets (((Parser *)parser)->m_ns_triplets)
+#define prologState (((Parser *)parser)->m_prologState)
+#define processor (((Parser *)parser)->m_processor)
+#define errorCode (((Parser *)parser)->m_errorCode)
+#define eventPtr (((Parser *)parser)->m_eventPtr)
+#define eventEndPtr (((Parser *)parser)->m_eventEndPtr)
+#define positionPtr (((Parser *)parser)->m_positionPtr)
+#define position (((Parser *)parser)->m_position)
+#define openInternalEntities (((Parser *)parser)->m_openInternalEntities)
+#define defaultExpandInternalEntities (((Parser *)parser)->m_defaultExpandInternalEntities)
+#define tagLevel (((Parser *)parser)->m_tagLevel)
+#define buffer (((Parser *)parser)->m_buffer)
+#define bufferPtr (((Parser *)parser)->m_bufferPtr)
+#define bufferEnd (((Parser *)parser)->m_bufferEnd)
+#define parseEndByteIndex (((Parser *)parser)->m_parseEndByteIndex)
+#define parseEndPtr (((Parser *)parser)->m_parseEndPtr)
+#define bufferLim (((Parser *)parser)->m_bufferLim)
+#define dataBuf (((Parser *)parser)->m_dataBuf)
+#define dataBufEnd (((Parser *)parser)->m_dataBufEnd)
+#define dtd (((Parser *)parser)->m_dtd)
+#define curBase (((Parser *)parser)->m_curBase)
+#define declEntity (((Parser *)parser)->m_declEntity)
+#define doctypeName (((Parser *)parser)->m_doctypeName)
+#define doctypeSysid (((Parser *)parser)->m_doctypeSysid)
+#define doctypePubid (((Parser *)parser)->m_doctypePubid)
+#define declAttributeType (((Parser *)parser)->m_declAttributeType)
+#define declNotationName (((Parser *)parser)->m_declNotationName)
+#define declNotationPublicId (((Parser *)parser)->m_declNotationPublicId)
+#define declElementType (((Parser *)parser)->m_declElementType)
+#define declAttributeId (((Parser *)parser)->m_declAttributeId)
+#define declAttributeIsCdata (((Parser *)parser)->m_declAttributeIsCdata)
+#define declAttributeIsId (((Parser *)parser)->m_declAttributeIsId)
+#define freeTagList (((Parser *)parser)->m_freeTagList)
+#define freeBindingList (((Parser *)parser)->m_freeBindingList)
+#define inheritedBindings (((Parser *)parser)->m_inheritedBindings)
+#define tagStack (((Parser *)parser)->m_tagStack)
+#define atts (((Parser *)parser)->m_atts)
+#define attsSize (((Parser *)parser)->m_attsSize)
+#define nSpecifiedAtts (((Parser *)parser)->m_nSpecifiedAtts)
+#define idAttIndex (((Parser *)parser)->m_idAttIndex)
+#define tempPool (((Parser *)parser)->m_tempPool)
+#define temp2Pool (((Parser *)parser)->m_temp2Pool)
+#define groupConnector (((Parser *)parser)->m_groupConnector)
+#define groupSize (((Parser *)parser)->m_groupSize)
+#define hadExternalDoctype (((Parser *)parser)->m_hadExternalDoctype)
+#define namespaceSeparator (((Parser *)parser)->m_namespaceSeparator)
+#ifdef XML_DTD
+#define parentParser (((Parser *)parser)->m_parentParser)
+#define paramEntityParsing (((Parser *)parser)->m_paramEntityParsing)
+#endif /* XML_DTD */
+
+#ifdef COMPILED_FROM_DSP
+BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID p) {
+  return TRUE;
+}
+#endif /* def COMPILED_FROM_DSP */
+
+#ifdef _MSC_VER
+#ifdef _DEBUG
+Parser *asParser(XML_Parser parser)
+{
+  return parser;
+}
+#endif
+#endif
+
+XML_Parser XML_ParserCreate(const XML_Char *encodingName)
+{
+  return XML_ParserCreate_MM(encodingName, NULL, NULL);
+}
+
+XML_Parser XML_ParserCreateNS(const XML_Char *encodingName, XML_Char nsSep)
+{
+  XML_Char tmp[2];
+  *tmp = nsSep;
+  return XML_ParserCreate_MM(encodingName, NULL, tmp);
+}
+
+XML_Parser
+XML_ParserCreate_MM(const XML_Char *encodingName,
+		    const XML_Memory_Handling_Suite *memsuite,
+		    const XML_Char *nameSep) {
+  
+  XML_Parser parser;
+  static
+  const XML_Char implicitContext[] = {
+    XML_T('x'), XML_T('m'), XML_T('l'), XML_T('='),
+    XML_T('h'), XML_T('t'), XML_T('t'), XML_T('p'), XML_T(':'),
+    XML_T('/'), XML_T('/'), XML_T('w'), XML_T('w'), XML_T('w'),
+    XML_T('.'), XML_T('w'), XML_T('3'),
+    XML_T('.'), XML_T('o'), XML_T('r'), XML_T('g'),
+    XML_T('/'), XML_T('X'), XML_T('M'), XML_T('L'),
+    XML_T('/'), XML_T('1'), XML_T('9'), XML_T('9'), XML_T('8'),
+    XML_T('/'), XML_T('n'), XML_T('a'), XML_T('m'), XML_T('e'),
+    XML_T('s'), XML_T('p'), XML_T('a'), XML_T('c'), XML_T('e'),
+    XML_T('\0')
+  };
+
+
+  if (memsuite) {
+    XML_Memory_Handling_Suite *mtemp;
+    parser = memsuite->malloc_fcn(sizeof(Parser));
+    mtemp = &(((Parser *) parser)->m_mem);
+    mtemp->malloc_fcn = memsuite->malloc_fcn;
+    mtemp->realloc_fcn = memsuite->realloc_fcn;
+    mtemp->free_fcn = memsuite->free_fcn;
+  }
+  else {
+    XML_Memory_Handling_Suite *mtemp;
+    parser = malloc(sizeof(Parser));
+    mtemp = &(((Parser *) parser)->m_mem);
+    mtemp->malloc_fcn = malloc;
+    mtemp->realloc_fcn = realloc;
+    mtemp->free_fcn = free;
+  }
+
+  if (!parser)
+    return parser;
+  processor = prologInitProcessor;
+  XmlPrologStateInit(&prologState);
+  userData = 0;
+  handlerArg = 0;
+  startElementHandler = 0;
+  endElementHandler = 0;
+  characterDataHandler = 0;
+  processingInstructionHandler = 0;
+  commentHandler = 0;
+  startCdataSectionHandler = 0;
+  endCdataSectionHandler = 0;
+  defaultHandler = 0;
+  startDoctypeDeclHandler = 0;
+  endDoctypeDeclHandler = 0;
+  unparsedEntityDeclHandler = 0;
+  notationDeclHandler = 0;
+  startNamespaceDeclHandler = 0;
+  endNamespaceDeclHandler = 0;
+  notStandaloneHandler = 0;
+  externalEntityRefHandler = 0;
+  externalEntityRefHandlerArg = parser;
+  unknownEncodingHandler = 0;
+  elementDeclHandler = 0;
+  attlistDeclHandler = 0;
+  entityDeclHandler = 0;
+  xmlDeclHandler = 0;
+  buffer = 0;
+  bufferPtr = 0;
+  bufferEnd = 0;
+  parseEndByteIndex = 0;
+  parseEndPtr = 0;
+  bufferLim = 0;
+  declElementType = 0;
+  declAttributeId = 0;
+  declEntity = 0;
+  doctypeName = 0;
+  doctypeSysid = 0;
+  doctypePubid = 0;
+  declAttributeType = 0;
+  declNotationName = 0;
+  declNotationPublicId = 0;
+  memset(&position, 0, sizeof(POSITION));
+  errorCode = XML_ERROR_NONE;
+  eventPtr = 0;
+  eventEndPtr = 0;
+  positionPtr = 0;
+  openInternalEntities = 0;
+  tagLevel = 0;
+  tagStack = 0;
+  freeTagList = 0;
+  freeBindingList = 0;
+  inheritedBindings = 0;
+  attsSize = INIT_ATTS_SIZE;
+  atts = MALLOC(attsSize * sizeof(ATTRIBUTE));
+  nSpecifiedAtts = 0;
+  dataBuf = MALLOC(INIT_DATA_BUF_SIZE * sizeof(XML_Char));
+  groupSize = 0;
+  groupConnector = 0;
+  hadExternalDoctype = 0;
+  unknownEncodingMem = 0;
+  unknownEncodingRelease = 0;
+  unknownEncodingData = 0;
+  unknownEncodingHandlerData = 0;
+  namespaceSeparator = '!';
+#ifdef XML_DTD
+  parentParser = 0;
+  paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+  ns = 0;
+  ns_triplets = 0;
+  poolInit(&tempPool, &(((Parser *) parser)->m_mem));
+  poolInit(&temp2Pool, &(((Parser *) parser)->m_mem));
+  protocolEncodingName = encodingName ? poolCopyString(&tempPool, encodingName) : 0;
+  curBase = 0;
+  if (!dtdInit(&dtd, parser) || !atts || !dataBuf
+      || (encodingName && !protocolEncodingName)) {
+    XML_ParserFree(parser);
+    return 0;
+  }
+  dataBufEnd = dataBuf + INIT_DATA_BUF_SIZE;
+
+  if (nameSep) {
+    XmlInitEncodingNS(&initEncoding, &encoding, 0);
+    ns = 1;
+    internalEncoding = XmlGetInternalEncodingNS();
+    namespaceSeparator = *nameSep;
+
+    if (! setContext(parser, implicitContext)) {
+      XML_ParserFree(parser);
+      return 0;
+    }
+  }
+  else {
+    XmlInitEncoding(&initEncoding, &encoding, 0);
+    internalEncoding = XmlGetInternalEncoding();
+  }
+
+  return parser;
+}  /* End XML_ParserCreate_MM */
+
+int XML_SetEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+  if (!encodingName)
+    protocolEncodingName = 0;
+  else {
+    protocolEncodingName = poolCopyString(&tempPool, encodingName);
+    if (!protocolEncodingName)
+      return 0;
+  }
+  return 1;
+}
+
+XML_Parser XML_ExternalEntityParserCreate(XML_Parser oldParser,
+					  const XML_Char *context,
+					  const XML_Char *encodingName)
+{
+  XML_Parser parser = oldParser;
+  DTD *oldDtd = &dtd;
+  XML_StartElementHandler oldStartElementHandler = startElementHandler;
+  XML_EndElementHandler oldEndElementHandler = endElementHandler;
+  XML_CharacterDataHandler oldCharacterDataHandler = characterDataHandler;
+  XML_ProcessingInstructionHandler oldProcessingInstructionHandler = processingInstructionHandler;
+  XML_CommentHandler oldCommentHandler = commentHandler;
+  XML_StartCdataSectionHandler oldStartCdataSectionHandler = startCdataSectionHandler;
+  XML_EndCdataSectionHandler oldEndCdataSectionHandler = endCdataSectionHandler;
+  XML_DefaultHandler oldDefaultHandler = defaultHandler;
+  XML_UnparsedEntityDeclHandler oldUnparsedEntityDeclHandler = unparsedEntityDeclHandler;
+  XML_NotationDeclHandler oldNotationDeclHandler = notationDeclHandler;
+  XML_StartNamespaceDeclHandler oldStartNamespaceDeclHandler = startNamespaceDeclHandler;
+  XML_EndNamespaceDeclHandler oldEndNamespaceDeclHandler = endNamespaceDeclHandler;
+  XML_NotStandaloneHandler oldNotStandaloneHandler = notStandaloneHandler;
+  XML_ExternalEntityRefHandler oldExternalEntityRefHandler = externalEntityRefHandler;
+  XML_UnknownEncodingHandler oldUnknownEncodingHandler = unknownEncodingHandler;
+  XML_ElementDeclHandler oldElementDeclHandler = elementDeclHandler;
+  XML_AttlistDeclHandler oldAttlistDeclHandler = attlistDeclHandler;
+  XML_EntityDeclHandler oldEntityDeclHandler = entityDeclHandler;
+  XML_XmlDeclHandler oldXmlDeclHandler = xmlDeclHandler;
+  ELEMENT_TYPE * oldDeclElementType = declElementType;
+
+  void *oldUserData = userData;
+  void *oldHandlerArg = handlerArg;
+  int oldDefaultExpandInternalEntities = defaultExpandInternalEntities;
+  void *oldExternalEntityRefHandlerArg = externalEntityRefHandlerArg;
+#ifdef XML_DTD
+  int oldParamEntityParsing = paramEntityParsing;
+#endif
+  int oldns_triplets = ns_triplets;
+
+  if (ns) {
+    XML_Char tmp[2];
+
+    *tmp = namespaceSeparator;
+    parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
+				 tmp);
+  }
+  else {
+    parser = XML_ParserCreate_MM(encodingName, &((Parser *)parser)->m_mem,
+				 NULL);
+  }
+
+  if (!parser)
+    return 0;
+
+  startElementHandler = oldStartElementHandler;
+  endElementHandler = oldEndElementHandler;
+  characterDataHandler = oldCharacterDataHandler;
+  processingInstructionHandler = oldProcessingInstructionHandler;
+  commentHandler = oldCommentHandler;
+  startCdataSectionHandler = oldStartCdataSectionHandler;
+  endCdataSectionHandler = oldEndCdataSectionHandler;
+  defaultHandler = oldDefaultHandler;
+  unparsedEntityDeclHandler = oldUnparsedEntityDeclHandler;
+  notationDeclHandler = oldNotationDeclHandler;
+  startNamespaceDeclHandler = oldStartNamespaceDeclHandler;
+  endNamespaceDeclHandler = oldEndNamespaceDeclHandler;
+  notStandaloneHandler = oldNotStandaloneHandler;
+  externalEntityRefHandler = oldExternalEntityRefHandler;
+  unknownEncodingHandler = oldUnknownEncodingHandler;
+  elementDeclHandler = oldElementDeclHandler;
+  attlistDeclHandler = oldAttlistDeclHandler;
+  entityDeclHandler = oldEntityDeclHandler;
+  xmlDeclHandler = oldXmlDeclHandler;
+  declElementType = oldDeclElementType;
+  userData = oldUserData;
+  if (oldUserData == oldHandlerArg)
+    handlerArg = userData;
+  else
+    handlerArg = parser;
+  if (oldExternalEntityRefHandlerArg != oldParser)
+    externalEntityRefHandlerArg = oldExternalEntityRefHandlerArg;
+  defaultExpandInternalEntities = oldDefaultExpandInternalEntities;
+  ns_triplets = oldns_triplets;
+#ifdef XML_DTD
+  paramEntityParsing = oldParamEntityParsing;
+  if (context) {
+#endif /* XML_DTD */
+    if (!dtdCopy(&dtd, oldDtd, parser) || !setContext(parser, context)) {
+      XML_ParserFree(parser);
+      return 0;
+    }
+    processor = externalEntityInitProcessor;
+#ifdef XML_DTD
+  }
+  else {
+    dtdSwap(&dtd, oldDtd);
+    parentParser = oldParser;
+    XmlPrologStateInitExternalEntity(&prologState);
+    dtd.complete = 1;
+    hadExternalDoctype = 1;
+  }
+#endif /* XML_DTD */
+  return parser;
+}
+
+static
+void destroyBindings(BINDING *bindings, XML_Parser parser)
+{
+  for (;;) {
+    BINDING *b = bindings;
+    if (!b)
+      break;
+    bindings = b->nextTagBinding;
+    FREE(b->uri);
+    FREE(b);
+  }
+}
+
+void XML_ParserFree(XML_Parser parser)
+{
+  for (;;) {
+    TAG *p;
+    if (tagStack == 0) {
+      if (freeTagList == 0)
+	break;
+      tagStack = freeTagList;
+      freeTagList = 0;
+    }
+    p = tagStack;
+    tagStack = tagStack->parent;
+    FREE(p->buf);
+    destroyBindings(p->bindings, parser);
+    FREE(p);
+  }
+  destroyBindings(freeBindingList, parser);
+  destroyBindings(inheritedBindings, parser);
+  poolDestroy(&tempPool);
+  poolDestroy(&temp2Pool);
+#ifdef XML_DTD
+  if (parentParser) {
+    if (hadExternalDoctype)
+      dtd.complete = 0;
+    dtdSwap(&dtd, &((Parser *)parentParser)->m_dtd);
+  }
+#endif /* XML_DTD */
+  dtdDestroy(&dtd, parser);
+  FREE((void *)atts);
+  if (groupConnector)
+    FREE(groupConnector);
+  if (buffer)
+    FREE(buffer);
+  FREE(dataBuf);
+  if (unknownEncodingMem)
+    FREE(unknownEncodingMem);
+  if (unknownEncodingRelease)
+    unknownEncodingRelease(unknownEncodingData);
+  FREE(parser);
+}
+
+void XML_UseParserAsHandlerArg(XML_Parser parser)
+{
+  handlerArg = parser;
+}
+
+void
+XML_SetReturnNSTriplet(XML_Parser parser, int do_nst) {
+  ns_triplets = do_nst;
+}
+
+void XML_SetUserData(XML_Parser parser, void *p)
+{
+  if (handlerArg == userData)
+    handlerArg = userData = p;
+  else
+    userData = p;
+}
+
+int XML_SetBase(XML_Parser parser, const XML_Char *p)
+{
+  if (p) {
+    p = poolCopyString(&dtd.pool, p);
+    if (!p)
+      return 0;
+    curBase = p;
+  }
+  else
+    curBase = 0;
+  return 1;
+}
+
+const XML_Char *XML_GetBase(XML_Parser parser)
+{
+  return curBase;
+}
+
+int XML_GetSpecifiedAttributeCount(XML_Parser parser)
+{
+  return nSpecifiedAtts;
+}
+
+int XML_GetIdAttributeIndex(XML_Parser parser)
+{
+  return idAttIndex;
+}
+
+void XML_SetElementHandler(XML_Parser parser,
+			   XML_StartElementHandler start,
+			   XML_EndElementHandler end)
+{
+  startElementHandler = start;
+  endElementHandler = end;
+}
+
+void XML_SetStartElementHandler(XML_Parser parser,
+				XML_StartElementHandler start) {
+  startElementHandler = start;
+}
+
+void XML_SetEndElementHandler(XML_Parser parser,
+			      XML_EndElementHandler end) {
+  endElementHandler = end;
+}
+
+void XML_SetCharacterDataHandler(XML_Parser parser,
+				 XML_CharacterDataHandler handler)
+{
+  characterDataHandler = handler;
+}
+
+void XML_SetProcessingInstructionHandler(XML_Parser parser,
+					 XML_ProcessingInstructionHandler handler)
+{
+  processingInstructionHandler = handler;
+}
+
+void XML_SetCommentHandler(XML_Parser parser,
+			   XML_CommentHandler handler)
+{
+  commentHandler = handler;
+}
+
+void XML_SetCdataSectionHandler(XML_Parser parser,
+				XML_StartCdataSectionHandler start,
+			        XML_EndCdataSectionHandler end)
+{
+  startCdataSectionHandler = start;
+  endCdataSectionHandler = end;
+}
+
+void XML_SetStartCdataSectionHandler(XML_Parser parser,
+                                     XML_StartCdataSectionHandler start) {
+  startCdataSectionHandler = start;
+}
+
+void XML_SetEndCdataSectionHandler(XML_Parser parser,
+                                   XML_EndCdataSectionHandler end) {
+  endCdataSectionHandler = end;
+}
+
+void XML_SetDefaultHandler(XML_Parser parser,
+			   XML_DefaultHandler handler)
+{
+  defaultHandler = handler;
+  defaultExpandInternalEntities = 0;
+}
+
+void XML_SetDefaultHandlerExpand(XML_Parser parser,
+				 XML_DefaultHandler handler)
+{
+  defaultHandler = handler;
+  defaultExpandInternalEntities = 1;
+}
+
+void XML_SetDoctypeDeclHandler(XML_Parser parser,
+			       XML_StartDoctypeDeclHandler start,
+			       XML_EndDoctypeDeclHandler end)
+{
+  startDoctypeDeclHandler = start;
+  endDoctypeDeclHandler = end;
+}
+
+void XML_SetStartDoctypeDeclHandler(XML_Parser parser,
+				    XML_StartDoctypeDeclHandler start) {
+  startDoctypeDeclHandler = start;
+}
+
+void XML_SetEndDoctypeDeclHandler(XML_Parser parser,
+				  XML_EndDoctypeDeclHandler end) {
+  endDoctypeDeclHandler = end;
+}
+
+void XML_SetUnparsedEntityDeclHandler(XML_Parser parser,
+				      XML_UnparsedEntityDeclHandler handler)
+{
+  unparsedEntityDeclHandler = handler;
+}
+
+void XML_SetNotationDeclHandler(XML_Parser parser,
+				XML_NotationDeclHandler handler)
+{
+  notationDeclHandler = handler;
+}
+
+void XML_SetNamespaceDeclHandler(XML_Parser parser,
+				 XML_StartNamespaceDeclHandler start,
+				 XML_EndNamespaceDeclHandler end)
+{
+  startNamespaceDeclHandler = start;
+  endNamespaceDeclHandler = end;
+}
+
+void XML_SetStartNamespaceDeclHandler(XML_Parser parser,
+				      XML_StartNamespaceDeclHandler start) {
+  startNamespaceDeclHandler = start;
+}
+
+void XML_SetEndNamespaceDeclHandler(XML_Parser parser,
+				    XML_EndNamespaceDeclHandler end) {
+  endNamespaceDeclHandler = end;
+}
+
+
+void XML_SetNotStandaloneHandler(XML_Parser parser,
+				 XML_NotStandaloneHandler handler)
+{
+  notStandaloneHandler = handler;
+}
+
+void XML_SetExternalEntityRefHandler(XML_Parser parser,
+				     XML_ExternalEntityRefHandler handler)
+{
+  externalEntityRefHandler = handler;
+}
+
+void XML_SetExternalEntityRefHandlerArg(XML_Parser parser, void *arg)
+{
+  if (arg)
+    externalEntityRefHandlerArg = arg;
+  else
+    externalEntityRefHandlerArg = parser;
+}
+
+void XML_SetUnknownEncodingHandler(XML_Parser parser,
+				   XML_UnknownEncodingHandler handler,
+				   void *data)
+{
+  unknownEncodingHandler = handler;
+  unknownEncodingHandlerData = data;
+}
+
+void XML_SetElementDeclHandler(XML_Parser parser,
+			       XML_ElementDeclHandler eldecl)
+{
+  elementDeclHandler = eldecl;
+}
+
+void XML_SetAttlistDeclHandler(XML_Parser parser,
+			       XML_AttlistDeclHandler attdecl)
+{
+  attlistDeclHandler = attdecl;
+}
+
+void XML_SetEntityDeclHandler(XML_Parser parser,
+			      XML_EntityDeclHandler handler)
+{
+  entityDeclHandler = handler;
+}
+
+void XML_SetXmlDeclHandler(XML_Parser parser,
+			   XML_XmlDeclHandler handler) {
+  xmlDeclHandler = handler;
+}
+
+int XML_SetParamEntityParsing(XML_Parser parser,
+			      enum XML_ParamEntityParsing parsing)
+{
+#ifdef XML_DTD
+  paramEntityParsing = parsing;
+  return 1;
+#else
+  return parsing == XML_PARAM_ENTITY_PARSING_NEVER;
+#endif
+}
+
+int XML_Parse(XML_Parser parser, const char *s, int len, int isFinal)
+{
+  if (len == 0) {
+    if (!isFinal)
+      return 1;
+    positionPtr = bufferPtr;
+    errorCode = processor(parser, bufferPtr, parseEndPtr = bufferEnd, 0);
+    if (errorCode == XML_ERROR_NONE)
+      return 1;
+    eventEndPtr = eventPtr;
+    processor = errorProcessor;
+    return 0;
+  }
+#ifndef XML_CONTEXT_BYTES
+  else if (bufferPtr == bufferEnd) {
+    const char *end;
+    int nLeftOver;
+    parseEndByteIndex += len;
+    positionPtr = s;
+    if (isFinal) {
+      errorCode = processor(parser, s, parseEndPtr = s + len, 0);
+      if (errorCode == XML_ERROR_NONE)
+	return 1;
+      eventEndPtr = eventPtr;
+      processor = errorProcessor;
+      return 0;
+    }
+    errorCode = processor(parser, s, parseEndPtr = s + len, &end);
+    if (errorCode != XML_ERROR_NONE) {
+      eventEndPtr = eventPtr;
+      processor = errorProcessor;
+      return 0;
+    }
+    XmlUpdatePosition(encoding, positionPtr, end, &position);
+    nLeftOver = s + len - end;
+    if (nLeftOver) {
+      if (buffer == 0 || nLeftOver > bufferLim - buffer) {
+	/* FIXME avoid integer overflow */
+	buffer = buffer == 0 ? MALLOC(len * 2) : REALLOC(buffer, len * 2);
+	/* FIXME storage leak if realloc fails */
+	if (!buffer) {
+	  errorCode = XML_ERROR_NO_MEMORY;
+	  eventPtr = eventEndPtr = 0;
+	  processor = errorProcessor;
+	  return 0;
+	}
+	bufferLim = buffer + len * 2;
+      }
+      memcpy(buffer, end, nLeftOver);
+      bufferPtr = buffer;
+      bufferEnd = buffer + nLeftOver;
+    }
+    return 1;
+  }
+#endif  /* not defined XML_CONTEXT_BYTES */
+  else {
+    memcpy(XML_GetBuffer(parser, len), s, len);
+    return XML_ParseBuffer(parser, len, isFinal);
+  }
+}
+
+int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
+{
+  const char *start = bufferPtr;
+  positionPtr = start;
+  bufferEnd += len;
+  parseEndByteIndex += len;
+  errorCode = processor(parser, start, parseEndPtr = bufferEnd,
+			isFinal ? (const char **)0 : &bufferPtr);
+  if (errorCode == XML_ERROR_NONE) {
+    if (!isFinal)
+      XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
+    return 1;
+  }
+  else {
+    eventEndPtr = eventPtr;
+    processor = errorProcessor;
+    return 0;
+  }
+}
+
+void *XML_GetBuffer(XML_Parser parser, int len)
+{
+  if (len > bufferLim - bufferEnd) {
+    /* FIXME avoid integer overflow */
+    int neededSize = len + (bufferEnd - bufferPtr);
+#ifdef XML_CONTEXT_BYTES
+    int keep = bufferPtr - buffer;
+
+    if (keep > XML_CONTEXT_BYTES)
+      keep = XML_CONTEXT_BYTES;
+    neededSize += keep;
+#endif  /* defined XML_CONTEXT_BYTES */
+    if (neededSize  <= bufferLim - buffer) {
+#ifdef XML_CONTEXT_BYTES
+      if (keep < bufferPtr - buffer) {
+	int offset = (bufferPtr - buffer) - keep;
+	memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
+	bufferEnd -= offset;
+	bufferPtr -= offset;
+      }
+#else
+      memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
+      bufferEnd = buffer + (bufferEnd - bufferPtr);
+      bufferPtr = buffer;
+#endif  /* not defined XML_CONTEXT_BYTES */
+    }
+    else {
+      char *newBuf;
+      int bufferSize = bufferLim - bufferPtr;
+      if (bufferSize == 0)
+	bufferSize = INIT_BUFFER_SIZE;
+      do {
+	bufferSize *= 2;
+      } while (bufferSize < neededSize);
+      newBuf = MALLOC(bufferSize);
+      if (newBuf == 0) {
+	errorCode = XML_ERROR_NO_MEMORY;
+	return 0;
+      }
+      bufferLim = newBuf + bufferSize;
+#ifdef XML_CONTEXT_BYTES
+      if (bufferPtr) {
+	int keep = bufferPtr - buffer;
+	if (keep > XML_CONTEXT_BYTES)
+	  keep = XML_CONTEXT_BYTES;
+	memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
+	FREE(buffer);
+	buffer = newBuf;
+	bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
+	bufferPtr = buffer + keep;
+      }
+      else {
+	bufferEnd = newBuf + (bufferEnd - bufferPtr);
+	bufferPtr = buffer = newBuf;
+      }
+#else
+      if (bufferPtr) {
+	memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
+	FREE(buffer);
+      }
+      bufferEnd = newBuf + (bufferEnd - bufferPtr);
+      bufferPtr = buffer = newBuf;
+#endif  /* not defined XML_CONTEXT_BYTES */
+    }
+  }
+  return bufferEnd;
+}
+
+enum XML_Error XML_GetErrorCode(XML_Parser parser)
+{
+  return errorCode;
+}
+
+long XML_GetCurrentByteIndex(XML_Parser parser)
+{
+  if (eventPtr)
+    return parseEndByteIndex - (parseEndPtr - eventPtr);
+  return -1;
+}
+
+int XML_GetCurrentByteCount(XML_Parser parser)
+{
+  if (eventEndPtr && eventPtr)
+    return eventEndPtr - eventPtr;
+  return 0;
+}
+
+const char * XML_GetInputContext(XML_Parser parser, int *offset, int *size)
+{
+#ifdef XML_CONTEXT_BYTES
+  if (eventPtr && buffer) {
+    *offset = eventPtr - buffer;
+    *size   = bufferEnd - buffer;
+    return buffer;
+  }
+#endif /* defined XML_CONTEXT_BYTES */
+  return (char *) 0;
+}
+
+int XML_GetCurrentLineNumber(XML_Parser parser)
+{
+  if (eventPtr) {
+    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+    positionPtr = eventPtr;
+  }
+  return position.lineNumber + 1;
+}
+
+int XML_GetCurrentColumnNumber(XML_Parser parser)
+{
+  if (eventPtr) {
+    XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
+    positionPtr = eventPtr;
+  }
+  return position.columnNumber;
+}
+
+void XML_DefaultCurrent(XML_Parser parser)
+{
+  if (defaultHandler) {
+    if (openInternalEntities)
+      reportDefault(parser,
+	            internalEncoding,
+		    openInternalEntities->internalEventPtr,
+		    openInternalEntities->internalEventEndPtr);
+    else
+      reportDefault(parser, encoding, eventPtr, eventEndPtr);
+  }
+}
+
+const XML_LChar *XML_ErrorString(int code)
+{
+  static const XML_LChar *message[] = {
+    0,
+    XML_T("out of memory"),
+    XML_T("syntax error"),
+    XML_T("no element found"),
+    XML_T("not well-formed (invalid token)"),
+    XML_T("unclosed token"),
+    XML_T("unclosed token"),
+    XML_T("mismatched tag"),
+    XML_T("duplicate attribute"),
+    XML_T("junk after document element"),
+    XML_T("illegal parameter entity reference"),
+    XML_T("undefined entity"),
+    XML_T("recursive entity reference"),
+    XML_T("asynchronous entity"),
+    XML_T("reference to invalid character number"),
+    XML_T("reference to binary entity"),
+    XML_T("reference to external entity in attribute"),
+    XML_T("xml processing instruction not at start of external entity"),
+    XML_T("unknown encoding"),
+    XML_T("encoding specified in XML declaration is incorrect"),
+    XML_T("unclosed CDATA section"),
+    XML_T("error in processing external entity reference"),
+    XML_T("document is not standalone"),
+    XML_T("unexpected parser state - please send a bug report")
+  };
+  if (code > 0 && code < sizeof(message)/sizeof(message[0]))
+    return message[code];
+  return 0;
+}
+
+const XML_LChar *
+XML_ExpatVersion() {
+  return VERSION;
+}
+
+static
+enum XML_Error contentProcessor(XML_Parser parser,
+				const char *start,
+				const char *end,
+				const char **endPtr)
+{
+  return doContent(parser, 0, encoding, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor(XML_Parser parser,
+					   const char *start,
+					   const char *end,
+					   const char **endPtr)
+{
+  enum XML_Error result = initializeEncoding(parser);
+  if (result != XML_ERROR_NONE)
+    return result;
+  processor = externalEntityInitProcessor2;
+  return externalEntityInitProcessor2(parser, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor2(XML_Parser parser,
+					    const char *start,
+					    const char *end,
+					    const char **endPtr)
+{
+  const char *next;
+  int tok = XmlContentTok(encoding, start, end, &next);
+  switch (tok) {
+  case XML_TOK_BOM:
+    start = next;
+    break;
+  case XML_TOK_PARTIAL:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_UNCLOSED_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_PARTIAL_CHAR;
+  }
+  processor = externalEntityInitProcessor3;
+  return externalEntityInitProcessor3(parser, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityInitProcessor3(XML_Parser parser,
+					    const char *start,
+					    const char *end,
+					    const char **endPtr)
+{
+  const char *next;
+  int tok = XmlContentTok(encoding, start, end, &next);
+  switch (tok) {
+  case XML_TOK_XML_DECL:
+    {
+      enum XML_Error result = processXmlDecl(parser, 1, start, next);
+      if (result != XML_ERROR_NONE)
+	return result;
+      start = next;
+    }
+    break;
+  case XML_TOK_PARTIAL:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_UNCLOSED_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (endPtr) {
+      *endPtr = start;
+      return XML_ERROR_NONE;
+    }
+    eventPtr = start;
+    return XML_ERROR_PARTIAL_CHAR;
+  }
+  processor = externalEntityContentProcessor;
+  tagLevel = 1;
+  return doContent(parser, 1, encoding, start, end, endPtr);
+}
+
+static
+enum XML_Error externalEntityContentProcessor(XML_Parser parser,
+					      const char *start,
+					      const char *end,
+					      const char **endPtr)
+{
+  return doContent(parser, 1, encoding, start, end, endPtr);
+}
+
+static enum XML_Error
+doContent(XML_Parser parser,
+	  int startTagLevel,
+	  const ENCODING *enc,
+	  const char *s,
+	  const char *end,
+	  const char **nextPtr)
+{
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  for (;;) {
+    const char *next = s; /* XmlContentTok doesn't always set the last arg */
+    int tok = XmlContentTok(enc, s, end, &next);
+    *eventEndPP = next;
+    switch (tok) {
+    case XML_TOK_TRAILING_CR:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      *eventEndPP = end;
+      if (characterDataHandler) {
+	XML_Char c = 0xA;
+	characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, end);
+      if (startTagLevel == 0)
+	return XML_ERROR_NO_ELEMENTS;
+      if (tagLevel != startTagLevel)
+	return XML_ERROR_ASYNC_ENTITY;
+      return XML_ERROR_NONE;
+    case XML_TOK_NONE:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      if (startTagLevel > 0) {
+	if (tagLevel != startTagLevel)
+	  return XML_ERROR_ASYNC_ENTITY;
+	return XML_ERROR_NONE;
+      }
+      return XML_ERROR_NO_ELEMENTS;
+    case XML_TOK_INVALID:
+      *eventPP = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    case XML_TOK_ENTITY_REF:
+      {
+	const XML_Char *name;
+	ENTITY *entity;
+	XML_Char ch = XmlPredefinedEntityName(enc,
+					      s + enc->minBytesPerChar,
+					      next - enc->minBytesPerChar);
+	if (ch) {
+	  if (characterDataHandler)
+	    characterDataHandler(handlerArg, &ch, 1);
+	  else if (defaultHandler)
+	    reportDefault(parser, enc, s, next);
+	  break;
+	}
+	name = poolStoreString(&dtd.pool, enc,
+				s + enc->minBytesPerChar,
+				next - enc->minBytesPerChar);
+	if (!name)
+	  return XML_ERROR_NO_MEMORY;
+	entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
+	poolDiscard(&dtd.pool);
+	if (!entity) {
+	  if (dtd.complete || dtd.standalone)
+	    return XML_ERROR_UNDEFINED_ENTITY;
+	  if (defaultHandler)
+	    reportDefault(parser, enc, s, next);
+	  break;
+	}
+	if (entity->open)
+	  return XML_ERROR_RECURSIVE_ENTITY_REF;
+	if (entity->notation)
+	  return XML_ERROR_BINARY_ENTITY_REF;
+	if (entity) {
+	  if (entity->textPtr) {
+	    enum XML_Error result;
+	    OPEN_INTERNAL_ENTITY openEntity;
+	    if (defaultHandler && !defaultExpandInternalEntities) {
+	      reportDefault(parser, enc, s, next);
+	      break;
+	    }
+	    entity->open = 1;
+	    openEntity.next = openInternalEntities;
+	    openInternalEntities = &openEntity;
+	    openEntity.entity = entity;
+	    openEntity.internalEventPtr = 0;
+	    openEntity.internalEventEndPtr = 0;
+	    result = doContent(parser,
+			       tagLevel,
+			       internalEncoding,
+			       (char *)entity->textPtr,
+			       (char *)(entity->textPtr + entity->textLen),
+			       0);
+	    entity->open = 0;
+	    openInternalEntities = openEntity.next;
+	    if (result)
+	      return result;
+	  }
+	  else if (externalEntityRefHandler) {
+	    const XML_Char *context;
+	    entity->open = 1;
+	    context = getContext(parser);
+	    entity->open = 0;
+	    if (!context)
+	      return XML_ERROR_NO_MEMORY;
+	    if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+				          context,
+					  entity->base,
+					  entity->systemId,
+					  entity->publicId))
+	      return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+	    poolDiscard(&tempPool);
+	  }
+	  else if (defaultHandler)
+	    reportDefault(parser, enc, s, next);
+	}
+	break;
+      }
+    case XML_TOK_START_TAG_WITH_ATTS:
+      if (!startElementHandler) {
+	enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
+	if (result)
+	  return result;
+      }
+      /* fall through */
+    case XML_TOK_START_TAG_NO_ATTS:
+      {
+	TAG *tag;
+	if (freeTagList) {
+	  tag = freeTagList;
+	  freeTagList = freeTagList->parent;
+	}
+	else {
+	  tag = MALLOC(sizeof(TAG));
+	  if (!tag)
+	    return XML_ERROR_NO_MEMORY;
+	  tag->buf = MALLOC(INIT_TAG_BUF_SIZE);
+	  if (!tag->buf)
+	    return XML_ERROR_NO_MEMORY;
+	  tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
+	}
+	tag->bindings = 0;
+	tag->parent = tagStack;
+	tagStack = tag;
+	tag->name.localPart = 0;
+	tag->rawName = s + enc->minBytesPerChar;
+	tag->rawNameLength = XmlNameLength(enc, tag->rawName);
+	if (nextPtr) {
+	  /* Need to guarantee that:
+	     tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)) <= tag->bufEnd - sizeof(XML_Char) */
+	  if (tag->rawNameLength + (int)(sizeof(XML_Char) - 1) + (int)sizeof(XML_Char) > tag->bufEnd - tag->buf) {
+	    int bufSize = tag->rawNameLength * 4;
+	    bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
+	    tag->buf = REALLOC(tag->buf, bufSize);
+	    if (!tag->buf)
+	      return XML_ERROR_NO_MEMORY;
+	    tag->bufEnd = tag->buf + bufSize;
+	  }
+	  memcpy(tag->buf, tag->rawName, tag->rawNameLength);
+	  tag->rawName = tag->buf;
+	}
+	++tagLevel;
+	if (startElementHandler) {
+	  enum XML_Error result;
+	  XML_Char *toPtr;
+	  for (;;) {
+	    const char *rawNameEnd = tag->rawName + tag->rawNameLength;
+	    const char *fromPtr = tag->rawName;
+	    int bufSize;
+	    if (nextPtr)
+	      toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
+	    else
+	      toPtr = (XML_Char *)tag->buf;
+	    tag->name.str = toPtr;
+	    XmlConvert(enc,
+		       &fromPtr, rawNameEnd,
+		       (ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
+	    if (fromPtr == rawNameEnd)
+	      break;
+	    bufSize = (tag->bufEnd - tag->buf) << 1;
+	    tag->buf = REALLOC(tag->buf, bufSize);
+	    if (!tag->buf)
+	      return XML_ERROR_NO_MEMORY;
+	    tag->bufEnd = tag->buf + bufSize;
+	    if (nextPtr)
+	      tag->rawName = tag->buf;
+	  }
+	  *toPtr = XML_T('\0');
+	  result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
+	  if (result)
+	    return result;
+	  startElementHandler(handlerArg, tag->name.str, (const XML_Char **)atts);
+	  poolClear(&tempPool);
+	}
+	else {
+	  tag->name.str = 0;
+	  if (defaultHandler)
+	    reportDefault(parser, enc, s, next);
+	}
+	break;
+      }
+    case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
+      if (!startElementHandler) {
+	enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
+	if (result)
+	  return result;
+      }
+      /* fall through */
+    case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
+      if (startElementHandler || endElementHandler) {
+	const char *rawName = s + enc->minBytesPerChar;
+	enum XML_Error result;
+	BINDING *bindings = 0;
+	TAG_NAME name;
+	name.str = poolStoreString(&tempPool, enc, rawName,
+				   rawName + XmlNameLength(enc, rawName));
+	if (!name.str)
+	  return XML_ERROR_NO_MEMORY;
+	poolFinish(&tempPool);
+	result = storeAtts(parser, enc, s, &name, &bindings);
+	if (result)
+	  return result;
+	poolFinish(&tempPool);
+	if (startElementHandler)
+	  startElementHandler(handlerArg, name.str, (const XML_Char **)atts);
+	if (endElementHandler) {
+	  if (startElementHandler)
+	    *eventPP = *eventEndPP;
+	  endElementHandler(handlerArg, name.str);
+	}
+	poolClear(&tempPool);
+	while (bindings) {
+	  BINDING *b = bindings;
+	  if (endNamespaceDeclHandler)
+	    endNamespaceDeclHandler(handlerArg, b->prefix->name);
+	  bindings = bindings->nextTagBinding;
+	  b->nextTagBinding = freeBindingList;
+	  freeBindingList = b;
+	  b->prefix->binding = b->prevPrefixBinding;
+	}
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      if (tagLevel == 0)
+	return epilogProcessor(parser, next, end, nextPtr);
+      break;
+    case XML_TOK_END_TAG:
+      if (tagLevel == startTagLevel)
+        return XML_ERROR_ASYNC_ENTITY;
+      else {
+	int len;
+	const char *rawName;
+	TAG *tag = tagStack;
+	tagStack = tag->parent;
+	tag->parent = freeTagList;
+	freeTagList = tag;
+	rawName = s + enc->minBytesPerChar*2;
+	len = XmlNameLength(enc, rawName);
+	if (len != tag->rawNameLength
+	    || memcmp(tag->rawName, rawName, len) != 0) {
+	  *eventPP = rawName;
+	  return XML_ERROR_TAG_MISMATCH;
+	}
+	--tagLevel;
+	if (endElementHandler && tag->name.str) {
+	  if (tag->name.localPart) {
+	    XML_Char *to = (XML_Char *)tag->name.str + tag->name.uriLen;
+	    const XML_Char *from = tag->name.localPart;
+	    while ((*to++ = *from++) != 0)
+	      ;
+	  }
+	  endElementHandler(handlerArg, tag->name.str);
+	}
+	else if (defaultHandler)
+	  reportDefault(parser, enc, s, next);
+	while (tag->bindings) {
+	  BINDING *b = tag->bindings;
+	  if (endNamespaceDeclHandler)
+	    endNamespaceDeclHandler(handlerArg, b->prefix->name);
+	  tag->bindings = tag->bindings->nextTagBinding;
+	  b->nextTagBinding = freeBindingList;
+	  freeBindingList = b;
+	  b->prefix->binding = b->prevPrefixBinding;
+	}
+	if (tagLevel == 0)
+	  return epilogProcessor(parser, next, end, nextPtr);
+      }
+      break;
+    case XML_TOK_CHAR_REF:
+      {
+	int n = XmlCharRefNumber(enc, s);
+	if (n < 0)
+	  return XML_ERROR_BAD_CHAR_REF;
+	if (characterDataHandler) {
+	  XML_Char buf[XML_ENCODE_MAX];
+	  characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
+	}
+	else if (defaultHandler)
+	  reportDefault(parser, enc, s, next);
+      }
+      break;
+    case XML_TOK_XML_DECL:
+      return XML_ERROR_MISPLACED_XML_PI;
+    case XML_TOK_DATA_NEWLINE:
+      if (characterDataHandler) {
+	XML_Char c = 0xA;
+	characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_CDATA_SECT_OPEN:
+      {
+	enum XML_Error result;
+	if (startCdataSectionHandler)
+  	  startCdataSectionHandler(handlerArg);
+#if 0
+	/* Suppose you doing a transformation on a document that involves
+	   changing only the character data.  You set up a defaultHandler
+	   and a characterDataHandler.  The defaultHandler simply copies
+	   characters through.  The characterDataHandler does the transformation
+	   and writes the characters out escaping them as necessary.  This case
+	   will fail to work if we leave out the following two lines (because &
+	   and < inside CDATA sections will be incorrectly escaped).
+
+	   However, now we have a start/endCdataSectionHandler, so it seems
+	   easier to let the user deal with this. */
+
+	else if (characterDataHandler)
+  	  characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+	else if (defaultHandler)
+	  reportDefault(parser, enc, s, next);
+	result = doCdataSection(parser, enc, &next, end, nextPtr);
+	if (!next) {
+	  processor = cdataSectionProcessor;
+	  return result;
+	}
+      }
+      break;
+    case XML_TOK_TRAILING_RSQB:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      if (characterDataHandler) {
+	if (MUST_CONVERT(enc, s)) {
+	  ICHAR *dataPtr = (ICHAR *)dataBuf;
+	  XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+	  characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+	}
+	else
+	  characterDataHandler(handlerArg,
+		  	       (XML_Char *)s,
+			       (XML_Char *)end - (XML_Char *)s);
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, end);
+      if (startTagLevel == 0) {
+        *eventPP = end;
+	return XML_ERROR_NO_ELEMENTS;
+      }
+      if (tagLevel != startTagLevel) {
+	*eventPP = end;
+	return XML_ERROR_ASYNC_ENTITY;
+      }
+      return XML_ERROR_NONE;
+    case XML_TOK_DATA_CHARS:
+      if (characterDataHandler) {
+	if (MUST_CONVERT(enc, s)) {
+	  for (;;) {
+	    ICHAR *dataPtr = (ICHAR *)dataBuf;
+	    XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+	    *eventEndPP = s;
+	    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+	    if (s == next)
+	      break;
+	    *eventPP = s;
+	  }
+	}
+	else
+	  characterDataHandler(handlerArg,
+			       (XML_Char *)s,
+			       (XML_Char *)next - (XML_Char *)s);
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_PI:
+      if (!reportProcessingInstruction(parser, enc, s, next))
+	return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_COMMENT:
+      if (!reportComment(parser, enc, s, next))
+	return XML_ERROR_NO_MEMORY;
+      break;
+    default:
+      if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      break;
+    }
+    *eventPP = s = next;
+  }
+  /* not reached */
+}
+
+/* If tagNamePtr is non-null, build a real list of attributes,
+otherwise just check the attributes for well-formedness. */
+
+static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
+				const char *attStr, TAG_NAME *tagNamePtr,
+				BINDING **bindingsPtr)
+{
+  ELEMENT_TYPE *elementType = 0;
+  int nDefaultAtts = 0;
+  const XML_Char **appAtts;   /* the attribute list to pass to the application */
+  int attIndex = 0;
+  int i;
+  int n;
+  int nPrefixes = 0;
+  BINDING *binding;
+  const XML_Char *localPart;
+
+  /* lookup the element type name */
+  if (tagNamePtr) {
+    elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str,0);
+    if (!elementType) {
+      tagNamePtr->str = poolCopyString(&dtd.pool, tagNamePtr->str);
+      if (!tagNamePtr->str)
+	return XML_ERROR_NO_MEMORY;
+      elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, tagNamePtr->str, sizeof(ELEMENT_TYPE));
+      if (!elementType)
+        return XML_ERROR_NO_MEMORY;
+      if (ns && !setElementTypePrefix(parser, elementType))
+        return XML_ERROR_NO_MEMORY;
+    }
+    nDefaultAtts = elementType->nDefaultAtts;
+  }
+  /* get the attributes from the tokenizer */
+  n = XmlGetAttributes(enc, attStr, attsSize, atts);
+  if (n + nDefaultAtts > attsSize) {
+    int oldAttsSize = attsSize;
+    attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
+    atts = REALLOC((void *)atts, attsSize * sizeof(ATTRIBUTE));
+    if (!atts)
+      return XML_ERROR_NO_MEMORY;
+    if (n > oldAttsSize)
+      XmlGetAttributes(enc, attStr, n, atts);
+  }
+  appAtts = (const XML_Char **)atts;
+  for (i = 0; i < n; i++) {
+    /* add the name and value to the attribute list */
+    ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
+					 atts[i].name
+					 + XmlNameLength(enc, atts[i].name));
+    if (!attId)
+      return XML_ERROR_NO_MEMORY;
+    /* detect duplicate attributes */
+    if ((attId->name)[-1]) {
+      if (enc == encoding)
+	eventPtr = atts[i].name;
+      return XML_ERROR_DUPLICATE_ATTRIBUTE;
+    }
+    (attId->name)[-1] = 1;
+    appAtts[attIndex++] = attId->name;
+    if (!atts[i].normalized) {
+      enum XML_Error result;
+      int isCdata = 1;
+
+      /* figure out whether declared as other than CDATA */
+      if (attId->maybeTokenized) {
+	int j;
+	for (j = 0; j < nDefaultAtts; j++) {
+	  if (attId == elementType->defaultAtts[j].id) {
+	    isCdata = elementType->defaultAtts[j].isCdata;
+	    break;
+	  }
+	}
+      }
+
+      /* normalize the attribute value */
+      result = storeAttributeValue(parser, enc, isCdata,
+				   atts[i].valuePtr, atts[i].valueEnd,
+			           &tempPool);
+      if (result)
+	return result;
+      if (tagNamePtr) {
+	appAtts[attIndex] = poolStart(&tempPool);
+	poolFinish(&tempPool);
+      }
+      else
+	poolDiscard(&tempPool);
+    }
+    else if (tagNamePtr) {
+      /* the value did not need normalizing */
+      appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
+      if (appAtts[attIndex] == 0)
+	return XML_ERROR_NO_MEMORY;
+      poolFinish(&tempPool);
+    }
+    /* handle prefixed attribute names */
+    if (attId->prefix && tagNamePtr) {
+      if (attId->xmlns) {
+	/* deal with namespace declarations here */
+        if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
+          return XML_ERROR_NO_MEMORY;
+        --attIndex;
+      }
+      else {
+	/* deal with other prefixed names later */
+        attIndex++;
+        nPrefixes++;
+        (attId->name)[-1] = 2;
+      }
+    }
+    else
+      attIndex++;
+  }
+  if (tagNamePtr) {
+    int j;
+    nSpecifiedAtts = attIndex;
+    if (elementType->idAtt && (elementType->idAtt->name)[-1]) {
+      for (i = 0; i < attIndex; i += 2)
+	if (appAtts[i] == elementType->idAtt->name) {
+	  idAttIndex = i;
+	  break;
+	}
+    }
+    else
+      idAttIndex = -1;
+    /* do attribute defaulting */
+    for (j = 0; j < nDefaultAtts; j++) {
+      const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
+      if (!(da->id->name)[-1] && da->value) {
+        if (da->id->prefix) {
+          if (da->id->xmlns) {
+	    if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
+	      return XML_ERROR_NO_MEMORY;
+	  }
+          else {
+	    (da->id->name)[-1] = 2;
+	    nPrefixes++;
+  	    appAtts[attIndex++] = da->id->name;
+	    appAtts[attIndex++] = da->value;
+	  }
+	}
+	else {
+	  (da->id->name)[-1] = 1;
+	  appAtts[attIndex++] = da->id->name;
+	  appAtts[attIndex++] = da->value;
+	}
+      }
+    }
+    appAtts[attIndex] = 0;
+  }
+  i = 0;
+  if (nPrefixes) {
+    /* expand prefixed attribute names */
+    for (; i < attIndex; i += 2) {
+      if (appAtts[i][-1] == 2) {
+        ATTRIBUTE_ID *id;
+        ((XML_Char *)(appAtts[i]))[-1] = 0;
+	id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
+	if (id->prefix->binding) {
+	  int j;
+	  const BINDING *b = id->prefix->binding;
+	  const XML_Char *s = appAtts[i];
+	  for (j = 0; j < b->uriLen; j++) {
+	    if (!poolAppendChar(&tempPool, b->uri[j]))
+	      return XML_ERROR_NO_MEMORY;
+	  }
+	  while (*s++ != ':')
+	    ;
+	  do {
+	    if (!poolAppendChar(&tempPool, *s))
+	      return XML_ERROR_NO_MEMORY;
+	  } while (*s++);
+	  if (ns_triplets) {
+	    tempPool.ptr[-1] = namespaceSeparator;
+	    s = b->prefix->name;
+	    do {
+	      if (!poolAppendChar(&tempPool, *s))
+		return XML_ERROR_NO_MEMORY;
+	    } while (*s++);
+	  }
+
+	  appAtts[i] = poolStart(&tempPool);
+	  poolFinish(&tempPool);
+	}
+	if (!--nPrefixes)
+	  break;
+      }
+      else
+	((XML_Char *)(appAtts[i]))[-1] = 0;
+    }
+  }
+  /* clear the flags that say whether attributes were specified */
+  for (; i < attIndex; i += 2)
+    ((XML_Char *)(appAtts[i]))[-1] = 0;
+  if (!tagNamePtr)
+    return XML_ERROR_NONE;
+  for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
+    binding->attId->name[-1] = 0;
+  /* expand the element type name */
+  if (elementType->prefix) {
+    binding = elementType->prefix->binding;
+    if (!binding)
+      return XML_ERROR_NONE;
+    localPart = tagNamePtr->str;
+    while (*localPart++ != XML_T(':'))
+      ;
+  }
+  else if (dtd.defaultPrefix.binding) {
+    binding = dtd.defaultPrefix.binding;
+    localPart = tagNamePtr->str;
+  }
+  else
+    return XML_ERROR_NONE;
+  tagNamePtr->localPart = localPart;
+  tagNamePtr->uriLen = binding->uriLen;
+  for (i = 0; localPart[i++];)
+    ;
+  n = i + binding->uriLen;
+  if (n > binding->uriAlloc) {
+    TAG *p;
+    XML_Char *uri = MALLOC((n + EXPAND_SPARE) * sizeof(XML_Char));
+    if (!uri)
+      return XML_ERROR_NO_MEMORY;
+    binding->uriAlloc = n + EXPAND_SPARE;
+    memcpy(uri, binding->uri, binding->uriLen * sizeof(XML_Char));
+    for (p = tagStack; p; p = p->parent)
+      if (p->name.str == binding->uri)
+	p->name.str = uri;
+    FREE(binding->uri);
+    binding->uri = uri;
+  }
+  memcpy(binding->uri + binding->uriLen, localPart, i * sizeof(XML_Char));
+  tagNamePtr->str = binding->uri;
+  return XML_ERROR_NONE;
+}
+
+static
+int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
+{
+  BINDING *b;
+  int len;
+  for (len = 0; uri[len]; len++)
+    ;
+  if (namespaceSeparator)
+    len++;
+  if (freeBindingList) {
+    b = freeBindingList;
+    if (len > b->uriAlloc) {
+      b->uri = REALLOC(b->uri, sizeof(XML_Char) * (len + EXPAND_SPARE));
+      if (!b->uri)
+	return 0;
+      b->uriAlloc = len + EXPAND_SPARE;
+    }
+    freeBindingList = b->nextTagBinding;
+  }
+  else {
+    b = MALLOC(sizeof(BINDING));
+    if (!b)
+      return 0;
+    b->uri = MALLOC(sizeof(XML_Char) * (len + EXPAND_SPARE));
+    if (!b->uri) {
+      FREE(b);
+      return 0;
+    }
+    b->uriAlloc = len + EXPAND_SPARE;
+  }
+  b->uriLen = len;
+  memcpy(b->uri, uri, len * sizeof(XML_Char));
+  if (namespaceSeparator)
+    b->uri[len - 1] = namespaceSeparator;
+  b->prefix = prefix;
+  b->attId = attId;
+  b->prevPrefixBinding = prefix->binding;
+  if (*uri == XML_T('\0') && prefix == &dtd.defaultPrefix)
+    prefix->binding = 0;
+  else
+    prefix->binding = b;
+  b->nextTagBinding = *bindingsPtr;
+  *bindingsPtr = b;
+  if (startNamespaceDeclHandler)
+    startNamespaceDeclHandler(handlerArg, prefix->name,
+			      prefix->binding ? uri : 0);
+  return 1;
+}
+
+/* The idea here is to avoid using stack for each CDATA section when
+the whole file is parsed with one call. */
+
+static
+enum XML_Error cdataSectionProcessor(XML_Parser parser,
+				     const char *start,
+			    	     const char *end,
+				     const char **endPtr)
+{
+  enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
+  if (start) {
+    processor = contentProcessor;
+    return contentProcessor(parser, start, end, endPtr);
+  }
+  return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null if
+the section is not yet closed. */
+
+static
+enum XML_Error doCdataSection(XML_Parser parser,
+			      const ENCODING *enc,
+			      const char **startPtr,
+			      const char *end,
+			      const char **nextPtr)
+{
+  const char *s = *startPtr;
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    *eventPP = s;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  *startPtr = 0;
+  for (;;) {
+    const char *next;
+    int tok = XmlCdataSectionTok(enc, s, end, &next);
+    *eventEndPP = next;
+    switch (tok) {
+    case XML_TOK_CDATA_SECT_CLOSE:
+      if (endCdataSectionHandler)
+	endCdataSectionHandler(handlerArg);
+#if 0
+      /* see comment under XML_TOK_CDATA_SECT_OPEN */
+      else if (characterDataHandler)
+	characterDataHandler(handlerArg, dataBuf, 0);
+#endif
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      *startPtr = next;
+      return XML_ERROR_NONE;
+    case XML_TOK_DATA_NEWLINE:
+      if (characterDataHandler) {
+	XML_Char c = 0xA;
+	characterDataHandler(handlerArg, &c, 1);
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_DATA_CHARS:
+      if (characterDataHandler) {
+	if (MUST_CONVERT(enc, s)) {
+	  for (;;) {
+  	    ICHAR *dataPtr = (ICHAR *)dataBuf;
+	    XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
+	    *eventEndPP = next;
+	    characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+	    if (s == next)
+	      break;
+	    *eventPP = s;
+	  }
+	}
+	else
+	  characterDataHandler(handlerArg,
+		  	       (XML_Char *)s,
+			       (XML_Char *)next - (XML_Char *)s);
+      }
+      else if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      break;
+    case XML_TOK_INVALID:
+      *eventPP = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    case XML_TOK_PARTIAL:
+    case XML_TOK_NONE:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_CDATA_SECTION;
+    default:
+      *eventPP = next;
+      return XML_ERROR_UNEXPECTED_STATE;
+    }
+    *eventPP = s = next;
+  }
+  /* not reached */
+}
+
+#ifdef XML_DTD
+
+/* The idea here is to avoid using stack for each IGNORE section when
+the whole file is parsed with one call. */
+
+static
+enum XML_Error ignoreSectionProcessor(XML_Parser parser,
+				      const char *start,
+				      const char *end,
+				      const char **endPtr)
+{
+  enum XML_Error result = doIgnoreSection(parser, encoding, &start, end, endPtr);
+  if (start) {
+    processor = prologProcessor;
+    return prologProcessor(parser, start, end, endPtr);
+  }
+  return result;
+}
+
+/* startPtr gets set to non-null is the section is closed, and to null if
+the section is not yet closed. */
+
+static
+enum XML_Error doIgnoreSection(XML_Parser parser,
+			       const ENCODING *enc,
+			       const char **startPtr,
+			       const char *end,
+			       const char **nextPtr)
+{
+  const char *next;
+  int tok;
+  const char *s = *startPtr;
+  const char **eventPP;
+  const char **eventEndPP;
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    *eventPP = s;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  *eventPP = s;
+  *startPtr = 0;
+  tok = XmlIgnoreSectionTok(enc, s, end, &next);
+  *eventEndPP = next;
+  switch (tok) {
+  case XML_TOK_IGNORE_SECT:
+    if (defaultHandler)
+      reportDefault(parser, enc, s, next);
+    *startPtr = next;
+    return XML_ERROR_NONE;
+  case XML_TOK_INVALID:
+    *eventPP = next;
+    return XML_ERROR_INVALID_TOKEN;
+  case XML_TOK_PARTIAL_CHAR:
+    if (nextPtr) {
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    }
+    return XML_ERROR_PARTIAL_CHAR;
+  case XML_TOK_PARTIAL:
+  case XML_TOK_NONE:
+    if (nextPtr) {
+      *nextPtr = s;
+      return XML_ERROR_NONE;
+    }
+    return XML_ERROR_SYNTAX; /* XML_ERROR_UNCLOSED_IGNORE_SECTION */
+  default:
+    *eventPP = next;
+    return XML_ERROR_UNEXPECTED_STATE;
+  }
+  /* not reached */
+}
+
+#endif /* XML_DTD */
+
+static enum XML_Error
+initializeEncoding(XML_Parser parser)
+{
+  const char *s;
+#ifdef XML_UNICODE
+  char encodingBuf[128];
+  if (!protocolEncodingName)
+    s = 0;
+  else {
+    int i;
+    for (i = 0; protocolEncodingName[i]; i++) {
+      if (i == sizeof(encodingBuf) - 1
+	  || (protocolEncodingName[i] & ~0x7f) != 0) {
+	encodingBuf[0] = '\0';
+	break;
+      }
+      encodingBuf[i] = (char)protocolEncodingName[i];
+    }
+    encodingBuf[i] = '\0';
+    s = encodingBuf;
+  }
+#else
+  s = protocolEncodingName;
+#endif
+  if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
+    return XML_ERROR_NONE;
+  return handleUnknownEncoding(parser, protocolEncodingName);
+}
+
+static enum XML_Error
+processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
+	       const char *s, const char *next)
+{
+  const char *encodingName = 0;
+  const char *storedEncName = 0;
+  const ENCODING *newEncoding = 0;
+  const char *version = 0;
+  const char *versionend;
+  const char *storedversion = 0;
+  int standalone = -1;
+  if (!(ns
+        ? XmlParseXmlDeclNS
+	: XmlParseXmlDecl)(isGeneralTextEntity,
+		           encoding,
+		           s,
+		           next,
+		           &eventPtr,
+		           &version,
+			   &versionend,
+		           &encodingName,
+		           &newEncoding,
+		           &standalone))
+    return XML_ERROR_SYNTAX;
+  if (!isGeneralTextEntity && standalone == 1) {
+    dtd.standalone = 1;
+#ifdef XML_DTD
+    if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
+      paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
+#endif /* XML_DTD */
+  }
+  if (xmlDeclHandler) {
+    if (encodingName) {
+      storedEncName = poolStoreString(&temp2Pool,
+				      encoding,
+				      encodingName,
+				      encodingName
+				      + XmlNameLength(encoding, encodingName));
+      if (! storedEncName)
+	return XML_ERROR_NO_MEMORY;
+      poolFinish(&temp2Pool);
+    }
+    if (version) {
+      storedversion = poolStoreString(&temp2Pool,
+				      encoding,
+				      version,
+				      versionend - encoding->minBytesPerChar);
+      if (! storedversion)
+	return XML_ERROR_NO_MEMORY;
+    }
+    xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
+  }
+  else if (defaultHandler)
+    reportDefault(parser, encoding, s, next);
+  if (!protocolEncodingName) {
+    if (newEncoding) {
+      if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
+	eventPtr = encodingName;
+	return XML_ERROR_INCORRECT_ENCODING;
+      }
+      encoding = newEncoding;
+    }
+    else if (encodingName) {
+      enum XML_Error result;
+      if (! storedEncName) {
+	storedEncName = poolStoreString(&temp2Pool,
+					encoding,
+					encodingName,
+					encodingName
+					+ XmlNameLength(encoding, encodingName));
+	if (! storedEncName)
+	  return XML_ERROR_NO_MEMORY;
+      }
+      result = handleUnknownEncoding(parser, storedEncName);
+      poolClear(&tempPool);
+      if (result == XML_ERROR_UNKNOWN_ENCODING)
+	eventPtr = encodingName;
+      return result;
+    }
+  }
+
+  if (storedEncName || storedversion)
+    poolClear(&temp2Pool);
+
+  return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
+{
+  if (unknownEncodingHandler) {
+    XML_Encoding info;
+    int i;
+    for (i = 0; i < 256; i++)
+      info.map[i] = -1;
+    info.convert = 0;
+    info.data = 0;
+    info.release = 0;
+    if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
+      ENCODING *enc;
+      unknownEncodingMem = MALLOC(XmlSizeOfUnknownEncoding());
+      if (!unknownEncodingMem) {
+	if (info.release)
+	  info.release(info.data);
+	return XML_ERROR_NO_MEMORY;
+      }
+      enc = (ns
+	     ? XmlInitUnknownEncodingNS
+	     : XmlInitUnknownEncoding)(unknownEncodingMem,
+				       info.map,
+				       info.convert,
+				       info.data);
+      if (enc) {
+	unknownEncodingData = info.data;
+	unknownEncodingRelease = info.release;
+	encoding = enc;
+	return XML_ERROR_NONE;
+      }
+    }
+    if (info.release)
+      info.release(info.data);
+  }
+  return XML_ERROR_UNKNOWN_ENCODING;
+}
+
+static enum XML_Error
+prologInitProcessor(XML_Parser parser,
+		    const char *s,
+		    const char *end,
+		    const char **nextPtr)
+{
+  enum XML_Error result = initializeEncoding(parser);
+  if (result != XML_ERROR_NONE)
+    return result;
+  processor = prologProcessor;
+  return prologProcessor(parser, s, end, nextPtr);
+}
+
+static enum XML_Error
+prologProcessor(XML_Parser parser,
+		const char *s,
+		const char *end,
+		const char **nextPtr)
+{
+  const char *next;
+  int tok = XmlPrologTok(encoding, s, end, &next);
+  return doProlog(parser, encoding, s, end, tok, next, nextPtr);
+}
+
+static enum XML_Error
+doProlog(XML_Parser parser,
+	 const ENCODING *enc,
+	 const char *s,
+	 const char *end,
+	 int tok,
+	 const char *next,
+	 const char **nextPtr)
+{
+#ifdef XML_DTD
+  static const XML_Char externalSubsetName[] = { '#' , '\0' };
+#endif /* XML_DTD */
+
+  const char **eventPP;
+  const char **eventEndPP;
+  enum XML_Content_Quant quant;
+
+  if (enc == encoding) {
+    eventPP = &eventPtr;
+    eventEndPP = &eventEndPtr;
+  }
+  else {
+    eventPP = &(openInternalEntities->internalEventPtr);
+    eventEndPP = &(openInternalEntities->internalEventEndPtr);
+  }
+  for (;;) {
+    int role;
+    *eventPP = s;
+    *eventEndPP = next;
+    if (tok <= 0) {
+      if (nextPtr != 0 && tok != XML_TOK_INVALID) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      switch (tok) {
+      case XML_TOK_INVALID:
+	*eventPP = next;
+	return XML_ERROR_INVALID_TOKEN;
+      case XML_TOK_PARTIAL:
+	return XML_ERROR_UNCLOSED_TOKEN;
+      case XML_TOK_PARTIAL_CHAR:
+	return XML_ERROR_PARTIAL_CHAR;
+      case XML_TOK_NONE:
+#ifdef XML_DTD
+	if (enc != encoding)
+	  return XML_ERROR_NONE;
+	if (parentParser) {
+	  if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
+	      == XML_ROLE_ERROR)
+	    return XML_ERROR_SYNTAX;
+	  hadExternalDoctype = 0;
+	  return XML_ERROR_NONE;
+	}
+#endif /* XML_DTD */
+	return XML_ERROR_NO_ELEMENTS;
+      default:
+	tok = -tok;
+	next = end;
+	break;
+      }
+    }
+    role = XmlTokenRole(&prologState, tok, s, next, enc);
+    switch (role) {
+    case XML_ROLE_XML_DECL:
+      {
+	enum XML_Error result = processXmlDecl(parser, 0, s, next);
+	if (result != XML_ERROR_NONE)
+	  return result;
+	enc = encoding;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_NAME:
+      if (startDoctypeDeclHandler) {
+	doctypeName = poolStoreString(&tempPool, enc, s, next);
+	if (! doctypeName)
+	  return XML_ERROR_NO_MEMORY;
+	poolFinish(&tempPool);
+	doctypeSysid = 0;
+	doctypePubid = 0;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
+      if (startDoctypeDeclHandler) {
+	startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
+				doctypePubid, 1);
+	doctypeName = 0;
+	poolClear(&tempPool);
+      }
+      break;
+#ifdef XML_DTD
+    case XML_ROLE_TEXT_DECL:
+      {
+	enum XML_Error result = processXmlDecl(parser, 1, s, next);
+	if (result != XML_ERROR_NONE)
+	  return result;
+	enc = encoding;
+      }
+      break;
+#endif /* XML_DTD */
+    case XML_ROLE_DOCTYPE_PUBLIC_ID:
+      if (startDoctypeDeclHandler) {
+	doctypePubid = poolStoreString(&tempPool, enc, s + 1, next - 1);
+	if (! doctypePubid)
+	  return XML_ERROR_NO_MEMORY;
+	poolFinish(&tempPool);
+      }
+#ifdef XML_DTD
+      declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+				    externalSubsetName,
+				    sizeof(ENTITY));
+      if (!declEntity)
+	return XML_ERROR_NO_MEMORY;
+#endif /* XML_DTD */
+      /* fall through */
+    case XML_ROLE_ENTITY_PUBLIC_ID:
+      if (!XmlIsPublicId(enc, s, next, eventPP))
+	return XML_ERROR_SYNTAX;
+      if (declEntity) {
+	XML_Char *tem = poolStoreString(&dtd.pool,
+	                                enc,
+					s + enc->minBytesPerChar,
+	  				next - enc->minBytesPerChar);
+	if (!tem)
+	  return XML_ERROR_NO_MEMORY;
+	normalizePublicId(tem);
+	declEntity->publicId = tem;
+	poolFinish(&dtd.pool);
+      }
+      break;
+    case XML_ROLE_DOCTYPE_CLOSE:
+      if (doctypeName) {
+	startDoctypeDeclHandler(handlerArg, doctypeName,
+				doctypeSysid, doctypePubid, 0);
+	poolClear(&tempPool);
+      }
+      if (dtd.complete && hadExternalDoctype) {
+	dtd.complete = 0;
+#ifdef XML_DTD
+	if (paramEntityParsing && externalEntityRefHandler) {
+	  ENTITY *entity = (ENTITY *)lookup(&dtd.paramEntities,
+					    externalSubsetName,
+					    0);
+	  if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+					0,
+					entity->base,
+					entity->systemId,
+					entity->publicId))
+	   return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+	}
+#endif /* XML_DTD */
+	if (!dtd.complete
+	    && !dtd.standalone
+	    && notStandaloneHandler
+	    && !notStandaloneHandler(handlerArg))
+	  return XML_ERROR_NOT_STANDALONE;
+      }
+      if (endDoctypeDeclHandler)
+	endDoctypeDeclHandler(handlerArg);
+      break;
+    case XML_ROLE_INSTANCE_START:
+      processor = contentProcessor;
+      return contentProcessor(parser, s, end, nextPtr);
+    case XML_ROLE_ATTLIST_ELEMENT_NAME:
+      declElementType = getElementType(parser, enc, s, next);
+      if (!declElementType)
+	return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_ROLE_ATTRIBUTE_NAME:
+      declAttributeId = getAttributeId(parser, enc, s, next);
+      if (!declAttributeId)
+	return XML_ERROR_NO_MEMORY;
+      declAttributeIsCdata = 0;
+      declAttributeType = 0;
+      declAttributeIsId = 0;
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
+      declAttributeIsCdata = 1;
+      declAttributeType = "CDATA";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_ID:
+      declAttributeIsId = 1;
+      declAttributeType = "ID";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
+      declAttributeType = "IDREF";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
+      declAttributeType = "IDREFS";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
+      declAttributeType = "ENTITY";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
+      declAttributeType = "ENTITIES";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
+      declAttributeType = "NMTOKEN";
+      break;
+    case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
+      declAttributeType = "NMTOKENS";
+      break;
+
+    case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
+    case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
+      if (attlistDeclHandler)
+      {
+	char *prefix;
+	if (declAttributeType) {
+	  prefix = "|";
+	}
+	else {
+	  prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
+		    ? "NOTATION("
+		    : "(");
+	}
+	if (! poolAppendString(&tempPool, prefix))
+	  return XML_ERROR_NO_MEMORY;
+	if (! poolAppend(&tempPool, enc, s, next))
+	  return XML_ERROR_NO_MEMORY;
+	declAttributeType = tempPool.start;
+      }
+      break;
+    case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
+    case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
+      if (dtd.complete
+	  && !defineAttribute(declElementType, declAttributeId,
+			      declAttributeIsCdata, declAttributeIsId, 0,
+			      parser))
+	return XML_ERROR_NO_MEMORY;
+      if (attlistDeclHandler && declAttributeType) {
+	if (*declAttributeType == '('
+	    || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
+	  /* Enumerated or Notation type */
+	  if (! poolAppendChar(&tempPool, ')')
+	      || ! poolAppendChar(&tempPool, '\0'))
+	    return XML_ERROR_NO_MEMORY;
+	  declAttributeType = tempPool.start;
+	  poolFinish(&tempPool);
+	}
+	*eventEndPP = s;
+	attlistDeclHandler(handlerArg, declElementType->name,
+			   declAttributeId->name, declAttributeType,
+			   0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
+	poolClear(&tempPool);
+      }
+      break;
+    case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
+    case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
+      {
+	const XML_Char *attVal;
+	enum XML_Error result
+	  = storeAttributeValue(parser, enc, declAttributeIsCdata,
+				s + enc->minBytesPerChar,
+			        next - enc->minBytesPerChar,
+			        &dtd.pool);
+	if (result)
+	  return result;
+	attVal = poolStart(&dtd.pool);
+	poolFinish(&dtd.pool);
+	if (dtd.complete
+	    /* ID attributes aren't allowed to have a default */
+	    && !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0, attVal, parser))
+	  return XML_ERROR_NO_MEMORY;
+	if (attlistDeclHandler && declAttributeType) {
+	  if (*declAttributeType == '('
+	      || (*declAttributeType == 'N' && declAttributeType[1] == 'O')) {
+	    /* Enumerated or Notation type */
+	    if (! poolAppendChar(&tempPool, ')')
+		|| ! poolAppendChar(&tempPool, '\0'))
+	      return XML_ERROR_NO_MEMORY;
+	    declAttributeType = tempPool.start;
+	    poolFinish(&tempPool);
+	  }
+	  *eventEndPP = s;
+	  attlistDeclHandler(handlerArg, declElementType->name,
+			     declAttributeId->name, declAttributeType,
+			     attVal,
+			     role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
+	  poolClear(&tempPool);
+	}
+	break;
+      }
+    case XML_ROLE_ENTITY_VALUE:
+      {
+	enum XML_Error result = storeEntityValue(parser, enc,
+						 s + enc->minBytesPerChar,
+						 next - enc->minBytesPerChar);
+	if (declEntity) {
+	  declEntity->textPtr = poolStart(&dtd.pool);
+	  declEntity->textLen = poolLength(&dtd.pool);
+	  poolFinish(&dtd.pool);
+	  if (entityDeclHandler) {
+	    *eventEndPP = s;
+	    entityDeclHandler(handlerArg,
+			      declEntity->name,
+			      declEntity->is_param,
+			      declEntity->textPtr,
+			      declEntity->textLen,
+			      curBase, 0, 0, 0);
+	  }
+	}
+	else
+	  poolDiscard(&dtd.pool);
+	if (result != XML_ERROR_NONE)
+	  return result;
+      }
+      break;
+    case XML_ROLE_DOCTYPE_SYSTEM_ID:
+      if (startDoctypeDeclHandler) {
+	doctypeSysid = poolStoreString(&tempPool, enc, s + 1, next - 1);
+	if (! doctypeSysid)
+	  return XML_ERROR_NO_MEMORY;
+	poolFinish(&tempPool);
+      }
+      if (!dtd.standalone
+#ifdef XML_DTD
+	  && !paramEntityParsing
+#endif /* XML_DTD */
+	  && notStandaloneHandler
+	  && !notStandaloneHandler(handlerArg))
+	return XML_ERROR_NOT_STANDALONE;
+      hadExternalDoctype = 1;
+#ifndef XML_DTD
+      break;
+#else /* XML_DTD */
+      if (!declEntity) {
+	declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+				      externalSubsetName,
+				      sizeof(ENTITY));
+	declEntity->publicId = 0;
+	if (!declEntity)
+	  return XML_ERROR_NO_MEMORY;
+      }
+      /* fall through */
+#endif /* XML_DTD */
+    case XML_ROLE_ENTITY_SYSTEM_ID:
+      if (declEntity) {
+	declEntity->systemId = poolStoreString(&dtd.pool, enc,
+	                                       s + enc->minBytesPerChar,
+	  				       next - enc->minBytesPerChar);
+	if (!declEntity->systemId)
+	  return XML_ERROR_NO_MEMORY;
+	declEntity->base = curBase;
+	poolFinish(&dtd.pool);
+      }
+      break;
+    case XML_ROLE_ENTITY_COMPLETE:
+      if (declEntity && entityDeclHandler) {
+	*eventEndPP = s;
+	entityDeclHandler(handlerArg,
+			  declEntity->name,
+			  0,0,0,
+			  declEntity->base,
+			  declEntity->systemId,
+			  declEntity->publicId,
+			  0);
+      }
+      break;
+    case XML_ROLE_ENTITY_NOTATION_NAME:
+      if (declEntity) {
+	declEntity->notation = poolStoreString(&dtd.pool, enc, s, next);
+	if (!declEntity->notation)
+	  return XML_ERROR_NO_MEMORY;
+	poolFinish(&dtd.pool);
+	if (unparsedEntityDeclHandler) {
+	  *eventEndPP = s;
+	  unparsedEntityDeclHandler(handlerArg,
+				    declEntity->name,
+				    declEntity->base,
+				    declEntity->systemId,
+				    declEntity->publicId,
+				    declEntity->notation);
+	}
+	else if (entityDeclHandler) {
+	  *eventEndPP = s;
+	  entityDeclHandler(handlerArg,
+			    declEntity->name,
+			    0,0,0,
+			    declEntity->base,
+			    declEntity->systemId,
+			    declEntity->publicId,
+			    declEntity->notation);
+	}
+      }
+      break;
+    case XML_ROLE_GENERAL_ENTITY_NAME:
+      {
+	const XML_Char *name;
+	if (XmlPredefinedEntityName(enc, s, next)) {
+	  declEntity = 0;
+	  break;
+	}
+	name = poolStoreString(&dtd.pool, enc, s, next);
+	if (!name)
+	  return XML_ERROR_NO_MEMORY;
+	if (dtd.complete) {
+	  declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
+	  if (!declEntity)
+	    return XML_ERROR_NO_MEMORY;
+	  if (declEntity->name != name) {
+	    poolDiscard(&dtd.pool);
+	    declEntity = 0;
+	  }
+	  else {
+	    poolFinish(&dtd.pool);
+	    declEntity->publicId = 0;
+	    declEntity->is_param = 0;
+	  }
+	}
+	else {
+	  poolDiscard(&dtd.pool);
+	  declEntity = 0;
+	}
+      }
+      break;
+    case XML_ROLE_PARAM_ENTITY_NAME:
+#ifdef XML_DTD
+      if (dtd.complete) {
+	const XML_Char *name = poolStoreString(&dtd.pool, enc, s, next);
+	if (!name)
+	  return XML_ERROR_NO_MEMORY;
+	declEntity = (ENTITY *)lookup(&dtd.paramEntities,
+				      name, sizeof(ENTITY));
+	if (!declEntity)
+	  return XML_ERROR_NO_MEMORY;
+	if (declEntity->name != name) {
+	  poolDiscard(&dtd.pool);
+	  declEntity = 0;
+	}
+	else {
+	  poolFinish(&dtd.pool);
+	  declEntity->publicId = 0;
+	  declEntity->is_param = 1;
+	}
+      }
+#else /* not XML_DTD */
+      declEntity = 0;
+#endif /* not XML_DTD */
+      break;
+    case XML_ROLE_NOTATION_NAME:
+      declNotationPublicId = 0;
+      declNotationName = 0;
+      if (notationDeclHandler) {
+	declNotationName = poolStoreString(&tempPool, enc, s, next);
+	if (!declNotationName)
+	  return XML_ERROR_NO_MEMORY;
+	poolFinish(&tempPool);
+      }
+      break;
+    case XML_ROLE_NOTATION_PUBLIC_ID:
+      if (!XmlIsPublicId(enc, s, next, eventPP))
+	return XML_ERROR_SYNTAX;
+      if (declNotationName) {
+	XML_Char *tem = poolStoreString(&tempPool,
+	                                enc,
+					s + enc->minBytesPerChar,
+	  				next - enc->minBytesPerChar);
+	if (!tem)
+	  return XML_ERROR_NO_MEMORY;
+	normalizePublicId(tem);
+	declNotationPublicId = tem;
+	poolFinish(&tempPool);
+      }
+      break;
+    case XML_ROLE_NOTATION_SYSTEM_ID:
+      if (declNotationName && notationDeclHandler) {
+	const XML_Char *systemId
+	  = poolStoreString(&tempPool, enc,
+			    s + enc->minBytesPerChar,
+	  		    next - enc->minBytesPerChar);
+	if (!systemId)
+	  return XML_ERROR_NO_MEMORY;
+	*eventEndPP = s;
+	notationDeclHandler(handlerArg,
+			    declNotationName,
+			    curBase,
+			    systemId,
+			    declNotationPublicId);
+      }
+      poolClear(&tempPool);
+      break;
+    case XML_ROLE_NOTATION_NO_SYSTEM_ID:
+      if (declNotationPublicId && notationDeclHandler) {
+	*eventEndPP = s;
+	notationDeclHandler(handlerArg,
+			    declNotationName,
+			    curBase,
+			    0,
+			    declNotationPublicId);
+      }
+      poolClear(&tempPool);
+      break;
+    case XML_ROLE_ERROR:
+      switch (tok) {
+      case XML_TOK_PARAM_ENTITY_REF:
+	return XML_ERROR_PARAM_ENTITY_REF;
+      case XML_TOK_XML_DECL:
+	return XML_ERROR_MISPLACED_XML_PI;
+      default:
+	return XML_ERROR_SYNTAX;
+      }
+#ifdef XML_DTD
+    case XML_ROLE_IGNORE_SECT:
+      {
+	enum XML_Error result;
+	if (defaultHandler)
+	  reportDefault(parser, enc, s, next);
+	result = doIgnoreSection(parser, enc, &next, end, nextPtr);
+	if (!next) {
+	  processor = ignoreSectionProcessor;
+	  return result;
+	}
+      }
+      break;
+#endif /* XML_DTD */
+    case XML_ROLE_GROUP_OPEN:
+      if (prologState.level >= groupSize) {
+	if (groupSize) {
+	  groupConnector = REALLOC(groupConnector, groupSize *= 2);
+	  if (dtd.scaffIndex)
+	    dtd.scaffIndex = REALLOC(dtd.scaffIndex, groupSize * sizeof(int));
+	}
+	else
+	  groupConnector = MALLOC(groupSize = 32);
+	if (!groupConnector)
+	  return XML_ERROR_NO_MEMORY;
+      }
+      groupConnector[prologState.level] = 0;
+      if (dtd.in_eldecl) {
+	int myindex = nextScaffoldPart(parser);
+	if (myindex < 0)
+	  return XML_ERROR_NO_MEMORY;
+	dtd.scaffIndex[dtd.scaffLevel] = myindex;
+	dtd.scaffLevel++;
+	dtd.scaffold[myindex].type = XML_CTYPE_SEQ;
+      }
+      break;
+    case XML_ROLE_GROUP_SEQUENCE:
+      if (groupConnector[prologState.level] == '|')
+	return XML_ERROR_SYNTAX;
+      groupConnector[prologState.level] = ',';
+      break;
+    case XML_ROLE_GROUP_CHOICE:
+      if (groupConnector[prologState.level] == ',')
+	return XML_ERROR_SYNTAX;
+      if (dtd.in_eldecl
+	  && ! groupConnector[prologState.level]
+	  && dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type != XML_CTYPE_MIXED
+	  ) {
+	dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_CHOICE;
+      }
+      groupConnector[prologState.level] = '|';
+      break;
+    case XML_ROLE_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+    case XML_ROLE_INNER_PARAM_ENTITY_REF:
+      if (paramEntityParsing
+	  && (dtd.complete || role == XML_ROLE_INNER_PARAM_ENTITY_REF)) {
+	const XML_Char *name;
+	ENTITY *entity;
+	name = poolStoreString(&dtd.pool, enc,
+				s + enc->minBytesPerChar,
+				next - enc->minBytesPerChar);
+	if (!name)
+	  return XML_ERROR_NO_MEMORY;
+	entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
+	poolDiscard(&dtd.pool);
+	if (!entity) {
+	  /* FIXME what to do if !dtd.complete? */
+	  return XML_ERROR_UNDEFINED_ENTITY;
+	}
+	if (entity->open)
+	  return XML_ERROR_RECURSIVE_ENTITY_REF;
+	if (entity->textPtr) {
+	  enum XML_Error result;
+	  result = processInternalParamEntity(parser, entity);
+	  if (result != XML_ERROR_NONE)
+	    return result;
+	  break;
+	}
+	if (role == XML_ROLE_INNER_PARAM_ENTITY_REF)
+	  return XML_ERROR_PARAM_ENTITY_REF;
+	if (externalEntityRefHandler) {
+	  dtd.complete = 0;
+	  entity->open = 1;
+	  if (!externalEntityRefHandler(externalEntityRefHandlerArg,
+					0,
+					entity->base,
+					entity->systemId,
+					entity->publicId)) {
+	    entity->open = 0;
+	    return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
+	  }
+	  entity->open = 0;
+	  if (dtd.complete)
+	    break;
+	}
+      }
+#endif /* XML_DTD */
+      if (!dtd.standalone
+	  && notStandaloneHandler
+	  && !notStandaloneHandler(handlerArg))
+	return XML_ERROR_NOT_STANDALONE;
+      dtd.complete = 0;
+      if (defaultHandler)
+	reportDefault(parser, enc, s, next);
+      break;
+
+      /* Element declaration stuff */
+
+    case XML_ROLE_ELEMENT_NAME:
+      if (elementDeclHandler) {
+	declElementType = getElementType(parser, enc, s, next);
+	if (! declElementType)
+	  return XML_ERROR_NO_MEMORY;
+	dtd.scaffLevel = 0;
+	dtd.scaffCount = 0;
+	dtd.in_eldecl = 1;
+      }
+      break;
+
+    case XML_ROLE_CONTENT_ANY:
+    case XML_ROLE_CONTENT_EMPTY:
+      if (dtd.in_eldecl) {
+	if (elementDeclHandler) {
+	  XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
+	  if (! content)
+	    return XML_ERROR_NO_MEMORY;
+	  content->quant = XML_CQUANT_NONE;
+	  content->name = 0;
+	  content->numchildren = 0;
+	  content->children = 0;
+	  content->type = ((role == XML_ROLE_CONTENT_ANY) ?
+			   XML_CTYPE_ANY :
+			   XML_CTYPE_EMPTY);
+	  *eventEndPP = s;
+	  elementDeclHandler(handlerArg, declElementType->name, content);
+	}
+	dtd.in_eldecl = 0;
+      }
+      break;
+      
+    case XML_ROLE_CONTENT_PCDATA:
+      if (dtd.in_eldecl) {
+	dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]].type = XML_CTYPE_MIXED;
+      }
+      break;
+
+    case XML_ROLE_CONTENT_ELEMENT:
+      quant = XML_CQUANT_NONE;
+      goto elementContent;
+    case XML_ROLE_CONTENT_ELEMENT_OPT:
+      quant = XML_CQUANT_OPT;
+      goto elementContent;
+    case XML_ROLE_CONTENT_ELEMENT_REP:
+      quant = XML_CQUANT_REP;
+      goto elementContent;
+    case XML_ROLE_CONTENT_ELEMENT_PLUS:
+      quant = XML_CQUANT_PLUS;
+    elementContent:
+      if (dtd.in_eldecl)
+	{
+	  ELEMENT_TYPE *el;
+	  const char *nxt = quant == XML_CQUANT_NONE ? next : next - 1;
+	  int myindex = nextScaffoldPart(parser);
+	  if (myindex < 0)
+	    return XML_ERROR_NO_MEMORY;
+	  dtd.scaffold[myindex].type = XML_CTYPE_NAME;
+	  dtd.scaffold[myindex].quant = quant;
+	  el = getElementType(parser, enc, s, nxt);
+	  if (! el)
+	    return XML_ERROR_NO_MEMORY;
+	  dtd.scaffold[myindex].name = el->name;
+	  dtd.contentStringLen +=  nxt - s + 1;
+	}
+      break;
+
+    case XML_ROLE_GROUP_CLOSE:
+      quant = XML_CQUANT_NONE;
+      goto closeGroup;
+    case XML_ROLE_GROUP_CLOSE_OPT:
+      quant = XML_CQUANT_OPT;
+      goto closeGroup;
+    case XML_ROLE_GROUP_CLOSE_REP:
+      quant = XML_CQUANT_REP;
+      goto closeGroup;
+    case XML_ROLE_GROUP_CLOSE_PLUS:
+      quant = XML_CQUANT_PLUS;
+    closeGroup:
+      if (dtd.in_eldecl) {
+	dtd.scaffLevel--;
+	dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel]].quant = quant;
+	if (dtd.scaffLevel == 0) {
+	  if (elementDeclHandler) {
+	    XML_Content *model = build_model(parser);
+	    if (! model)
+	      return XML_ERROR_NO_MEMORY;
+	    *eventEndPP = s;
+	    elementDeclHandler(handlerArg, declElementType->name, model);
+	  }
+	  dtd.in_eldecl = 0;
+	  dtd.contentStringLen = 0;
+	}
+      }
+      break;
+      /* End element declaration stuff */
+
+    case XML_ROLE_NONE:
+      switch (tok) {
+      case XML_TOK_PI:
+	if (!reportProcessingInstruction(parser, enc, s, next))
+	  return XML_ERROR_NO_MEMORY;
+	break;
+      case XML_TOK_COMMENT:
+	if (!reportComment(parser, enc, s, next))
+	  return XML_ERROR_NO_MEMORY;
+	break;
+      }
+      break;
+    }
+    if (defaultHandler) {
+      switch (tok) {
+      case XML_TOK_PI:
+      case XML_TOK_COMMENT:
+      case XML_TOK_BOM:
+      case XML_TOK_XML_DECL:
+#ifdef XML_DTD
+      case XML_TOK_IGNORE_SECT:
+#endif /* XML_DTD */
+      case XML_TOK_PARAM_ENTITY_REF:
+	break;
+      default:
+#ifdef XML_DTD
+	if (role != XML_ROLE_IGNORE_SECT)
+#endif /* XML_DTD */
+	  reportDefault(parser, enc, s, next);
+      }
+    }
+    s = next;
+    tok = XmlPrologTok(enc, s, end, &next);
+  }
+  /* not reached */
+}
+
+static
+enum XML_Error epilogProcessor(XML_Parser parser,
+			       const char *s,
+			       const char *end,
+			       const char **nextPtr)
+{
+  processor = epilogProcessor;
+  eventPtr = s;
+  for (;;) {
+    const char *next;
+    int tok = XmlPrologTok(encoding, s, end, &next);
+    eventEndPtr = next;
+    switch (tok) {
+    case -XML_TOK_PROLOG_S:
+      if (defaultHandler) {
+	eventEndPtr = end;
+	reportDefault(parser, encoding, s, end);
+      }
+      /* fall through */
+    case XML_TOK_NONE:
+      if (nextPtr)
+	*nextPtr = end;
+      return XML_ERROR_NONE;
+    case XML_TOK_PROLOG_S:
+      if (defaultHandler)
+	reportDefault(parser, encoding, s, next);
+      break;
+    case XML_TOK_PI:
+      if (!reportProcessingInstruction(parser, encoding, s, next))
+	return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_COMMENT:
+      if (!reportComment(parser, encoding, s, next))
+	return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_INVALID:
+      eventPtr = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      return XML_ERROR_UNCLOSED_TOKEN;
+    case XML_TOK_PARTIAL_CHAR:
+      if (nextPtr) {
+	*nextPtr = s;
+	return XML_ERROR_NONE;
+      }
+      return XML_ERROR_PARTIAL_CHAR;
+    default:
+      return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
+    }
+    eventPtr = s = next;
+  }
+}
+
+#ifdef XML_DTD
+
+static enum XML_Error
+processInternalParamEntity(XML_Parser parser, ENTITY *entity)
+{
+  const char *s, *end, *next;
+  int tok;
+  enum XML_Error result;
+  OPEN_INTERNAL_ENTITY openEntity;
+  entity->open = 1;
+  openEntity.next = openInternalEntities;
+  openInternalEntities = &openEntity;
+  openEntity.entity = entity;
+  openEntity.internalEventPtr = 0;
+  openEntity.internalEventEndPtr = 0;
+  s = (char *)entity->textPtr;
+  end = (char *)(entity->textPtr + entity->textLen);
+  tok = XmlPrologTok(internalEncoding, s, end, &next);
+  result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
+  entity->open = 0;
+  openInternalEntities = openEntity.next;
+  return result;
+}
+
+#endif /* XML_DTD */
+
+static
+enum XML_Error errorProcessor(XML_Parser parser,
+			      const char *s,
+			      const char *end,
+			      const char **nextPtr)
+{
+  return errorCode;
+}
+
+static enum XML_Error
+storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
+		    const char *ptr, const char *end,
+		    STRING_POOL *pool)
+{
+  enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
+  if (result)
+    return result;
+  if (!isCdata && poolLength(pool) && poolLastChar(pool) == 0x20)
+    poolChop(pool);
+  if (!poolAppendChar(pool, XML_T('\0')))
+    return XML_ERROR_NO_MEMORY;
+  return XML_ERROR_NONE;
+}
+
+static enum XML_Error
+appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
+		     const char *ptr, const char *end,
+		     STRING_POOL *pool)
+{
+  for (;;) {
+    const char *next;
+    int tok = XmlAttributeValueTok(enc, ptr, end, &next);
+    switch (tok) {
+    case XML_TOK_NONE:
+      return XML_ERROR_NONE;
+    case XML_TOK_INVALID:
+      if (enc == encoding)
+	eventPtr = next;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_PARTIAL:
+      if (enc == encoding)
+	eventPtr = ptr;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_CHAR_REF:
+      {
+	XML_Char buf[XML_ENCODE_MAX];
+	int i;
+	int n = XmlCharRefNumber(enc, ptr);
+	if (n < 0) {
+	  if (enc == encoding)
+	    eventPtr = ptr;
+      	  return XML_ERROR_BAD_CHAR_REF;
+	}
+	if (!isCdata
+	    && n == 0x20 /* space */
+	    && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+	  break;
+	n = XmlEncode(n, (ICHAR *)buf);
+	if (!n) {
+	  if (enc == encoding)
+	    eventPtr = ptr;
+	  return XML_ERROR_BAD_CHAR_REF;
+	}
+	for (i = 0; i < n; i++) {
+	  if (!poolAppendChar(pool, buf[i]))
+	    return XML_ERROR_NO_MEMORY;
+	}
+      }
+      break;
+    case XML_TOK_DATA_CHARS:
+      if (!poolAppend(pool, enc, ptr, next))
+	return XML_ERROR_NO_MEMORY;
+      break;
+      break;
+    case XML_TOK_TRAILING_CR:
+      next = ptr + enc->minBytesPerChar;
+      /* fall through */
+    case XML_TOK_ATTRIBUTE_VALUE_S:
+    case XML_TOK_DATA_NEWLINE:
+      if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == 0x20))
+	break;
+      if (!poolAppendChar(pool, 0x20))
+	return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_ENTITY_REF:
+      {
+	const XML_Char *name;
+	ENTITY *entity;
+	XML_Char ch = XmlPredefinedEntityName(enc,
+					      ptr + enc->minBytesPerChar,
+					      next - enc->minBytesPerChar);
+	if (ch) {
+	  if (!poolAppendChar(pool, ch))
+  	    return XML_ERROR_NO_MEMORY;
+	  break;
+	}
+	name = poolStoreString(&temp2Pool, enc,
+			       ptr + enc->minBytesPerChar,
+			       next - enc->minBytesPerChar);
+	if (!name)
+	  return XML_ERROR_NO_MEMORY;
+	entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
+	poolDiscard(&temp2Pool);
+	if (!entity) {
+	  if (dtd.complete) {
+	    if (enc == encoding)
+	      eventPtr = ptr;
+	    return XML_ERROR_UNDEFINED_ENTITY;
+	  }
+	}
+	else if (entity->open) {
+	  if (enc == encoding)
+	    eventPtr = ptr;
+	  return XML_ERROR_RECURSIVE_ENTITY_REF;
+	}
+	else if (entity->notation) {
+	  if (enc == encoding)
+	    eventPtr = ptr;
+	  return XML_ERROR_BINARY_ENTITY_REF;
+	}
+	else if (!entity->textPtr) {
+	  if (enc == encoding)
+	    eventPtr = ptr;
+  	  return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF;
+	}
+	else {
+	  enum XML_Error result;
+	  const XML_Char *textEnd = entity->textPtr + entity->textLen;
+	  entity->open = 1;
+	  result = appendAttributeValue(parser, internalEncoding, isCdata, (char *)entity->textPtr, (char *)textEnd, pool);
+	  entity->open = 0;
+	  if (result)
+	    return result;
+	}
+      }
+      break;
+    default:
+      if (enc == encoding)
+	eventPtr = ptr;
+      return XML_ERROR_UNEXPECTED_STATE;
+    }
+    ptr = next;
+  }
+  /* not reached */
+}
+
+static
+enum XML_Error storeEntityValue(XML_Parser parser,
+				const ENCODING *enc,
+				const char *entityTextPtr,
+				const char *entityTextEnd)
+{
+  STRING_POOL *pool = &(dtd.pool);
+  for (;;) {
+    const char *next;
+    int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
+    switch (tok) {
+    case XML_TOK_PARAM_ENTITY_REF:
+#ifdef XML_DTD
+      if (parentParser || enc != encoding) {
+	enum XML_Error result;
+	const XML_Char *name;
+	ENTITY *entity;
+	name = poolStoreString(&tempPool, enc,
+			       entityTextPtr + enc->minBytesPerChar,
+			       next - enc->minBytesPerChar);
+	if (!name)
+	  return XML_ERROR_NO_MEMORY;
+	entity = (ENTITY *)lookup(&dtd.paramEntities, name, 0);
+	poolDiscard(&tempPool);
+	if (!entity) {
+	  if (enc == encoding)
+	    eventPtr = entityTextPtr;
+	  return XML_ERROR_UNDEFINED_ENTITY;
+	}
+	if (entity->open) {
+	  if (enc == encoding)
+	    eventPtr = entityTextPtr;
+	  return XML_ERROR_RECURSIVE_ENTITY_REF;
+	}
+	if (entity->systemId) {
+	  if (enc == encoding)
+	    eventPtr = entityTextPtr;
+	  return XML_ERROR_PARAM_ENTITY_REF;
+	}
+	entity->open = 1;
+	result = storeEntityValue(parser,
+				  internalEncoding,
+				  (char *)entity->textPtr,
+				  (char *)(entity->textPtr + entity->textLen));
+	entity->open = 0;
+	if (result)
+	  return result;
+	break;
+      }
+#endif /* XML_DTD */
+      eventPtr = entityTextPtr;
+      return XML_ERROR_SYNTAX;
+    case XML_TOK_NONE:
+      return XML_ERROR_NONE;
+    case XML_TOK_ENTITY_REF:
+    case XML_TOK_DATA_CHARS:
+      if (!poolAppend(pool, enc, entityTextPtr, next))
+	return XML_ERROR_NO_MEMORY;
+      break;
+    case XML_TOK_TRAILING_CR:
+      next = entityTextPtr + enc->minBytesPerChar;
+      /* fall through */
+    case XML_TOK_DATA_NEWLINE:
+      if (pool->end == pool->ptr && !poolGrow(pool))
+	return XML_ERROR_NO_MEMORY;
+      *(pool->ptr)++ = 0xA;
+      break;
+    case XML_TOK_CHAR_REF:
+      {
+	XML_Char buf[XML_ENCODE_MAX];
+	int i;
+	int n = XmlCharRefNumber(enc, entityTextPtr);
+	if (n < 0) {
+	  if (enc == encoding)
+	    eventPtr = entityTextPtr;
+	  return XML_ERROR_BAD_CHAR_REF;
+	}
+	n = XmlEncode(n, (ICHAR *)buf);
+	if (!n) {
+	  if (enc == encoding)
+	    eventPtr = entityTextPtr;
+	  return XML_ERROR_BAD_CHAR_REF;
+	}
+	for (i = 0; i < n; i++) {
+	  if (pool->end == pool->ptr && !poolGrow(pool))
+	    return XML_ERROR_NO_MEMORY;
+	  *(pool->ptr)++ = buf[i];
+	}
+      }
+      break;
+    case XML_TOK_PARTIAL:
+      if (enc == encoding)
+	eventPtr = entityTextPtr;
+      return XML_ERROR_INVALID_TOKEN;
+    case XML_TOK_INVALID:
+      if (enc == encoding)
+	eventPtr = next;
+      return XML_ERROR_INVALID_TOKEN;
+    default:
+      if (enc == encoding)
+	eventPtr = entityTextPtr;
+      return XML_ERROR_UNEXPECTED_STATE;
+    }
+    entityTextPtr = next;
+  }
+  /* not reached */
+}
+
+static void
+normalizeLines(XML_Char *s)
+{
+  XML_Char *p;
+  for (;; s++) {
+    if (*s == XML_T('\0'))
+      return;
+    if (*s == 0xD)
+      break;
+  }
+  p = s;
+  do {
+    if (*s == 0xD) {
+      *p++ = 0xA;
+      if (*++s == 0xA)
+        s++;
+    }
+    else
+      *p++ = *s++;
+  } while (*s);
+  *p = XML_T('\0');
+}
+
+static int
+reportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+{
+  const XML_Char *target;
+  XML_Char *data;
+  const char *tem;
+  if (!processingInstructionHandler) {
+    if (defaultHandler)
+      reportDefault(parser, enc, start, end);
+    return 1;
+  }
+  start += enc->minBytesPerChar * 2;
+  tem = start + XmlNameLength(enc, start);
+  target = poolStoreString(&tempPool, enc, start, tem);
+  if (!target)
+    return 0;
+  poolFinish(&tempPool);
+  data = poolStoreString(&tempPool, enc,
+			XmlSkipS(enc, tem),
+			end - enc->minBytesPerChar*2);
+  if (!data)
+    return 0;
+  normalizeLines(data);
+  processingInstructionHandler(handlerArg, target, data);
+  poolClear(&tempPool);
+  return 1;
+}
+
+static int
+reportComment(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+{
+  XML_Char *data;
+  if (!commentHandler) {
+    if (defaultHandler)
+      reportDefault(parser, enc, start, end);
+    return 1;
+  }
+  data = poolStoreString(&tempPool,
+                         enc,
+                         start + enc->minBytesPerChar * 4, 
+			 end - enc->minBytesPerChar * 3);
+  if (!data)
+    return 0;
+  normalizeLines(data);
+  commentHandler(handlerArg, data);
+  poolClear(&tempPool);
+  return 1;
+}
+
+static void
+reportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end)
+{
+  if (MUST_CONVERT(enc, s)) {
+    const char **eventPP;
+    const char **eventEndPP;
+    if (enc == encoding) {
+      eventPP = &eventPtr;
+      eventEndPP = &eventEndPtr;
+    }
+    else {
+      eventPP = &(openInternalEntities->internalEventPtr);
+      eventEndPP = &(openInternalEntities->internalEventEndPtr);
+    }
+    do {
+      ICHAR *dataPtr = (ICHAR *)dataBuf;
+      XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
+      *eventEndPP = s;
+      defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
+      *eventPP = s;
+    } while (s != end);
+  }
+  else
+    defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
+}
+
+
+static int
+defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata,
+		int isId, const XML_Char *value, XML_Parser parser)
+{
+  DEFAULT_ATTRIBUTE *att;
+  if (value || isId) {
+    /* The handling of default attributes gets messed up if we have
+       a default which duplicates a non-default. */
+    int i;
+    for (i = 0; i < type->nDefaultAtts; i++)
+      if (attId == type->defaultAtts[i].id)
+	return 1;
+    if (isId && !type->idAtt && !attId->xmlns)
+      type->idAtt = attId;
+  }
+  if (type->nDefaultAtts == type->allocDefaultAtts) {
+    if (type->allocDefaultAtts == 0) {
+      type->allocDefaultAtts = 8;
+      type->defaultAtts = MALLOC(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
+    }
+    else {
+      type->allocDefaultAtts *= 2;
+      type->defaultAtts = REALLOC(type->defaultAtts,
+				  type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE));
+    }
+    if (!type->defaultAtts)
+      return 0;
+  }
+  att = type->defaultAtts + type->nDefaultAtts;
+  att->id = attId;
+  att->value = value;
+  att->isCdata = isCdata;
+  if (!isCdata)
+    attId->maybeTokenized = 1;
+  type->nDefaultAtts += 1;
+  return 1;
+}
+
+static int setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
+{
+  const XML_Char *name;
+  for (name = elementType->name; *name; name++) {
+    if (*name == XML_T(':')) {
+      PREFIX *prefix;
+      const XML_Char *s;
+      for (s = elementType->name; s != name; s++) {
+	if (!poolAppendChar(&dtd.pool, *s))
+	  return 0;
+      }
+      if (!poolAppendChar(&dtd.pool, XML_T('\0')))
+	return 0;
+      prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
+      if (!prefix)
+	return 0;
+      if (prefix->name == poolStart(&dtd.pool))
+	poolFinish(&dtd.pool);
+      else
+	poolDiscard(&dtd.pool);
+      elementType->prefix = prefix;
+
+    }
+  }
+  return 1;
+}
+
+static ATTRIBUTE_ID *
+getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end)
+{
+  ATTRIBUTE_ID *id;
+  const XML_Char *name;
+  if (!poolAppendChar(&dtd.pool, XML_T('\0')))
+    return 0;
+  name = poolStoreString(&dtd.pool, enc, start, end);
+  if (!name)
+    return 0;
+  ++name;
+  id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID));
+  if (!id)
+    return 0;
+  if (id->name != name)
+    poolDiscard(&dtd.pool);
+  else {
+    poolFinish(&dtd.pool);
+    if (!ns)
+      ;
+    else if (name[0] == 'x'
+	&& name[1] == 'm'
+	&& name[2] == 'l'
+	&& name[3] == 'n'
+	&& name[4] == 's'
+	&& (name[5] == XML_T('\0') || name[5] == XML_T(':'))) {
+      if (name[5] == '\0')
+	id->prefix = &dtd.defaultPrefix;
+      else
+	id->prefix = (PREFIX *)lookup(&dtd.prefixes, name + 6, sizeof(PREFIX));
+      id->xmlns = 1;
+    }
+    else {
+      int i;
+      for (i = 0; name[i]; i++) {
+	if (name[i] == XML_T(':')) {
+	  int j;
+	  for (j = 0; j < i; j++) {
+	    if (!poolAppendChar(&dtd.pool, name[j]))
+	      return 0;
+	  }
+	  if (!poolAppendChar(&dtd.pool, XML_T('\0')))
+	    return 0;
+	  id->prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&dtd.pool), sizeof(PREFIX));
+	  if (id->prefix->name == poolStart(&dtd.pool))
+	    poolFinish(&dtd.pool);
+	  else
+	    poolDiscard(&dtd.pool);
+	  break;
+	}
+      }
+    }
+  }
+  return id;
+}
+
+#define CONTEXT_SEP XML_T('\f')
+
+static
+const XML_Char *getContext(XML_Parser parser)
+{
+  HASH_TABLE_ITER iter;
+  int needSep = 0;
+
+  if (dtd.defaultPrefix.binding) {
+    int i;
+    int len;
+    if (!poolAppendChar(&tempPool, XML_T('=')))
+      return 0;
+    len = dtd.defaultPrefix.binding->uriLen;
+    if (namespaceSeparator != XML_T('\0'))
+      len--;
+    for (i = 0; i < len; i++)
+      if (!poolAppendChar(&tempPool, dtd.defaultPrefix.binding->uri[i]))
+  	return 0;
+    needSep = 1;
+  }
+
+  hashTableIterInit(&iter, &(dtd.prefixes));
+  for (;;) {
+    int i;
+    int len;
+    const XML_Char *s;
+    PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
+    if (!prefix)
+      break;
+    if (!prefix->binding)
+      continue;
+    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+      return 0;
+    for (s = prefix->name; *s; s++)
+      if (!poolAppendChar(&tempPool, *s))
+        return 0;
+    if (!poolAppendChar(&tempPool, XML_T('=')))
+      return 0;
+    len = prefix->binding->uriLen;
+    if (namespaceSeparator != XML_T('\0'))
+      len--;
+    for (i = 0; i < len; i++)
+      if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
+        return 0;
+    needSep = 1;
+  }
+
+
+  hashTableIterInit(&iter, &(dtd.generalEntities));
+  for (;;) {
+    const XML_Char *s;
+    ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
+    if (!e)
+      break;
+    if (!e->open)
+      continue;
+    if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
+      return 0;
+    for (s = e->name; *s; s++)
+      if (!poolAppendChar(&tempPool, *s))
+        return 0;
+    needSep = 1;
+  }
+
+  if (!poolAppendChar(&tempPool, XML_T('\0')))
+    return 0;
+  return tempPool.start;
+}
+
+static
+int setContext(XML_Parser parser, const XML_Char *context)
+{
+  const XML_Char *s = context;
+
+  while (*context != XML_T('\0')) {
+    if (*s == CONTEXT_SEP || *s == XML_T('\0')) {
+      ENTITY *e;
+      if (!poolAppendChar(&tempPool, XML_T('\0')))
+	return 0;
+      e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0);
+      if (e)
+	e->open = 1;
+      if (*s != XML_T('\0'))
+	s++;
+      context = s;
+      poolDiscard(&tempPool);
+    }
+    else if (*s == '=') {
+      PREFIX *prefix;
+      if (poolLength(&tempPool) == 0)
+	prefix = &dtd.defaultPrefix;
+      else {
+	if (!poolAppendChar(&tempPool, XML_T('\0')))
+	  return 0;
+	prefix = (PREFIX *)lookup(&dtd.prefixes, poolStart(&tempPool), sizeof(PREFIX));
+	if (!prefix)
+	  return 0;
+        if (prefix->name == poolStart(&tempPool)) {
+	  prefix->name = poolCopyString(&dtd.pool, prefix->name);
+	  if (!prefix->name)
+	    return 0;
+	}
+	poolDiscard(&tempPool);
+      }
+      for (context = s + 1; *context != CONTEXT_SEP && *context != XML_T('\0'); context++)
+        if (!poolAppendChar(&tempPool, *context))
+          return 0;
+      if (!poolAppendChar(&tempPool, XML_T('\0')))
+	return 0;
+      if (!addBinding(parser, prefix, 0, poolStart(&tempPool), &inheritedBindings))
+	return 0;
+      poolDiscard(&tempPool);
+      if (*context != XML_T('\0'))
+	++context;
+      s = context;
+    }
+    else {
+      if (!poolAppendChar(&tempPool, *s))
+	return 0;
+      s++;
+    }
+  }
+  return 1;
+}
+
+
+static
+void normalizePublicId(XML_Char *publicId)
+{
+  XML_Char *p = publicId;
+  XML_Char *s;
+  for (s = publicId; *s; s++) {
+    switch (*s) {
+    case 0x20:
+    case 0xD:
+    case 0xA:
+      if (p != publicId && p[-1] != 0x20)
+	*p++ = 0x20;
+      break;
+    default:
+      *p++ = *s;
+    }
+  }
+  if (p != publicId && p[-1] == 0x20)
+    --p;
+  *p = XML_T('\0');
+}
+
+static int dtdInit(DTD *p, XML_Parser parser)
+{
+  XML_Memory_Handling_Suite *ms = &((Parser *) parser)->m_mem; 
+  poolInit(&(p->pool), ms);
+  hashTableInit(&(p->generalEntities), ms);
+  hashTableInit(&(p->elementTypes), ms);
+  hashTableInit(&(p->attributeIds), ms);
+  hashTableInit(&(p->prefixes), ms);
+  p->complete = 1;
+  p->standalone = 0;
+#ifdef XML_DTD
+  hashTableInit(&(p->paramEntities), ms);
+#endif /* XML_DTD */
+  p->defaultPrefix.name = 0;
+  p->defaultPrefix.binding = 0;
+
+  p->in_eldecl = 0;
+  p->scaffIndex = 0;
+  p->scaffLevel = 0;
+  p->scaffold = 0;
+  p->contentStringLen = 0;
+  p->scaffSize = 0;
+  p->scaffCount = 0;
+
+  return 1;
+}
+
+#ifdef XML_DTD
+
+static void dtdSwap(DTD *p1, DTD *p2)
+{
+  DTD tem;
+  memcpy(&tem, p1, sizeof(DTD));
+  memcpy(p1, p2, sizeof(DTD));
+  memcpy(p2, &tem, sizeof(DTD));
+}
+
+#endif /* XML_DTD */
+
+static void dtdDestroy(DTD *p, XML_Parser parser)
+{
+  HASH_TABLE_ITER iter;
+  hashTableIterInit(&iter, &(p->elementTypes));
+  for (;;) {
+    ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+    if (!e)
+      break;
+    if (e->allocDefaultAtts != 0)
+      FREE(e->defaultAtts);
+  }
+  hashTableDestroy(&(p->generalEntities));
+#ifdef XML_DTD
+  hashTableDestroy(&(p->paramEntities));
+#endif /* XML_DTD */
+  hashTableDestroy(&(p->elementTypes));
+  hashTableDestroy(&(p->attributeIds));
+  hashTableDestroy(&(p->prefixes));
+  poolDestroy(&(p->pool));
+  if (p->scaffIndex)
+    FREE(p->scaffIndex);
+  if (p->scaffold)
+    FREE(p->scaffold);
+}
+
+/* Do a deep copy of the DTD.  Return 0 for out of memory; non-zero otherwise.
+The new DTD has already been initialized. */
+
+static int dtdCopy(DTD *newDtd, const DTD *oldDtd, XML_Parser parser)
+{
+  HASH_TABLE_ITER iter;
+
+  /* Copy the prefix table. */
+
+  hashTableIterInit(&iter, &(oldDtd->prefixes));
+  for (;;) {
+    const XML_Char *name;
+    const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
+    if (!oldP)
+      break;
+    name = poolCopyString(&(newDtd->pool), oldP->name);
+    if (!name)
+      return 0;
+    if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
+      return 0;
+  }
+
+  hashTableIterInit(&iter, &(oldDtd->attributeIds));
+
+  /* Copy the attribute id table. */
+
+  for (;;) {
+    ATTRIBUTE_ID *newA;
+    const XML_Char *name;
+    const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter);
+
+    if (!oldA)
+      break;
+    /* Remember to allocate the scratch byte before the name. */
+    if (!poolAppendChar(&(newDtd->pool), XML_T('\0')))
+      return 0;
+    name = poolCopyString(&(newDtd->pool), oldA->name);
+    if (!name)
+      return 0;
+    ++name;
+    newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID));
+    if (!newA)
+      return 0;
+    newA->maybeTokenized = oldA->maybeTokenized;
+    if (oldA->prefix) {
+      newA->xmlns = oldA->xmlns;
+      if (oldA->prefix == &oldDtd->defaultPrefix)
+	newA->prefix = &newDtd->defaultPrefix;
+      else
+	newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldA->prefix->name, 0);
+    }
+  }
+
+  /* Copy the element type table. */
+
+  hashTableIterInit(&iter, &(oldDtd->elementTypes));
+
+  for (;;) {
+    int i;
+    ELEMENT_TYPE *newE;
+    const XML_Char *name;
+    const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter);
+    if (!oldE)
+      break;
+    name = poolCopyString(&(newDtd->pool), oldE->name);
+    if (!name)
+      return 0;
+    newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE));
+    if (!newE)
+      return 0;
+    if (oldE->nDefaultAtts) {
+      newE->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
+      if (!newE->defaultAtts)
+	return 0;
+    }
+    if (oldE->idAtt)
+      newE->idAtt = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
+    newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
+    if (oldE->prefix)
+      newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes), oldE->prefix->name, 0);
+    for (i = 0; i < newE->nDefaultAtts; i++) {
+      newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0);
+      newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata;
+      if (oldE->defaultAtts[i].value) {
+	newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value);
+	if (!newE->defaultAtts[i].value)
+  	  return 0;
+      }
+      else
+	newE->defaultAtts[i].value = 0;
+    }
+  }
+
+  /* Copy the entity tables. */
+  if (!copyEntityTable(&(newDtd->generalEntities),
+		       &(newDtd->pool),
+		       &(oldDtd->generalEntities), parser))
+      return 0;
+
+#ifdef XML_DTD
+  if (!copyEntityTable(&(newDtd->paramEntities),
+		       &(newDtd->pool),
+		       &(oldDtd->paramEntities), parser))
+      return 0;
+#endif /* XML_DTD */
+
+  newDtd->complete = oldDtd->complete;
+  newDtd->standalone = oldDtd->standalone;
+
+  /* Don't want deep copying for scaffolding */
+  newDtd->in_eldecl = oldDtd->in_eldecl;
+  newDtd->scaffold = oldDtd->scaffold;
+  newDtd->contentStringLen = oldDtd->contentStringLen;
+  newDtd->scaffSize = oldDtd->scaffSize;
+  newDtd->scaffLevel = oldDtd->scaffLevel;
+  newDtd->scaffIndex = oldDtd->scaffIndex;
+
+  return 1;
+}  /* End dtdCopy */
+
+static int copyEntityTable(HASH_TABLE *newTable,
+			   STRING_POOL *newPool,
+			   const HASH_TABLE *oldTable,
+			   XML_Parser parser)
+{
+  HASH_TABLE_ITER iter;
+  const XML_Char *cachedOldBase = 0;
+  const XML_Char *cachedNewBase = 0;
+
+  hashTableIterInit(&iter, oldTable);
+
+  for (;;) {
+    ENTITY *newE;
+    const XML_Char *name;
+    const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
+    if (!oldE)
+      break;
+    name = poolCopyString(newPool, oldE->name);
+    if (!name)
+      return 0;
+    newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
+    if (!newE)
+      return 0;
+    if (oldE->systemId) {
+      const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
+      if (!tem)
+	return 0;
+      newE->systemId = tem;
+      if (oldE->base) {
+	if (oldE->base == cachedOldBase)
+	  newE->base = cachedNewBase;
+	else {
+	  cachedOldBase = oldE->base;
+	  tem = poolCopyString(newPool, cachedOldBase);
+	  if (!tem)
+	    return 0;
+	  cachedNewBase = newE->base = tem;
+	}
+      }
+    }
+    else {
+      const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr, oldE->textLen);
+      if (!tem)
+	return 0;
+      newE->textPtr = tem;
+      newE->textLen = oldE->textLen;
+    }
+    if (oldE->notation) {
+      const XML_Char *tem = poolCopyString(newPool, oldE->notation);
+      if (!tem)
+	return 0;
+      newE->notation = tem;
+    }
+  }
+  return 1;
+}
+
+#define INIT_SIZE 64
+
+static
+int keyeq(KEY s1, KEY s2)
+{
+  for (; *s1 == *s2; s1++, s2++)
+    if (*s1 == 0)
+      return 1;
+  return 0;
+}
+
+static
+unsigned long hash(KEY s)
+{
+  unsigned long h = 0;
+  while (*s)
+    h = (h << 5) + h + (unsigned char)*s++;
+  return h;
+}
+
+static
+NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
+{
+  size_t i;
+  if (table->size == 0) {
+    size_t tsize;
+
+    if (!createSize)
+      return 0;
+    tsize = INIT_SIZE * sizeof(NAMED *);
+    table->v = table->mem->malloc_fcn(tsize);
+    if (!table->v)
+      return 0;
+    memset(table->v, 0, tsize);
+    table->size = INIT_SIZE;
+    table->usedLim = INIT_SIZE / 2;
+    i = hash(name) & (table->size - 1);
+  }
+  else {
+    unsigned long h = hash(name);
+    for (i = h & (table->size - 1);
+         table->v[i];
+         i == 0 ? i = table->size - 1 : --i) {
+      if (keyeq(name, table->v[i]->name))
+	return table->v[i];
+    }
+    if (!createSize)
+      return 0;
+    if (table->used == table->usedLim) {
+      /* check for overflow */
+      size_t newSize = table->size * 2;
+      size_t tsize = newSize * sizeof(NAMED *);
+      NAMED **newV = table->mem->malloc_fcn(tsize);
+      if (!newV)
+	return 0;
+      memset(newV, 0, tsize);
+      for (i = 0; i < table->size; i++)
+	if (table->v[i]) {
+	  size_t j;
+	  for (j = hash(table->v[i]->name) & (newSize - 1);
+	       newV[j];
+	       j == 0 ? j = newSize - 1 : --j)
+	    ;
+	  newV[j] = table->v[i];
+	}
+      table->mem->free_fcn(table->v);
+      table->v = newV;
+      table->size = newSize;
+      table->usedLim = newSize/2;
+      for (i = h & (table->size - 1);
+	   table->v[i];
+	   i == 0 ? i = table->size - 1 : --i)
+	;
+    }
+  }
+  table->v[i] = table->mem->malloc_fcn(createSize);
+  if (!table->v[i])
+    return 0;
+  memset(table->v[i], 0, createSize);
+  table->v[i]->name = name;
+  (table->used)++;
+  return table->v[i];
+}
+
+static
+void hashTableDestroy(HASH_TABLE *table)
+{
+  size_t i;
+  for (i = 0; i < table->size; i++) {
+    NAMED *p = table->v[i];
+    if (p)
+      table->mem->free_fcn(p);
+  }
+  if (table->v)
+    table->mem->free_fcn(table->v);
+}
+
+static
+void hashTableInit(HASH_TABLE *p, XML_Memory_Handling_Suite *ms)
+{
+  p->size = 0;
+  p->usedLim = 0;
+  p->used = 0;
+  p->v = 0;
+  p->mem = ms;
+}
+
+static
+void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
+{
+  iter->p = table->v;
+  iter->end = iter->p + table->size;
+}
+
+static
+NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
+{
+  while (iter->p != iter->end) {
+    NAMED *tem = *(iter->p)++;
+    if (tem)
+      return tem;
+  }
+  return 0;
+}
+
+
+static
+void poolInit(STRING_POOL *pool, XML_Memory_Handling_Suite *ms)
+{
+  pool->blocks = 0;
+  pool->freeBlocks = 0;
+  pool->start = 0;
+  pool->ptr = 0;
+  pool->end = 0;
+  pool->mem = ms;
+}
+
+static
+void poolClear(STRING_POOL *pool)
+{
+  if (!pool->freeBlocks)
+    pool->freeBlocks = pool->blocks;
+  else {
+    BLOCK *p = pool->blocks;
+    while (p) {
+      BLOCK *tem = p->next;
+      p->next = pool->freeBlocks;
+      pool->freeBlocks = p;
+      p = tem;
+    }
+  }
+  pool->blocks = 0;
+  pool->start = 0;
+  pool->ptr = 0;
+  pool->end = 0;
+}
+
+static
+void poolDestroy(STRING_POOL *pool)
+{
+  BLOCK *p = pool->blocks;
+  while (p) {
+    BLOCK *tem = p->next;
+    pool->mem->free_fcn(p);
+    p = tem;
+  }
+  pool->blocks = 0;
+  p = pool->freeBlocks;
+  while (p) {
+    BLOCK *tem = p->next;
+    pool->mem->free_fcn(p);
+    p = tem;
+  }
+  pool->freeBlocks = 0;
+  pool->ptr = 0;
+  pool->start = 0;
+  pool->end = 0;
+}
+
+static
+XML_Char *poolAppend(STRING_POOL *pool, const ENCODING *enc,
+		     const char *ptr, const char *end)
+{
+  if (!pool->ptr && !poolGrow(pool))
+    return 0;
+  for (;;) {
+    XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
+    if (ptr == end)
+      break;
+    if (!poolGrow(pool))
+      return 0;
+  }
+  return pool->start;
+}
+
+static const XML_Char *poolCopyString(STRING_POOL *pool, const XML_Char *s)
+{
+  do {
+    if (!poolAppendChar(pool, *s))
+      return 0;
+  } while (*s++);
+  s = pool->start;
+  poolFinish(pool);
+  return s;
+}
+
+static const XML_Char *poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
+{
+  if (!pool->ptr && !poolGrow(pool))
+    return 0;
+  for (; n > 0; --n, s++) {
+    if (!poolAppendChar(pool, *s))
+      return 0;
+
+  }
+  s = pool->start;
+  poolFinish(pool);
+  return s;
+}
+
+static
+const XML_Char *poolAppendString(STRING_POOL *pool, const XML_Char *s)
+{
+  while (*s) {
+    if (!poolAppendChar(pool, *s))
+      return 0;
+    s++;
+  } 
+  return pool->start;
+}  /* End poolAppendString */
+
+static
+XML_Char *poolStoreString(STRING_POOL *pool, const ENCODING *enc,
+			  const char *ptr, const char *end)
+{
+  if (!poolAppend(pool, enc, ptr, end))
+    return 0;
+  if (pool->ptr == pool->end && !poolGrow(pool))
+    return 0;
+  *(pool->ptr)++ = 0;
+  return pool->start;
+}
+
+static
+int poolGrow(STRING_POOL *pool)
+{
+  if (pool->freeBlocks) {
+    if (pool->start == 0) {
+      pool->blocks = pool->freeBlocks;
+      pool->freeBlocks = pool->freeBlocks->next;
+      pool->blocks->next = 0;
+      pool->start = pool->blocks->s;
+      pool->end = pool->start + pool->blocks->size;
+      pool->ptr = pool->start;
+      return 1;
+    }
+    if (pool->end - pool->start < pool->freeBlocks->size) {
+      BLOCK *tem = pool->freeBlocks->next;
+      pool->freeBlocks->next = pool->blocks;
+      pool->blocks = pool->freeBlocks;
+      pool->freeBlocks = tem;
+      memcpy(pool->blocks->s, pool->start, (pool->end - pool->start) * sizeof(XML_Char));
+      pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+      pool->start = pool->blocks->s;
+      pool->end = pool->start + pool->blocks->size;
+      return 1;
+    }
+  }
+  if (pool->blocks && pool->start == pool->blocks->s) {
+    int blockSize = (pool->end - pool->start)*2;
+    pool->blocks = pool->mem->realloc_fcn(pool->blocks, offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
+    if (!pool->blocks)
+      return 0;
+    pool->blocks->size = blockSize;
+    pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
+    pool->start = pool->blocks->s;
+    pool->end = pool->start + blockSize;
+  }
+  else {
+    BLOCK *tem;
+    int blockSize = pool->end - pool->start;
+    if (blockSize < INIT_BLOCK_SIZE)
+      blockSize = INIT_BLOCK_SIZE;
+    else
+      blockSize *= 2;
+    tem = pool->mem->malloc_fcn(offsetof(BLOCK, s) + blockSize * sizeof(XML_Char));
+    if (!tem)
+      return 0;
+    tem->size = blockSize;
+    tem->next = pool->blocks;
+    pool->blocks = tem;
+    if (pool->ptr != pool->start)
+      memcpy(tem->s, pool->start, (pool->ptr - pool->start) * sizeof(XML_Char));
+    pool->ptr = tem->s + (pool->ptr - pool->start);
+    pool->start = tem->s;
+    pool->end = tem->s + blockSize;
+  }
+  return 1;
+}
+
+static int
+nextScaffoldPart(XML_Parser parser)
+{
+  CONTENT_SCAFFOLD * me;
+  int next;
+
+  if (! dtd.scaffIndex) {
+    dtd.scaffIndex = MALLOC(groupSize * sizeof(int));
+    if (! dtd.scaffIndex)
+      return -1;
+    dtd.scaffIndex[0] = 0;
+  }
+
+  if (dtd.scaffCount >= dtd.scaffSize) {
+    if (dtd.scaffold) {
+      dtd.scaffSize *= 2;
+      dtd.scaffold = (CONTENT_SCAFFOLD *) REALLOC(dtd.scaffold,
+					      dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
+    }
+    else {
+      dtd.scaffSize = 32;
+      dtd.scaffold = (CONTENT_SCAFFOLD *) MALLOC(dtd.scaffSize * sizeof(CONTENT_SCAFFOLD));
+    }
+    if (! dtd.scaffold)
+      return -1;
+  }
+  next = dtd.scaffCount++;
+  me = &dtd.scaffold[next];
+  if (dtd.scaffLevel) { 
+    CONTENT_SCAFFOLD *parent = &dtd.scaffold[dtd.scaffIndex[dtd.scaffLevel - 1]];
+    if (parent->lastchild) {
+      dtd.scaffold[parent->lastchild].nextsib = next;
+    }
+    if (! parent->childcnt)
+      parent->firstchild = next;
+    parent->lastchild = next;
+    parent->childcnt++;
+  }
+  me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
+  return next;
+}  /* End nextScaffoldPart */
+
+static void
+build_node (XML_Parser parser,
+	    int src_node,
+	    XML_Content *dest,
+	    XML_Content **contpos,
+	    char **strpos)
+{
+  dest->type = dtd.scaffold[src_node].type;
+  dest->quant = dtd.scaffold[src_node].quant;
+  if (dest->type == XML_CTYPE_NAME) {
+    const char *src;
+    dest->name = *strpos;
+    src = dtd.scaffold[src_node].name;
+    for (;;) {
+      *(*strpos)++ = *src;
+      if (! *src)
+	break;
+      src++;
+    }
+    dest->numchildren = 0;
+    dest->children = 0;
+  }
+  else {
+    unsigned int i;
+    int cn;
+    dest->numchildren = dtd.scaffold[src_node].childcnt;
+    dest->children = *contpos;
+    *contpos += dest->numchildren;
+    for (i = 0, cn = dtd.scaffold[src_node].firstchild;
+	 i < dest->numchildren;
+	 i++, cn = dtd.scaffold[cn].nextsib) {
+      build_node(parser, cn, &(dest->children[i]), contpos, strpos);
+    }
+    dest->name = 0;
+  }
+}  /* End build_node */
+
+static XML_Content *
+build_model (XML_Parser parser)
+{
+  XML_Content *ret;
+  XML_Content *cpos;
+  char * str;
+  int allocsize = dtd.scaffCount * sizeof(XML_Content) + dtd.contentStringLen;
+  
+  ret = MALLOC(allocsize);
+  if (! ret)
+    return 0;
+
+  str =  (char *) (&ret[dtd.scaffCount]);
+  cpos = &ret[1];
+
+  build_node(parser, 0, ret, &cpos, &str);
+  return ret;
+}  /* End build_model */
+
+static ELEMENT_TYPE *
+getElementType(XML_Parser parser,
+	       const ENCODING *enc,
+	       const char *ptr,
+	       const char *end)
+{
+  const XML_Char *name = poolStoreString(&dtd.pool, enc, ptr, end);
+  ELEMENT_TYPE *ret;
+
+  if (! name)
+    return 0;
+  ret = (ELEMENT_TYPE *) lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
+  if (! ret)
+    return 0;
+  if (ret->name != name)
+    poolDiscard(&dtd.pool);
+  else {
+    poolFinish(&dtd.pool);
+    if (!setElementTypePrefix(parser, ret))
+      return 0;
+  }
+  return ret;
+}  /* End getElementType */
diff --git a/external/expat/xmlrole.c b/external/expat/xmlrole.c
new file mode 100644
index 0000000..cae2462
--- /dev/null
+++ b/external/expat/xmlrole.c
@@ -0,0 +1,1275 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+static char RCSId[]
+  = "$Header: /cvsroot/ogdi/devdir/external/expat/xmlrole.c,v 1.1 2001/04/12 05:25:36 warmerda Exp $";
+
+#ifdef COMPILED_FROM_DSP
+#  include "winconfig.h"
+#else
+#  include <config.h>
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include "xmlrole.h"
+#include "ascii.h"
+
+/* Doesn't check:
+
+ that ,| are not mixed in a model group
+ content of literals
+
+*/
+
+static const char KW_ANY[] = { ASCII_A, ASCII_N, ASCII_Y, '\0' };
+static const char KW_ATTLIST[] = { ASCII_A, ASCII_T, ASCII_T, ASCII_L, ASCII_I, ASCII_S, ASCII_T, '\0' };
+static const char KW_CDATA[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_DOCTYPE[] = { ASCII_D, ASCII_O, ASCII_C, ASCII_T, ASCII_Y, ASCII_P, ASCII_E, '\0' };
+static const char KW_ELEMENT[] = { ASCII_E, ASCII_L, ASCII_E, ASCII_M, ASCII_E, ASCII_N, ASCII_T, '\0' };
+static const char KW_EMPTY[] = { ASCII_E, ASCII_M, ASCII_P, ASCII_T, ASCII_Y, '\0' };
+static const char KW_ENTITIES[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_I, ASCII_E, ASCII_S, '\0' };
+static const char KW_ENTITY[] = { ASCII_E, ASCII_N, ASCII_T, ASCII_I, ASCII_T, ASCII_Y, '\0' };
+static const char KW_FIXED[] = { ASCII_F, ASCII_I, ASCII_X, ASCII_E, ASCII_D, '\0' };
+static const char KW_ID[] = { ASCII_I, ASCII_D, '\0' };
+static const char KW_IDREF[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, '\0' };
+static const char KW_IDREFS[] = { ASCII_I, ASCII_D, ASCII_R, ASCII_E, ASCII_F, ASCII_S, '\0' };
+static const char KW_IGNORE[] = { ASCII_I, ASCII_G, ASCII_N, ASCII_O, ASCII_R, ASCII_E, '\0' };
+static const char KW_IMPLIED[] = { ASCII_I, ASCII_M, ASCII_P, ASCII_L, ASCII_I, ASCII_E, ASCII_D, '\0' };
+static const char KW_INCLUDE[] = { ASCII_I, ASCII_N, ASCII_C, ASCII_L, ASCII_U, ASCII_D, ASCII_E, '\0' };
+static const char KW_NDATA[] = { ASCII_N, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_NMTOKEN[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, '\0' };
+static const char KW_NMTOKENS[] = { ASCII_N, ASCII_M, ASCII_T, ASCII_O, ASCII_K, ASCII_E, ASCII_N, ASCII_S, '\0' };
+static const char KW_NOTATION[] = { ASCII_N, ASCII_O, ASCII_T, ASCII_A, ASCII_T, ASCII_I, ASCII_O, ASCII_N, '\0' };
+static const char KW_PCDATA[] = { ASCII_P, ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, '\0' };
+static const char KW_PUBLIC[] = { ASCII_P, ASCII_U, ASCII_B, ASCII_L, ASCII_I, ASCII_C, '\0' };
+static const char KW_REQUIRED[] = { ASCII_R, ASCII_E, ASCII_Q, ASCII_U, ASCII_I, ASCII_R, ASCII_E, ASCII_D, '\0' };
+static const char KW_SYSTEM[] = { ASCII_S, ASCII_Y, ASCII_S, ASCII_T, ASCII_E, ASCII_M, '\0' };
+
+#ifndef MIN_BYTES_PER_CHAR
+#define MIN_BYTES_PER_CHAR(enc) ((enc)->minBytesPerChar)
+#endif
+
+#ifdef XML_DTD
+#define setTopLevel(state) \
+  ((state)->handler = ((state)->documentEntity \
+                       ? internalSubset \
+                       : externalSubset1))
+#else /* not XML_DTD */
+#define setTopLevel(state) ((state)->handler = internalSubset)
+#endif /* not XML_DTD */
+
+typedef int PROLOG_HANDLER(PROLOG_STATE *state,
+			   int tok,
+			   const char *ptr,
+			   const char *end,
+			   const ENCODING *enc);
+
+static PROLOG_HANDLER
+  prolog0, prolog1, prolog2,
+  doctype0, doctype1, doctype2, doctype3, doctype4, doctype5,
+  internalSubset,
+  entity0, entity1, entity2, entity3, entity4, entity5, entity6,
+  entity7, entity8, entity9,
+  notation0, notation1, notation2, notation3, notation4,
+  attlist0, attlist1, attlist2, attlist3, attlist4, attlist5, attlist6,
+  attlist7, attlist8, attlist9,
+  element0, element1, element2, element3, element4, element5, element6,
+  element7,
+#ifdef XML_DTD
+  externalSubset0, externalSubset1,
+  condSect0, condSect1, condSect2,
+#endif /* XML_DTD */
+  declClose,
+  error;
+
+static
+int common(PROLOG_STATE *state, int tok);
+
+static
+int prolog0(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    state->handler = prolog1;
+    return XML_ROLE_NONE;
+  case XML_TOK_XML_DECL:
+    state->handler = prolog1;
+    return XML_ROLE_XML_DECL;
+  case XML_TOK_PI:
+    state->handler = prolog1;
+    return XML_ROLE_NONE;
+  case XML_TOK_COMMENT:
+    state->handler = prolog1;
+  case XML_TOK_BOM:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_OPEN:
+    if (!XmlNameMatchesAscii(enc,
+			     ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+			     end,
+			     KW_DOCTYPE))
+      break;
+    state->handler = doctype0;
+    return XML_ROLE_NONE;
+  case XML_TOK_INSTANCE_START:
+    state->handler = error;
+    return XML_ROLE_INSTANCE_START;
+  }
+  return common(state, tok);
+}
+
+static
+int prolog1(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_PI:
+  case XML_TOK_COMMENT:
+  case XML_TOK_BOM:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_OPEN:
+    if (!XmlNameMatchesAscii(enc,
+			     ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+			     end,
+			     KW_DOCTYPE))
+      break;
+    state->handler = doctype0;
+    return XML_ROLE_NONE;
+  case XML_TOK_INSTANCE_START:
+    state->handler = error;
+    return XML_ROLE_INSTANCE_START;
+  }
+  return common(state, tok);
+}
+
+static
+int prolog2(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_PI:
+  case XML_TOK_COMMENT:
+    return XML_ROLE_NONE;
+  case XML_TOK_INSTANCE_START:
+    state->handler = error;
+    return XML_ROLE_INSTANCE_START;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype0(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = doctype1;
+    return XML_ROLE_DOCTYPE_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype1(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = internalSubset;
+    return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
+  case XML_TOK_DECL_CLOSE:
+    state->handler = prolog2;
+    return XML_ROLE_DOCTYPE_CLOSE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = doctype3;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = doctype2;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype2(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = doctype3;
+    return XML_ROLE_DOCTYPE_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype3(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = doctype4;
+    return XML_ROLE_DOCTYPE_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype4(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = internalSubset;
+    return XML_ROLE_DOCTYPE_INTERNAL_SUBSET;
+  case XML_TOK_DECL_CLOSE:
+    state->handler = prolog2;
+    return XML_ROLE_DOCTYPE_CLOSE;
+  }
+  return common(state, tok);
+}
+
+static
+int doctype5(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    state->handler = prolog2;
+    return XML_ROLE_DOCTYPE_CLOSE;
+  }
+  return common(state, tok);
+}
+
+static
+int internalSubset(PROLOG_STATE *state,
+		   int tok,
+		   const char *ptr,
+		   const char *end,
+		   const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_OPEN:
+    if (XmlNameMatchesAscii(enc,
+			    ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+			    end,
+			    KW_ENTITY)) {
+      state->handler = entity0;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc,
+			    ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+			    end,
+			    KW_ATTLIST)) {
+      state->handler = attlist0;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc,
+			    ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+			    end,
+			    KW_ELEMENT)) {
+      state->handler = element0;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc,
+			    ptr + 2 * MIN_BYTES_PER_CHAR(enc),
+			    end,
+			    KW_NOTATION)) {
+      state->handler = notation0;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_PI:
+  case XML_TOK_COMMENT:
+    return XML_ROLE_NONE;
+  case XML_TOK_PARAM_ENTITY_REF:
+    return XML_ROLE_PARAM_ENTITY_REF;
+  case XML_TOK_CLOSE_BRACKET:
+    state->handler = doctype5;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static
+int externalSubset0(PROLOG_STATE *state,
+		    int tok,
+		    const char *ptr,
+		    const char *end,
+		    const ENCODING *enc)
+{
+  state->handler = externalSubset1;
+  if (tok == XML_TOK_XML_DECL)
+    return XML_ROLE_TEXT_DECL;
+  return externalSubset1(state, tok, ptr, end, enc);
+}
+
+static
+int externalSubset1(PROLOG_STATE *state,
+		    int tok,
+		    const char *ptr,
+		    const char *end,
+		    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_COND_SECT_OPEN:
+    state->handler = condSect0;
+    return XML_ROLE_NONE;
+  case XML_TOK_COND_SECT_CLOSE:
+    if (state->includeLevel == 0)
+      break;
+    state->includeLevel -= 1;
+    return XML_ROLE_NONE;
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_BRACKET:
+    break;
+  case XML_TOK_NONE:
+    if (state->includeLevel)
+      break;
+    return XML_ROLE_NONE;
+  default:
+    return internalSubset(state, tok, ptr, end, enc);
+  }
+  return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static
+int entity0(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_PERCENT:
+    state->handler = entity1;
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = entity2;
+    return XML_ROLE_GENERAL_ENTITY_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int entity1(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = entity7;
+    return XML_ROLE_PARAM_ENTITY_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int entity2(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = entity4;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = entity3;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_ENTITY_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int entity3(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity4;
+    return XML_ROLE_ENTITY_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+
+static
+int entity4(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity5;
+    return XML_ROLE_ENTITY_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int entity5(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_ENTITY_COMPLETE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_NDATA)) {
+      state->handler = entity6;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static
+int entity6(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = declClose;
+    return XML_ROLE_ENTITY_NOTATION_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int entity7(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = entity9;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = entity8;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_ENTITY_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int entity8(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = entity9;
+    return XML_ROLE_ENTITY_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int entity9(PROLOG_STATE *state,
+	    int tok,
+	    const char *ptr,
+	    const char *end,
+	    const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_ENTITY_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int notation0(PROLOG_STATE *state,
+	      int tok,
+	      const char *ptr,
+	      const char *end,
+	      const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = notation1;
+    return XML_ROLE_NOTATION_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int notation1(PROLOG_STATE *state,
+	      int tok,
+	      const char *ptr,
+	      const char *end,
+	      const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_SYSTEM)) {
+      state->handler = notation3;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_PUBLIC)) {
+      state->handler = notation2;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static
+int notation2(PROLOG_STATE *state,
+	      int tok,
+	      const char *ptr,
+	      const char *end,
+	      const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = notation4;
+    return XML_ROLE_NOTATION_PUBLIC_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int notation3(PROLOG_STATE *state,
+	      int tok,
+	      const char *ptr,
+	      const char *end,
+	      const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_NOTATION_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int notation4(PROLOG_STATE *state,
+	      int tok,
+	      const char *ptr,
+	      const char *end,
+	      const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = declClose;
+    return XML_ROLE_NOTATION_SYSTEM_ID;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_NOTATION_NO_SYSTEM_ID;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist0(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = attlist1;
+    return XML_ROLE_ATTLIST_ELEMENT_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist1(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = attlist2;
+    return XML_ROLE_ATTRIBUTE_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist2(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    {
+      static const char *types[] = {
+	KW_CDATA,
+        KW_ID,
+        KW_IDREF,
+        KW_IDREFS,
+        KW_ENTITY,
+        KW_ENTITIES,
+        KW_NMTOKEN,
+        KW_NMTOKENS,
+      };
+      int i;
+      for (i = 0; i < (int)(sizeof(types)/sizeof(types[0])); i++)
+	if (XmlNameMatchesAscii(enc, ptr, end, types[i])) {
+	  state->handler = attlist8;
+	  return XML_ROLE_ATTRIBUTE_TYPE_CDATA + i;
+	}
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_NOTATION)) {
+      state->handler = attlist5;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_OPEN_PAREN:
+    state->handler = attlist3;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist3(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NMTOKEN:
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = attlist4;
+    return XML_ROLE_ATTRIBUTE_ENUM_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist4(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->handler = attlist8;
+    return XML_ROLE_NONE;
+  case XML_TOK_OR:
+    state->handler = attlist3;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist5(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_PAREN:
+    state->handler = attlist6;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+
+static
+int attlist6(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    state->handler = attlist7;
+    return XML_ROLE_ATTRIBUTE_NOTATION_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist7(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->handler = attlist8;
+    return XML_ROLE_NONE;
+  case XML_TOK_OR:
+    state->handler = attlist6;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+/* default value */
+static
+int attlist8(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_POUND_NAME:
+    if (XmlNameMatchesAscii(enc,
+			    ptr + MIN_BYTES_PER_CHAR(enc),
+			    end,
+			    KW_IMPLIED)) {
+      state->handler = attlist1;
+      return XML_ROLE_IMPLIED_ATTRIBUTE_VALUE;
+    }
+    if (XmlNameMatchesAscii(enc,
+			    ptr + MIN_BYTES_PER_CHAR(enc),
+			    end,
+			    KW_REQUIRED)) {
+      state->handler = attlist1;
+      return XML_ROLE_REQUIRED_ATTRIBUTE_VALUE;
+    }
+    if (XmlNameMatchesAscii(enc,
+			    ptr + MIN_BYTES_PER_CHAR(enc),
+			    end,
+			    KW_FIXED)) {
+      state->handler = attlist9;
+      return XML_ROLE_NONE;
+    }
+    break;
+  case XML_TOK_LITERAL:
+    state->handler = attlist1;
+    return XML_ROLE_DEFAULT_ATTRIBUTE_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int attlist9(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_LITERAL:
+    state->handler = attlist1;
+    return XML_ROLE_FIXED_ATTRIBUTE_VALUE;
+  }
+  return common(state, tok);
+}
+
+static
+int element0(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element1;
+    return XML_ROLE_ELEMENT_NAME;
+  }
+  return common(state, tok);
+}
+
+static
+int element1(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_EMPTY)) {
+      state->handler = declClose;
+      return XML_ROLE_CONTENT_EMPTY;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_ANY)) {
+      state->handler = declClose;
+      return XML_ROLE_CONTENT_ANY;
+    }
+    break;
+  case XML_TOK_OPEN_PAREN:
+    state->handler = element2;
+    state->level = 1;
+    return XML_ROLE_GROUP_OPEN;
+  }
+  return common(state, tok);
+}
+
+static
+int element2(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_POUND_NAME:
+    if (XmlNameMatchesAscii(enc,
+			    ptr + MIN_BYTES_PER_CHAR(enc),
+			    end,
+			    KW_PCDATA)) {
+      state->handler = element3;
+      return XML_ROLE_CONTENT_PCDATA;
+    }
+    break;
+  case XML_TOK_OPEN_PAREN:
+    state->level = 2;
+    state->handler = element6;
+    return XML_ROLE_GROUP_OPEN;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT;
+  case XML_TOK_NAME_QUESTION:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_OPT;
+  case XML_TOK_NAME_ASTERISK:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_REP;
+  case XML_TOK_NAME_PLUS:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_PLUS;
+  }
+  return common(state, tok);
+}
+
+static
+int element3(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE;
+  case XML_TOK_CLOSE_PAREN_ASTERISK:
+    state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_REP;
+  case XML_TOK_OR:
+    state->handler = element4;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int element4(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element5;
+    return XML_ROLE_CONTENT_ELEMENT;
+  }
+  return common(state, tok);
+}
+
+static
+int element5(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN_ASTERISK:
+    state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_REP;
+  case XML_TOK_OR:
+    state->handler = element4;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int element6(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_PAREN:
+    state->level += 1;
+    return XML_ROLE_GROUP_OPEN;
+  case XML_TOK_NAME:
+  case XML_TOK_PREFIXED_NAME:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT;
+  case XML_TOK_NAME_QUESTION:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_OPT;
+  case XML_TOK_NAME_ASTERISK:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_REP;
+  case XML_TOK_NAME_PLUS:
+    state->handler = element7;
+    return XML_ROLE_CONTENT_ELEMENT_PLUS;
+  }
+  return common(state, tok);
+}
+
+static
+int element7(PROLOG_STATE *state,
+	     int tok,
+	     const char *ptr,
+	     const char *end,
+	     const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_CLOSE_PAREN:
+    state->level -= 1;
+    if (state->level == 0)
+      state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE;
+  case XML_TOK_CLOSE_PAREN_ASTERISK:
+    state->level -= 1;
+    if (state->level == 0)
+      state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_REP;
+  case XML_TOK_CLOSE_PAREN_QUESTION:
+    state->level -= 1;
+    if (state->level == 0)
+      state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_OPT;
+  case XML_TOK_CLOSE_PAREN_PLUS:
+    state->level -= 1;
+    if (state->level == 0)
+      state->handler = declClose;
+    return XML_ROLE_GROUP_CLOSE_PLUS;
+  case XML_TOK_COMMA:
+    state->handler = element6;
+    return XML_ROLE_GROUP_SEQUENCE;
+  case XML_TOK_OR:
+    state->handler = element6;
+    return XML_ROLE_GROUP_CHOICE;
+  }
+  return common(state, tok);
+}
+
+#ifdef XML_DTD
+
+static
+int condSect0(PROLOG_STATE *state,
+	      int tok,
+	      const char *ptr,
+	      const char *end,
+	      const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_NAME:
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_INCLUDE)) {
+      state->handler = condSect1;
+      return XML_ROLE_NONE;
+    }
+    if (XmlNameMatchesAscii(enc, ptr, end, KW_IGNORE)) {
+      state->handler = condSect2;
+      return XML_ROLE_NONE;
+    }
+    break;
+  }
+  return common(state, tok);
+}
+
+static
+int condSect1(PROLOG_STATE *state,
+	      int tok,
+	      const char *ptr,
+	      const char *end,
+	      const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = externalSubset1;
+    state->includeLevel += 1;
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+static
+int condSect2(PROLOG_STATE *state,
+	      int tok,
+	      const char *ptr,
+	      const char *end,
+	      const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_OPEN_BRACKET:
+    state->handler = externalSubset1;
+    return XML_ROLE_IGNORE_SECT;
+  }
+  return common(state, tok);
+}
+
+#endif /* XML_DTD */
+
+static
+int declClose(PROLOG_STATE *state,
+	      int tok,
+	      const char *ptr,
+	      const char *end,
+	      const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_PROLOG_S:
+    return XML_ROLE_NONE;
+  case XML_TOK_DECL_CLOSE:
+    setTopLevel(state);
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+
+#if 0
+
+static
+int ignore(PROLOG_STATE *state,
+	   int tok,
+	   const char *ptr,
+	   const char *end,
+	   const ENCODING *enc)
+{
+  switch (tok) {
+  case XML_TOK_DECL_CLOSE:
+    state->handler = internalSubset;
+    return 0;
+  default:
+    return XML_ROLE_NONE;
+  }
+  return common(state, tok);
+}
+#endif
+
+static
+int error(PROLOG_STATE *state,
+	  int tok,
+	  const char *ptr,
+	  const char *end,
+	  const ENCODING *enc)
+{
+  return XML_ROLE_NONE;
+}
+
+static
+int common(PROLOG_STATE *state, int tok)
+{
+#ifdef XML_DTD
+  if (!state->documentEntity && tok == XML_TOK_PARAM_ENTITY_REF)
+    return XML_ROLE_INNER_PARAM_ENTITY_REF;
+#endif
+  state->handler = error;
+  return XML_ROLE_ERROR;
+}
+
+void XmlPrologStateInit(PROLOG_STATE *state)
+{
+  state->handler = prolog0;
+#ifdef XML_DTD
+  state->documentEntity = 1;
+  state->includeLevel = 0;
+#endif /* XML_DTD */
+}
+
+#ifdef XML_DTD
+
+void XmlPrologStateInitExternalEntity(PROLOG_STATE *state)
+{
+  state->handler = externalSubset0;
+  state->documentEntity = 0;
+  state->includeLevel = 0;
+}
+
+#endif /* XML_DTD */
diff --git a/external/expat/xmlrole.h b/external/expat/xmlrole.h
new file mode 100644
index 0000000..db3ebc8
--- /dev/null
+++ b/external/expat/xmlrole.h
@@ -0,0 +1,100 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#ifndef XmlRole_INCLUDED
+#define XmlRole_INCLUDED 1
+
+#include "xmltok.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum {
+  XML_ROLE_ERROR = -1,
+  XML_ROLE_NONE = 0,
+  XML_ROLE_XML_DECL,
+  XML_ROLE_INSTANCE_START,
+  XML_ROLE_DOCTYPE_NAME,
+  XML_ROLE_DOCTYPE_SYSTEM_ID,
+  XML_ROLE_DOCTYPE_PUBLIC_ID,
+  XML_ROLE_DOCTYPE_INTERNAL_SUBSET,
+  XML_ROLE_DOCTYPE_CLOSE,
+  XML_ROLE_GENERAL_ENTITY_NAME,
+  XML_ROLE_PARAM_ENTITY_NAME,
+  XML_ROLE_ENTITY_VALUE,
+  XML_ROLE_ENTITY_SYSTEM_ID,
+  XML_ROLE_ENTITY_PUBLIC_ID,
+  XML_ROLE_ENTITY_COMPLETE,
+  XML_ROLE_ENTITY_NOTATION_NAME,
+  XML_ROLE_NOTATION_NAME,
+  XML_ROLE_NOTATION_SYSTEM_ID,
+  XML_ROLE_NOTATION_NO_SYSTEM_ID,
+  XML_ROLE_NOTATION_PUBLIC_ID,
+  XML_ROLE_ATTRIBUTE_NAME,
+  XML_ROLE_ATTRIBUTE_TYPE_CDATA,
+  XML_ROLE_ATTRIBUTE_TYPE_ID,
+  XML_ROLE_ATTRIBUTE_TYPE_IDREF,
+  XML_ROLE_ATTRIBUTE_TYPE_IDREFS,
+  XML_ROLE_ATTRIBUTE_TYPE_ENTITY,
+  XML_ROLE_ATTRIBUTE_TYPE_ENTITIES,
+  XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN,
+  XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS,
+  XML_ROLE_ATTRIBUTE_ENUM_VALUE,
+  XML_ROLE_ATTRIBUTE_NOTATION_VALUE,
+  XML_ROLE_ATTLIST_ELEMENT_NAME,
+  XML_ROLE_IMPLIED_ATTRIBUTE_VALUE,
+  XML_ROLE_REQUIRED_ATTRIBUTE_VALUE,
+  XML_ROLE_DEFAULT_ATTRIBUTE_VALUE,
+  XML_ROLE_FIXED_ATTRIBUTE_VALUE,
+  XML_ROLE_ELEMENT_NAME,
+  XML_ROLE_CONTENT_ANY,
+  XML_ROLE_CONTENT_EMPTY,
+  XML_ROLE_CONTENT_PCDATA,
+  XML_ROLE_GROUP_OPEN,
+  XML_ROLE_GROUP_CLOSE,
+  XML_ROLE_GROUP_CLOSE_REP,
+  XML_ROLE_GROUP_CLOSE_OPT,
+  XML_ROLE_GROUP_CLOSE_PLUS,
+  XML_ROLE_GROUP_CHOICE,
+  XML_ROLE_GROUP_SEQUENCE,
+  XML_ROLE_CONTENT_ELEMENT,
+  XML_ROLE_CONTENT_ELEMENT_REP,
+  XML_ROLE_CONTENT_ELEMENT_OPT,
+  XML_ROLE_CONTENT_ELEMENT_PLUS,
+#ifdef XML_DTD
+  XML_ROLE_TEXT_DECL,
+  XML_ROLE_IGNORE_SECT,
+  XML_ROLE_INNER_PARAM_ENTITY_REF,
+#endif /* XML_DTD */
+  XML_ROLE_PARAM_ENTITY_REF
+};
+
+typedef struct prolog_state {
+  int (*handler)(struct prolog_state *state,
+	         int tok,
+		 const char *ptr,
+		 const char *end,
+		 const ENCODING *enc);
+  unsigned level;
+#ifdef XML_DTD
+  unsigned includeLevel;
+  int documentEntity;
+#endif /* XML_DTD */
+} PROLOG_STATE;
+
+void XmlPrologStateInit(PROLOG_STATE *);
+#ifdef XML_DTD
+void XmlPrologStateInitExternalEntity(PROLOG_STATE *);
+#endif /* XML_DTD */
+
+#define XmlTokenRole(state, tok, ptr, end, enc) \
+ (((state)->handler)(state, tok, ptr, end, enc))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlRole_INCLUDED */
diff --git a/external/expat/xmltok.c b/external/expat/xmltok.c
new file mode 100644
index 0000000..483f506
--- /dev/null
+++ b/external/expat/xmltok.c
@@ -0,0 +1,1568 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+static char RCSId[]
+  = "$Header: /cvsroot/ogdi/devdir/external/expat/xmltok.c,v 1.1 2001/04/12 05:25:37 warmerda Exp $";
+
+#ifdef COMPILED_FROM_DSP
+#  include "winconfig.h"
+#else
+#  include <config.h>
+#endif /* ndef COMPILED_FROM_DSP */
+
+#include "xmltok.h"
+#include "nametab.h"
+
+#ifdef XML_DTD
+#define IGNORE_SECTION_TOK_VTABLE , PREFIX(ignoreSectionTok)
+#else
+#define IGNORE_SECTION_TOK_VTABLE /* as nothing */
+#endif
+
+#define VTABLE1 \
+  { PREFIX(prologTok), PREFIX(contentTok), \
+    PREFIX(cdataSectionTok) IGNORE_SECTION_TOK_VTABLE }, \
+  { PREFIX(attributeValueTok), PREFIX(entityValueTok) }, \
+  PREFIX(sameName), \
+  PREFIX(nameMatchesAscii), \
+  PREFIX(nameLength), \
+  PREFIX(skipS), \
+  PREFIX(getAtts), \
+  PREFIX(charRefNumber), \
+  PREFIX(predefinedEntityName), \
+  PREFIX(updatePosition), \
+  PREFIX(isPublicId)
+
+#define VTABLE VTABLE1, PREFIX(toUtf8), PREFIX(toUtf16)
+
+#define UCS2_GET_NAMING(pages, hi, lo) \
+   (namingBitmap[(pages[hi] << 3) + ((lo) >> 5)] & (1 << ((lo) & 0x1F)))
+
+/* A 2 byte UTF-8 representation splits the characters 11 bits
+between the bottom 5 and 6 bits of the bytes.
+We need 8 bits to index into pages, 3 bits to add to that index and
+5 bits to generate the mask. */
+#define UTF8_GET_NAMING2(pages, byte) \
+    (namingBitmap[((pages)[(((byte)[0]) >> 2) & 7] << 3) \
+                      + ((((byte)[0]) & 3) << 1) \
+                      + ((((byte)[1]) >> 5) & 1)] \
+         & (1 << (((byte)[1]) & 0x1F)))
+
+/* A 3 byte UTF-8 representation splits the characters 16 bits
+between the bottom 4, 6 and 6 bits of the bytes.
+We need 8 bits to index into pages, 3 bits to add to that index and
+5 bits to generate the mask. */
+#define UTF8_GET_NAMING3(pages, byte) \
+  (namingBitmap[((pages)[((((byte)[0]) & 0xF) << 4) \
+                             + ((((byte)[1]) >> 2) & 0xF)] \
+		       << 3) \
+                      + ((((byte)[1]) & 3) << 1) \
+                      + ((((byte)[2]) >> 5) & 1)] \
+         & (1 << (((byte)[2]) & 0x1F)))
+
+#define UTF8_GET_NAMING(pages, p, n) \
+  ((n) == 2 \
+  ? UTF8_GET_NAMING2(pages, (const unsigned char *)(p)) \
+  : ((n) == 3 \
+     ? UTF8_GET_NAMING3(pages, (const unsigned char *)(p)) \
+     : 0))
+
+#define UTF8_INVALID3(p) \
+  ((*p) == 0xED \
+  ? (((p)[1] & 0x20) != 0) \
+  : ((*p) == 0xEF \
+     ? ((p)[1] == 0xBF && ((p)[2] == 0xBF || (p)[2] == 0xBE)) \
+     : 0))
+
+#define UTF8_INVALID4(p) ((*p) == 0xF4 && ((p)[1] & 0x30) != 0)
+
+static
+int isNever(const ENCODING *enc, const char *p)
+{
+  return 0;
+}
+
+static
+int utf8_isName2(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING2(namePages, (const unsigned char *)p);
+}
+
+static
+int utf8_isName3(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING3(namePages, (const unsigned char *)p);
+}
+
+#define utf8_isName4 isNever
+
+static
+int utf8_isNmstrt2(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING2(nmstrtPages, (const unsigned char *)p);
+}
+
+static
+int utf8_isNmstrt3(const ENCODING *enc, const char *p)
+{
+  return UTF8_GET_NAMING3(nmstrtPages, (const unsigned char *)p);
+}
+
+#define utf8_isNmstrt4 isNever
+
+#define utf8_isInvalid2 isNever
+
+static
+int utf8_isInvalid3(const ENCODING *enc, const char *p)
+{
+  return UTF8_INVALID3((const unsigned char *)p);
+}
+
+static
+int utf8_isInvalid4(const ENCODING *enc, const char *p)
+{
+  return UTF8_INVALID4((const unsigned char *)p);
+}
+
+struct normal_encoding {
+  ENCODING enc;
+  unsigned char type[256];
+#ifdef XML_MIN_SIZE
+  int (*byteType)(const ENCODING *, const char *);
+  int (*isNameMin)(const ENCODING *, const char *);
+  int (*isNmstrtMin)(const ENCODING *, const char *);
+  int (*byteToAscii)(const ENCODING *, const char *);
+  int (*charMatches)(const ENCODING *, const char *, int);
+#endif /* XML_MIN_SIZE */
+  int (*isName2)(const ENCODING *, const char *);
+  int (*isName3)(const ENCODING *, const char *);
+  int (*isName4)(const ENCODING *, const char *);
+  int (*isNmstrt2)(const ENCODING *, const char *);
+  int (*isNmstrt3)(const ENCODING *, const char *);
+  int (*isNmstrt4)(const ENCODING *, const char *);
+  int (*isInvalid2)(const ENCODING *, const char *);
+  int (*isInvalid3)(const ENCODING *, const char *);
+  int (*isInvalid4)(const ENCODING *, const char *);
+};
+
+#ifdef XML_MIN_SIZE
+
+#define STANDARD_VTABLE(E) \
+ E ## byteType, \
+ E ## isNameMin, \
+ E ## isNmstrtMin, \
+ E ## byteToAscii, \
+ E ## charMatches,
+
+#else
+
+#define STANDARD_VTABLE(E) /* as nothing */
+
+#endif
+
+#define NORMAL_VTABLE(E) \
+ E ## isName2, \
+ E ## isName3, \
+ E ## isName4, \
+ E ## isNmstrt2, \
+ E ## isNmstrt3, \
+ E ## isNmstrt4, \
+ E ## isInvalid2, \
+ E ## isInvalid3, \
+ E ## isInvalid4
+
+static int checkCharRefNumber(int);
+
+#include "xmltok_impl.h"
+#include "ascii.h"
+
+#ifdef XML_MIN_SIZE
+#define sb_isNameMin isNever
+#define sb_isNmstrtMin isNever
+#endif
+
+#ifdef XML_MIN_SIZE
+#define MINBPC(enc) ((enc)->minBytesPerChar)
+#else
+/* minimum bytes per character */
+#define MINBPC(enc) 1
+#endif
+
+#define SB_BYTE_TYPE(enc, p) \
+  (((struct normal_encoding *)(enc))->type[(unsigned char)*(p)])
+
+#ifdef XML_MIN_SIZE
+static
+int sb_byteType(const ENCODING *enc, const char *p)
+{
+  return SB_BYTE_TYPE(enc, p);
+}
+#define BYTE_TYPE(enc, p) \
+ (((const struct normal_encoding *)(enc))->byteType(enc, p))
+#else
+#define BYTE_TYPE(enc, p) SB_BYTE_TYPE(enc, p)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define BYTE_TO_ASCII(enc, p) \
+ (((const struct normal_encoding *)(enc))->byteToAscii(enc, p))
+static
+int sb_byteToAscii(const ENCODING *enc, const char *p)
+{
+  return *p;
+}
+#else
+#define BYTE_TO_ASCII(enc, p) (*(p))
+#endif
+
+#define IS_NAME_CHAR(enc, p, n) \
+ (((const struct normal_encoding *)(enc))->isName ## n(enc, p))
+#define IS_NMSTRT_CHAR(enc, p, n) \
+ (((const struct normal_encoding *)(enc))->isNmstrt ## n(enc, p))
+#define IS_INVALID_CHAR(enc, p, n) \
+ (((const struct normal_encoding *)(enc))->isInvalid ## n(enc, p))
+
+#ifdef XML_MIN_SIZE
+#define IS_NAME_CHAR_MINBPC(enc, p) \
+ (((const struct normal_encoding *)(enc))->isNameMin(enc, p))
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) \
+ (((const struct normal_encoding *)(enc))->isNmstrtMin(enc, p))
+#else
+#define IS_NAME_CHAR_MINBPC(enc, p) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) (0)
+#endif
+
+#ifdef XML_MIN_SIZE
+#define CHAR_MATCHES(enc, p, c) \
+ (((const struct normal_encoding *)(enc))->charMatches(enc, p, c))
+static
+int sb_charMatches(const ENCODING *enc, const char *p, int c)
+{
+  return *p == c;
+}
+#else
+/* c is an ASCII character */
+#define CHAR_MATCHES(enc, p, c) (*(p) == c)
+#endif
+
+#define PREFIX(ident) normal_ ## ident
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+enum {  /* UTF8_cvalN is value of masked first byte of N byte sequence */
+  UTF8_cval1 = 0x00,
+  UTF8_cval2 = 0xc0,
+  UTF8_cval3 = 0xe0,
+  UTF8_cval4 = 0xf0
+};
+
+static
+void utf8_toUtf8(const ENCODING *enc,
+		 const char **fromP, const char *fromLim,
+		 char **toP, const char *toLim)
+{
+  char *to;
+  const char *from;
+  if (fromLim - *fromP > toLim - *toP) {
+    /* Avoid copying partial characters. */
+    for (fromLim = *fromP + (toLim - *toP); fromLim > *fromP; fromLim--)
+      if (((unsigned char)fromLim[-1] & 0xc0) != 0x80)
+	break;
+  }
+  for (to = *toP, from = *fromP; from != fromLim; from++, to++)
+    *to = *from;
+  *fromP = from;
+  *toP = to;
+}
+
+static
+void utf8_toUtf16(const ENCODING *enc,
+		  const char **fromP, const char *fromLim,
+		  unsigned short **toP, const unsigned short *toLim)
+{
+  unsigned short *to = *toP;
+  const char *from = *fromP;
+  while (from != fromLim && to != toLim) {
+    switch (((struct normal_encoding *)enc)->type[(unsigned char)*from]) {
+    case BT_LEAD2:
+      *to++ = ((from[0] & 0x1f) << 6) | (from[1] & 0x3f);
+      from += 2;
+      break;
+    case BT_LEAD3:
+      *to++ = ((from[0] & 0xf) << 12) | ((from[1] & 0x3f) << 6) | (from[2] & 0x3f);
+      from += 3;
+      break;
+    case BT_LEAD4:
+      {
+	unsigned long n;
+	if (to + 1 == toLim)
+	  break;
+	n = ((from[0] & 0x7) << 18) | ((from[1] & 0x3f) << 12) | ((from[2] & 0x3f) << 6) | (from[3] & 0x3f);
+	n -= 0x10000;
+	to[0] = (unsigned short)((n >> 10) | 0xD800);
+	to[1] = (unsigned short)((n & 0x3FF) | 0xDC00);
+	to += 2;
+	from += 4;
+      }
+      break;
+    default:
+      *to++ = *from++;
+      break;
+    }
+  }
+  *fromP = from;
+  *toP = to;
+}
+
+#ifdef XML_NS
+static const struct normal_encoding utf8_encoding_ns = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#include "asciitab.h"
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+#endif
+
+static const struct normal_encoding utf8_encoding = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_utf8_encoding_ns = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#include "iasciitab.h"
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+#endif
+
+static const struct normal_encoding internal_utf8_encoding = {
+  { VTABLE1, utf8_toUtf8, utf8_toUtf16, 1, 1, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "utf8tab.h"
+  },
+  STANDARD_VTABLE(sb_) NORMAL_VTABLE(utf8_)
+};
+
+static
+void latin1_toUtf8(const ENCODING *enc,
+		   const char **fromP, const char *fromLim,
+		   char **toP, const char *toLim)
+{
+  for (;;) {
+    unsigned char c;
+    if (*fromP == fromLim)
+      break;
+    c = (unsigned char)**fromP;
+    if (c & 0x80) {
+      if (toLim - *toP < 2)
+	break;
+      *(*toP)++ = ((c >> 6) | UTF8_cval2);
+      *(*toP)++ = ((c & 0x3f) | 0x80);
+      (*fromP)++;
+    }
+    else {
+      if (*toP == toLim)
+	break;
+      *(*toP)++ = *(*fromP)++;
+    }
+  }
+}
+
+static
+void latin1_toUtf16(const ENCODING *enc,
+		    const char **fromP, const char *fromLim,
+		    unsigned short **toP, const unsigned short *toLim)
+{
+  while (*fromP != fromLim && *toP != toLim)
+    *(*toP)++ = (unsigned char)*(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding latin1_encoding_ns = {
+  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+  {
+#include "asciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding latin1_encoding = {
+  { VTABLE1, latin1_toUtf8, latin1_toUtf16, 1, 0, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+static
+void ascii_toUtf8(const ENCODING *enc,
+		  const char **fromP, const char *fromLim,
+		  char **toP, const char *toLim)
+{
+  while (*fromP != fromLim && *toP != toLim)
+    *(*toP)++ = *(*fromP)++;
+}
+
+#ifdef XML_NS
+
+static const struct normal_encoding ascii_encoding_ns = {
+  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+  {
+#include "asciitab.h"
+/* BT_NONXML == 0 */
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+#endif
+
+static const struct normal_encoding ascii_encoding = {
+  { VTABLE1, ascii_toUtf8, latin1_toUtf16, 1, 1, 0 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+/* BT_NONXML == 0 */
+  },
+  STANDARD_VTABLE(sb_)
+};
+
+static int unicode_byte_type(char hi, char lo)
+{
+  switch ((unsigned char)hi) {
+  case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+    return BT_LEAD4;
+  case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+    return BT_TRAIL;
+  case 0xFF:
+    switch ((unsigned char)lo) {
+    case 0xFF:
+    case 0xFE:
+      return BT_NONXML;
+    }
+    break;
+  }
+  return BT_NONASCII;
+}
+
+#define DEFINE_UTF16_TO_UTF8(E) \
+static \
+void E ## toUtf8(const ENCODING *enc, \
+		 const char **fromP, const char *fromLim, \
+		 char **toP, const char *toLim) \
+{ \
+  const char *from; \
+  for (from = *fromP; from != fromLim; from += 2) { \
+    int plane; \
+    unsigned char lo2; \
+    unsigned char lo = GET_LO(from); \
+    unsigned char hi = GET_HI(from); \
+    switch (hi) { \
+    case 0: \
+      if (lo < 0x80) { \
+        if (*toP == toLim) { \
+          *fromP = from; \
+	  return; \
+        } \
+        *(*toP)++ = lo; \
+        break; \
+      } \
+      /* fall through */ \
+    case 0x1: case 0x2: case 0x3: \
+    case 0x4: case 0x5: case 0x6: case 0x7: \
+      if (toLim -  *toP < 2) { \
+        *fromP = from; \
+	return; \
+      } \
+      *(*toP)++ = ((lo >> 6) | (hi << 2) |  UTF8_cval2); \
+      *(*toP)++ = ((lo & 0x3f) | 0x80); \
+      break; \
+    default: \
+      if (toLim -  *toP < 3)  { \
+        *fromP = from; \
+	return; \
+      } \
+      /* 16 bits divided 4, 6, 6 amongst 3 bytes */ \
+      *(*toP)++ = ((hi >> 4) | UTF8_cval3); \
+      *(*toP)++ = (((hi & 0xf) << 2) | (lo >> 6) | 0x80); \
+      *(*toP)++ = ((lo & 0x3f) | 0x80); \
+      break; \
+    case 0xD8: case 0xD9: case 0xDA: case 0xDB: \
+      if (toLim -  *toP < 4) { \
+	*fromP = from; \
+	return; \
+      } \
+      plane = (((hi & 0x3) << 2) | ((lo >> 6) & 0x3)) + 1; \
+      *(*toP)++ = ((plane >> 2) | UTF8_cval4); \
+      *(*toP)++ = (((lo >> 2) & 0xF) | ((plane & 0x3) << 4) | 0x80); \
+      from += 2; \
+      lo2 = GET_LO(from); \
+      *(*toP)++ = (((lo & 0x3) << 4) \
+	           | ((GET_HI(from) & 0x3) << 2) \
+		   | (lo2 >> 6) \
+		   | 0x80); \
+      *(*toP)++ = ((lo2 & 0x3f) | 0x80); \
+      break; \
+    } \
+  } \
+  *fromP = from; \
+}
+
+#define DEFINE_UTF16_TO_UTF16(E) \
+static \
+void E ## toUtf16(const ENCODING *enc, \
+		  const char **fromP, const char *fromLim, \
+		  unsigned short **toP, const unsigned short *toLim) \
+{ \
+  /* Avoid copying first half only of surrogate */ \
+  if (fromLim - *fromP > ((toLim - *toP) << 1) \
+      && (GET_HI(fromLim - 2) & 0xF8) == 0xD8) \
+    fromLim -= 2; \
+  for (; *fromP != fromLim && *toP != toLim; *fromP += 2) \
+    *(*toP)++ = (GET_HI(*fromP) << 8) | GET_LO(*fromP); \
+}
+
+#define SET2(ptr, ch) \
+  (((ptr)[0] = ((ch) & 0xff)), ((ptr)[1] = ((ch) >> 8)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[0])
+#define GET_HI(ptr) ((unsigned char)(ptr)[1])
+
+DEFINE_UTF16_TO_UTF8(little2_)
+DEFINE_UTF16_TO_UTF16(little2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define SET2(ptr, ch) \
+  (((ptr)[0] = ((ch) >> 8)), ((ptr)[1] = ((ch) & 0xFF)))
+#define GET_LO(ptr) ((unsigned char)(ptr)[1])
+#define GET_HI(ptr) ((unsigned char)(ptr)[0])
+
+DEFINE_UTF16_TO_UTF8(big2_)
+DEFINE_UTF16_TO_UTF16(big2_)
+
+#undef SET2
+#undef GET_LO
+#undef GET_HI
+
+#define LITTLE2_BYTE_TYPE(enc, p) \
+ ((p)[1] == 0 \
+  ? ((struct normal_encoding *)(enc))->type[(unsigned char)*(p)] \
+  : unicode_byte_type((p)[1], (p)[0]))
+#define LITTLE2_BYTE_TO_ASCII(enc, p) ((p)[1] == 0 ? (p)[0] : -1)
+#define LITTLE2_CHAR_MATCHES(enc, p, c) ((p)[1] == 0 && (p)[0] == c)
+#define LITTLE2_IS_NAME_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(namePages, (unsigned char)p[1], (unsigned char)p[0])
+#define LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[1], (unsigned char)p[0])
+
+#ifdef XML_MIN_SIZE
+
+static
+int little2_byteType(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_BYTE_TYPE(enc, p);
+}
+
+static
+int little2_byteToAscii(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_BYTE_TO_ASCII(enc, p);
+}
+
+static
+int little2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+  return LITTLE2_CHAR_MATCHES(enc, p, c);
+}
+
+static
+int little2_isNameMin(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static
+int little2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+  return LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, little2_toUtf8, little2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) little2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) LITTLE2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) LITTLE2_BYTE_TO_ASCII(enc, p) 
+#define CHAR_MATCHES(enc, p, c) LITTLE2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) LITTLE2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) LITTLE2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding little2_encoding_ns = { 
+  { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 12
+    1
+#else
+    0
+#endif
+  },
+  {
+#include "asciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding little2_encoding = { 
+  { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 12
+    1
+#else
+    0
+#endif
+  },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#if XML_BYTE_ORDER != 21
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_little2_encoding_ns = { 
+  { VTABLE, 2, 0, 1 },
+  {
+#include "iasciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_little2_encoding = { 
+  { VTABLE, 2, 0, 1 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(little2_)
+};
+
+#endif
+
+
+#define BIG2_BYTE_TYPE(enc, p) \
+ ((p)[0] == 0 \
+  ? ((struct normal_encoding *)(enc))->type[(unsigned char)(p)[1]] \
+  : unicode_byte_type((p)[0], (p)[1]))
+#define BIG2_BYTE_TO_ASCII(enc, p) ((p)[0] == 0 ? (p)[1] : -1)
+#define BIG2_CHAR_MATCHES(enc, p, c) ((p)[0] == 0 && (p)[1] == c)
+#define BIG2_IS_NAME_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(namePages, (unsigned char)p[0], (unsigned char)p[1])
+#define BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p) \
+  UCS2_GET_NAMING(nmstrtPages, (unsigned char)p[0], (unsigned char)p[1])
+
+#ifdef XML_MIN_SIZE
+
+static
+int big2_byteType(const ENCODING *enc, const char *p)
+{
+  return BIG2_BYTE_TYPE(enc, p);
+}
+
+static
+int big2_byteToAscii(const ENCODING *enc, const char *p)
+{
+  return BIG2_BYTE_TO_ASCII(enc, p);
+}
+
+static
+int big2_charMatches(const ENCODING *enc, const char *p, int c)
+{
+  return BIG2_CHAR_MATCHES(enc, p, c);
+}
+
+static
+int big2_isNameMin(const ENCODING *enc, const char *p)
+{
+  return BIG2_IS_NAME_CHAR_MINBPC(enc, p);
+}
+
+static
+int big2_isNmstrtMin(const ENCODING *enc, const char *p)
+{
+  return BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p);
+}
+
+#undef VTABLE
+#define VTABLE VTABLE1, big2_toUtf8, big2_toUtf16
+
+#else /* not XML_MIN_SIZE */
+
+#undef PREFIX
+#define PREFIX(ident) big2_ ## ident
+#define MINBPC(enc) 2
+/* CHAR_MATCHES is guaranteed to have MINBPC bytes available. */
+#define BYTE_TYPE(enc, p) BIG2_BYTE_TYPE(enc, p)
+#define BYTE_TO_ASCII(enc, p) BIG2_BYTE_TO_ASCII(enc, p) 
+#define CHAR_MATCHES(enc, p, c) BIG2_CHAR_MATCHES(enc, p, c)
+#define IS_NAME_CHAR(enc, p, n) 0
+#define IS_NAME_CHAR_MINBPC(enc, p) BIG2_IS_NAME_CHAR_MINBPC(enc, p)
+#define IS_NMSTRT_CHAR(enc, p, n) (0)
+#define IS_NMSTRT_CHAR_MINBPC(enc, p) BIG2_IS_NMSTRT_CHAR_MINBPC(enc, p)
+
+#include "xmltok_impl.c"
+
+#undef MINBPC
+#undef BYTE_TYPE
+#undef BYTE_TO_ASCII
+#undef CHAR_MATCHES
+#undef IS_NAME_CHAR
+#undef IS_NAME_CHAR_MINBPC
+#undef IS_NMSTRT_CHAR
+#undef IS_NMSTRT_CHAR_MINBPC
+#undef IS_INVALID_CHAR
+
+#endif /* not XML_MIN_SIZE */
+
+#ifdef XML_NS
+
+static const struct normal_encoding big2_encoding_ns = {
+  { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 21
+  1
+#else
+  0
+#endif
+  },
+  {
+#include "asciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding big2_encoding = {
+  { VTABLE, 2, 0,
+#if XML_BYTE_ORDER == 21
+  1
+#else
+  0
+#endif
+  },
+  {
+#define BT_COLON BT_NMSTRT
+#include "asciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#if XML_BYTE_ORDER != 12
+
+#ifdef XML_NS
+
+static const struct normal_encoding internal_big2_encoding_ns = {
+  { VTABLE, 2, 0, 1 },
+  {
+#include "iasciitab.h"
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+static const struct normal_encoding internal_big2_encoding = {
+  { VTABLE, 2, 0, 1 },
+  {
+#define BT_COLON BT_NMSTRT
+#include "iasciitab.h"
+#undef BT_COLON
+#include "latin1tab.h"
+  },
+  STANDARD_VTABLE(big2_)
+};
+
+#endif
+
+#undef PREFIX
+
+static
+int streqci(const char *s1, const char *s2)
+{
+  for (;;) {
+    char c1 = *s1++;
+    char c2 = *s2++;
+    if (ASCII_a <= c1 && c1 <= ASCII_z)
+      c1 += ASCII_A - ASCII_a;
+    if (ASCII_a <= c2 && c2 <= ASCII_z)
+      c2 += ASCII_A - ASCII_a;
+    if (c1 != c2)
+      return 0;
+    if (!c1)
+      break;
+  }
+  return 1;
+}
+
+static
+void initUpdatePosition(const ENCODING *enc, const char *ptr,
+			const char *end, POSITION *pos)
+{
+  normal_updatePosition(&utf8_encoding.enc, ptr, end, pos);
+}
+
+static
+int toAscii(const ENCODING *enc, const char *ptr, const char *end)
+{
+  char buf[1];
+  char *p = buf;
+  XmlUtf8Convert(enc, &ptr, end, &p, p + 1);
+  if (p == buf)
+    return -1;
+  else
+    return buf[0];
+}
+
+static
+int isSpace(int c)
+{
+  switch (c) {
+  case 0x20:
+  case 0xD:
+  case 0xA:
+  case 0x9:	
+    return 1;
+  }
+  return 0;
+}
+
+/* Return 1 if there's just optional white space
+or there's an S followed by name=val. */
+static
+int parsePseudoAttribute(const ENCODING *enc,
+			 const char *ptr,
+			 const char *end,
+			 const char **namePtr,
+			 const char **nameEndPtr,
+			 const char **valPtr,
+			 const char **nextTokPtr)
+{
+  int c;
+  char open;
+  if (ptr == end) {
+    *namePtr = 0;
+    return 1;
+  }
+  if (!isSpace(toAscii(enc, ptr, end))) {
+    *nextTokPtr = ptr;
+    return 0;
+  }
+  do {
+    ptr += enc->minBytesPerChar;
+  } while (isSpace(toAscii(enc, ptr, end)));
+  if (ptr == end) {
+    *namePtr = 0;
+    return 1;
+  }
+  *namePtr = ptr;
+  for (;;) {
+    c = toAscii(enc, ptr, end);
+    if (c == -1) {
+      *nextTokPtr = ptr;
+      return 0;
+    }
+    if (c == ASCII_EQUALS) {
+      *nameEndPtr = ptr;
+      break;
+    }
+    if (isSpace(c)) {
+      *nameEndPtr = ptr;
+      do {
+	ptr += enc->minBytesPerChar;
+      } while (isSpace(c = toAscii(enc, ptr, end)));
+      if (c != ASCII_EQUALS) {
+	*nextTokPtr = ptr;
+	return 0;
+      }
+      break;
+    }
+    ptr += enc->minBytesPerChar;
+  }
+  if (ptr == *namePtr) {
+    *nextTokPtr = ptr;
+    return 0;
+  }
+  ptr += enc->minBytesPerChar;
+  c = toAscii(enc, ptr, end);
+  while (isSpace(c)) {
+    ptr += enc->minBytesPerChar;
+    c = toAscii(enc, ptr, end);
+  }
+  if (c != ASCII_QUOT && c != ASCII_APOS) {
+    *nextTokPtr = ptr;
+    return 0;
+  }
+  open = c;
+  ptr += enc->minBytesPerChar;
+  *valPtr = ptr;
+  for (;; ptr += enc->minBytesPerChar) {
+    c = toAscii(enc, ptr, end);
+    if (c == open)
+      break;
+    if (!(ASCII_a <= c && c <= ASCII_z)
+	&& !(ASCII_A <= c && c <= ASCII_Z)
+	&& !(ASCII_0 <= c && c <= ASCII_9)
+	&& c != ASCII_PERIOD
+	&& c != ASCII_MINUS
+	&& c != ASCII_UNDERSCORE) {
+      *nextTokPtr = ptr;
+      return 0;
+    }
+  }
+  *nextTokPtr = ptr + enc->minBytesPerChar;
+  return 1;
+}
+
+static const char KW_version[] = {
+  ASCII_v, ASCII_e, ASCII_r, ASCII_s, ASCII_i, ASCII_o, ASCII_n, '\0'
+};
+
+static const char KW_encoding[] = {
+  ASCII_e, ASCII_n, ASCII_c, ASCII_o, ASCII_d, ASCII_i, ASCII_n, ASCII_g, '\0'
+};
+
+static const char KW_standalone[] = {
+  ASCII_s, ASCII_t, ASCII_a, ASCII_n, ASCII_d, ASCII_a, ASCII_l, ASCII_o, ASCII_n, ASCII_e, '\0'
+};
+
+static const char KW_yes[] = {
+  ASCII_y, ASCII_e, ASCII_s,  '\0'
+};
+
+static const char KW_no[] = {
+  ASCII_n, ASCII_o,  '\0'
+};
+
+static
+int doParseXmlDecl(const ENCODING *(*encodingFinder)(const ENCODING *,
+		                                     const char *,
+						     const char *),
+		   int isGeneralTextEntity,
+		   const ENCODING *enc,
+		   const char *ptr,
+		   const char *end,
+		   const char **badPtr,
+		   const char **versionPtr,
+		   const char **versionEndPtr,
+		   const char **encodingName,
+		   const ENCODING **encoding,
+		   int *standalone)
+{
+  const char *val = 0;
+  const char *name = 0;
+  const char *nameEnd = 0;
+  ptr += 5 * enc->minBytesPerChar;
+  end -= 2 * enc->minBytesPerChar;
+  if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr) || !name) {
+    *badPtr = ptr;
+    return 0;
+  }
+  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_version)) {
+    if (!isGeneralTextEntity) {
+      *badPtr = name;
+      return 0;
+    }
+  }
+  else {
+    if (versionPtr)
+      *versionPtr = val;
+    if (versionEndPtr)
+      *versionEndPtr = ptr;
+    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+      *badPtr = ptr;
+      return 0;
+    }
+    if (!name) {
+      if (isGeneralTextEntity) {
+	/* a TextDecl must have an EncodingDecl */
+	*badPtr = ptr;
+	return 0;
+      }
+      return 1;
+    }
+  }
+  if (XmlNameMatchesAscii(enc, name, nameEnd, KW_encoding)) {
+    int c = toAscii(enc, val, end);
+    if (!(ASCII_a <= c && c <= ASCII_z) && !(ASCII_A <= c && c <= ASCII_Z)) {
+      *badPtr = val;
+      return 0;
+    }
+    if (encodingName)
+      *encodingName = val;
+    if (encoding)
+      *encoding = encodingFinder(enc, val, ptr - enc->minBytesPerChar);
+    if (!parsePseudoAttribute(enc, ptr, end, &name, &nameEnd, &val, &ptr)) {
+      *badPtr = ptr;
+      return 0;
+    }
+    if (!name)
+      return 1;
+  }
+  if (!XmlNameMatchesAscii(enc, name, nameEnd, KW_standalone) || isGeneralTextEntity) {
+    *badPtr = name;
+    return 0;
+  }
+  if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_yes)) {
+    if (standalone)
+      *standalone = 1;
+  }
+  else if (XmlNameMatchesAscii(enc, val, ptr - enc->minBytesPerChar, KW_no)) {
+    if (standalone)
+      *standalone = 0;
+  }
+  else {
+    *badPtr = val;
+    return 0;
+  }
+  while (isSpace(toAscii(enc, ptr, end)))
+    ptr += enc->minBytesPerChar;
+  if (ptr != end) {
+    *badPtr = ptr;
+    return 0;
+  }
+  return 1;
+}
+
+static
+int checkCharRefNumber(int result)
+{
+  switch (result >> 8) {
+  case 0xD8: case 0xD9: case 0xDA: case 0xDB:
+  case 0xDC: case 0xDD: case 0xDE: case 0xDF:
+    return -1;
+  case 0:
+    if (latin1_encoding.type[result] == BT_NONXML)
+      return -1;
+    break;
+  case 0xFF:
+    if (result == 0xFFFE || result == 0xFFFF)
+      return -1;
+    break;
+  }
+  return result;
+}
+
+int XmlUtf8Encode(int c, char *buf)
+{
+  enum {
+    /* minN is minimum legal resulting value for N byte sequence */
+    min2 = 0x80,
+    min3 = 0x800,
+    min4 = 0x10000
+  };
+
+  if (c < 0)
+    return 0;
+  if (c < min2) {
+    buf[0] = (c | UTF8_cval1);
+    return 1;
+  }
+  if (c < min3) {
+    buf[0] = ((c >> 6) | UTF8_cval2);
+    buf[1] = ((c & 0x3f) | 0x80);
+    return 2;
+  }
+  if (c < min4) {
+    buf[0] = ((c >> 12) | UTF8_cval3);
+    buf[1] = (((c >> 6) & 0x3f) | 0x80);
+    buf[2] = ((c & 0x3f) | 0x80);
+    return 3;
+  }
+  if (c < 0x110000) {
+    buf[0] = ((c >> 18) | UTF8_cval4);
+    buf[1] = (((c >> 12) & 0x3f) | 0x80);
+    buf[2] = (((c >> 6) & 0x3f) | 0x80);
+    buf[3] = ((c & 0x3f) | 0x80);
+    return 4;
+  }
+  return 0;
+}
+
+int XmlUtf16Encode(int charNum, unsigned short *buf)
+{
+  if (charNum < 0)
+    return 0;
+  if (charNum < 0x10000) {
+    buf[0] = charNum;
+    return 1;
+  }
+  if (charNum < 0x110000) {
+    charNum -= 0x10000;
+    buf[0] = (charNum >> 10) + 0xD800;
+    buf[1] = (charNum & 0x3FF) + 0xDC00;
+    return 2;
+  }
+  return 0;
+}
+
+struct unknown_encoding {
+  struct normal_encoding normal;
+  int (*convert)(void *userData, const char *p);
+  void *userData;
+  unsigned short utf16[256];
+  char utf8[256][4];
+};
+
+int XmlSizeOfUnknownEncoding(void)
+{
+  return sizeof(struct unknown_encoding);
+}
+
+static
+int unknown_isName(const ENCODING *enc, const char *p)
+{
+  int c = ((const struct unknown_encoding *)enc)
+	  ->convert(((const struct unknown_encoding *)enc)->userData, p);
+  if (c & ~0xFFFF)
+    return 0;
+  return UCS2_GET_NAMING(namePages, c >> 8, c & 0xFF);
+}
+
+static
+int unknown_isNmstrt(const ENCODING *enc, const char *p)
+{
+  int c = ((const struct unknown_encoding *)enc)
+	  ->convert(((const struct unknown_encoding *)enc)->userData, p);
+  if (c & ~0xFFFF)
+    return 0;
+  return UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xFF);
+}
+
+static
+int unknown_isInvalid(const ENCODING *enc, const char *p)
+{
+  int c = ((const struct unknown_encoding *)enc)
+	   ->convert(((const struct unknown_encoding *)enc)->userData, p);
+  return (c & ~0xFFFF) || checkCharRefNumber(c) < 0;
+}
+
+static
+void unknown_toUtf8(const ENCODING *enc,
+		    const char **fromP, const char *fromLim,
+		    char **toP, const char *toLim)
+{
+  char buf[XML_UTF8_ENCODE_MAX];
+  for (;;) {
+    const char *utf8;
+    int n;
+    if (*fromP == fromLim)
+      break;
+    utf8 = ((const struct unknown_encoding *)enc)->utf8[(unsigned char)**fromP];
+    n = *utf8++;
+    if (n == 0) {
+      int c = ((const struct unknown_encoding *)enc)
+	      ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
+      n = XmlUtf8Encode(c, buf);
+      if (n > toLim - *toP)
+	break;
+      utf8 = buf;
+      *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
+	         - (BT_LEAD2 - 2);
+    }
+    else {
+      if (n > toLim - *toP)
+	break;
+      (*fromP)++;
+    }
+    do {
+      *(*toP)++ = *utf8++;
+    } while (--n != 0);
+  }
+}
+
+static
+void unknown_toUtf16(const ENCODING *enc,
+		     const char **fromP, const char *fromLim,
+		     unsigned short **toP, const unsigned short *toLim)
+{
+  while (*fromP != fromLim && *toP != toLim) {
+    unsigned short c
+      = ((const struct unknown_encoding *)enc)->utf16[(unsigned char)**fromP];
+    if (c == 0) {
+      c = (unsigned short)((const struct unknown_encoding *)enc)
+	   ->convert(((const struct unknown_encoding *)enc)->userData, *fromP);
+      *fromP += ((const struct normal_encoding *)enc)->type[(unsigned char)**fromP]
+	         - (BT_LEAD2 - 2);
+    }
+    else
+      (*fromP)++;
+    *(*toP)++ = c;
+  }
+}
+
+ENCODING *
+XmlInitUnknownEncoding(void *mem,
+		       int *table,
+		       int (*convert)(void *userData, const char *p),
+		       void *userData)
+{
+  int i;
+  struct unknown_encoding *e = mem;
+  for (i = 0; i < (int)sizeof(struct normal_encoding); i++)
+    ((char *)mem)[i] = ((char *)&latin1_encoding)[i];
+  for (i = 0; i < 128; i++)
+    if (latin1_encoding.type[i] != BT_OTHER
+        && latin1_encoding.type[i] != BT_NONXML
+	&& table[i] != i)
+      return 0;
+  for (i = 0; i < 256; i++) {
+    int c = table[i];
+    if (c == -1) {
+      e->normal.type[i] = BT_MALFORM;
+      /* This shouldn't really get used. */
+      e->utf16[i] = 0xFFFF;
+      e->utf8[i][0] = 1;
+      e->utf8[i][1] = 0;
+    }
+    else if (c < 0) {
+      if (c < -4)
+	return 0;
+      e->normal.type[i] = BT_LEAD2 - (c + 2);
+      e->utf8[i][0] = 0;
+      e->utf16[i] = 0;
+    }
+    else if (c < 0x80) {
+      if (latin1_encoding.type[c] != BT_OTHER
+	  && latin1_encoding.type[c] != BT_NONXML
+	  && c != i)
+	return 0;
+      e->normal.type[i] = latin1_encoding.type[c];
+      e->utf8[i][0] = 1;
+      e->utf8[i][1] = (char)c;
+      e->utf16[i] = c == 0 ? 0xFFFF : c;
+    }
+    else if (checkCharRefNumber(c) < 0) {
+      e->normal.type[i] = BT_NONXML;
+      /* This shouldn't really get used. */
+      e->utf16[i] = 0xFFFF;
+      e->utf8[i][0] = 1;
+      e->utf8[i][1] = 0;
+    }
+    else {
+      if (c > 0xFFFF)
+	return 0;
+      if (UCS2_GET_NAMING(nmstrtPages, c >> 8, c & 0xff))
+	e->normal.type[i] = BT_NMSTRT;
+      else if (UCS2_GET_NAMING(namePages, c >> 8, c & 0xff))
+	e->normal.type[i] = BT_NAME;
+      else
+	e->normal.type[i] = BT_OTHER;
+      e->utf8[i][0] = (char)XmlUtf8Encode(c, e->utf8[i] + 1);
+      e->utf16[i] = c;
+    }
+  }
+  e->userData = userData;
+  e->convert = convert;
+  if (convert) {
+    e->normal.isName2 = unknown_isName;
+    e->normal.isName3 = unknown_isName;
+    e->normal.isName4 = unknown_isName;
+    e->normal.isNmstrt2 = unknown_isNmstrt;
+    e->normal.isNmstrt3 = unknown_isNmstrt;
+    e->normal.isNmstrt4 = unknown_isNmstrt;
+    e->normal.isInvalid2 = unknown_isInvalid;
+    e->normal.isInvalid3 = unknown_isInvalid;
+    e->normal.isInvalid4 = unknown_isInvalid;
+  }
+  e->normal.enc.utf8Convert = unknown_toUtf8;
+  e->normal.enc.utf16Convert = unknown_toUtf16;
+  return &(e->normal.enc);
+}
+
+/* If this enumeration is changed, getEncodingIndex and encodings
+must also be changed. */
+enum {
+  UNKNOWN_ENC = -1,
+  ISO_8859_1_ENC = 0,
+  US_ASCII_ENC,
+  UTF_8_ENC,
+  UTF_16_ENC,
+  UTF_16BE_ENC,
+  UTF_16LE_ENC,
+  /* must match encodingNames up to here */
+  NO_ENC
+};
+
+static const char KW_ISO_8859_1[] = {
+  ASCII_I, ASCII_S, ASCII_O, ASCII_MINUS, ASCII_8, ASCII_8, ASCII_5, ASCII_9, ASCII_MINUS, ASCII_1, '\0'
+};
+static const char KW_US_ASCII[] = {
+  ASCII_U, ASCII_S, ASCII_MINUS, ASCII_A, ASCII_S, ASCII_C, ASCII_I, ASCII_I, '\0'
+};
+static const char KW_UTF_8[] =	{
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_8, '\0'
+};
+static const char KW_UTF_16[] =	{
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, '\0'
+};
+static const char KW_UTF_16BE[] = {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_B, ASCII_E, '\0'
+};
+static const char KW_UTF_16LE[] = {
+  ASCII_U, ASCII_T, ASCII_F, ASCII_MINUS, ASCII_1, ASCII_6, ASCII_L, ASCII_E, '\0'
+};
+
+static
+int getEncodingIndex(const char *name)
+{
+  static const char *encodingNames[] = {
+    KW_ISO_8859_1,
+    KW_US_ASCII,
+    KW_UTF_8,
+    KW_UTF_16,
+    KW_UTF_16BE,
+    KW_UTF_16LE,
+  };
+  int i;
+  if (name == 0)
+    return NO_ENC;
+  for (i = 0; i < (int)(sizeof(encodingNames)/sizeof(encodingNames[0])); i++)
+    if (streqci(name, encodingNames[i]))
+      return i;
+  return UNKNOWN_ENC;
+}
+
+/* For binary compatibility, we store the index of the encoding specified
+at initialization in the isUtf16 member. */
+
+#define INIT_ENC_INDEX(enc) ((int)(enc)->initEnc.isUtf16)
+#define SET_INIT_ENC_INDEX(enc, i) ((enc)->initEnc.isUtf16 = (char)i)
+
+/* This is what detects the encoding.
+encodingTable maps from encoding indices to encodings;
+INIT_ENC_INDEX(enc) is the index of the external (protocol) specified encoding;
+state is XML_CONTENT_STATE if we're parsing an external text entity,
+and XML_PROLOG_STATE otherwise.
+*/
+
+
+static
+int initScan(const ENCODING **encodingTable,
+	     const INIT_ENCODING *enc,
+	     int state,
+	     const char *ptr,
+	     const char *end,
+	     const char **nextTokPtr)
+{
+  const ENCODING **encPtr;
+
+  if (ptr == end)
+    return XML_TOK_NONE;
+  encPtr = enc->encPtr;
+  if (ptr + 1 == end) {
+    /* only a single byte available for auto-detection */
+#ifndef XML_DTD /* FIXME */
+    /* a well-formed document entity must have more than one byte */
+    if (state != XML_CONTENT_STATE)
+      return XML_TOK_PARTIAL;
+#endif
+    /* so we're parsing an external text entity... */
+    /* if UTF-16 was externally specified, then we need at least 2 bytes */
+    switch (INIT_ENC_INDEX(enc)) {
+    case UTF_16_ENC:
+    case UTF_16LE_ENC:
+    case UTF_16BE_ENC:
+      return XML_TOK_PARTIAL;
+    }
+    switch ((unsigned char)*ptr) {
+    case 0xFE:
+    case 0xFF:
+    case 0xEF: /* possibly first byte of UTF-8 BOM */
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+	  && state == XML_CONTENT_STATE)
+	break;
+      /* fall through */
+    case 0x00:
+    case 0x3C:
+      return XML_TOK_PARTIAL;
+    }
+  }
+  else {
+    switch (((unsigned char)ptr[0] << 8) | (unsigned char)ptr[1]) {
+    case 0xFEFF:
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+	  && state == XML_CONTENT_STATE)
+	break;
+      *nextTokPtr = ptr + 2;
+      *encPtr = encodingTable[UTF_16BE_ENC];
+      return XML_TOK_BOM;
+    /* 00 3C is handled in the default case */
+    case 0x3C00:
+      if ((INIT_ENC_INDEX(enc) == UTF_16BE_ENC
+	   || INIT_ENC_INDEX(enc) == UTF_16_ENC)
+	  && state == XML_CONTENT_STATE)
+	break;
+      *encPtr = encodingTable[UTF_16LE_ENC];
+      return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+    case 0xFFFE:
+      if (INIT_ENC_INDEX(enc) == ISO_8859_1_ENC
+	  && state == XML_CONTENT_STATE)
+	break;
+      *nextTokPtr = ptr + 2;
+      *encPtr = encodingTable[UTF_16LE_ENC];
+      return XML_TOK_BOM;
+    case 0xEFBB:
+      /* Maybe a UTF-8 BOM (EF BB BF) */
+      /* If there's an explicitly specified (external) encoding
+         of ISO-8859-1 or some flavour of UTF-16
+         and this is an external text entity,
+	 don't look for the BOM,
+         because it might be a legal data. */
+      if (state == XML_CONTENT_STATE) {
+	int e = INIT_ENC_INDEX(enc);
+	if (e == ISO_8859_1_ENC || e == UTF_16BE_ENC || e == UTF_16LE_ENC || e == UTF_16_ENC)
+	  break;
+      }
+      if (ptr + 2 == end)
+	return XML_TOK_PARTIAL;
+      if ((unsigned char)ptr[2] == 0xBF) {
+	*encPtr = encodingTable[UTF_8_ENC];
+	return XML_TOK_BOM;
+      }
+      break;
+    default:
+      if (ptr[0] == '\0') {
+	/* 0 isn't a legal data character. Furthermore a document entity can only
+	   start with ASCII characters.  So the only way this can fail to be big-endian
+	   UTF-16 if it it's an external parsed general entity that's labelled as
+	   UTF-16LE. */
+	if (state == XML_CONTENT_STATE && INIT_ENC_INDEX(enc) == UTF_16LE_ENC)
+	  break;
+	*encPtr = encodingTable[UTF_16BE_ENC];
+	return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+      }
+      else if (ptr[1] == '\0') {
+	/* We could recover here in the case:
+	    - parsing an external entity
+	    - second byte is 0
+	    - no externally specified encoding
+	    - no encoding declaration
+	   by assuming UTF-16LE.  But we don't, because this would mean when
+	   presented just with a single byte, we couldn't reliably determine
+	   whether we needed further bytes. */
+	if (state == XML_CONTENT_STATE)
+	  break;
+	*encPtr = encodingTable[UTF_16LE_ENC];
+	return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+      }
+      break;
+    }
+  }
+  *encPtr = encodingTable[INIT_ENC_INDEX(enc)];
+  return XmlTok(*encPtr, state, ptr, end, nextTokPtr);
+}
+
+
+#define NS(x) x
+#define ns(x) x
+#include "xmltok_ns.c"
+#undef NS
+#undef ns
+
+#ifdef XML_NS
+
+#define NS(x) x ## NS
+#define ns(x) x ## _ns
+
+#include "xmltok_ns.c"
+
+#undef NS
+#undef ns
+
+ENCODING *
+XmlInitUnknownEncodingNS(void *mem,
+		         int *table,
+		         int (*convert)(void *userData, const char *p),
+		         void *userData)
+{
+  ENCODING *enc = XmlInitUnknownEncoding(mem, table, convert, userData);
+  if (enc)
+    ((struct normal_encoding *)enc)->type[ASCII_COLON] = BT_COLON;
+  return enc;
+}
+
+#endif /* XML_NS */
diff --git a/external/expat/xmltok.h b/external/expat/xmltok.h
new file mode 100644
index 0000000..8b02324
--- /dev/null
+++ b/external/expat/xmltok.h
@@ -0,0 +1,299 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#ifndef XmlTok_INCLUDED
+#define XmlTok_INCLUDED 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The following token may be returned by XmlContentTok */
+#define XML_TOK_TRAILING_RSQB -5 /* ] or ]] at the end of the scan; might be start of
+                                    illegal ]]> sequence */
+/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
+#define XML_TOK_NONE -4    /* The string to be scanned is empty */
+#define XML_TOK_TRAILING_CR -3 /* A CR at the end of the scan;
+                                  might be part of CRLF sequence */ 
+#define XML_TOK_PARTIAL_CHAR -2 /* only part of a multibyte sequence */
+#define XML_TOK_PARTIAL -1 /* only part of a token */
+#define XML_TOK_INVALID 0
+
+/* The following tokens are returned by XmlContentTok; some are also
+  returned by XmlAttributeValueTok, XmlEntityTok, XmlCdataSectionTok */
+
+#define XML_TOK_START_TAG_WITH_ATTS 1
+#define XML_TOK_START_TAG_NO_ATTS 2
+#define XML_TOK_EMPTY_ELEMENT_WITH_ATTS 3 /* empty element tag <e/> */
+#define XML_TOK_EMPTY_ELEMENT_NO_ATTS 4
+#define XML_TOK_END_TAG 5
+#define XML_TOK_DATA_CHARS 6
+#define XML_TOK_DATA_NEWLINE 7
+#define XML_TOK_CDATA_SECT_OPEN 8
+#define XML_TOK_ENTITY_REF 9
+#define XML_TOK_CHAR_REF 10     /* numeric character reference */
+
+/* The following tokens may be returned by both XmlPrologTok and XmlContentTok */
+#define XML_TOK_PI 11      /* processing instruction */
+#define XML_TOK_XML_DECL 12 /* XML decl or text decl */
+#define XML_TOK_COMMENT 13
+#define XML_TOK_BOM 14     /* Byte order mark */
+
+/* The following tokens are returned only by XmlPrologTok */
+#define XML_TOK_PROLOG_S 15
+#define XML_TOK_DECL_OPEN 16 /* <!foo */
+#define XML_TOK_DECL_CLOSE 17 /* > */
+#define XML_TOK_NAME 18
+#define XML_TOK_NMTOKEN 19
+#define XML_TOK_POUND_NAME 20 /* #name */
+#define XML_TOK_OR 21 /* | */
+#define XML_TOK_PERCENT 22
+#define XML_TOK_OPEN_PAREN 23
+#define XML_TOK_CLOSE_PAREN 24
+#define XML_TOK_OPEN_BRACKET 25
+#define XML_TOK_CLOSE_BRACKET 26
+#define XML_TOK_LITERAL 27
+#define XML_TOK_PARAM_ENTITY_REF 28
+#define XML_TOK_INSTANCE_START 29
+
+/* The following occur only in element type declarations */
+#define XML_TOK_NAME_QUESTION 30 /* name? */
+#define XML_TOK_NAME_ASTERISK 31 /* name* */
+#define XML_TOK_NAME_PLUS 32 /* name+ */
+#define XML_TOK_COND_SECT_OPEN 33 /* <![ */
+#define XML_TOK_COND_SECT_CLOSE 34 /* ]]> */
+#define XML_TOK_CLOSE_PAREN_QUESTION 35 /* )? */
+#define XML_TOK_CLOSE_PAREN_ASTERISK 36 /* )* */
+#define XML_TOK_CLOSE_PAREN_PLUS 37 /* )+ */
+#define XML_TOK_COMMA 38
+
+/* The following token is returned only by XmlAttributeValueTok */
+#define XML_TOK_ATTRIBUTE_VALUE_S 39
+
+/* The following token is returned only by XmlCdataSectionTok */
+#define XML_TOK_CDATA_SECT_CLOSE 40
+
+/* With namespace processing this is returned by XmlPrologTok
+   for a name with a colon. */
+#define XML_TOK_PREFIXED_NAME 41
+
+#ifdef XML_DTD
+#define XML_TOK_IGNORE_SECT 42
+#endif /* XML_DTD */
+
+#ifdef XML_DTD
+#define XML_N_STATES 4
+#else /* not XML_DTD */
+#define XML_N_STATES 3
+#endif /* not XML_DTD */
+
+#define XML_PROLOG_STATE 0
+#define XML_CONTENT_STATE 1
+#define XML_CDATA_SECTION_STATE 2
+#ifdef XML_DTD
+#define XML_IGNORE_SECTION_STATE 3
+#endif /* XML_DTD */
+
+#define XML_N_LITERAL_TYPES 2
+#define XML_ATTRIBUTE_VALUE_LITERAL 0
+#define XML_ENTITY_VALUE_LITERAL 1
+
+/* The size of the buffer passed to XmlUtf8Encode must be at least this. */
+#define XML_UTF8_ENCODE_MAX 4
+/* The size of the buffer passed to XmlUtf16Encode must be at least this. */
+#define XML_UTF16_ENCODE_MAX 2
+
+typedef struct position {
+  /* first line and first column are 0 not 1 */
+  unsigned long lineNumber;
+  unsigned long columnNumber;
+} POSITION;
+
+typedef struct {
+  const char *name;
+  const char *valuePtr;
+  const char *valueEnd;
+  char normalized;
+} ATTRIBUTE;
+
+struct encoding;
+typedef struct encoding ENCODING;
+
+struct encoding {
+  int (*scanners[XML_N_STATES])(const ENCODING *,
+			        const char *,
+			        const char *,
+			        const char **);
+  int (*literalScanners[XML_N_LITERAL_TYPES])(const ENCODING *,
+					      const char *,
+					      const char *,
+					      const char **);
+  int (*sameName)(const ENCODING *,
+	          const char *, const char *);
+  int (*nameMatchesAscii)(const ENCODING *,
+			  const char *, const char *, const char *);
+  int (*nameLength)(const ENCODING *, const char *);
+  const char *(*skipS)(const ENCODING *, const char *);
+  int (*getAtts)(const ENCODING *enc, const char *ptr,
+	         int attsMax, ATTRIBUTE *atts);
+  int (*charRefNumber)(const ENCODING *enc, const char *ptr);
+  int (*predefinedEntityName)(const ENCODING *, const char *, const char *);
+  void (*updatePosition)(const ENCODING *,
+			 const char *ptr,
+			 const char *end,
+			 POSITION *);
+  int (*isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+		    const char **badPtr);
+  void (*utf8Convert)(const ENCODING *enc,
+		      const char **fromP,
+		      const char *fromLim,
+		      char **toP,
+		      const char *toLim);
+  void (*utf16Convert)(const ENCODING *enc,
+		       const char **fromP,
+		       const char *fromLim,
+		       unsigned short **toP,
+		       const unsigned short *toLim);
+  int minBytesPerChar;
+  char isUtf8;
+  char isUtf16;
+};
+
+/*
+Scan the string starting at ptr until the end of the next complete token,
+but do not scan past eptr.  Return an integer giving the type of token.
+
+Return XML_TOK_NONE when ptr == eptr; nextTokPtr will not be set.
+
+Return XML_TOK_PARTIAL when the string does not contain a complete token;
+nextTokPtr will not be set.
+
+Return XML_TOK_INVALID when the string does not start a valid token; nextTokPtr
+will be set to point to the character which made the token invalid.
+
+Otherwise the string starts with a valid token; nextTokPtr will be set to point
+to the character following the end of that token.
+
+Each data character counts as a single token, but adjacent data characters
+may be returned together.  Similarly for characters in the prolog outside
+literals, comments and processing instructions.
+*/
+
+
+#define XmlTok(enc, state, ptr, end, nextTokPtr) \
+  (((enc)->scanners[state])(enc, ptr, end, nextTokPtr))
+
+#define XmlPrologTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_PROLOG_STATE, ptr, end, nextTokPtr)
+
+#define XmlContentTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_CONTENT_STATE, ptr, end, nextTokPtr)
+
+#define XmlCdataSectionTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_CDATA_SECTION_STATE, ptr, end, nextTokPtr)
+
+#ifdef XML_DTD
+
+#define XmlIgnoreSectionTok(enc, ptr, end, nextTokPtr) \
+   XmlTok(enc, XML_IGNORE_SECTION_STATE, ptr, end, nextTokPtr)
+
+#endif /* XML_DTD */
+
+/* This is used for performing a 2nd-level tokenization on
+the content of a literal that has already been returned by XmlTok. */ 
+
+#define XmlLiteralTok(enc, literalType, ptr, end, nextTokPtr) \
+  (((enc)->literalScanners[literalType])(enc, ptr, end, nextTokPtr))
+
+#define XmlAttributeValueTok(enc, ptr, end, nextTokPtr) \
+   XmlLiteralTok(enc, XML_ATTRIBUTE_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlEntityValueTok(enc, ptr, end, nextTokPtr) \
+   XmlLiteralTok(enc, XML_ENTITY_VALUE_LITERAL, ptr, end, nextTokPtr)
+
+#define XmlSameName(enc, ptr1, ptr2) (((enc)->sameName)(enc, ptr1, ptr2))
+
+#define XmlNameMatchesAscii(enc, ptr1, end1, ptr2) \
+  (((enc)->nameMatchesAscii)(enc, ptr1, end1, ptr2))
+
+#define XmlNameLength(enc, ptr) \
+  (((enc)->nameLength)(enc, ptr))
+
+#define XmlSkipS(enc, ptr) \
+  (((enc)->skipS)(enc, ptr))
+
+#define XmlGetAttributes(enc, ptr, attsMax, atts) \
+  (((enc)->getAtts)(enc, ptr, attsMax, atts))
+
+#define XmlCharRefNumber(enc, ptr) \
+  (((enc)->charRefNumber)(enc, ptr))
+
+#define XmlPredefinedEntityName(enc, ptr, end) \
+  (((enc)->predefinedEntityName)(enc, ptr, end))
+
+#define XmlUpdatePosition(enc, ptr, end, pos) \
+  (((enc)->updatePosition)(enc, ptr, end, pos))
+
+#define XmlIsPublicId(enc, ptr, end, badPtr) \
+  (((enc)->isPublicId)(enc, ptr, end, badPtr))
+
+#define XmlUtf8Convert(enc, fromP, fromLim, toP, toLim) \
+  (((enc)->utf8Convert)(enc, fromP, fromLim, toP, toLim))
+
+#define XmlUtf16Convert(enc, fromP, fromLim, toP, toLim) \
+  (((enc)->utf16Convert)(enc, fromP, fromLim, toP, toLim))
+
+typedef struct {
+  ENCODING initEnc;
+  const ENCODING **encPtr;
+} INIT_ENCODING;
+
+int  XmlParseXmlDecl(int isGeneralTextEntity,
+			      const ENCODING *enc,
+			      const char *ptr,
+	  		      const char *end,
+			      const char **badPtr,
+			      const char **versionPtr,
+			      const char **versionEndPtr,
+			      const char **encodingNamePtr,
+			      const ENCODING **namedEncodingPtr,
+			      int *standalonePtr);
+
+int  XmlInitEncoding(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING  *XmlGetUtf8InternalEncoding(void);
+const ENCODING  *XmlGetUtf16InternalEncoding(void);
+int  XmlUtf8Encode(int charNumber, char *buf);
+int  XmlUtf16Encode(int charNumber, unsigned short *buf);
+
+int  XmlSizeOfUnknownEncoding(void);
+ENCODING  *
+XmlInitUnknownEncoding(void *mem,
+		       int *table,
+		       int (*conv)(void *userData, const char *p),
+		       void *userData);
+
+int  XmlParseXmlDeclNS(int isGeneralTextEntity,
+			        const ENCODING *enc,
+			        const char *ptr,
+	  		        const char *end,
+			        const char **badPtr,
+			        const char **versionPtr,
+				const char **versionEndPtr,
+			        const char **encodingNamePtr,
+			        const ENCODING **namedEncodingPtr,
+			        int *standalonePtr);
+int  XmlInitEncodingNS(INIT_ENCODING *, const ENCODING **, const char *name);
+const ENCODING  *XmlGetUtf8InternalEncodingNS(void);
+const ENCODING  *XmlGetUtf16InternalEncodingNS(void);
+ENCODING  *
+XmlInitUnknownEncodingNS(void *mem,
+		         int *table,
+		         int (*conv)(void *userData, const char *p),
+		         void *userData);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* not XmlTok_INCLUDED */
diff --git a/external/expat/xmltok_impl.c b/external/expat/xmltok_impl.c
new file mode 100644
index 0000000..36d2065
--- /dev/null
+++ b/external/expat/xmltok_impl.c
@@ -0,0 +1,1768 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+#ifndef IS_INVALID_CHAR
+#define IS_INVALID_CHAR(enc, ptr, n) (0)
+#endif
+
+#define INVALID_LEAD_CASE(n, ptr, nextTokPtr) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n) \
+	return XML_TOK_PARTIAL_CHAR; \
+      if (IS_INVALID_CHAR(enc, ptr, n)) { \
+        *(nextTokPtr) = (ptr); \
+        return XML_TOK_INVALID; \
+      } \
+      ptr += n; \
+      break;
+
+#define INVALID_CASES(ptr, nextTokPtr) \
+  INVALID_LEAD_CASE(2, ptr, nextTokPtr) \
+  INVALID_LEAD_CASE(3, ptr, nextTokPtr) \
+  INVALID_LEAD_CASE(4, ptr, nextTokPtr) \
+  case BT_NONXML: \
+  case BT_MALFORM: \
+  case BT_TRAIL: \
+    *(nextTokPtr) = (ptr); \
+    return XML_TOK_INVALID;
+
+#define CHECK_NAME_CASE(n, enc, ptr, end, nextTokPtr) \
+   case BT_LEAD ## n: \
+     if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
+     if (!IS_NAME_CHAR(enc, ptr, n)) { \
+       *nextTokPtr = ptr; \
+       return XML_TOK_INVALID; \
+     } \
+     ptr += n; \
+     break;
+
+#define CHECK_NAME_CASES(enc, ptr, end, nextTokPtr) \
+  case BT_NONASCII: \
+    if (!IS_NAME_CHAR_MINBPC(enc, ptr)) { \
+      *nextTokPtr = ptr; \
+      return XML_TOK_INVALID; \
+    } \
+  case BT_NMSTRT: \
+  case BT_HEX: \
+  case BT_DIGIT: \
+  case BT_NAME: \
+  case BT_MINUS: \
+    ptr += MINBPC(enc); \
+    break; \
+  CHECK_NAME_CASE(2, enc, ptr, end, nextTokPtr) \
+  CHECK_NAME_CASE(3, enc, ptr, end, nextTokPtr) \
+  CHECK_NAME_CASE(4, enc, ptr, end, nextTokPtr)
+
+#define CHECK_NMSTRT_CASE(n, enc, ptr, end, nextTokPtr) \
+   case BT_LEAD ## n: \
+     if (end - ptr < n) \
+       return XML_TOK_PARTIAL_CHAR; \
+     if (!IS_NMSTRT_CHAR(enc, ptr, n)) { \
+       *nextTokPtr = ptr; \
+       return XML_TOK_INVALID; \
+     } \
+     ptr += n; \
+     break;
+
+#define CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr) \
+  case BT_NONASCII: \
+    if (!IS_NMSTRT_CHAR_MINBPC(enc, ptr)) { \
+      *nextTokPtr = ptr; \
+      return XML_TOK_INVALID; \
+    } \
+  case BT_NMSTRT: \
+  case BT_HEX: \
+    ptr += MINBPC(enc); \
+    break; \
+  CHECK_NMSTRT_CASE(2, enc, ptr, end, nextTokPtr) \
+  CHECK_NMSTRT_CASE(3, enc, ptr, end, nextTokPtr) \
+  CHECK_NMSTRT_CASE(4, enc, ptr, end, nextTokPtr)
+
+#ifndef PREFIX
+#define PREFIX(ident) ident
+#endif
+
+/* ptr points to character following "<!-" */
+
+static
+int PREFIX(scanComment)(const ENCODING *enc, const char *ptr, const char *end,
+			const char **nextTokPtr)
+{
+  if (ptr != end) {
+    if (!CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+    ptr += MINBPC(enc);
+    while (ptr != end) {
+      switch (BYTE_TYPE(enc, ptr)) {
+      INVALID_CASES(ptr, nextTokPtr)
+      case BT_MINUS:
+	if ((ptr += MINBPC(enc)) == end)
+	  return XML_TOK_PARTIAL;
+	if (CHAR_MATCHES(enc, ptr, ASCII_MINUS)) {
+	  if ((ptr += MINBPC(enc)) == end)
+	    return XML_TOK_PARTIAL;
+	  if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+	    *nextTokPtr = ptr;
+	    return XML_TOK_INVALID;
+	  }
+	  *nextTokPtr = ptr + MINBPC(enc);
+	  return XML_TOK_COMMENT;
+	}
+	break;
+      default:
+	ptr += MINBPC(enc);
+	break;
+      }
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<!" */
+
+static
+int PREFIX(scanDecl)(const ENCODING *enc, const char *ptr, const char *end,
+		     const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_MINUS:
+    return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_LSQB:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_COND_SECT_OPEN;
+  case BT_NMSTRT:
+  case BT_HEX:
+    ptr += MINBPC(enc);
+    break;
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_PERCNT:
+      if (ptr + MINBPC(enc) == end)
+	return XML_TOK_PARTIAL;
+      /* don't allow <!ENTITY% foo "whatever"> */
+      switch (BYTE_TYPE(enc, ptr + MINBPC(enc))) {
+      case BT_S: case BT_CR: case BT_LF: case BT_PERCNT:
+	*nextTokPtr = ptr;
+	return XML_TOK_INVALID;
+      }
+      /* fall through */
+    case BT_S: case BT_CR: case BT_LF:
+      *nextTokPtr = ptr;
+      return XML_TOK_DECL_OPEN;
+    case BT_NMSTRT:
+    case BT_HEX:
+      ptr += MINBPC(enc);
+      break;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(checkPiTarget)(const ENCODING *enc, const char *ptr, const char *end, int *tokPtr)
+{
+  int upper = 0;
+  *tokPtr = XML_TOK_PI;
+  if (end - ptr != MINBPC(enc)*3)
+    return 1;
+  switch (BYTE_TO_ASCII(enc, ptr)) {
+  case ASCII_x:
+    break;
+  case ASCII_X:
+    upper = 1;
+    break;
+  default:
+    return 1;
+  }
+  ptr += MINBPC(enc);
+  switch (BYTE_TO_ASCII(enc, ptr)) {
+  case ASCII_m:
+    break;
+  case ASCII_M:
+    upper = 1;
+    break;
+  default:
+    return 1;
+  }
+  ptr += MINBPC(enc);
+  switch (BYTE_TO_ASCII(enc, ptr)) {
+  case ASCII_l:
+    break;
+  case ASCII_L:
+    upper = 1;
+    break;
+  default:
+    return 1;
+  }
+  if (upper)
+    return 0;
+  *tokPtr = XML_TOK_XML_DECL;
+  return 1;
+}
+
+/* ptr points to character following "<?" */
+
+static
+int PREFIX(scanPi)(const ENCODING *enc, const char *ptr, const char *end,
+		   const char **nextTokPtr)
+{
+  int tok;
+  const char *target = ptr;
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_S: case BT_CR: case BT_LF:
+      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+	*nextTokPtr = ptr;
+	return XML_TOK_INVALID;
+      }
+      ptr += MINBPC(enc);
+      while (ptr != end) {
+        switch (BYTE_TYPE(enc, ptr)) {
+        INVALID_CASES(ptr, nextTokPtr)
+	case BT_QUEST:
+	  ptr += MINBPC(enc);
+	  if (ptr == end)
+	    return XML_TOK_PARTIAL;
+	  if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+	    *nextTokPtr = ptr + MINBPC(enc);
+	    return tok;
+	  }
+	  break;
+	default:
+	  ptr += MINBPC(enc);
+	  break;
+	}
+      }
+      return XML_TOK_PARTIAL;
+    case BT_QUEST:
+      if (!PREFIX(checkPiTarget)(enc, target, ptr, &tok)) {
+	*nextTokPtr = ptr;
+	return XML_TOK_INVALID;
+      }
+      ptr += MINBPC(enc);
+      if (ptr == end)
+	return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+	*nextTokPtr = ptr + MINBPC(enc);
+	return tok;
+      }
+      /* fall through */
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+
+static
+int PREFIX(scanCdataSection)(const ENCODING *enc, const char *ptr, const char *end,
+			     const char **nextTokPtr)
+{
+  static const char CDATA_LSQB[] = { ASCII_C, ASCII_D, ASCII_A, ASCII_T, ASCII_A, ASCII_LSQB };
+  int i;
+  /* CDATA[ */
+  if (end - ptr < 6 * MINBPC(enc))
+    return XML_TOK_PARTIAL;
+  for (i = 0; i < 6; i++, ptr += MINBPC(enc)) {
+    if (!CHAR_MATCHES(enc, ptr, CDATA_LSQB[i])) {
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_CDATA_SECT_OPEN;
+}
+
+static
+int PREFIX(cdataSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
+			    const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_NONE;
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      if (n == 0)
+	return XML_TOK_PARTIAL;
+      end = ptr + n;
+    }
+  }
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_RSQB:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_PARTIAL;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+      break;
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_PARTIAL;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+      ptr -= MINBPC(enc);
+      break;
+    }
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_CDATA_SECT_CLOSE;
+  case BT_CR:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_PARTIAL;
+    if (BYTE_TYPE(enc, ptr) == BT_LF)
+      ptr += MINBPC(enc);
+    *nextTokPtr = ptr;
+    return XML_TOK_DATA_NEWLINE;
+  case BT_LF:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_DATA_NEWLINE;
+  INVALID_CASES(ptr, nextTokPtr)
+  default:
+    ptr += MINBPC(enc);
+    break;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+	*nextTokPtr = ptr; \
+	return XML_TOK_DATA_CHARS; \
+      } \
+      ptr += n; \
+      break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_NONXML:
+    case BT_MALFORM:
+    case BT_TRAIL:
+    case BT_CR:
+    case BT_LF:
+    case BT_RSQB:
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "</" */
+
+static
+int PREFIX(scanEndTag)(const ENCODING *enc, const char *ptr, const char *end,
+		       const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_S: case BT_CR: case BT_LF:
+      for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+	switch (BYTE_TYPE(enc, ptr)) {
+	case BT_S: case BT_CR: case BT_LF:
+	  break;
+	case BT_GT:
+	  *nextTokPtr = ptr + MINBPC(enc);
+          return XML_TOK_END_TAG;
+	default:
+	  *nextTokPtr = ptr;
+	  return XML_TOK_INVALID;
+	}
+      }
+      return XML_TOK_PARTIAL;
+#ifdef XML_NS
+    case BT_COLON:
+      /* no need to check qname syntax here, since end-tag must match exactly */
+      ptr += MINBPC(enc);
+      break;
+#endif
+    case BT_GT:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_END_TAG;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#X" */
+
+static
+int PREFIX(scanHexCharRef)(const ENCODING *enc, const char *ptr, const char *end,
+			   const char **nextTokPtr)
+{
+  if (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_DIGIT:
+    case BT_HEX:
+      break;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_DIGIT:
+      case BT_HEX:
+	break;
+      case BT_SEMI:
+	*nextTokPtr = ptr + MINBPC(enc);
+	return XML_TOK_CHAR_REF;
+      default:
+	*nextTokPtr = ptr;
+	return XML_TOK_INVALID;
+      }
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&#" */
+
+static
+int PREFIX(scanCharRef)(const ENCODING *enc, const char *ptr, const char *end,
+			const char **nextTokPtr)
+{
+  if (ptr != end) {
+    if (CHAR_MATCHES(enc, ptr, ASCII_x))
+      return PREFIX(scanHexCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_DIGIT:
+      break;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+    for (ptr += MINBPC(enc); ptr != end; ptr += MINBPC(enc)) {
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_DIGIT:
+	break;
+      case BT_SEMI:
+	*nextTokPtr = ptr + MINBPC(enc);
+	return XML_TOK_CHAR_REF;
+      default:
+	*nextTokPtr = ptr;
+	return XML_TOK_INVALID;
+      }
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "&" */
+
+static
+int PREFIX(scanRef)(const ENCODING *enc, const char *ptr, const char *end,
+		    const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_NUM:
+    return PREFIX(scanCharRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_SEMI:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_ENTITY_REF;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following first character of attribute name */
+
+static
+int PREFIX(scanAtts)(const ENCODING *enc, const char *ptr, const char *end,
+		     const char **nextTokPtr)
+{
+#ifdef XML_NS
+  int hadColon = 0;
+#endif
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+    case BT_COLON:
+      if (hadColon) {
+	*nextTokPtr = ptr;
+	return XML_TOK_INVALID;
+      }
+      hadColon = 1;
+      ptr += MINBPC(enc);
+      if (ptr == end)
+	return XML_TOK_PARTIAL;
+      switch (BYTE_TYPE(enc, ptr)) {
+      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+      default:
+	*nextTokPtr = ptr;
+	return XML_TOK_INVALID;
+      }
+      break;
+#endif
+    case BT_S: case BT_CR: case BT_LF:
+      for (;;) {
+	int t;
+
+	ptr += MINBPC(enc);
+	if (ptr == end)
+	  return XML_TOK_PARTIAL;
+	t = BYTE_TYPE(enc, ptr);
+	if (t == BT_EQUALS)
+	  break;
+	switch (t) {
+	case BT_S:
+	case BT_LF:
+	case BT_CR:
+	  break;
+	default:
+	  *nextTokPtr = ptr;
+	  return XML_TOK_INVALID;
+	}
+      }
+    /* fall through */
+    case BT_EQUALS:
+      {
+	int open;
+#ifdef XML_NS
+	hadColon = 0;
+#endif
+	for (;;) {
+	  
+	  ptr += MINBPC(enc);
+	  if (ptr == end)
+	    return XML_TOK_PARTIAL;
+	  open = BYTE_TYPE(enc, ptr);
+	  if (open == BT_QUOT || open == BT_APOS)
+	    break;
+	  switch (open) {
+	  case BT_S:
+	  case BT_LF:
+	  case BT_CR:
+	    break;
+	  default:
+	    *nextTokPtr = ptr;
+	    return XML_TOK_INVALID;
+	  }
+	}
+	ptr += MINBPC(enc);
+	/* in attribute value */
+	for (;;) {
+	  int t;
+	  if (ptr == end)
+	    return XML_TOK_PARTIAL;
+	  t = BYTE_TYPE(enc, ptr);
+	  if (t == open)
+	    break;
+	  switch (t) {
+	  INVALID_CASES(ptr, nextTokPtr)
+	  case BT_AMP:
+	    {
+	      int tok = PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, &ptr);
+	      if (tok <= 0) {
+		if (tok == XML_TOK_INVALID)
+		  *nextTokPtr = ptr;
+		return tok;
+	      }
+	      break;
+	    }
+	  case BT_LT:
+	    *nextTokPtr = ptr;
+	    return XML_TOK_INVALID;
+	  default:
+	    ptr += MINBPC(enc);
+	    break;
+	  }
+	}
+	ptr += MINBPC(enc);
+	if (ptr == end)
+	  return XML_TOK_PARTIAL;
+	switch (BYTE_TYPE(enc, ptr)) {
+	case BT_S:
+	case BT_CR:
+	case BT_LF:
+	  break;
+	case BT_SOL:
+	  goto sol;
+	case BT_GT:
+	  goto gt;
+	default:
+	  *nextTokPtr = ptr;
+	  return XML_TOK_INVALID;
+	}
+	/* ptr points to closing quote */
+	for (;;) {
+	  ptr += MINBPC(enc);
+	  if (ptr == end)
+	    return XML_TOK_PARTIAL;
+	  switch (BYTE_TYPE(enc, ptr)) {
+	  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+	  case BT_S: case BT_CR: case BT_LF:
+	    continue;
+	  case BT_GT:
+          gt:
+	    *nextTokPtr = ptr + MINBPC(enc);
+	    return XML_TOK_START_TAG_WITH_ATTS;
+	  case BT_SOL:
+          sol:
+	    ptr += MINBPC(enc);
+	    if (ptr == end)
+	      return XML_TOK_PARTIAL;
+	    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+	      *nextTokPtr = ptr;
+	      return XML_TOK_INVALID;
+	    }
+	    *nextTokPtr = ptr + MINBPC(enc);
+	    return XML_TOK_EMPTY_ELEMENT_WITH_ATTS;
+	  default:
+	    *nextTokPtr = ptr;
+	    return XML_TOK_INVALID;
+	  }
+	  break;
+	}
+	break;
+      }
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+/* ptr points to character following "<" */
+
+static
+int PREFIX(scanLt)(const ENCODING *enc, const char *ptr, const char *end,
+		   const char **nextTokPtr)
+{
+#ifdef XML_NS
+  int hadColon;
+#endif
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_EXCL:
+    if ((ptr += MINBPC(enc)) == end)
+      return XML_TOK_PARTIAL;
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_MINUS:
+      return PREFIX(scanComment)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    case BT_LSQB:
+      return PREFIX(scanCdataSection)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  case BT_QUEST:
+    return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_SOL:
+    return PREFIX(scanEndTag)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+#ifdef XML_NS
+  hadColon = 0;
+#endif
+  /* we have a start-tag */
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+#ifdef XML_NS
+    case BT_COLON:
+      if (hadColon) {
+	*nextTokPtr = ptr;
+	return XML_TOK_INVALID;
+      }
+      hadColon = 1;
+      ptr += MINBPC(enc);
+      if (ptr == end)
+	return XML_TOK_PARTIAL;
+      switch (BYTE_TYPE(enc, ptr)) {
+      CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+      default:
+        *nextTokPtr = ptr;
+        return XML_TOK_INVALID;
+      }
+      break;
+#endif
+    case BT_S: case BT_CR: case BT_LF:
+      {
+        ptr += MINBPC(enc);
+	while (ptr != end) {
+	  switch (BYTE_TYPE(enc, ptr)) {
+	  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+	  case BT_GT:
+	    goto gt;
+	  case BT_SOL:
+	    goto sol;
+	  case BT_S: case BT_CR: case BT_LF:
+	    ptr += MINBPC(enc);
+	    continue;
+	  default:
+	    *nextTokPtr = ptr;
+	    return XML_TOK_INVALID;
+	  }
+	  return PREFIX(scanAtts)(enc, ptr, end, nextTokPtr);
+	}
+	return XML_TOK_PARTIAL;
+      }
+    case BT_GT:
+    gt:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_START_TAG_NO_ATTS;
+    case BT_SOL:
+    sol:
+      ptr += MINBPC(enc);
+      if (ptr == end)
+	return XML_TOK_PARTIAL;
+      if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+	*nextTokPtr = ptr;
+	return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_EMPTY_ELEMENT_NO_ATTS;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(contentTok)(const ENCODING *enc, const char *ptr, const char *end,
+		       const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_NONE;
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      if (n == 0)
+	return XML_TOK_PARTIAL;
+      end = ptr + n;
+    }
+  }
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_LT:
+    return PREFIX(scanLt)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_AMP:
+    return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_CR:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_TRAILING_CR;
+    if (BYTE_TYPE(enc, ptr) == BT_LF)
+      ptr += MINBPC(enc);
+    *nextTokPtr = ptr;
+    return XML_TOK_DATA_NEWLINE;
+  case BT_LF:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_DATA_NEWLINE;
+  case BT_RSQB:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_TRAILING_RSQB;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_RSQB))
+      break;
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return XML_TOK_TRAILING_RSQB;
+    if (!CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+      ptr -= MINBPC(enc);
+      break;
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  INVALID_CASES(ptr, nextTokPtr)
+  default:
+    ptr += MINBPC(enc);
+    break;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      if (end - ptr < n || IS_INVALID_CHAR(enc, ptr, n)) { \
+	*nextTokPtr = ptr; \
+	return XML_TOK_DATA_CHARS; \
+      } \
+      ptr += n; \
+      break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_RSQB:
+      if (ptr + MINBPC(enc) != end) {
+	 if (!CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_RSQB)) {
+	   ptr += MINBPC(enc);
+	   break;
+	 }
+	 if (ptr + 2*MINBPC(enc) != end) {
+	   if (!CHAR_MATCHES(enc, ptr + 2*MINBPC(enc), ASCII_GT)) {
+	     ptr += MINBPC(enc);
+	     break;
+	   }
+	   *nextTokPtr = ptr + 2*MINBPC(enc);
+	   return XML_TOK_INVALID;
+	 }
+      }
+      /* fall through */
+    case BT_AMP:
+    case BT_LT:
+    case BT_NONXML:
+    case BT_MALFORM:
+    case BT_TRAIL:
+    case BT_CR:
+    case BT_LF:
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+/* ptr points to character following "%" */
+
+static
+int PREFIX(scanPercent)(const ENCODING *enc, const char *ptr, const char *end,
+			const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  case BT_S: case BT_LF: case BT_CR: case BT_PERCNT:
+    *nextTokPtr = ptr;
+    return XML_TOK_PERCENT;
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_SEMI:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_PARAM_ENTITY_REF;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(scanPoundName)(const ENCODING *enc, const char *ptr, const char *end,
+			  const char **nextTokPtr)
+{
+  if (ptr == end)
+    return XML_TOK_PARTIAL;
+  switch (BYTE_TYPE(enc, ptr)) {
+  CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_CR: case BT_LF: case BT_S:
+    case BT_RPAR: case BT_GT: case BT_PERCNT: case BT_VERBAR:
+      *nextTokPtr = ptr;
+      return XML_TOK_POUND_NAME;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return -XML_TOK_POUND_NAME;
+}
+
+static
+int PREFIX(scanLit)(int open, const ENCODING *enc,
+		    const char *ptr, const char *end,
+		    const char **nextTokPtr)
+{
+  while (ptr != end) {
+    int t = BYTE_TYPE(enc, ptr);
+    switch (t) {
+    INVALID_CASES(ptr, nextTokPtr)
+    case BT_QUOT:
+    case BT_APOS:
+      ptr += MINBPC(enc);
+      if (t != open)
+	break;
+      if (ptr == end)
+	return -XML_TOK_LITERAL;
+      *nextTokPtr = ptr;
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_S: case BT_CR: case BT_LF:
+      case BT_GT: case BT_PERCNT: case BT_LSQB:
+	return XML_TOK_LITERAL;
+      default:
+	return XML_TOK_INVALID;
+      }
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+static
+int PREFIX(prologTok)(const ENCODING *enc, const char *ptr, const char *end,
+		      const char **nextTokPtr)
+{
+  int tok;
+  if (ptr == end)
+    return XML_TOK_NONE;
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      if (n == 0)
+	return XML_TOK_PARTIAL;
+      end = ptr + n;
+    }
+  }
+  switch (BYTE_TYPE(enc, ptr)) {
+  case BT_QUOT:
+    return PREFIX(scanLit)(BT_QUOT, enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_APOS:
+    return PREFIX(scanLit)(BT_APOS, enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_LT:
+    {
+      ptr += MINBPC(enc);
+      if (ptr == end)
+	return XML_TOK_PARTIAL;
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_EXCL:
+	return PREFIX(scanDecl)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      case BT_QUEST:
+	return PREFIX(scanPi)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      case BT_NMSTRT:
+      case BT_HEX:
+      case BT_NONASCII:
+      case BT_LEAD2:
+      case BT_LEAD3:
+      case BT_LEAD4:
+	*nextTokPtr = ptr - MINBPC(enc);
+	return XML_TOK_INSTANCE_START;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  case BT_CR:
+    if (ptr + MINBPC(enc) == end)
+      return -XML_TOK_PROLOG_S;
+    /* fall through */
+  case BT_S: case BT_LF:
+    for (;;) {
+      ptr += MINBPC(enc);
+      if (ptr == end)
+	break;
+      switch (BYTE_TYPE(enc, ptr)) {
+      case BT_S: case BT_LF:
+	break;
+      case BT_CR:
+	/* don't split CR/LF pair */
+	if (ptr + MINBPC(enc) != end)
+	  break;
+	/* fall through */
+      default:
+	*nextTokPtr = ptr;
+	return XML_TOK_PROLOG_S;
+      }
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_PROLOG_S;
+  case BT_PERCNT:
+    return PREFIX(scanPercent)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+  case BT_COMMA:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_COMMA;
+  case BT_LSQB:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_OPEN_BRACKET;
+  case BT_RSQB:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return -XML_TOK_CLOSE_BRACKET;
+    if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+      if (ptr + MINBPC(enc) == end)
+	return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_GT)) {
+	*nextTokPtr = ptr + 2*MINBPC(enc);
+	return XML_TOK_COND_SECT_CLOSE;
+      }
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_CLOSE_BRACKET;
+  case BT_LPAR:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_OPEN_PAREN;
+  case BT_RPAR:
+    ptr += MINBPC(enc);
+    if (ptr == end)
+      return -XML_TOK_CLOSE_PAREN;
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_AST:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_CLOSE_PAREN_ASTERISK;
+    case BT_QUEST:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_CLOSE_PAREN_QUESTION;
+    case BT_PLUS:
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_CLOSE_PAREN_PLUS;
+    case BT_CR: case BT_LF: case BT_S:
+    case BT_GT: case BT_COMMA: case BT_VERBAR:
+    case BT_RPAR:
+      *nextTokPtr = ptr;
+      return XML_TOK_CLOSE_PAREN;
+    }
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  case BT_VERBAR:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_OR;
+  case BT_GT:
+    *nextTokPtr = ptr + MINBPC(enc);
+    return XML_TOK_DECL_CLOSE;
+  case BT_NUM:
+    return PREFIX(scanPoundName)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+#define LEAD_CASE(n) \
+  case BT_LEAD ## n: \
+    if (end - ptr < n) \
+      return XML_TOK_PARTIAL_CHAR; \
+    if (IS_NMSTRT_CHAR(enc, ptr, n)) { \
+      ptr += n; \
+      tok = XML_TOK_NAME; \
+      break; \
+    } \
+    if (IS_NAME_CHAR(enc, ptr, n)) { \
+      ptr += n; \
+      tok = XML_TOK_NMTOKEN; \
+      break; \
+    } \
+    *nextTokPtr = ptr; \
+    return XML_TOK_INVALID;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+  case BT_NMSTRT:
+  case BT_HEX:
+    tok = XML_TOK_NAME;
+    ptr += MINBPC(enc);
+    break;
+  case BT_DIGIT:
+  case BT_NAME:
+  case BT_MINUS:
+#ifdef XML_NS
+  case BT_COLON:
+#endif
+    tok = XML_TOK_NMTOKEN;
+    ptr += MINBPC(enc);
+    break;
+  case BT_NONASCII:
+    if (IS_NMSTRT_CHAR_MINBPC(enc, ptr)) {
+      ptr += MINBPC(enc);
+      tok = XML_TOK_NAME;
+      break;
+    }
+    if (IS_NAME_CHAR_MINBPC(enc, ptr)) {
+      ptr += MINBPC(enc);
+      tok = XML_TOK_NMTOKEN;
+      break;
+    }
+    /* fall through */
+  default:
+    *nextTokPtr = ptr;
+    return XML_TOK_INVALID;
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+    case BT_GT: case BT_RPAR: case BT_COMMA:
+    case BT_VERBAR: case BT_LSQB: case BT_PERCNT:
+    case BT_S: case BT_CR: case BT_LF:
+      *nextTokPtr = ptr;
+      return tok;
+#ifdef XML_NS
+    case BT_COLON:
+      ptr += MINBPC(enc);
+      switch (tok) {
+      case XML_TOK_NAME:
+	if (ptr == end)
+	  return XML_TOK_PARTIAL;
+	tok = XML_TOK_PREFIXED_NAME;
+	switch (BYTE_TYPE(enc, ptr)) {
+	CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
+	default:
+	  tok = XML_TOK_NMTOKEN;
+	  break;
+	}
+	break;
+      case XML_TOK_PREFIXED_NAME:
+	tok = XML_TOK_NMTOKEN;
+	break;
+      }
+      break;
+#endif
+    case BT_PLUS:
+      if (tok == XML_TOK_NMTOKEN)  {
+	*nextTokPtr = ptr;
+	return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_NAME_PLUS;
+    case BT_AST:
+      if (tok == XML_TOK_NMTOKEN)  {
+	*nextTokPtr = ptr;
+	return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_NAME_ASTERISK;
+    case BT_QUEST:
+      if (tok == XML_TOK_NMTOKEN)  {
+	*nextTokPtr = ptr;
+	return XML_TOK_INVALID;
+      }
+      *nextTokPtr = ptr + MINBPC(enc);
+      return XML_TOK_NAME_QUESTION;
+    default:
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    }
+  }
+  return -tok;
+}
+
+static
+int PREFIX(attributeValueTok)(const ENCODING *enc, const char *ptr, const char *end,
+			      const char **nextTokPtr)
+{
+  const char *start;
+  if (ptr == end)
+    return XML_TOK_NONE;
+  start = ptr;
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: ptr += n; break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_AMP:
+      if (ptr == start)
+	return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_LT:
+      /* this is for inside entity references */
+      *nextTokPtr = ptr;
+      return XML_TOK_INVALID;
+    case BT_LF:
+      if (ptr == start) {
+	*nextTokPtr = ptr + MINBPC(enc);
+	return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_CR:
+      if (ptr == start) {
+	ptr += MINBPC(enc);
+	if (ptr == end)
+	  return XML_TOK_TRAILING_CR;
+	if (BYTE_TYPE(enc, ptr) == BT_LF)
+	  ptr += MINBPC(enc);
+	*nextTokPtr = ptr;
+	return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_S:
+      if (ptr == start) {
+	*nextTokPtr = ptr + MINBPC(enc);
+	return XML_TOK_ATTRIBUTE_VALUE_S;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+static
+int PREFIX(entityValueTok)(const ENCODING *enc, const char *ptr, const char *end,
+			   const char **nextTokPtr)
+{
+  const char *start;
+  if (ptr == end)
+    return XML_TOK_NONE;
+  start = ptr;
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: ptr += n; break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_AMP:
+      if (ptr == start)
+	return PREFIX(scanRef)(enc, ptr + MINBPC(enc), end, nextTokPtr);
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_PERCNT:
+      if (ptr == start) {
+	int tok =  PREFIX(scanPercent)(enc, ptr + MINBPC(enc),
+				       end, nextTokPtr);
+	return (tok == XML_TOK_PERCENT) ? XML_TOK_INVALID : tok;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_LF:
+      if (ptr == start) {
+	*nextTokPtr = ptr + MINBPC(enc);
+	return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    case BT_CR:
+      if (ptr == start) {
+	ptr += MINBPC(enc);
+	if (ptr == end)
+	  return XML_TOK_TRAILING_CR;
+	if (BYTE_TYPE(enc, ptr) == BT_LF)
+	  ptr += MINBPC(enc);
+	*nextTokPtr = ptr;
+	return XML_TOK_DATA_NEWLINE;
+      }
+      *nextTokPtr = ptr;
+      return XML_TOK_DATA_CHARS;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  *nextTokPtr = ptr;
+  return XML_TOK_DATA_CHARS;
+}
+
+#ifdef XML_DTD
+
+static
+int PREFIX(ignoreSectionTok)(const ENCODING *enc, const char *ptr, const char *end,
+			     const char **nextTokPtr)
+{
+  int level = 0;
+  if (MINBPC(enc) > 1) {
+    size_t n = end - ptr;
+    if (n & (MINBPC(enc) - 1)) {
+      n &= ~(MINBPC(enc) - 1);
+      end = ptr + n;
+    }
+  }
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    INVALID_CASES(ptr, nextTokPtr)
+    case BT_LT:
+      if ((ptr += MINBPC(enc)) == end)
+	return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr, ASCII_EXCL)) {
+	if ((ptr += MINBPC(enc)) == end)
+	  return XML_TOK_PARTIAL;
+	if (CHAR_MATCHES(enc, ptr, ASCII_LSQB)) {
+	  ++level;
+	  ptr += MINBPC(enc);
+	}
+      }
+      break;
+    case BT_RSQB:
+      if ((ptr += MINBPC(enc)) == end)
+	return XML_TOK_PARTIAL;
+      if (CHAR_MATCHES(enc, ptr, ASCII_RSQB)) {
+	if ((ptr += MINBPC(enc)) == end)
+	  return XML_TOK_PARTIAL;
+	if (CHAR_MATCHES(enc, ptr, ASCII_GT)) {
+	  ptr += MINBPC(enc);
+	  if (level == 0) {
+	    *nextTokPtr = ptr;
+	    return XML_TOK_IGNORE_SECT;
+	  }
+	  --level;
+	}
+      }
+      break;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+  }
+  return XML_TOK_PARTIAL;
+}
+
+#endif /* XML_DTD */
+
+static
+int PREFIX(isPublicId)(const ENCODING *enc, const char *ptr, const char *end,
+		       const char **badPtr)
+{
+  ptr += MINBPC(enc);
+  end -= MINBPC(enc);
+  for (; ptr != end; ptr += MINBPC(enc)) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_DIGIT:
+    case BT_HEX:
+    case BT_MINUS:
+    case BT_APOS:
+    case BT_LPAR:
+    case BT_RPAR:
+    case BT_PLUS:
+    case BT_COMMA:
+    case BT_SOL:
+    case BT_EQUALS:
+    case BT_QUEST:
+    case BT_CR:
+    case BT_LF:
+    case BT_SEMI:
+    case BT_EXCL:
+    case BT_AST:
+    case BT_PERCNT:
+    case BT_NUM:
+#ifdef XML_NS
+    case BT_COLON:
+#endif
+      break;
+    case BT_S:
+      if (CHAR_MATCHES(enc, ptr, ASCII_TAB)) {
+	*badPtr = ptr;
+	return 0;
+      }
+      break;
+    case BT_NAME:
+    case BT_NMSTRT:
+      if (!(BYTE_TO_ASCII(enc, ptr) & ~0x7f))
+	break;
+    default:
+      switch (BYTE_TO_ASCII(enc, ptr)) {
+      case 0x24: /* $ */
+      case 0x40: /* @ */
+	break;
+      default:
+	*badPtr = ptr;
+	return 0;
+      }
+      break;
+    }
+  }
+  return 1;
+}
+
+/* This must only be called for a well-formed start-tag or empty element tag.
+Returns the number of attributes.  Pointers to the first attsMax attributes 
+are stored in atts. */
+
+static
+int PREFIX(getAtts)(const ENCODING *enc, const char *ptr,
+		    int attsMax, ATTRIBUTE *atts)
+{
+  enum { other, inName, inValue } state = inName;
+  int nAtts = 0;
+  int open = 0; /* defined when state == inValue;
+		   initialization just to shut up compilers */
+
+  for (ptr += MINBPC(enc);; ptr += MINBPC(enc)) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define START_NAME \
+      if (state == other) { \
+	if (nAtts < attsMax) { \
+	  atts[nAtts].name = ptr; \
+	  atts[nAtts].normalized = 1; \
+	} \
+	state = inName; \
+      }
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: START_NAME ptr += (n - MINBPC(enc)); break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_NONASCII:
+    case BT_NMSTRT:
+    case BT_HEX:
+      START_NAME
+      break;
+#undef START_NAME
+    case BT_QUOT:
+      if (state != inValue) {
+	if (nAtts < attsMax)
+	  atts[nAtts].valuePtr = ptr + MINBPC(enc);
+        state = inValue;
+        open = BT_QUOT;
+      }
+      else if (open == BT_QUOT) {
+        state = other;
+	if (nAtts < attsMax)
+	  atts[nAtts].valueEnd = ptr;
+	nAtts++;
+      }
+      break;
+    case BT_APOS:
+      if (state != inValue) {
+	if (nAtts < attsMax)
+	  atts[nAtts].valuePtr = ptr + MINBPC(enc);
+        state = inValue;
+        open = BT_APOS;
+      }
+      else if (open == BT_APOS) {
+        state = other;
+	if (nAtts < attsMax)
+	  atts[nAtts].valueEnd = ptr;
+	nAtts++;
+      }
+      break;
+    case BT_AMP:
+      if (nAtts < attsMax)
+	atts[nAtts].normalized = 0;
+      break;
+    case BT_S:
+      if (state == inName)
+        state = other;
+      else if (state == inValue
+	       && nAtts < attsMax
+	       && atts[nAtts].normalized
+	       && (ptr == atts[nAtts].valuePtr
+		   || BYTE_TO_ASCII(enc, ptr) != ASCII_SPACE
+		   || BYTE_TO_ASCII(enc, ptr + MINBPC(enc)) == ASCII_SPACE
+	           || BYTE_TYPE(enc, ptr + MINBPC(enc)) == open))
+	atts[nAtts].normalized = 0;
+      break;
+    case BT_CR: case BT_LF:
+      /* This case ensures that the first attribute name is counted
+         Apart from that we could just change state on the quote. */
+      if (state == inName)
+        state = other;
+      else if (state == inValue && nAtts < attsMax)
+	atts[nAtts].normalized = 0;
+      break;
+    case BT_GT:
+    case BT_SOL:
+      if (state != inValue)
+	return nAtts;
+      break;
+    default:
+      break;
+    }
+  }
+  /* not reached */
+}
+
+static
+int PREFIX(charRefNumber)(const ENCODING *enc, const char *ptr)
+{
+  int result = 0;
+  /* skip &# */
+  ptr += 2*MINBPC(enc);
+  if (CHAR_MATCHES(enc, ptr, ASCII_x)) {
+    for (ptr += MINBPC(enc); !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+      int c = BYTE_TO_ASCII(enc, ptr);
+      switch (c) {
+      case ASCII_0: case ASCII_1: case ASCII_2: case ASCII_3: case ASCII_4:
+      case ASCII_5: case ASCII_6: case ASCII_7: case ASCII_8: case ASCII_9:
+	result <<= 4;
+	result |= (c - ASCII_0);
+	break;
+      case ASCII_A: case ASCII_B: case ASCII_C: case ASCII_D: case ASCII_E: case ASCII_F:
+	result <<= 4;
+	result += 10 + (c - ASCII_A);
+	break;
+      case ASCII_a: case ASCII_b: case ASCII_c: case ASCII_d: case ASCII_e: case ASCII_f:
+	result <<= 4;
+	result += 10 + (c - ASCII_a);
+	break;
+      }
+      if (result >= 0x110000)
+	return -1;
+    }
+  }
+  else {
+    for (; !CHAR_MATCHES(enc, ptr, ASCII_SEMI); ptr += MINBPC(enc)) {
+      int c = BYTE_TO_ASCII(enc, ptr);
+      result *= 10;
+      result += (c - ASCII_0);
+      if (result >= 0x110000)
+	return -1;
+    }
+  }
+  return checkCharRefNumber(result);
+}
+
+static
+int PREFIX(predefinedEntityName)(const ENCODING *enc, const char *ptr, const char *end)
+{
+  switch ((end - ptr)/MINBPC(enc)) {
+  case 2:
+    if (CHAR_MATCHES(enc, ptr + MINBPC(enc), ASCII_t)) {
+      switch (BYTE_TO_ASCII(enc, ptr)) {
+      case ASCII_l:
+	return ASCII_LT;
+      case ASCII_g:
+	return ASCII_GT;
+      }
+    }
+    break;
+  case 3:
+    if (CHAR_MATCHES(enc, ptr, ASCII_a)) {
+      ptr += MINBPC(enc);
+      if (CHAR_MATCHES(enc, ptr, ASCII_m)) {
+	ptr += MINBPC(enc);
+	if (CHAR_MATCHES(enc, ptr, ASCII_p))
+	  return ASCII_AMP;
+      }
+    }
+    break;
+  case 4:
+    switch (BYTE_TO_ASCII(enc, ptr)) {
+    case ASCII_q:
+      ptr += MINBPC(enc);
+      if (CHAR_MATCHES(enc, ptr, ASCII_u)) {
+	ptr += MINBPC(enc);
+	if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+	  ptr += MINBPC(enc);
+  	  if (CHAR_MATCHES(enc, ptr, ASCII_t))
+	    return ASCII_QUOT;
+	}
+      }
+      break;
+    case ASCII_a:
+      ptr += MINBPC(enc);
+      if (CHAR_MATCHES(enc, ptr, ASCII_p)) {
+	ptr += MINBPC(enc);
+	if (CHAR_MATCHES(enc, ptr, ASCII_o)) {
+	  ptr += MINBPC(enc);
+  	  if (CHAR_MATCHES(enc, ptr, ASCII_s))
+	    return ASCII_APOS;
+	}
+      }
+      break;
+    }
+  }
+  return 0;
+}
+
+static
+int PREFIX(sameName)(const ENCODING *enc, const char *ptr1, const char *ptr2)
+{
+  for (;;) {
+    switch (BYTE_TYPE(enc, ptr1)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      if (*ptr1++ != *ptr2++) \
+	return 0;
+    LEAD_CASE(4) LEAD_CASE(3) LEAD_CASE(2)
+#undef LEAD_CASE
+      /* fall through */
+      if (*ptr1++ != *ptr2++)
+	return 0;
+      break;
+    case BT_NONASCII:
+    case BT_NMSTRT:
+#ifdef XML_NS
+    case BT_COLON:
+#endif
+    case BT_HEX:
+    case BT_DIGIT:
+    case BT_NAME:
+    case BT_MINUS:
+      if (*ptr2++ != *ptr1++)
+	return 0;
+      if (MINBPC(enc) > 1) {
+	if (*ptr2++ != *ptr1++)
+	  return 0;
+	if (MINBPC(enc) > 2) {
+	  if (*ptr2++ != *ptr1++)
+	    return 0;
+          if (MINBPC(enc) > 3) {
+	    if (*ptr2++ != *ptr1++)
+      	      return 0;
+	  }
+	}
+      }
+      break;
+    default:
+      if (MINBPC(enc) == 1 && *ptr1 == *ptr2)
+	return 1;
+      switch (BYTE_TYPE(enc, ptr2)) {
+      case BT_LEAD2:
+      case BT_LEAD3:
+      case BT_LEAD4:
+      case BT_NONASCII:
+      case BT_NMSTRT:
+#ifdef XML_NS
+      case BT_COLON:
+#endif
+      case BT_HEX:
+      case BT_DIGIT:
+      case BT_NAME:
+      case BT_MINUS:
+	return 0;
+      default:
+	return 1;
+      }
+    }
+  }
+  /* not reached */
+}
+
+static
+int PREFIX(nameMatchesAscii)(const ENCODING *enc, const char *ptr1,
+			     const char *end1, const char *ptr2)
+{
+  for (; *ptr2; ptr1 += MINBPC(enc), ptr2++) {
+    if (ptr1 == end1)
+      return 0;
+    if (!CHAR_MATCHES(enc, ptr1, *ptr2))
+      return 0;
+  }
+  return ptr1 == end1;
+}
+
+static
+int PREFIX(nameLength)(const ENCODING *enc, const char *ptr)
+{
+  const char *start = ptr;
+  for (;;) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: ptr += n; break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_NONASCII:
+    case BT_NMSTRT:
+#ifdef XML_NS
+    case BT_COLON:
+#endif
+    case BT_HEX:
+    case BT_DIGIT:
+    case BT_NAME:
+    case BT_MINUS:
+      ptr += MINBPC(enc);
+      break;
+    default:
+      return ptr - start;
+    }
+  }
+}
+
+static
+const char *PREFIX(skipS)(const ENCODING *enc, const char *ptr)
+{
+  for (;;) {
+    switch (BYTE_TYPE(enc, ptr)) {
+    case BT_LF:
+    case BT_CR:
+    case BT_S:
+      ptr += MINBPC(enc);
+      break;
+    default:
+      return ptr;
+    }
+  }
+}
+
+static
+void PREFIX(updatePosition)(const ENCODING *enc,
+			    const char *ptr,
+			    const char *end,
+			    POSITION *pos)
+{
+  while (ptr != end) {
+    switch (BYTE_TYPE(enc, ptr)) {
+#define LEAD_CASE(n) \
+    case BT_LEAD ## n: \
+      ptr += n; \
+      break;
+    LEAD_CASE(2) LEAD_CASE(3) LEAD_CASE(4)
+#undef LEAD_CASE
+    case BT_LF:
+      pos->columnNumber = (unsigned)-1;
+      pos->lineNumber++;
+      ptr += MINBPC(enc);
+      break;
+    case BT_CR:
+      pos->lineNumber++;
+      ptr += MINBPC(enc);
+      if (ptr != end && BYTE_TYPE(enc, ptr) == BT_LF)
+	ptr += MINBPC(enc);
+      pos->columnNumber = (unsigned)-1;
+      break;
+    default:
+      ptr += MINBPC(enc);
+      break;
+    }
+    pos->columnNumber++;
+  }
+}
+
+#undef DO_LEAD_CASE
+#undef MULTIBYTE_CASES
+#undef INVALID_CASES
+#undef CHECK_NAME_CASE
+#undef CHECK_NAME_CASES
+#undef CHECK_NMSTRT_CASE
+#undef CHECK_NMSTRT_CASES
diff --git a/external/expat/xmltok_impl.h b/external/expat/xmltok_impl.h
new file mode 100644
index 0000000..da0ea60
--- /dev/null
+++ b/external/expat/xmltok_impl.h
@@ -0,0 +1,46 @@
+/*
+Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
+See the file COPYING for copying permission.
+*/
+
+enum {
+  BT_NONXML,
+  BT_MALFORM,
+  BT_LT,
+  BT_AMP,
+  BT_RSQB,
+  BT_LEAD2,
+  BT_LEAD3,
+  BT_LEAD4,
+  BT_TRAIL,
+  BT_CR,
+  BT_LF,
+  BT_GT,
+  BT_QUOT,
+  BT_APOS,
+  BT_EQUALS,
+  BT_QUEST,
+  BT_EXCL,
+  BT_SOL,
+  BT_SEMI,
+  BT_NUM,
+  BT_LSQB,
+  BT_S,
+  BT_NMSTRT,
+  BT_COLON,
+  BT_HEX,
+  BT_DIGIT,
+  BT_NAME,
+  BT_MINUS,
+  BT_OTHER, /* known not to be a name or name start character */
+  BT_NONASCII, /* might be a name or name start character */
+  BT_PERCNT,
+  BT_LPAR,
+  BT_RPAR,
+  BT_AST,
+  BT_PLUS,
+  BT_COMMA,
+  BT_VERBAR
+};
+
+#include <stddef.h>
diff --git a/external/expat/xmltok_ns.c b/external/expat/xmltok_ns.c
new file mode 100644
index 0000000..2185973
--- /dev/null
+++ b/external/expat/xmltok_ns.c
@@ -0,0 +1,98 @@
+const ENCODING *NS(XmlGetUtf8InternalEncoding)(void)
+{
+  return &ns(internal_utf8_encoding).enc;
+}
+
+const ENCODING *NS(XmlGetUtf16InternalEncoding)(void)
+{
+#if XML_BYTE_ORDER == 12
+  return &ns(internal_little2_encoding).enc;
+#elif XML_BYTE_ORDER == 21
+  return &ns(internal_big2_encoding).enc;
+#else
+  const short n = 1;
+  return *(const char *)&n ? &ns(internal_little2_encoding).enc : &ns(internal_big2_encoding).enc;
+#endif
+}
+
+static
+const ENCODING *NS(encodings)[] = {
+  &ns(latin1_encoding).enc,
+  &ns(ascii_encoding).enc,
+  &ns(utf8_encoding).enc,
+  &ns(big2_encoding).enc,
+  &ns(big2_encoding).enc,
+  &ns(little2_encoding).enc,
+  &ns(utf8_encoding).enc /* NO_ENC */
+};
+
+static
+int NS(initScanProlog)(const ENCODING *enc, const char *ptr, const char *end,
+		       const char **nextTokPtr)
+{
+  return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_PROLOG_STATE, ptr, end, nextTokPtr);
+}
+
+static
+int NS(initScanContent)(const ENCODING *enc, const char *ptr, const char *end,
+		       const char **nextTokPtr)
+{
+  return initScan(NS(encodings), (const INIT_ENCODING *)enc, XML_CONTENT_STATE, ptr, end, nextTokPtr);
+}
+
+int NS(XmlInitEncoding)(INIT_ENCODING *p, const ENCODING **encPtr, const char *name)
+{
+  int i = getEncodingIndex(name);
+  if (i == UNKNOWN_ENC)
+    return 0;
+  SET_INIT_ENC_INDEX(p, i);
+  p->initEnc.scanners[XML_PROLOG_STATE] = NS(initScanProlog);
+  p->initEnc.scanners[XML_CONTENT_STATE] = NS(initScanContent);
+  p->initEnc.updatePosition = initUpdatePosition;
+  p->encPtr = encPtr;
+  *encPtr = &(p->initEnc);
+  return 1;
+}
+
+static
+const ENCODING *NS(findEncoding)(const ENCODING *enc, const char *ptr, const char *end)
+{
+#define ENCODING_MAX 128
+  char buf[ENCODING_MAX];
+  char *p = buf;
+  int i;
+  XmlUtf8Convert(enc, &ptr, end, &p, p + ENCODING_MAX - 1);
+  if (ptr != end)
+    return 0;
+  *p = 0;
+  if (streqci(buf, KW_UTF_16) && enc->minBytesPerChar == 2)
+    return enc;
+  i = getEncodingIndex(buf);
+  if (i == UNKNOWN_ENC)
+    return 0;
+  return NS(encodings)[i];
+}
+
+int NS(XmlParseXmlDecl)(int isGeneralTextEntity,
+			const ENCODING *enc,
+			const char *ptr,
+			const char *end,
+			const char **badPtr,
+			const char **versionPtr,
+			const char **versionEndPtr,
+			const char **encodingName,
+			const ENCODING **encoding,
+			int *standalone)
+{
+  return doParseXmlDecl(NS(findEncoding),
+			isGeneralTextEntity,
+			enc,
+			ptr,
+			end,
+			badPtr,
+			versionPtr,
+			versionEndPtr,
+			encodingName,
+			encoding,
+			standalone);
+}
diff --git a/makefile b/external/makefile
similarity index 69%
copy from makefile
copy to external/makefile
index 8c62a03..6e0b464 100644
--- a/makefile
+++ b/external/makefile
@@ -10,17 +10,24 @@
 # representations about the suitability of this software for any purpose.
 # It is provided "as is" without express or implied warranty.
 
-EXTRA_INSTALL_TARGETS	=	mk_nonlocal_install_dirs
 
 include $(TOPDIR)/config/common.mak
  
 #
 # Sub-directories that need to be built
 #
-subdirs	= external vpflib ogdi contrib
+subdirs	= 
 
-ifneq ($(PROJ_SETTING),external)
-subdirs := proj $(subdirs) 
+ifeq ($(ZLIB_SETTING),internal)
+subdirs := zlib $(subdirs) 
+endif
+
+ifeq ($(TARGET),win32)
+subdirs += rpc_win32
+endif
+
+ifeq ($(EXPAT_SETTING),internal)
+subdirs := expat $(subdirs) 
 endif
 
 #
@@ -28,25 +35,15 @@ endif
 #
 all: $(subdirs) 
 
-
 #
 # Target to allow individual sub-directories to be built 
-# (e.g.  make cmpts)
+# (e.g.  make zlib)
 #
 .PHONY: $(subdirs)
-$(subdirs): mkinstalldirs
+$(subdirs): 
 	cd $@; $(MAKE)
 
 #
-# Make the (local) installation directories
-#
-.PHONY: mkinstalldirs
-mkinstalldirs:
-	@echo making install dirs using $(MKINSTALLDIR)
-	$(MKINSTALLDIR) $(TOPDIR)/lib/$(TARGET)/static
-	$(MKINSTALLDIR) $(TOPDIR)/bin/$(TARGET)
-
-#
 # Pass specialized targets into the sub-directories
 #
 .PHONY: $(STANDARD_TARGETS)
@@ -54,8 +51,3 @@ $(STANDARD_TARGETS):
 	@for i in $(subdirs); do \
 	  $(MAKE) --directory $$i $@; \
 	done
-
-
-mk_nonlocal_install_dirs:
-	$(MKINSTALLDIR) $(prefix) $(exec_prefix) $(INST_LIB) $(INST_BIN) $(INST_INCLUDE)
-
diff --git a/external/rpc_win32/LIBRPC/Makefile b/external/rpc_win32/LIBRPC/Makefile
new file mode 100644
index 0000000..6637e09
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/Makefile
@@ -0,0 +1,89 @@
+#
+#  Zlib compression library makefile
+#
+# Copyright (C) 1997 Logiciels et Applications Scientifiques (L.A.S.) Inc
+# Permission to use, copy, modify and distribute this software and
+# its documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies, that
+# both the copyright notice and this permission notice appear in
+# supporting documentation, and that the name of L.A.S. Inc not be used 
+# in advertising or publicity pertaining to distribution of the software 
+# without specific, written prior permission. L.A.S. Inc. makes no
+# representations about the suitability of this software for any purpose.
+# It is provided "as is" without express or implied warranty.
+#
+
+#
+# The names of the targets to build
+#
+TOBEGEN		= rpc
+TARGETGEN	= $(ARCHGEN)
+
+#
+# Source files
+#
+SOURCES =	clnt_raw.c \
+		xdr.c \
+		clnt_tcp.c \
+		clnt_udp.c \
+		pmap_rmt.c \
+		rpc_prot.c \
+		svc_autu.c \
+		svc_auth.c \
+		svc_raw.c \
+		svc_run.c \
+		svc_tcp.c \
+		svc_udp.c \
+		xdr_mem.c \
+		xdr_rec.c \
+		auth_non.c \
+		auth_uni.c \
+		authunix.c \
+		bindresv.c \
+		clnt_gen.c \
+		clnt_per.c \
+		clnt_sim.c \
+		get_myad.c \
+		getrpcen.c \
+		getrpcpo.c \
+		pmap_cln.c \
+		pmap_get.c \
+		pmap_gma.c \
+		pmap_pro.c \
+		pmap_pr.c \
+		rpc_call.c \
+		rpc_comm.c \
+		svc_simp.c \
+		xdr_arra.c \
+		xdr_floa.c \
+		xdr_refe.c \
+		xdr_stdi.c \
+		svc.c \
+		bcopy.c \
+		nt.c
+
+#
+# Compilation flags
+#
+INCLUDES = $(CURRENT_INCLUDE) $(OGDI_INCLUDE) $(PROJ_INCLUDE)\
+	   $(ZLIB_INCLUDE) $(GENERAL_INCLUDE) $(TCLTK_INCLUDE)
+CFLAGS 	= $(INCLUDES) $(COMMON_CFLAGS) $(FLAGS_X86DEF)
+LINK_LIBS= $(WIN_LINKLIB)
+
+
+#
+# Include the common configuration
+#
+include $(TOPDIR)/config/common.mak
+
+#
+# Primary target
+#
+all: MKOBJECTDIR
+	@echo "making $(TARGETGEN)"
+	$(MAKE) --directory $(OBJDIR) -f ../makefile PASS='depend' $(TARGETGEN)
+	$(MAKE) -f makeportmap.mak
+	$(MAKE) -f makerpcinfo.mak
+
+clean: default-clean
+
diff --git a/external/rpc_win32/LIBRPC/ONCRPC.DEF b/external/rpc_win32/LIBRPC/ONCRPC.DEF
new file mode 100644
index 0000000..2f57487
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/ONCRPC.DEF
@@ -0,0 +1,86 @@
+LIBRARY oncrpc
+EXPORTS
+authnone_create
+authunix_create
+authunix_create_default
+bcopy
+bzero
+bcmp
+clnt_create
+clnt_broadcast
+clnt_pcreateerror
+clnt_perrno
+clnt_perror
+clnt_spcreateerror
+clnt_sperrno
+clnt_sperror
+clntraw_create
+clnttcp_create
+clntudp_bufcreate
+clntudp_create
+get_myaddress
+getrpcbyname
+getrpcbynumber
+pmap_getmaps
+pmap_getport
+pmap_set
+pmap_unset
+rpc_nt_exit
+rpc_nt_init
+svc_getreq
+svc_getreqset
+svc_register
+svc_run
+svc_sendreply
+svc_unregister
+svcerr_auth
+svcerr_decode
+svcerr_noproc
+svcerr_noprog
+svcerr_progvers
+svcerr_systemerr
+svcerr_weakauth
+svcraw_create
+svctcp_create
+svcudp_bufcreate
+svcudp_create
+xdr_array
+xdr_authunix_parms
+xdr_bool
+xdr_bytes
+xdr_callhdr
+xdr_callmsg
+xdr_char
+xdr_des_block
+xdr_double
+xdr_enum
+xdr_float
+xdr_free
+xdr_int
+xdr_long
+xdr_netobj
+xdr_opaque
+xdr_opaque_auth
+xdr_pmap
+xdr_pmaplist
+xdr_pointer
+xdr_reference
+xdr_replymsg
+xdr_short
+xdr_string
+xdr_u_char
+xdr_u_int
+xdr_u_long
+xdr_u_short
+xdr_union
+xdr_vector
+xdr_void
+xdr_wrapstring
+xdrmem_create
+xdrrec_create
+xdrrec_endofrecord
+xdrrec_eof
+xdrrec_skiprecord
+xdrstdio_create
+xprt_register
+xprt_unregister
diff --git a/external/rpc_win32/LIBRPC/auth_non.c b/external/rpc_win32/LIBRPC/auth_non.c
new file mode 100644
index 0000000..9328755
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/auth_non.c
@@ -0,0 +1,144 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)auth_none.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * auth_none.c
+ * Creates a client authentication handle for passing "null" 
+ * credentials and verifiers to remote systems. 
+ * 
+ * Copyright (C) 1984, Sun Microsystems, Inc. 
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#define MAX_MARSHEL_SIZE 20
+
+/*
+ * Authenticator operations routines
+ */
+static void	authnone_verf();
+static void	authnone_destroy();
+static bool_t	authnone_marshal();
+static bool_t	authnone_validate();
+static bool_t	authnone_refresh();
+
+static struct auth_ops ops = {
+	authnone_verf,
+	authnone_marshal,
+	authnone_validate,
+	authnone_refresh,
+	authnone_destroy
+};
+
+static struct authnone_private {
+	AUTH	no_client;
+	char	marshalled_client[MAX_MARSHEL_SIZE];
+	u_int	mcnt;
+} *authnone_private;
+
+AUTH *
+authnone_create()
+{
+	register struct authnone_private *ap = authnone_private;
+	XDR xdr_stream;
+	register XDR *xdrs;
+
+	if (ap == 0) {
+		ap = (struct authnone_private *)calloc(1, sizeof (*ap));
+		if (ap == 0)
+			return (0);
+		authnone_private = ap;
+	}
+	if (!ap->mcnt) {
+		ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth;
+		ap->no_client.ah_ops = &ops;
+		xdrs = &xdr_stream;
+		xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHEL_SIZE,
+		    XDR_ENCODE);
+		(void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred);
+		(void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf);
+		ap->mcnt = XDR_GETPOS(xdrs);
+		XDR_DESTROY(xdrs);
+	}
+	return (&ap->no_client);
+}
+
+/*ARGSUSED*/
+static bool_t
+authnone_marshal(client, xdrs)
+	AUTH *client;
+	XDR *xdrs;
+{
+	register struct authnone_private *ap = authnone_private;
+
+	if (ap == 0)
+		return (0);
+	return ((*xdrs->x_ops->x_putbytes)(xdrs,
+	    ap->marshalled_client, ap->mcnt));
+}
+
+static void 
+authnone_verf()
+{
+}
+
+static bool_t
+authnone_validate()
+{
+
+	return (TRUE);
+}
+
+static bool_t
+authnone_refresh()
+{
+
+	return (FALSE);
+}
+
+static void
+authnone_destroy()
+{
+}
diff --git a/external/rpc_win32/LIBRPC/auth_uni.c b/external/rpc_win32/LIBRPC/auth_uni.c
new file mode 100644
index 0000000..ee482fe
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/auth_uni.c
@@ -0,0 +1,357 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)auth_unix.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * auth_unix.c, Implements UNIX style authentication parameters.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The system is very weak.  The client uses no encryption for it's
+ * credentials and only sends null verifiers.  The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ *
+ */
+
+#include <stdio.h>
+
+#ifdef WIN32
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_uni.h>
+#else
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+#endif
+
+/*
+ * Unix authenticator operations vector
+ */
+static void	authunix_nextverf();
+static bool_t	authunix_marshal();
+static bool_t	authunix_validate();
+static bool_t	authunix_refresh();
+static void	authunix_destroy();
+
+static struct auth_ops auth_unix_ops = {
+	authunix_nextverf,
+	authunix_marshal,
+	authunix_validate,
+	authunix_refresh,
+	authunix_destroy
+};
+
+/*
+ * This struct is pointed to by the ah_private field of an auth_handle.
+ */
+struct audata {
+	struct opaque_auth	au_origcred;	/* original credentials */
+	struct opaque_auth	au_shcred;	/* short hand cred */
+	u_long			au_shfaults;	/* short hand cache faults */
+	char			au_marshed[MAX_AUTH_BYTES];
+	u_int			au_mpos;	/* xdr pos at end of marshed */
+};
+#define	AUTH_PRIVATE(auth)	((struct audata *)auth->ah_private)
+
+static bool_t marshal_new_auth();
+
+
+/*
+ * Create a unix style authenticator.
+ * Returns an auth handle with the given stuff in it.
+ */
+AUTH *
+authunix_create(machname, uid, gid, len, aup_gids)
+	char *machname;
+	int uid;
+	int gid;
+	register int len;
+	int *aup_gids;
+{
+	struct authunix_parms aup;
+	char mymem[MAX_AUTH_BYTES];
+	struct timeval now;
+	XDR xdrs;
+	register AUTH *auth;
+	register struct audata *au;
+
+	/*
+	 * Allocate and set up auth handle
+	 */
+	auth = (AUTH *)mem_alloc(sizeof(*auth));
+#ifndef KERNEL
+	if (auth == NULL) {
+#ifdef WIN32
+		nt_rpc_report("authunix_create: out of memory\n");
+#else
+		(void)fprintf(stderr, "authunix_create: out of memory\n");
+#endif
+		return (NULL);
+	}
+#endif
+	au = (struct audata *)mem_alloc(sizeof(*au));
+#ifndef KERNEL
+	if (au == NULL) {
+#ifdef WIN32
+		nt_rpc_report("authunix_create: out of memory\n");
+#else
+		(void)fprintf(stderr, "authunix_create: out of memory\n");
+#endif
+		return (NULL);
+	}
+#endif
+	auth->ah_ops = &auth_unix_ops;
+	auth->ah_private = (caddr_t)au;
+	auth->ah_verf = au->au_shcred = _null_auth;
+	au->au_shfaults = 0;
+
+	/*
+	 * fill in param struct from the given params
+	 */
+	(void)gettimeofday(&now,  (struct timezone *)0);
+	aup.aup_time = now.tv_sec;
+	aup.aup_machname = machname;
+	aup.aup_uid = uid;
+	aup.aup_gid = gid;
+	aup.aup_len = (u_int)len;
+	aup.aup_gids = aup_gids;
+
+	/*
+	 * Serialize the parameters into origcred
+	 */
+	xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE);
+	if (! xdr_authunix_parms(&xdrs, &aup))
+		abort();
+	au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs);
+	au->au_origcred.oa_flavor = AUTH_UNIX;
+#ifdef KERNEL
+	au->au_origcred.oa_base = mem_alloc((u_int) len);
+#else
+	if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) {
+#ifdef WIN32
+		nt_rpc_report("authunix_create: out of memory\n");
+#else
+		(void)fprintf(stderr, "authunix_create: out of memory\n");
+#endif
+		return (NULL);
+	}
+#endif
+	bcopy(mymem, au->au_origcred.oa_base, (u_int)len);
+
+	/*
+	 * set auth handle to reflect new cred.
+	 */
+	auth->ah_cred = au->au_origcred;
+	marshal_new_auth(auth);
+	return (auth);
+}
+
+/*
+ * Returns an auth handle with parameters determined by doing lots of
+ * syscalls.
+ */
+AUTH *
+authunix_create_default()
+{
+	register int len;
+	char machname[MAX_MACHINE_NAME + 1];
+	register int uid;
+	register int gid;
+	int gids[NGRPS];
+
+	if (gethostname(machname, MAX_MACHINE_NAME) == -1)
+		abort();
+	machname[MAX_MACHINE_NAME] = 0;
+#ifdef WIN32
+/* who knows anything better? */
+	uid = 0;
+	gid = 0;
+	len = 1;
+	gids[0] = 0;
+#else
+	uid = geteuid();
+	gid = getegid();
+	if ((len = getgroups(NGRPS, gids)) < 0)
+		abort();
+#endif
+	return (authunix_create(machname, uid, gid, len, gids));
+}
+
+/*
+ * authunix operations
+ */
+
+static void
+authunix_nextverf(auth)
+	AUTH *auth;
+{
+	/* no action necessary */
+}
+
+static bool_t
+authunix_marshal(auth, xdrs)
+	AUTH *auth;
+	XDR *xdrs;
+{
+	register struct audata *au = AUTH_PRIVATE(auth);
+
+	return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos));
+}
+
+static bool_t
+authunix_validate(auth, verf)
+	register AUTH *auth;
+	struct opaque_auth verf;
+{
+	register struct audata *au;
+	XDR xdrs;
+
+	if (verf.oa_flavor == AUTH_SHORT) {
+		au = AUTH_PRIVATE(auth);
+		xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE);
+
+		if (au->au_shcred.oa_base != NULL) {
+			mem_free(au->au_shcred.oa_base,
+			    au->au_shcred.oa_length);
+			au->au_shcred.oa_base = NULL;
+		}
+		if (xdr_opaque_auth(&xdrs, &au->au_shcred)) {
+			auth->ah_cred = au->au_shcred;
+		} else {
+			xdrs.x_op = XDR_FREE;
+			(void)xdr_opaque_auth(&xdrs, &au->au_shcred);
+			au->au_shcred.oa_base = NULL;
+			auth->ah_cred = au->au_origcred;
+		}
+		marshal_new_auth(auth);
+	}
+	return (TRUE);
+}
+
+static bool_t
+authunix_refresh(auth)
+	register AUTH *auth;
+{
+	register struct audata *au = AUTH_PRIVATE(auth);
+	struct authunix_parms aup;
+	struct timeval now;
+	XDR xdrs;
+	register int stat;
+
+	if (auth->ah_cred.oa_base == au->au_origcred.oa_base) {
+		/* there is no hope.  Punt */
+		return (FALSE);
+	}
+	au->au_shfaults ++;
+
+	/* first deserialize the creds back into a struct authunix_parms */
+	aup.aup_machname = NULL;
+	aup.aup_gids = (int *)NULL;
+	xdrmem_create(&xdrs, au->au_origcred.oa_base,
+	    au->au_origcred.oa_length, XDR_DECODE);
+	stat = xdr_authunix_parms(&xdrs, &aup);
+	if (! stat)
+		goto done;
+
+	/* update the time and serialize in place */
+	(void)gettimeofday(&now, (struct timezone *)0);
+	aup.aup_time = now.tv_sec;
+	xdrs.x_op = XDR_ENCODE;
+	XDR_SETPOS(&xdrs, 0);
+	stat = xdr_authunix_parms(&xdrs, &aup);
+	if (! stat)
+		goto done;
+	auth->ah_cred = au->au_origcred;
+	marshal_new_auth(auth);
+done:
+	/* free the struct authunix_parms created by deserializing */
+	xdrs.x_op = XDR_FREE;
+	(void)xdr_authunix_parms(&xdrs, &aup);
+	XDR_DESTROY(&xdrs);
+	return (stat);
+}
+
+static void
+authunix_destroy(auth)
+	register AUTH *auth;
+{
+	register struct audata *au = AUTH_PRIVATE(auth);
+
+	mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length);
+
+	if (au->au_shcred.oa_base != NULL)
+		mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length);
+
+	mem_free(auth->ah_private, sizeof(struct audata));
+
+	if (auth->ah_verf.oa_base != NULL)
+		mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length);
+
+	mem_free((caddr_t)auth, sizeof(*auth));
+}
+
+/*
+ * Marshals (pre-serializes) an auth struct.
+ * sets private data, au_marshed and au_mpos
+ */
+static bool_t
+marshal_new_auth(auth)
+	register AUTH *auth;
+{
+	XDR		xdr_stream;
+	register XDR	*xdrs = &xdr_stream;
+	register struct audata *au = AUTH_PRIVATE(auth);
+
+	xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE);
+	if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) ||
+	    (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) {
+		perror("auth_none.c - Fatal marshalling problem");
+	} else {
+		au->au_mpos = XDR_GETPOS(xdrs);
+	}
+	XDR_DESTROY(xdrs);
+}
diff --git a/external/rpc_win32/LIBRPC/authunix.c b/external/rpc_win32/LIBRPC/authunix.c
new file mode 100644
index 0000000..e170ff0
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/authunix.c
@@ -0,0 +1,84 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)authunix_prot.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * authunix_prot.c
+ * XDR for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+
+#ifdef WIN32
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_uni.h>
+#else
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+#endif
+
+/*
+ * XDR for unix authentication parameters.
+ */
+bool_t
+xdr_authunix_parms(xdrs, p)
+	register XDR *xdrs;
+	register struct authunix_parms *p;
+{
+
+	if (xdr_u_long(xdrs, &(p->aup_time))
+	    && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME)
+	    && xdr_int(xdrs, &(p->aup_uid))
+	    && xdr_int(xdrs, &(p->aup_gid))
+	    && xdr_array(xdrs, (caddr_t *)&(p->aup_gids),
+		    &(p->aup_len), NGRPS, sizeof(int), xdr_int) ) {
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
diff --git a/external/rpc_win32/LIBRPC/bcopy.c b/external/rpc_win32/LIBRPC/bcopy.c
new file mode 100644
index 0000000..21ab8fb
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/bcopy.c
@@ -0,0 +1,64 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/*
+ *  bcopy.c --
+ *      Implements bcopy(2) and bzero(2) byte operations.
+ *
+ *  Author:
+ *      See-Mong Tan, 6/26/88
+ */
+
+#include <stdio.h>
+
+/*
+ *  bcopy(char *s1, char *s2, int len) --
+ *      Copies len bytes from s1 to s2
+ */
+void
+bcopy(s1, s2, len)
+	char *s1, *s2;
+	int len;
+{
+	for(; len > 0; len--)
+		*s2++ = *s1++;
+}
+
+/*
+ *  bzero(char *s, int len) --
+ *      Places len zero byes in s
+ */
+void
+bzero(s, len)
+	char *s;
+	int len;
+{
+	for(; len > 0; len--)
+		*s++ = (char) 0;
+}
+
+/*
+ *  bcmp() compares byte  string  b1  against  byte  string  b2, 
+ *  returning  zero  if  they are identical, non-zero otherwise. 
+ *  Both strings are assumed to be length bytes long.  bcmp() of 
+ *  length zero bytes always returns zero.                       
+*/
+int
+bcmp(s1, s2, len)
+	char *s1, *s2;
+	int len;
+{
+	for(; len > 0; len--, s1++, s2++)
+		if (*s1 != *s2)
+			return 1;
+	return 0;
+}
+	
diff --git a/external/rpc_win32/LIBRPC/bindresv.c b/external/rpc_win32/LIBRPC/bindresv.c
new file mode 100644
index 0000000..47e9e52
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/bindresv.c
@@ -0,0 +1,112 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+static  char sccsid[] = "@(#)bindresvport.c	2.2 88/07/29 4.0 RPCSRC 1.8 88/02/08 SMI";
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Copyright (c) 1987 by Sun Microsystems, Inc.
+ */
+
+#ifdef WIN32
+#include <rpc/rpc.h>
+#include <sys/types.h>
+#include <errno.h>
+#else
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#endif
+
+/*
+ * Bind a socket to a privileged IP port
+ */
+bindresvport(sd, sin)
+	int sd;
+	struct sockaddr_in *sin;
+{
+	int res;
+	static short port;
+	struct sockaddr_in myaddr;
+#ifdef WIN32
+	int my_errno;
+#else
+	extern int errno;
+#endif
+	int i;
+
+#define STARTPORT 600
+#define ENDPORT (IPPORT_RESERVED - 1)
+#define NPORTS	(ENDPORT - STARTPORT + 1)
+
+	if (sin == (struct sockaddr_in *)0) {
+		sin = &myaddr;
+		bzero(sin, sizeof (*sin));
+		sin->sin_family = AF_INET;
+	} else if (sin->sin_family != AF_INET) {
+#ifdef WIN32
+		my_errno = WSAEPFNOSUPPORT;
+#else
+		errno = EPFNOSUPPORT;
+#endif
+
+		return (-1);
+	}
+	if (port == 0) {
+		port = (getpid() % NPORTS) + STARTPORT;
+	}
+	res = -1;
+#ifdef WIN32
+	my_errno = WSAEADDRINUSE;
+	for (i = 0; i < NPORTS && res < 0 && my_errno == WSAEADDRINUSE; i++) {
+#else
+	errno = EADDRINUSE;
+	for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) {
+#endif
+		sin->sin_port = htons(port++);
+		if (port > ENDPORT) {
+			port = STARTPORT;
+		}
+		res = bind(sd, sin, sizeof(struct sockaddr_in));
+#ifdef WIN32
+		my_errno = WSAerrno;
+#endif
+	}
+	return (res);
+}
diff --git a/external/rpc_win32/LIBRPC/clnt_gen.c b/external/rpc_win32/LIBRPC/clnt_gen.c
new file mode 100644
index 0000000..19df320
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/clnt_gen.c
@@ -0,0 +1,151 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)clnt_generic.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";
+#endif
+/*
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+#ifdef WIN32
+#include <rpc/rpc.h>
+#include <errno.h>
+#else
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <netdb.h>
+#endif
+
+/*
+ * Generic client creation: takes (hostname, program-number, protocol) and
+ * returns client handle. Default options are set, which the user can 
+ * change using the rpc equivalent of ioctl()'s.
+ */
+CLIENT *
+clnt_create(hostname, prog, vers, proto)
+	char *hostname;
+	unsigned prog;
+	unsigned vers;
+	char *proto;
+{
+	struct hostent *h;
+	struct protoent *p;
+	struct sockaddr_in sin;
+	int sock;
+	struct timeval tv;
+	CLIENT *client;
+	unsigned long idaddr;
+	
+	/* Si le hostname n'est pas une adresse IP,
+	   essayer de le passer avec gethostbyname */
+
+	if ((idaddr = inet_addr(hostname)) != INADDR_NONE) {
+	  h = gethostbyaddr((char *) &idaddr,4,PF_INET);
+	  if (h == NULL) {
+	    rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
+	    return (NULL);
+	  }
+	} else {
+	  h = gethostbyname(hostname);
+	  if (h == NULL) {
+	    rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
+	    return (NULL);
+	  }
+	}
+	
+	if (h->h_addrtype != AF_INET) {
+		/*
+		 * Only support INET for now
+		 */
+		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+#ifdef WIN32
+		rpc_createerr.cf_error.re_errno = WSAEAFNOSUPPORT; 
+#else
+		rpc_createerr.cf_error.re_errno = EAFNOSUPPORT; 
+#endif
+		return (NULL);
+	}
+	sin.sin_family = h->h_addrtype;
+	sin.sin_port = 0;
+	bzero(sin.sin_zero, sizeof(sin.sin_zero));
+	bcopy(h->h_addr, (char*)&sin.sin_addr, h->h_length);
+	p = getprotobyname(proto);
+	if (p == NULL) {
+		rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
+#ifdef WIN32
+		rpc_createerr.cf_error.re_errno = WSAEPFNOSUPPORT;
+#else
+		rpc_createerr.cf_error.re_errno = EPFNOSUPPORT;
+#endif 
+		return (NULL);
+	}
+	sock = RPC_ANYSOCK;
+	switch (p->p_proto) {
+	case IPPROTO_UDP:
+		tv.tv_sec = 5;
+		tv.tv_usec = 0;
+		client = clntudp_create(&sin, prog, vers, tv, &sock);
+		if (client == NULL) {
+			return (NULL);
+		}
+		tv.tv_sec = 25;
+		clnt_control(client, CLSET_TIMEOUT, &tv);
+		break;
+	case IPPROTO_TCP:
+		client = clnttcp_create(&sin, prog, vers, &sock, 0, 0);
+		if (client == NULL) {
+			return (NULL);
+		}
+		tv.tv_sec = 25;
+		tv.tv_usec = 0;
+		clnt_control(client, CLSET_TIMEOUT, &tv);
+		break;
+	default:
+		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+#ifdef WIN32
+		rpc_createerr.cf_error.re_errno = WSAEPFNOSUPPORT; 
+#else
+		rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; 
+#endif
+		return (NULL);
+	}
+	return (client);
+}
diff --git a/external/rpc_win32/LIBRPC/clnt_per.c b/external/rpc_win32/LIBRPC/clnt_per.c
new file mode 100644
index 0000000..a69ec0b
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/clnt_per.c
@@ -0,0 +1,339 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)clnt_perror.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * clnt_perror.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+#include <stdio.h>
+#ifdef WIN32
+#include <stdlib.h>
+#endif
+
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <rpc/clnt.h>
+
+#ifndef WIN32
+extern char *sys_errlist[];
+extern char *sprintf();
+#endif
+static char *auth_errmsg();
+
+extern char *strcpy();
+
+static char *buf;
+
+static char *
+_buf()
+{
+
+	if (buf == 0)
+		buf = (char *)malloc(256);
+	return (buf);
+}
+
+/*
+ * Print reply error info
+ */
+char *
+clnt_sperror(rpch, s)
+	CLIENT *rpch;
+	char *s;
+{
+	struct rpc_err e;
+	void clnt_perrno();
+	char *err;
+	char *str = _buf();
+	char *strstart = str;
+
+	if (str == 0)
+		return (0);
+	CLNT_GETERR(rpch, &e);
+
+	(void) sprintf(str, "%s: ", s);
+	str += strlen(str);
+
+	(void) strcpy(str, clnt_sperrno(e.re_status));
+	str += strlen(str);
+
+	switch (e.re_status) {
+	case RPC_SUCCESS:
+	case RPC_CANTENCODEARGS:
+	case RPC_CANTDECODERES:
+	case RPC_TIMEDOUT:
+	case RPC_PROGUNAVAIL:
+	case RPC_PROCUNAVAIL:
+	case RPC_CANTDECODEARGS:
+	case RPC_SYSTEMERROR:
+	case RPC_UNKNOWNHOST:
+	case RPC_UNKNOWNPROTO:
+	case RPC_PMAPFAILURE:
+	case RPC_PROGNOTREGISTERED:
+	case RPC_FAILED:
+		break;
+
+	case RPC_CANTSEND:
+	case RPC_CANTRECV:
+		(void) sprintf(str, "; errno = %s",
+		    sys_errlist[e.re_errno]); 
+		str += strlen(str);
+		break;
+
+	case RPC_VERSMISMATCH:
+		(void) sprintf(str,
+			"; low version = %lu, high version = %lu",
+			e.re_vers.low, e.re_vers.high);
+		str += strlen(str);
+		break;
+
+	case RPC_AUTHERROR:
+		err = auth_errmsg(e.re_why);
+		(void) sprintf(str,"; why = ");
+		str += strlen(str);
+		if (err != NULL) {
+			(void) sprintf(str, "%s",err);
+		} else {
+			(void) sprintf(str,
+				"(unknown authentication error - %d)",
+				(int) e.re_why);
+		}
+		str += strlen(str);
+		break;
+
+	case RPC_PROGVERSMISMATCH:
+		(void) sprintf(str,
+			"; low version = %lu, high version = %lu",
+			e.re_vers.low, e.re_vers.high);
+		str += strlen(str);
+		break;
+
+	default:	/* unknown */
+		(void) sprintf(str,
+			"; s1 = %lu, s2 = %lu",
+			e.re_lb.s1, e.re_lb.s2);
+		str += strlen(str);
+		break;
+	}
+	(void) sprintf(str, "\n");
+	return(strstart) ;
+}
+
+void
+clnt_perror(rpch, s)
+	CLIENT *rpch;
+	char *s;
+{
+#ifdef WIN32
+	nt_rpc_report(clnt_sperror(rpch,s));
+#else
+	(void) fprintf(stderr,"%s",clnt_sperror(rpch,s));
+#endif
+}
+
+
+struct rpc_errtab {
+	enum clnt_stat status;
+	char *message;
+};
+
+static struct rpc_errtab  rpc_errlist[] = {
+	{ RPC_SUCCESS,
+		"RPC: Success" },
+	{ RPC_CANTENCODEARGS,
+		"RPC: Can't encode arguments" },
+	{ RPC_CANTDECODERES,
+		"RPC: Can't decode result" },
+	{ RPC_CANTSEND,
+		"RPC: Unable to send" },
+	{ RPC_CANTRECV,
+		"RPC: Unable to receive" },
+	{ RPC_TIMEDOUT,
+		"RPC: Timed out" },
+	{ RPC_VERSMISMATCH,
+		"RPC: Incompatible versions of RPC" },
+	{ RPC_AUTHERROR,
+		"RPC: Authentication error" },
+	{ RPC_PROGUNAVAIL,
+		"RPC: Program unavailable" },
+	{ RPC_PROGVERSMISMATCH,
+		"RPC: Program/version mismatch" },
+	{ RPC_PROCUNAVAIL,
+		"RPC: Procedure unavailable" },
+	{ RPC_CANTDECODEARGS,
+		"RPC: Server can't decode arguments" },
+	{ RPC_SYSTEMERROR,
+		"RPC: Remote system error" },
+	{ RPC_UNKNOWNHOST,
+		"RPC: Unknown host" },
+	{ RPC_UNKNOWNPROTO,
+		"RPC: Unknown protocol" },
+	{ RPC_PMAPFAILURE,
+		"RPC: Port mapper failure" },
+	{ RPC_PROGNOTREGISTERED,
+		"RPC: Program not registered"},
+	{ RPC_FAILED,
+		"RPC: Failed (unspecified error)"}
+};
+
+
+/*
+ * This interface for use by clntrpc
+ */
+char *
+clnt_sperrno(stat)
+	enum clnt_stat stat;
+{
+	int i;
+
+	for (i = 0; i < sizeof(rpc_errlist)/sizeof(struct rpc_errtab); i++) {
+		if (rpc_errlist[i].status == stat) {
+			return (rpc_errlist[i].message);
+		}
+	}
+	return ("RPC: (unknown error code)");
+}
+
+void
+clnt_perrno(num)
+	enum clnt_stat num;
+{
+#ifdef WIN32
+	nt_rpc_report(clnt_sperrno(num));
+#else
+	(void) fprintf(stderr,"%s",clnt_sperrno(num));
+#endif
+}
+
+
+char *
+clnt_spcreateerror(s)
+	char *s;
+{
+	extern int sys_nerr;
+#ifndef WIN32
+	extern char *sys_errlist[];
+#endif
+	char *str = _buf();
+
+	if (str == 0)
+		return(0);
+	(void) sprintf(str, "%s: ", s);
+	(void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat));
+	switch (rpc_createerr.cf_stat) {
+	case RPC_PMAPFAILURE:
+		(void) strcat(str, " - ");
+		(void) strcat(str,
+		    clnt_sperrno(rpc_createerr.cf_error.re_status));
+		break;
+
+	case RPC_SYSTEMERROR:
+		(void) strcat(str, " - ");
+		if (rpc_createerr.cf_error.re_errno > 0
+		    && rpc_createerr.cf_error.re_errno < sys_nerr)
+			(void) strcat(str,
+#ifdef WIN32
+			    "internal rpc error");
+#else
+			    sys_errlist[rpc_createerr.cf_error.re_errno]);
+#endif
+		else
+			(void) sprintf(&str[strlen(str)], "Error %d",
+			    rpc_createerr.cf_error.re_errno);
+		break;
+	}
+	(void) strcat(str, "\n");
+	return (str);
+}
+
+void
+clnt_pcreateerror(s)
+	char *s;
+{
+#ifdef WIN32
+	nt_rpc_report(clnt_spcreateerror(s));
+#else
+	(void) fprintf(stderr,"%s",clnt_spcreateerror(s));
+#endif
+}
+
+struct auth_errtab {
+	enum auth_stat status;
+	char *message;
+};
+
+static struct auth_errtab auth_errlist[] = {
+	{ AUTH_OK,
+		"Authentication OK" },
+	{ AUTH_BADCRED,
+		"Invalid client credential" },
+	{ AUTH_REJECTEDCRED,
+		"Server rejected credential" },
+	{ AUTH_BADVERF,
+		"Invalid client verifier" },
+	{ AUTH_REJECTEDVERF,
+		"Server rejected verifier" },
+	{ AUTH_TOOWEAK,
+		"Client credential too weak" },
+	{ AUTH_INVALIDRESP,
+		"Invalid server verifier" },
+	{ AUTH_FAILED,
+		"Failed (unspecified error)" },
+};
+
+static char *
+auth_errmsg(stat)
+	enum auth_stat stat;
+{
+	int i;
+
+	for (i = 0; i < sizeof(auth_errlist)/sizeof(struct auth_errtab); i++) {
+		if (auth_errlist[i].status == stat) {
+			return(auth_errlist[i].message);
+		}
+	}
+	return(NULL);
+}
diff --git a/external/rpc_win32/LIBRPC/clnt_raw.c b/external/rpc_win32/LIBRPC/clnt_raw.c
new file mode 100644
index 0000000..0fb3df1
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/clnt_raw.c
@@ -0,0 +1,252 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)clnt_raw.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * clnt_raw.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Memory based rpc for simple testing and timing.
+ * Interface to create an rpc client and server in the same process.
+ * This lets us similate rpc and get round trip overhead, without
+ * any interference from the kernal.
+ */
+
+#include <rpc/rpc.h>
+#ifdef WIN32
+#include <stdlib.h>
+#endif WIN32
+
+#define MCALL_MSG_SIZE 24
+
+/*
+ * This is the "network" we will be moving stuff over.
+ */
+static struct clntraw_private {
+	CLIENT	client_object;
+	XDR	xdr_stream;
+	char	_raw_buf[UDPMSGSIZE];
+	char	mashl_callmsg[MCALL_MSG_SIZE];
+	u_int	mcnt;
+} *clntraw_private;
+
+static enum clnt_stat	clntraw_call();
+static void		clntraw_abort();
+static void		clntraw_geterr();
+static bool_t		clntraw_freeres();
+static bool_t		clntraw_control();
+static void		clntraw_destroy();
+
+static struct clnt_ops client_ops = {
+	clntraw_call,
+	clntraw_abort,
+	clntraw_geterr,
+	clntraw_freeres,
+	clntraw_destroy,
+	clntraw_control
+};
+
+void	svc_getreq();
+
+/*
+ * Create a client handle for memory based rpc.
+ */
+CLIENT *
+clntraw_create(prog, vers)
+	u_long prog;
+	u_long vers;
+{
+	register struct clntraw_private *clp = clntraw_private;
+	struct rpc_msg call_msg;
+	XDR *xdrs = &clp->xdr_stream;
+	CLIENT	*client = &clp->client_object;
+
+	if (clp == 0) {
+		clp = (struct clntraw_private *)calloc(1, sizeof (*clp));
+		if (clp == 0)
+			return (0);
+		clntraw_private = clp;
+	}
+	/*
+	 * pre-serialize the staic part of the call msg and stash it away
+	 */
+	call_msg.rm_direction = CALL;
+	call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+	call_msg.rm_call.cb_prog = prog;
+	call_msg.rm_call.cb_vers = vers;
+	xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); 
+	if (! xdr_callhdr(xdrs, &call_msg)) {
+		perror("clnt_raw.c - Fatal header serialization error.");
+	}
+	clp->mcnt = XDR_GETPOS(xdrs);
+	XDR_DESTROY(xdrs);
+
+	/*
+	 * Set xdrmem for client/server shared buffer
+	 */
+	xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
+
+	/*
+	 * create client handle
+	 */
+	client->cl_ops = &client_ops;
+	client->cl_auth = authnone_create();
+	return (client);
+}
+
+static enum clnt_stat 
+clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
+	CLIENT *h;
+	u_long proc;
+	xdrproc_t xargs;
+	caddr_t argsp;
+	xdrproc_t xresults;
+	caddr_t resultsp;
+	struct timeval timeout;
+{
+	register struct clntraw_private *clp = clntraw_private;
+	register XDR *xdrs = &clp->xdr_stream;
+	struct rpc_msg msg;
+	enum clnt_stat status;
+	struct rpc_err error;
+
+	if (clp == 0)
+		return (RPC_FAILED);
+call_again:
+	/*
+	 * send request
+	 */
+	xdrs->x_op = XDR_ENCODE;
+	XDR_SETPOS(xdrs, 0);
+	((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ;
+	if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) ||
+	    (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+	    (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+	    (! (*xargs)(xdrs, argsp))) {
+		return (RPC_CANTENCODEARGS);
+	}
+	(void)XDR_GETPOS(xdrs);  /* called just to cause overhead */
+
+	/*
+	 * We have to call server input routine here because this is
+	 * all going on in one process. Yuk.
+	 */
+	svc_getreq(1);
+
+	/*
+	 * get results
+	 */
+	xdrs->x_op = XDR_DECODE;
+	XDR_SETPOS(xdrs, 0);
+	msg.acpted_rply.ar_verf = _null_auth;
+	msg.acpted_rply.ar_results.where = resultsp;
+	msg.acpted_rply.ar_results.proc = xresults;
+	if (! xdr_replymsg(xdrs, &msg))
+		return (RPC_CANTDECODERES);
+	_seterr_reply(&msg, &error);
+	status = error.re_status;
+
+	if (status == RPC_SUCCESS) {
+		if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
+			status = RPC_AUTHERROR;
+		}
+	}  /* end successful completion */
+	else {
+		if (AUTH_REFRESH(h->cl_auth))
+			goto call_again;
+	}  /* end of unsuccessful completion */
+
+	if (status == RPC_SUCCESS) {
+		if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
+			status = RPC_AUTHERROR;
+		}
+		if (msg.acpted_rply.ar_verf.oa_base != NULL) {
+			xdrs->x_op = XDR_FREE;
+			(void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
+		}
+	}
+
+	return (status);
+}
+
+static void
+clntraw_geterr()
+{
+}
+
+
+static bool_t
+clntraw_freeres(cl, xdr_res, res_ptr)
+	CLIENT *cl;
+	xdrproc_t xdr_res;
+	caddr_t res_ptr;
+{
+	register struct clntraw_private *clp = clntraw_private;
+	register XDR *xdrs = &clp->xdr_stream;
+	bool_t rval;
+
+	if (clp == 0)
+	{
+		rval = (bool_t) RPC_FAILED;
+		return (rval);
+	}
+	xdrs->x_op = XDR_FREE;
+	return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clntraw_abort()
+{
+}
+
+static bool_t
+clntraw_control()
+{
+	return (FALSE);
+}
+
+static void
+clntraw_destroy()
+{
+}
diff --git a/external/rpc_win32/LIBRPC/clnt_sim.c b/external/rpc_win32/LIBRPC/clnt_sim.c
new file mode 100644
index 0000000..1c1b753
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/clnt_sim.c
@@ -0,0 +1,129 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)clnt_simple.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/* 
+ * clnt_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#ifndef WIN32
+#include <sys/socket.h>
+#include <netdb.h>
+#include <strings.h>
+#endif
+
+static struct callrpc_private {
+	CLIENT	*client;
+	int	socket;
+	int	oldprognum, oldversnum, valid;
+	char	*oldhost;
+} *callrpc_private;
+
+callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
+	char *host;
+	xdrproc_t inproc, outproc;
+	char *in, *out;
+{
+	register struct callrpc_private *crp = callrpc_private;
+	struct sockaddr_in server_addr;
+	enum clnt_stat clnt_stat;
+	struct hostent *hp;
+	struct timeval timeout, tottimeout;
+
+	if (crp == 0) {
+		crp = (struct callrpc_private *)calloc(1, sizeof (*crp));
+		if (crp == 0)
+			return (0);
+		callrpc_private = crp;
+	}
+	if (crp->oldhost == NULL) {
+		crp->oldhost = malloc(256);
+		crp->oldhost[0] = 0;
+		crp->socket = RPC_ANYSOCK;
+	}
+	if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
+		&& strcmp(crp->oldhost, host) == 0) {
+		/* reuse old client */		
+	} else {
+		crp->valid = 0;
+#ifdef WIN32
+		(void)closesocket(crp->socket);
+#else
+		(void)close(crp->socket);
+#endif
+		crp->socket = RPC_ANYSOCK;
+		if (crp->client) {
+			clnt_destroy(crp->client);
+			crp->client = NULL;
+		}
+		if ((hp = gethostbyname(host)) == NULL)
+			return ((int) RPC_UNKNOWNHOST);
+		timeout.tv_usec = 0;
+		timeout.tv_sec = 5;
+		bcopy(hp->h_addr, (char *)&server_addr.sin_addr, hp->h_length);
+		server_addr.sin_family = AF_INET;
+		server_addr.sin_port =  0;
+		if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
+		    (u_long)versnum, timeout, &crp->socket)) == NULL)
+			return ((int) rpc_createerr.cf_stat);
+		crp->valid = 1;
+		crp->oldprognum = prognum;
+		crp->oldversnum = versnum;
+		(void) strcpy(crp->oldhost, host);
+	}
+	tottimeout.tv_sec = 25;
+	tottimeout.tv_usec = 0;
+	clnt_stat = clnt_call(crp->client, procnum, inproc, in,
+	    outproc, out, tottimeout);
+	/* 
+	 * if call failed, empty cache
+	 */
+	if (clnt_stat != RPC_SUCCESS)
+		crp->valid = 0;
+	return ((int) clnt_stat);
+}
diff --git a/external/rpc_win32/LIBRPC/clnt_tcp.c b/external/rpc_win32/LIBRPC/clnt_tcp.c
new file mode 100644
index 0000000..e906644
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/clnt_tcp.c
@@ -0,0 +1,554 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)clnt_tcp.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * TCP based RPC supports 'batched calls'.
+ * A sequence of calls may be batched-up in a send buffer.  The rpc call
+ * return immediately to the client even though the call was not necessarily
+ * sent.  The batching occurs if the results' xdr routine is NULL (0) AND
+ * the rpc timeout value is zero (see clnt.h, rpc).
+ *
+ * Clients should NOT casually batch calls that in fact return results; that is,
+ * the server side should be aware that a call is batched and not produce any
+ * return message.  Batched calls that produce many result messages can
+ * deadlock (netlock) the client and the server....
+ *
+ * Now go hang yourself.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#ifdef WIN32
+#include <errno.h>
+#include <rpc/pmap_cln.h>
+#else
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+#endif
+
+#define MCALL_MSG_SIZE 24
+
+#ifndef WIN32
+extern int errno;
+#endif
+
+static int	readtcp();
+static int	writetcp();
+
+static enum clnt_stat	clnttcp_call();
+static void		clnttcp_abort();
+static void		clnttcp_geterr();
+static bool_t		clnttcp_freeres();
+static bool_t           clnttcp_control();
+static void		clnttcp_destroy();
+
+static struct clnt_ops tcp_ops = {
+	clnttcp_call,
+	clnttcp_abort,
+	clnttcp_geterr,
+	clnttcp_freeres,
+	clnttcp_destroy,
+	clnttcp_control
+};
+
+struct ct_data {
+	int		ct_sock;
+	bool_t		ct_closeit;
+	struct timeval	ct_wait;
+	bool_t          ct_waitset;       /* wait set by clnt_control? */
+	struct sockaddr_in ct_addr;
+	struct rpc_err	ct_error;
+	char		ct_mcall[MCALL_MSG_SIZE];	/* marshalled callmsg */
+	u_int		ct_mpos;			/* pos after marshal */
+	XDR		ct_xdrs;
+};
+
+/*
+ * Create a client handle for a tcp/ip connection.
+ * If *sockp<0, *sockp is set to a newly created TCP socket and it is
+ * connected to raddr.  If *sockp non-negative then
+ * raddr is ignored.  The rpc/tcp package does buffering
+ * similar to stdio, so the client must pick send and receive buffer sizes,];
+ * 0 => use the default.
+ * If raddr->sin_port is 0, then a binder on the remote machine is
+ * consulted for the right port number.
+ * NB: *sockp is copied into a private area.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is set null authentication.  Caller may wish to set this
+ * something more useful.
+ */
+CLIENT *
+clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+	struct sockaddr_in *raddr;
+	u_long prog;
+	u_long vers;
+	register int *sockp;
+	u_int sendsz;
+	u_int recvsz;
+{
+	CLIENT *h;
+	register struct ct_data *ct;
+	struct timeval now;
+	struct rpc_msg call_msg;
+
+	h  = (CLIENT *)mem_alloc(sizeof(*h));
+	if (h == NULL) {
+#ifdef WIN32
+		nt_rpc_report("clnttcp_create: out of memory\n");
+		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+		rpc_createerr.cf_error.re_errno = ENOMEM;
+#else
+		(void)fprintf(stderr, "clnttcp_create: out of memory\n");
+		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+		rpc_createerr.cf_error.re_errno = errno;
+#endif
+		goto fooy;
+	}
+	ct = (struct ct_data *)mem_alloc(sizeof(*ct));
+	if (ct == NULL) {
+#ifdef WIN32
+		nt_rpc_report("clnttcp_create: out of memory\n");
+		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+		rpc_createerr.cf_error.re_errno = ENOMEM;
+#else
+		(void)fprintf(stderr, "clnttcp_create: out of memory\n");
+		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+		rpc_createerr.cf_error.re_errno = errno;
+#endif
+		goto fooy;
+	}
+
+	/*
+	 * If no port number given ask the pmap for one
+	 */
+	if (raddr->sin_port == 0) {
+		u_short port;
+		if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) {
+			mem_free((caddr_t)ct, sizeof(struct ct_data));
+			mem_free((caddr_t)h, sizeof(CLIENT));
+			return ((CLIENT *)NULL);
+		}
+		raddr->sin_port = htons(port);
+	}
+
+	/*
+	 * If no socket given, open one
+	 */
+#ifdef WIN32
+	if (*sockp == INVALID_SOCKET) {
+		*sockp = socket(AF_INET, SOCK_STREAM, 0);
+		(void)bindresvport(*sockp, (struct sockaddr_in *)0);
+		if ((*sockp == INVALID_SOCKET)
+		    || (connect(*sockp, (struct sockaddr *)raddr,
+		    sizeof(*raddr)) < 0)) {
+			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+			rpc_createerr.cf_error.re_errno = WSAerrno;
+			(void)closesocket(*sockp);
+#else
+	if (*sockp < 0) {
+		*sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+		(void)bindresvport(*sockp, (struct sockaddr_in *)0);
+		if ((*sockp < 0)
+		    || (connect(*sockp, (struct sockaddr *)raddr,
+		    sizeof(*raddr)) < 0)) {
+			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+			rpc_createerr.cf_error.re_errno = errno;
+			(void)close(*sockp);
+#endif
+			goto fooy;
+		}
+		ct->ct_closeit = TRUE;
+	} else {
+		ct->ct_closeit = FALSE;
+	}
+
+	/*
+	 * Set up private data struct
+	 */
+	ct->ct_sock = *sockp;
+	ct->ct_wait.tv_usec = 0;
+	ct->ct_waitset = FALSE;
+	ct->ct_addr = *raddr;
+
+	/*
+	 * Initialize call message
+	 */
+	(void)gettimeofday(&now, (struct timezone *)0);
+	call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
+	call_msg.rm_direction = CALL;
+	call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+	call_msg.rm_call.cb_prog = prog;
+	call_msg.rm_call.cb_vers = vers;
+
+	/*
+	 * pre-serialize the staic part of the call msg and stash it away
+	 */
+	xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE,
+	    XDR_ENCODE);
+	if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
+		if (ct->ct_closeit) {
+#ifdef WIN32
+			(void)closesocket(*sockp);
+#else
+			(void)close(*sockp);
+#endif
+		}
+		goto fooy;
+	}
+	ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
+	XDR_DESTROY(&(ct->ct_xdrs));
+
+	/*
+	 * Create a client handle which uses xdrrec for serialization
+	 * and authnone for authentication.
+	 */
+	xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
+	    (caddr_t)ct, readtcp, writetcp);
+	h->cl_ops = &tcp_ops;
+	h->cl_private = (caddr_t) ct;
+	h->cl_auth = authnone_create();
+	return (h);
+
+fooy:
+	/*
+	 * Something goofed, free stuff and barf
+	 */
+	mem_free((caddr_t)ct, sizeof(struct ct_data));
+	mem_free((caddr_t)h, sizeof(CLIENT));
+	return ((CLIENT *)NULL);
+}
+
+static enum clnt_stat
+clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
+	register CLIENT *h;
+	u_long proc;
+	xdrproc_t xdr_args;
+	caddr_t args_ptr;
+	xdrproc_t xdr_results;
+	caddr_t results_ptr;
+	struct timeval timeout;
+{
+	register struct ct_data *ct = (struct ct_data *) h->cl_private;
+	register XDR *xdrs = &(ct->ct_xdrs);
+	struct rpc_msg reply_msg;
+	u_long x_id;
+	u_long *msg_x_id = (u_long *)(ct->ct_mcall);	/* yuk */
+	register bool_t shipnow;
+	int refreshes = 2;
+
+	if (!ct->ct_waitset) {
+		ct->ct_wait = timeout;
+	}
+
+	shipnow =
+	    (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0
+	    && timeout.tv_usec == 0) ? FALSE : TRUE;
+
+call_again:
+	xdrs->x_op = XDR_ENCODE;
+	ct->ct_error.re_status = RPC_SUCCESS;
+	x_id = ntohl(--(*msg_x_id));
+	if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
+	    (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+	    (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
+	    (! (*xdr_args)(xdrs, args_ptr))) {
+		if (ct->ct_error.re_status == RPC_SUCCESS)
+			ct->ct_error.re_status = RPC_CANTENCODEARGS;
+		(void)xdrrec_endofrecord(xdrs, TRUE);
+		return (ct->ct_error.re_status);
+	}
+	if (! xdrrec_endofrecord(xdrs, shipnow))
+		return (ct->ct_error.re_status = RPC_CANTSEND);
+	if (! shipnow)
+		return (RPC_SUCCESS);
+	/*
+	 * Hack to provide rpc-based message passing
+	 */
+	if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+		return(ct->ct_error.re_status = RPC_TIMEDOUT);
+	}
+
+
+	/*
+	 * Keep receiving until we get a valid transaction id
+	 */
+	xdrs->x_op = XDR_DECODE;
+	while (TRUE) {
+		reply_msg.acpted_rply.ar_verf = _null_auth;
+		reply_msg.acpted_rply.ar_results.where = NULL;
+		reply_msg.acpted_rply.ar_results.proc = xdr_void;
+		if (! xdrrec_skiprecord(xdrs))
+			return (ct->ct_error.re_status);
+		/* now decode and validate the response header */
+		if (! xdr_replymsg(xdrs, &reply_msg)) {
+			if (ct->ct_error.re_status == RPC_SUCCESS)
+				continue;
+			return (ct->ct_error.re_status);
+		}
+		if (reply_msg.rm_xid == x_id)
+			break;
+	}
+
+	/*
+	 * process header
+	 */
+	_seterr_reply(&reply_msg, &(ct->ct_error));
+	if (ct->ct_error.re_status == RPC_SUCCESS) {
+		if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) {
+			ct->ct_error.re_status = RPC_AUTHERROR;
+			ct->ct_error.re_why = AUTH_INVALIDRESP;
+		} else if (! (*xdr_results)(xdrs, results_ptr)) {
+			if (ct->ct_error.re_status == RPC_SUCCESS)
+				ct->ct_error.re_status = RPC_CANTDECODERES;
+		}
+		/* free verifier ... */
+		if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+			xdrs->x_op = XDR_FREE;
+			(void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf));
+		}
+	}  /* end successful completion */
+	else {
+		/* maybe our credentials need to be refreshed ... */
+		if (refreshes-- && AUTH_REFRESH(h->cl_auth))
+			goto call_again;
+	}  /* end of unsuccessful completion */
+	return (ct->ct_error.re_status);
+}
+
+static void
+clnttcp_geterr(h, errp)
+	CLIENT *h;
+	struct rpc_err *errp;
+{
+	register struct ct_data *ct =
+	    (struct ct_data *) h->cl_private;
+
+	*errp = ct->ct_error;
+}
+
+static bool_t
+clnttcp_freeres(cl, xdr_res, res_ptr)
+	CLIENT *cl;
+	xdrproc_t xdr_res;
+	caddr_t res_ptr;
+{
+	register struct ct_data *ct = (struct ct_data *)cl->cl_private;
+	register XDR *xdrs = &(ct->ct_xdrs);
+
+	xdrs->x_op = XDR_FREE;
+	return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clnttcp_abort()
+{
+}
+
+static bool_t
+clnttcp_control(cl, request, info)
+	CLIENT *cl;
+	int request;
+	char *info;
+{
+	register struct ct_data *ct = (struct ct_data *)cl->cl_private;
+
+	switch (request) {
+	case CLSET_TIMEOUT:
+		ct->ct_wait = *(struct timeval *)info;
+		ct->ct_waitset = TRUE;
+		break;
+	case CLGET_TIMEOUT:
+		*(struct timeval *)info = ct->ct_wait;
+		break;
+	case CLGET_SERVER_ADDR:
+		*(struct sockaddr_in *)info = ct->ct_addr;
+		break;
+	default:
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+
+static void
+clnttcp_destroy(h)
+	CLIENT *h;
+{
+	register struct ct_data *ct =
+	    (struct ct_data *) h->cl_private;
+
+	if (ct->ct_closeit) {
+#ifdef WIN32
+		(void)closesocket(ct->ct_sock);
+#else
+		(void)close(ct->ct_sock);
+#endif
+	}
+	XDR_DESTROY(&(ct->ct_xdrs));
+	mem_free((caddr_t)ct, sizeof(struct ct_data));
+	mem_free((caddr_t)h, sizeof(CLIENT));
+}
+
+/*
+ * Interface between xdr serializer and tcp connection.
+ * Behaves like the system calls, read & write, but keeps some error state
+ * around for the rpc level.
+ */
+static int
+readtcp(ct, buf, len)
+	register struct ct_data *ct;
+	caddr_t buf;
+	register int len;
+{
+#ifdef FD_SETSIZE
+	fd_set mask;
+	fd_set readfds;
+
+	if (len == 0)
+		return (0);
+	FD_ZERO(&mask);
+	FD_SET(ct->ct_sock, &mask);
+#else
+	register int mask = 1 << (ct->ct_sock);
+	int readfds;
+
+	if (len == 0)
+		return (0);
+
+#endif /* def FD_SETSIZE */
+	while (TRUE) {
+		readfds = mask;
+#ifdef WIN32
+		switch (select(0 /* unused in winsock */, &readfds, (int*)NULL, (int*)NULL,
+			       &(ct->ct_wait))) {
+		case 0:
+			ct->ct_error.re_status = RPC_TIMEDOUT;
+			return (-1);
+
+		case -1:
+			if (WSAerrno == EINTR)
+				continue;
+			ct->ct_error.re_status = RPC_CANTRECV;
+			ct->ct_error.re_errno = WSAerrno;
+			return (-1);
+		}
+		break;
+	}
+	switch (len = recv(ct->ct_sock, buf, len, 0)) {
+
+	case 0:
+		/* premature eof */
+		ct->ct_error.re_errno = WSAECONNRESET;
+		ct->ct_error.re_status = RPC_CANTRECV;
+		len = -1;  /* it's really an error */
+		break;
+
+	case -1:
+		ct->ct_error.re_errno = WSAerrno;
+		ct->ct_error.re_status = RPC_CANTRECV;
+		break;
+	}
+	return (len);
+#else
+		switch (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL,
+			       &(ct->ct_wait))) {
+		case 0:
+			ct->ct_error.re_status = RPC_TIMEDOUT;
+			return (-1);
+
+		case -1:
+			if (errno == EINTR)
+				continue;
+			ct->ct_error.re_status = RPC_CANTRECV;
+			ct->ct_error.re_errno = errno;
+			return (-1);
+		}
+		break;
+	}
+	switch (len = read(ct->ct_sock, buf, len)) {
+
+	case 0:
+		/* premature eof */
+		ct->ct_error.re_errno = ECONNRESET;
+		ct->ct_error.re_status = RPC_CANTRECV;
+		len = -1;  /* it's really an error */
+		break;
+
+	case -1:
+		ct->ct_error.re_errno = errno;
+		ct->ct_error.re_status = RPC_CANTRECV;
+		break;
+	}
+	return (len);
+#endif
+}
+
+static int
+writetcp(ct, buf, len)
+	struct ct_data *ct;
+	caddr_t buf;
+	int len;
+{
+	register int i, cnt;
+
+	for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+#ifdef WIN32
+		if ((i = send(ct->ct_sock, buf, cnt, 0)) == -1) {
+			ct->ct_error.re_errno = WSAerrno;
+#else
+		if ((i = write(ct->ct_sock, buf, cnt)) == -1) {
+			ct->ct_error.re_errno = errno;
+#endif
+			ct->ct_error.re_status = RPC_CANTSEND;
+			return (-1);
+		}
+	}
+	return (len);
+}
diff --git a/external/rpc_win32/LIBRPC/clnt_udp.c b/external/rpc_win32/LIBRPC/clnt_udp.c
new file mode 100644
index 0000000..be0f28d
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/clnt_udp.c
@@ -0,0 +1,508 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)clnt_udp.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * clnt_udp.c, Implements a UDP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#ifdef WIN32
+#include <errno.h>
+#include <rpc/pmap_cln.h>
+#else
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+
+extern int errno;
+#endif
+
+/*
+ * UDP bases client side rpc operations
+ */
+static enum clnt_stat	clntudp_call();
+static void		clntudp_abort();
+static void		clntudp_geterr();
+static bool_t		clntudp_freeres();
+static bool_t           clntudp_control();
+static void		clntudp_destroy();
+
+static struct clnt_ops udp_ops = {
+	clntudp_call,
+	clntudp_abort,
+	clntudp_geterr,
+	clntudp_freeres,
+	clntudp_destroy,
+	clntudp_control
+};
+
+/*
+ * Private data kept per client handle
+ */
+struct cu_data {
+	int		   cu_sock;
+	bool_t		   cu_closeit;
+	struct sockaddr_in cu_raddr;
+	int		   cu_rlen;
+	struct timeval	   cu_wait;
+	struct timeval     cu_total;
+	struct rpc_err	   cu_error;
+	XDR		   cu_outxdrs;
+	u_int		   cu_xdrpos;
+	u_int		   cu_sendsz;
+	char		   *cu_outbuf;
+	u_int		   cu_recvsz;
+	char		   cu_inbuf[1];
+};
+
+/*
+ * Create a UDP based client handle.
+ * If *sockp<0, *sockp is set to a newly created UPD socket.
+ * If raddr->sin_port is 0 a binder on the remote machine
+ * is consulted for the correct port number.
+ * NB: It is the clients responsibility to close *sockp.
+ * NB: The rpch->cl_auth is initialized to null authentication.
+ *     Caller may wish to set this something more useful.
+ *
+ * wait is the amount of time used between retransmitting a call if
+ * no response has been heard;  retransmition occurs until the actual
+ * rpc call times out.
+ *
+ * sendsz and recvsz are the maximum allowable packet sizes that can be
+ * sent and received.
+ */
+CLIENT *
+clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+	struct sockaddr_in *raddr;
+	u_long program;
+	u_long version;
+	struct timeval wait;
+	register int *sockp;
+	u_int sendsz;
+	u_int recvsz;
+{
+	CLIENT *cl;
+	register struct cu_data *cu;
+	struct timeval now;
+	struct rpc_msg call_msg;
+
+	cl = (CLIENT *)mem_alloc(sizeof(CLIENT));
+	if (cl == NULL) {
+#ifdef WIN32
+		nt_rpc_report("clntudp_create: out of memory\n");
+		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+		rpc_createerr.cf_error.re_errno = ENOMEM;
+#else
+		(void) fprintf(stderr, "clntudp_create: out of memory\n");
+		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+		rpc_createerr.cf_error.re_errno = errno;
+#endif
+		goto fooy;
+	}
+	sendsz = ((sendsz + 3) / 4) * 4;
+	recvsz = ((recvsz + 3) / 4) * 4;
+	cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz);
+	if (cu == NULL) {
+#ifdef WIN32
+		nt_rpc_report("clntudp_create: out of memory\n");
+		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+		rpc_createerr.cf_error.re_errno = ENOMEM;
+#else
+		(void) fprintf(stderr, "clntudp_create: out of memory\n");
+		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+		rpc_createerr.cf_error.re_errno = errno;
+#endif
+		goto fooy;
+	}
+	cu->cu_outbuf = &cu->cu_inbuf[recvsz];
+
+	(void)gettimeofday(&now, (struct timezone *)0);
+	if (raddr->sin_port == 0) {
+		u_short port;
+		if ((port =
+		    pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
+			goto fooy;
+		}
+		raddr->sin_port = htons(port);
+	}
+	cl->cl_ops = &udp_ops;
+	cl->cl_private = (caddr_t)cu;
+	cu->cu_raddr = *raddr;
+	cu->cu_rlen = sizeof (cu->cu_raddr);
+	cu->cu_wait = wait;
+	cu->cu_total.tv_sec = -1;
+	cu->cu_total.tv_usec = -1;
+	cu->cu_sendsz = sendsz;
+	cu->cu_recvsz = recvsz;
+	call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
+	call_msg.rm_direction = CALL;
+	call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+	call_msg.rm_call.cb_prog = program;
+	call_msg.rm_call.cb_vers = version;
+	xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf,
+	    sendsz, XDR_ENCODE);
+	if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {
+		goto fooy;
+	}
+	cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));
+	if (*sockp < 0) {
+		int dontblock = 1;
+
+		*sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+#ifdef WIN32
+		if (*sockp == INVALID_SOCKET) {
+			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+			rpc_createerr.cf_error.re_errno = WSAerrno;
+#else
+		if (*sockp < 0) {
+			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
+			rpc_createerr.cf_error.re_errno = errno;
+#endif
+			goto fooy;
+		}
+		/* attempt to bind to prov port */
+		(void)bindresvport(*sockp, (struct sockaddr_in *)0);
+		/* the sockets rpc controls are non-blocking */
+#ifdef WIN32
+		(void)ioctlsocket(*sockp, FIONBIO, (char *) &dontblock);
+#else
+		(void)ioctl(*sockp, FIONBIO, (char *) &dontblock);
+#endif
+		cu->cu_closeit = TRUE;
+	} else {
+		cu->cu_closeit = FALSE;
+	}
+	cu->cu_sock = *sockp;
+	cl->cl_auth = authnone_create();
+	return (cl);
+fooy:
+	if (cu)
+		mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz);
+	if (cl)
+		mem_free((caddr_t)cl, sizeof(CLIENT));
+	return ((CLIENT *)NULL);
+}
+
+CLIENT *
+clntudp_create(raddr, program, version, wait, sockp)
+	struct sockaddr_in *raddr;
+	u_long program;
+	u_long version;
+	struct timeval wait;
+	register int *sockp;
+{
+
+	return(clntudp_bufcreate(raddr, program, version, wait, sockp,
+	    UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum clnt_stat
+clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
+	register CLIENT	*cl;		/* client handle */
+	u_long		proc;		/* procedure number */
+	xdrproc_t	xargs;		/* xdr routine for args */
+	caddr_t		argsp;		/* pointer to args */
+	xdrproc_t	xresults;	/* xdr routine for results */
+	caddr_t		resultsp;	/* pointer to results */
+	struct timeval	utimeout;	/* seconds to wait before giving up */
+{
+	register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+	register XDR *xdrs;
+	register int outlen;
+	register int inlen;
+	int fromlen;
+#ifdef FD_SETSIZE
+	fd_set readfds;
+	fd_set mask;
+#else
+	int readfds;
+	register int mask;
+#endif /* def FD_SETSIZE */
+	struct sockaddr_in from;
+	struct rpc_msg reply_msg;
+	XDR reply_xdrs;
+	struct timeval time_waited;
+	bool_t ok;
+	int nrefreshes = 2;	/* number of times to refresh cred */
+	struct timeval timeout;
+
+	if (cu->cu_total.tv_usec == -1) {
+		timeout = utimeout;     /* use supplied timeout */
+	} else {
+		timeout = cu->cu_total; /* use default timeout */
+	}
+
+	time_waited.tv_sec = 0;
+	time_waited.tv_usec = 0;
+call_again:
+	xdrs = &(cu->cu_outxdrs);
+	xdrs->x_op = XDR_ENCODE;
+	XDR_SETPOS(xdrs, cu->cu_xdrpos);
+	/*
+	 * the transaction is the first thing in the out buffer
+	 */
+	(*(u_short *)(cu->cu_outbuf))++;
+
+	if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+	    (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
+	    (! (*xargs)(xdrs, argsp)))
+		return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
+
+	outlen = (int)XDR_GETPOS(xdrs);
+
+send_again:
+	if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,
+	    (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen)
+	    != outlen) {
+#ifdef WIN32
+		cu->cu_error.re_errno = WSAerrno;
+#else
+		cu->cu_error.re_errno = errno;
+#endif
+		return (cu->cu_error.re_status = RPC_CANTSEND);
+	}
+
+	/*
+	 * Hack to provide rpc-based message passing
+	 */
+	if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+		return (cu->cu_error.re_status = RPC_TIMEDOUT);
+	}
+	/*
+	 * sub-optimal code appears here because we have
+	 * some clock time to spare while the packets are in flight.
+	 * (We assume that this is actually only executed once.)
+	 */
+	reply_msg.acpted_rply.ar_verf = _null_auth;
+	reply_msg.acpted_rply.ar_results.where = resultsp;
+	reply_msg.acpted_rply.ar_results.proc = xresults;
+#ifdef FD_SETSIZE
+	FD_ZERO(&mask);
+	FD_SET(cu->cu_sock, &mask);
+#else
+	mask = 1 << cu->cu_sock;
+#endif /* def FD_SETSIZE */
+	for (;;) {
+		readfds = mask;
+#ifdef WIN32
+		switch (select(0 /* unused in winsock */, &readfds, (int *)NULL,
+#else
+		switch (select(_rpc_dtablesize(), &readfds, (int *)NULL, 
+#endif
+			       (int *)NULL, &(cu->cu_wait))) {
+
+		case 0:
+			time_waited.tv_sec += cu->cu_wait.tv_sec;
+			time_waited.tv_usec += cu->cu_wait.tv_usec;
+			while (time_waited.tv_usec >= 1000000) {
+				time_waited.tv_sec++;
+				time_waited.tv_usec -= 1000000;
+			}
+			if ((time_waited.tv_sec < timeout.tv_sec) ||
+				((time_waited.tv_sec == timeout.tv_sec) &&
+				(time_waited.tv_usec < timeout.tv_usec)))
+				goto send_again;
+			return (cu->cu_error.re_status = RPC_TIMEDOUT);
+
+		/*
+		 * buggy in other cases because time_waited is not being
+		 * updated.
+		 */
+		case -1:
+#ifdef WIN32
+			if (WSAerrno == WSAEINTR)
+				continue;
+			cu->cu_error.re_errno = WSAerrno;
+#else
+			if (errno == EINTR)
+				continue;	
+			cu->cu_error.re_errno = errno;
+#endif
+			return (cu->cu_error.re_status = RPC_CANTRECV);
+		}
+		do {
+			fromlen = sizeof(struct sockaddr);
+			inlen = recvfrom(cu->cu_sock, cu->cu_inbuf,
+				(int) cu->cu_recvsz, 0,
+				(struct sockaddr *)&from, &fromlen);
+#ifdef WIN32
+		} while (inlen < 0 && WSAerrno == EINTR);
+		if (inlen < 0) {
+			if (WSAerrno == WSAEWOULDBLOCK)
+				continue;
+			cu->cu_error.re_errno = WSAerrno;
+#else
+		} while (inlen < 0 && errno == EINTR);
+		if (inlen < 0) {
+			if (errno == EWOULDBLOCK)
+				continue;	
+			cu->cu_error.re_errno = errno;
+#endif
+			return (cu->cu_error.re_status = RPC_CANTRECV);
+		}
+		if (inlen < sizeof(u_long))
+			continue;
+		/* see if reply transaction id matches sent id */
+		if (*((u_long *)(cu->cu_inbuf)) != *((u_long *)(cu->cu_outbuf)))
+			continue;
+		/* we now assume we have the proper reply */
+		break;
+	}
+
+	/*
+	 * now decode and validate the response
+	 */
+	xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE);
+	ok = xdr_replymsg(&reply_xdrs, &reply_msg);
+	/* XDR_DESTROY(&reply_xdrs);  save a few cycles on noop destroy */
+	if (ok) {
+		_seterr_reply(&reply_msg, &(cu->cu_error));
+		if (cu->cu_error.re_status == RPC_SUCCESS) {
+			if (! AUTH_VALIDATE(cl->cl_auth,
+				&reply_msg.acpted_rply.ar_verf)) {
+				cu->cu_error.re_status = RPC_AUTHERROR;
+				cu->cu_error.re_why = AUTH_INVALIDRESP;
+			}
+			if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) {
+				xdrs->x_op = XDR_FREE;
+				(void)xdr_opaque_auth(xdrs,
+				    &(reply_msg.acpted_rply.ar_verf));
+			}
+		}  /* end successful completion */
+		else {
+			/* maybe our credentials need to be refreshed ... */
+			if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) {
+				nrefreshes--;
+				goto call_again;
+			}
+		}  /* end of unsuccessful completion */
+	}  /* end of valid reply message */
+	else {
+		cu->cu_error.re_status = RPC_CANTDECODERES;
+	}
+	return (cu->cu_error.re_status);
+}
+
+static void
+clntudp_geterr(cl, errp)
+	CLIENT *cl;
+	struct rpc_err *errp;
+{
+	register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+	*errp = cu->cu_error;
+}
+
+
+static bool_t
+clntudp_freeres(cl, xdr_res, res_ptr)
+	CLIENT *cl;
+	xdrproc_t xdr_res;
+	caddr_t res_ptr;
+{
+	register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+	register XDR *xdrs = &(cu->cu_outxdrs);
+
+	xdrs->x_op = XDR_FREE;
+	return ((*xdr_res)(xdrs, res_ptr));
+}
+
+static void
+clntudp_abort(/*h*/)
+	/*CLIENT *h;*/
+{
+}
+
+static bool_t
+clntudp_control(cl, request, info)
+	CLIENT *cl;
+	int request;
+	char *info;
+{
+	register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+	switch (request) {
+	case CLSET_TIMEOUT:
+		cu->cu_total = *(struct timeval *)info;
+		break;
+	case CLGET_TIMEOUT:
+		*(struct timeval *)info = cu->cu_total;
+		break;
+	case CLSET_RETRY_TIMEOUT:
+		cu->cu_wait = *(struct timeval *)info;
+		break;
+	case CLGET_RETRY_TIMEOUT:
+		*(struct timeval *)info = cu->cu_wait;
+		break;
+	case CLGET_SERVER_ADDR:
+		*(struct sockaddr_in *)info = cu->cu_raddr;
+		break;
+	default:
+		return (FALSE);
+	}
+	return (TRUE);
+}
+
+static void
+clntudp_destroy(cl)
+	CLIENT *cl;
+{
+	register struct cu_data *cu = (struct cu_data *)cl->cl_private;
+
+	if (cu->cu_closeit) {
+#ifdef WIN32
+		(void)closesocket(cu->cu_sock);
+#else
+		(void)close(cu->cu_sock);
+#endif
+	}
+	XDR_DESTROY(&(cu->cu_outxdrs));
+	mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz));
+	mem_free((caddr_t)cl, sizeof(CLIENT));
+}
diff --git a/external/rpc_win32/LIBRPC/get_myad.c b/external/rpc_win32/LIBRPC/get_myad.c
new file mode 100644
index 0000000..8528786
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/get_myad.c
@@ -0,0 +1,127 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)get_myaddress.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";
+#endif
+/*
+ * get_myaddress.c
+ *
+ * Get client's IP address via ioctl.  This avoids using the yellowpages.
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifdef WIN32
+#include <rpc/rpc.h>
+#include <rpc/pmap_pro.h>
+#include <stdio.h>
+
+#define MAX_NAME_LEN	255
+#else
+#include <rpc/types.h>
+#include <rpc/pmap_prot.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+/* 
+ * don't use gethostbyname, which would invoke yellow pages
+ */
+#endif
+
+get_myaddress(addr)
+	struct sockaddr_in *addr;
+{
+#ifdef WIN32
+struct hostent	*Hostent;
+char my_name[MAX_NAME_LEN];
+
+	gethostname(my_name, MAX_NAME_LEN);
+	Hostent = gethostbyname(my_name);
+
+	if (Hostent == NULL) {
+		errno;
+		perror("Can not get host info");
+		exit (1);
+	}
+
+	addr->sin_family = AF_INET;
+	addr->sin_port = htons(PMAPPORT);
+	bcopy((char *)Hostent->h_addr, (char *)&addr->sin_addr, 
+							Hostent->h_length);
+
+#else	
+	int s;
+	char buf[BUFSIZ];
+	struct ifconf ifc;
+	struct ifreq ifreq, *ifr;
+	int len;
+
+	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+	    perror("get_myaddress: socket");
+	    exit(1);
+	}
+	ifc.ifc_len = sizeof (buf);
+	ifc.ifc_buf = buf;
+	if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
+		perror("get_myaddress: ioctl (get interface configuration)");
+		exit(1);
+	}
+	ifr = ifc.ifc_req;
+	for (len = ifc.ifc_len; len; len -= sizeof ifreq) {
+		ifreq = *ifr;
+		if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+			perror("get_myaddress: ioctl");
+			exit(1);
+		}
+		if ((ifreq.ifr_flags & IFF_UP) &&
+		    ifr->ifr_addr.sa_family == AF_INET) {
+			*addr = *((struct sockaddr_in *)&ifr->ifr_addr);
+			addr->sin_port = htons(PMAPPORT);
+			break;
+		}
+		ifr++;
+	}
+	(void) close(s);
+#endif
+}
diff --git a/external/rpc_win32/LIBRPC/getopt.c b/external/rpc_win32/LIBRPC/getopt.c
new file mode 100644
index 0000000..4ec1081
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/getopt.c
@@ -0,0 +1,52 @@
+/* got this off net.sources */
+#include <stdio.h>
+#include <string.h>
+#include "getopt.h"
+
+/*
+ * get option letter from argument vector
+ */
+int	opterr = 1,		/* useless, never set or used */
+	optind = 1,		/* index into parent argv vector */
+	optopt;			/* character checked for validity */
+char	*optarg;		/* argument associated with option */
+
+#define BADCH	(int)'?'
+#define EMSG	""
+#define errmsg(s) fputs(*argv,stderr);fputs(s,stderr); \
+		fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);
+
+int
+getopt(int argc,char **argv,char *ostr)
+{
+	static char	*place = EMSG;	/* option letter processing */
+	register char	*oli;		/* option letter list index */
+	char	*index();
+
+	if(!*place) {			/* update scanning pointer */
+		if(optind >= argc || *(place = argv[optind]) != '-' || !*++place) return(EOF);
+		if (*place == '-') {	/* found "--" */
+			++optind;
+			return(EOF);
+		}
+	}				/* option letter okay? */
+	if ((optopt = (int)*place++) == (int)':' || !(oli = strchr(ostr,optopt))) {
+		if(!*place) ++optind;
+		errmsg(": illegal option -- ");
+	}
+	if (*++oli != ':') {		/* don't need argument */
+		optarg = NULL;
+		if (!*place) ++optind;
+	}
+	else {				/* need an argument */
+		if (*place) optarg = place;	/* no white space */
+		else if (argc <= ++optind) {	/* no arg */
+			place = EMSG;
+			errmsg(": option requires an argument -- ");
+		}
+	 	else optarg = argv[optind];	/* white space */
+		place = EMSG;
+		++optind;
+	}
+	return(optopt);			/* dump back option letter */
+}
diff --git a/external/rpc_win32/LIBRPC/getopt.h b/external/rpc_win32/LIBRPC/getopt.h
new file mode 100644
index 0000000..eee7324
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/getopt.h
@@ -0,0 +1,3 @@
+extern int optind;
+extern char *optarg;
+extern int getopt	(int argc,char **nargv, char *ostr);
diff --git a/external/rpc_win32/LIBRPC/getrpcen.c b/external/rpc_win32/LIBRPC/getrpcen.c
new file mode 100644
index 0000000..51ae173
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/getrpcen.c
@@ -0,0 +1,256 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)getrpcent.c	2.2 88/07/29 4.0 RPCSRC */
+#if !defined(lint) && defined(SCCSIDS)
+static  char sccsid[] = "@(#)getrpcent.c 1.9 87/08/11  Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <rpc/rpc.h>
+#ifndef WIN32
+#include <netdb.h>
+#include <sys/socket.h>
+#endif
+
+/*
+ * Internet version.
+ */
+struct rpcdata {
+	FILE	*rpcf;
+	char	*current;
+	int	currentlen;
+	int	stayopen;
+#define	MAXALIASES	35
+	char	*rpc_aliases[MAXALIASES];
+	struct	rpcent rpc;
+	char	line[BUFSIZ+1];
+	char	*domain;
+} *rpcdata, *_rpcdata();
+
+static	struct rpcent *interpret();
+struct	hostent *gethostent();
+#ifdef WIN32
+#define index(str,ch) strchr(str,ch)
+#else
+char	*inet_ntoa();
+static	char *index();
+#endif
+
+#ifdef WIN32
+static char RPCDB[] = "%SystemRoot%\\system32\\drivers\\etc\\rpc";
+#else
+static char RPCDB[] = "/etc/rpc";
+#endif
+
+static struct rpcdata *
+_rpcdata()
+{
+	register struct rpcdata *d = rpcdata;
+
+	if (d == 0) {
+		d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
+		rpcdata = d;
+	}
+	return (d);
+}
+
+struct rpcent *
+getrpcbynumber(number)
+	register int number;
+{
+	register struct rpcdata *d = _rpcdata();
+	register struct rpcent *p;
+	int reason;
+	char adrstr[16], *val = NULL;
+	int vallen;
+
+	if (d == 0)
+		return (0);
+	setrpcent(0);
+	while (p = getrpcent()) {
+		if (p->r_number == number)
+			break;
+	}
+	endrpcent();
+	return (p);
+}
+
+struct rpcent *
+getrpcbyname(name)
+	char *name;
+{
+	struct rpcent *rpc;
+	char **rp;
+
+	setrpcent(0);
+	while(rpc = getrpcent()) {
+		if (strcmp(rpc->r_name, name) == 0)
+			return (rpc);
+		for (rp = rpc->r_aliases; *rp != NULL; rp++) {
+			if (strcmp(*rp, name) == 0)
+				return (rpc);
+		}
+	}
+	endrpcent();
+	return (NULL);
+}
+
+setrpcent(f)
+	int f;
+{
+	register struct rpcdata *d = _rpcdata();
+
+	if (d == 0)
+		return;
+	if (d->rpcf == NULL)
+		d->rpcf = fopen(RPCDB, "r");
+	else
+		rewind(d->rpcf);
+	if (d->current)
+		free(d->current);
+	d->current = NULL;
+	d->stayopen |= f;
+}
+
+endrpcent()
+{
+	register struct rpcdata *d = _rpcdata();
+
+	if (d == 0)
+		return;
+	if (d->current && !d->stayopen) {
+		free(d->current);
+		d->current = NULL;
+	}
+	if (d->rpcf && !d->stayopen) {
+		fclose(d->rpcf);
+		d->rpcf = NULL;
+	}
+}
+
+struct rpcent *
+getrpcent()
+{
+	struct rpcent *hp;
+	int reason;
+	char *key = NULL, *val = NULL;
+	int keylen, vallen;
+	register struct rpcdata *d = _rpcdata();
+
+	if (d == 0)
+		return(NULL);
+	if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL)
+		return (NULL);
+    if (fgets(d->line, BUFSIZ, d->rpcf) == NULL)
+		return (NULL);
+	return interpret(d->line, strlen(d->line));
+}
+
+static struct rpcent *
+interpret(val, len)
+{
+	register struct rpcdata *d = _rpcdata();
+	char *p;
+	register char *cp, **q;
+
+	if (d == 0)
+		return;
+	strncpy(d->line, val, len);
+	p = d->line;
+	d->line[len] = '\n';
+	if (*p == '#')
+		return (getrpcent());
+	cp = index(p, '#');
+	if (cp == NULL)
+    {
+		cp = index(p, '\n');
+		if (cp == NULL)
+			return (getrpcent());
+	}
+	*cp = '\0';
+	cp = index(p, ' ');
+	if (cp == NULL)
+    {
+		cp = index(p, '\t');
+		if (cp == NULL)
+			return (getrpcent());
+	}
+	*cp++ = '\0';
+	/* THIS STUFF IS INTERNET SPECIFIC */
+	d->rpc.r_name = d->line;
+	while (*cp == ' ' || *cp == '\t')
+		cp++;
+	d->rpc.r_number = atoi(cp);
+	q = d->rpc.r_aliases = d->rpc_aliases;
+	cp = index(p, ' ');
+	if (cp != NULL)
+		*cp++ = '\0';
+	else
+    {
+		cp = index(p, '\t');
+		if (cp != NULL)
+			*cp++ = '\0';
+	}
+	while (cp && *cp) {
+		if (*cp == ' ' || *cp == '\t') {
+			cp++;
+			continue;
+		}
+		if (q < &(d->rpc_aliases[MAXALIASES - 1]))
+			*q++ = cp;
+		cp = index(p, ' ');
+		if (cp != NULL)
+			*cp++ = '\0';
+		else
+	    {
+			cp = index(p, '\t');
+			if (cp != NULL)
+				*cp++ = '\0';
+		}
+	}
+	*q = NULL;
+	return (&d->rpc);
+}
diff --git a/external/rpc_win32/LIBRPC/getrpcpo.c b/external/rpc_win32/LIBRPC/getrpcpo.c
new file mode 100644
index 0000000..e69de29
diff --git a/external/rpc_win32/LIBRPC/makeportmap.mak b/external/rpc_win32/LIBRPC/makeportmap.mak
new file mode 100644
index 0000000..63adaa5
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/makeportmap.mak
@@ -0,0 +1,41 @@
+#
+#  Zlib compression library makefile
+#
+#  Copyright (c) 1997 Logiciels et Applications Scientifiques (L.A.S.) Inc.
+#  Il est strictement interdit de publier ou de devoiler le contenu de ce
+#  programme sans avoir prealablement obtenu la permission de L.A.S. Inc.
+#  It is strictly forbidden to publish or divulge the content of
+#  these programs without the prior permission of L.A.S. Inc.
+#
+
+#
+# The names of the targets to build
+#
+TOBEGEN		= portmap
+TARGETGEN	= $(PROGGEN)
+
+#
+# Source files
+#
+SOURCES =	portmap.c
+
+#
+# Compilation flags
+#
+INCLUDES = $(CURRENT_INCLUDE) $(OGDI_INCLUDE) $(PROJ_INCLUDE)\
+	   $(ZLIB_INCLUDE) $(GENERAL_INCLUDE) $(TCLTK_INCLUDE)
+CFLAGS 	= $(INCLUDES) $(COMMON_CFLAGS) $(FLAGS_X86DEF)
+LINK_LIBS= $(WIN_LINKLIB) $(RPC_LINKLIB)
+
+
+#
+# Include the common configuration
+#
+include $(TOPDIR)/config/common.mak
+
+#
+# Primary target
+#
+all: MKOBJECTDIR
+	@echo "making $(TARGETGEN)"
+	$(MAKE) --directory $(OBJDIR) -f ../makeportmap.mak PASS='depend' $(TARGETGEN)
diff --git a/external/rpc_win32/LIBRPC/makerpcinfo.mak b/external/rpc_win32/LIBRPC/makerpcinfo.mak
new file mode 100644
index 0000000..fff06eb
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/makerpcinfo.mak
@@ -0,0 +1,40 @@
+#
+#  Zlib compression library makefile
+#
+#  Copyright (c) 1997 Logiciels et Applications Scientifiques (L.A.S.) Inc.
+#  Il est strictement interdit de publier ou de devoiler le contenu de ce
+#  programme sans avoir prealablement obtenu la permission de L.A.S. Inc.
+#  It is strictly forbidden to publish or divulge the content of
+#  these programs without the prior permission of L.A.S. Inc.
+#
+
+#
+# The names of the targets to build
+#
+TOBEGEN		= rpcinfo
+TARGETGEN	= $(PROGGEN)
+
+#
+# Source files
+#
+SOURCES = rpcinfo.c getopt.c
+
+#
+# Compilation flags
+#
+INCLUDES = $(CURRENT_INCLUDE) $(OGDI_INCLUDE) $(PROJ_INCLUDE)\
+	   $(ZLIB_INCLUDE) $(GENERAL_INCLUDE) $(TCLTK_INCLUDE)
+CFLAGS 	= $(INCLUDES) $(COMMON_CFLAGS) $(FLAGS_X86DEF)
+LINK_LIBS= $(WIN_LINKLIB) $(RPC_LINKLIB)
+
+#
+# Include the common configuration
+#
+include $(TOPDIR)/config/common.mak
+
+#
+# Primary target
+#
+all: MKOBJECTDIR
+	@echo "making $(TARGETGEN)"
+	$(MAKE) --directory $(OBJDIR) -f ../makerpcinfo.mak PASS='depend' $(TARGETGEN)
diff --git a/external/rpc_win32/LIBRPC/nt.c b/external/rpc_win32/LIBRPC/nt.c
new file mode 100644
index 0000000..d33d4af
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/nt.c
@@ -0,0 +1,65 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+#include <rpc/rpc.h>
+#include <stdio.h>
+#include <winsock.h>
+
+WSADATA WSAData;
+
+static int init = 0;
+
+int rpc_nt_init(void)
+{
+	if (! init)
+		if (WSAStartup(0x0101, &WSAData)) {
+			nt_rpc_report("WSAStartup failed\n");
+			WSACleanup();
+			return -1;
+		}
+	init = 1;
+	return 0;
+}
+
+int rpc_nt_exit(void)
+{
+	return WSACleanup();
+}
+
+VOID
+nt_rpc_report(LPTSTR lpszMsg)
+{
+    CHAR    chMsg[256];
+    HANDLE  hEventSource;
+    LPTSTR  lpszStrings[2];
+
+    // Use event logging to log the error.
+    //
+    hEventSource = RegisterEventSource(NULL,
+                            TEXT("rpc.dll"));
+
+    sprintf(chMsg, "sunrpc report: %d", GetLastError());
+    lpszStrings[0] = chMsg;
+    lpszStrings[1] = lpszMsg;
+
+    if (hEventSource != NULL) {
+        ReportEvent(hEventSource, // handle of event source
+            EVENTLOG_WARNING_TYPE, // event type
+            0,                    // event category
+            0,                    // event ID
+            NULL,                 // current user's SID
+            2,                    // strings in lpszStrings
+            0,                    // no bytes of raw data
+            lpszStrings,          // array of error strings
+            NULL);                // no raw data
+
+        (VOID) DeregisterEventSource(hEventSource);
+    }
+}
+
diff --git a/external/rpc_win32/LIBRPC/pmap_cln.c b/external/rpc_win32/LIBRPC/pmap_cln.c
new file mode 100644
index 0000000..c0c9535
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/pmap_cln.c
@@ -0,0 +1,148 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)pmap_clnt.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_clnt.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <string.h>
+#include <rpc/rpc.h>
+#ifdef WIN32
+#include <rpc/pmap_pro.h>
+#include <rpc/pmap_cln.h>
+#else
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#endif
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+void clnt_perror();
+
+
+/*
+ * Set a mapping between program,version and port.
+ * Calls the pmap service remotely to do the mapping.
+ */
+bool_t
+pmap_set(program, version, protocol, port)
+	u_long program;
+	u_long version;
+	int protocol;
+	u_short port;
+{
+	struct sockaddr_in myaddress;
+	int socket = -1;
+	register CLIENT *client;
+	struct pmap parms;
+	bool_t rslt;
+
+	/* Get rid of Purify errors that are harmless but causing warnings */
+	memset(&myaddress, 0, sizeof(myaddress));
+	get_myaddress(&myaddress);
+	client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
+	    timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+	if (client == (CLIENT *)NULL)
+		return (FALSE);
+	parms.pm_prog = program;
+	parms.pm_vers = version;
+	parms.pm_prot = protocol;
+	parms.pm_port = port;
+	if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt,
+	    tottimeout) != RPC_SUCCESS) {
+		clnt_perror(client, "Cannot register service");
+		return (FALSE);
+	}
+	CLNT_DESTROY(client);
+#if 0 /* Socket gets closed in CLNT_DESTROY, no point in doing it here */
+#ifdef WIN32
+	(void)closesocket(socket);
+#else
+	(void)close(socket);
+#endif
+#endif
+	return (rslt);
+}
+
+/*
+ * Remove the mapping between program,version and port.
+ * Calls the pmap service remotely to do the un-mapping.
+ */
+bool_t
+pmap_unset(program, version)
+	u_long program;
+	u_long version;
+{
+	struct sockaddr_in myaddress;
+	int socket = -1;
+	register CLIENT *client;
+	struct pmap parms;
+	bool_t rslt;
+
+	/* Get rid of Purify errors that are harmless but causing warnings */
+	memset(&myaddress, 0, sizeof(myaddress));
+	get_myaddress(&myaddress);
+	client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
+	    timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+	if (client == (CLIENT *)NULL)
+		return (FALSE);
+	parms.pm_prog = program;
+	parms.pm_vers = version;
+	parms.pm_port = parms.pm_prot = 0;
+	CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt,
+	    tottimeout);
+	CLNT_DESTROY(client);
+#if 0 /* Socket gets closed in CLNT_DESTROY, no point in doing it here */
+#ifdef WIN32
+	(void)closesocket(socket);
+#else
+	(void)close(socket);
+#endif
+#endif
+	return (rslt);
+}
diff --git a/external/rpc_win32/LIBRPC/pmap_get.c b/external/rpc_win32/LIBRPC/pmap_get.c
new file mode 100644
index 0000000..ca3c056
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/pmap_get.c
@@ -0,0 +1,98 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)pmap_getport.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_getport.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_pro.h>
+#include <rpc/pmap_cln.h>
+
+static struct timeval timeout = { 5, 0 };
+static struct timeval tottimeout = { 60, 0 };
+
+/*
+ * Find the mapped port for program,version.
+ * Calls the pmap service remotely to do the lookup.
+ * Returns 0 if no map exists.
+ */
+u_short
+pmap_getport(address, program, version, protocol)
+	struct sockaddr_in *address;
+	u_long program;
+	u_long version;
+	u_int protocol;
+{
+	u_short port = 0;
+	int socket = -1;
+	register CLIENT *client;
+	struct pmap parms;
+
+	address->sin_port = htons(PMAPPORT);
+	client = clntudp_bufcreate(address, PMAPPROG,
+	    PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+	if (client != (CLIENT *)NULL) {
+		parms.pm_prog = program;
+		parms.pm_vers = version;
+		parms.pm_prot = protocol;
+		parms.pm_port = 0;  /* not needed or used */
+		if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms,
+		    xdr_u_short, &port, tottimeout) != RPC_SUCCESS){
+			rpc_createerr.cf_stat = RPC_PMAPFAILURE;
+			clnt_geterr(client, &rpc_createerr.cf_error);
+		} else if (port == 0) {
+			rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
+		}
+		/* CLNT_DESTROY calls close() or closesocket() */
+		CLNT_DESTROY(client);
+	} else {
+		(void)closesocket(socket);
+	}
+	address->sin_port = 0;
+	return (port);
+}
diff --git a/external/rpc_win32/LIBRPC/pmap_gma.c b/external/rpc_win32/LIBRPC/pmap_gma.c
new file mode 100644
index 0000000..f84953b
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/pmap_gma.c
@@ -0,0 +1,107 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)pmap_getmaps.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_getmap.c
+ * Client interface to pmap rpc service.
+ * contains pmap_getmaps, which is only tcp service involved
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#ifdef WIN32
+#include <stdlib.h>
+#include <rpc/pmap_pro.h>
+#include <rpc/pmap_cln.h>
+#else
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#endif
+#define NAMELEN 255
+#define MAX_BROADCAST_SIZE 1400
+
+#ifndef WIN32
+extern int errno;
+#endif
+
+/*
+ * Get a copy of the current port maps.
+ * Calls the pmap service remotely to do get the maps.
+ */
+struct pmaplist *
+pmap_getmaps(address)
+	 struct sockaddr_in *address;
+{
+	struct pmaplist *head = (struct pmaplist *)NULL;
+	int socket = -1;
+	struct timeval minutetimeout;
+	register CLIENT *client;
+
+	minutetimeout.tv_sec = 60;
+	minutetimeout.tv_usec = 0;
+	address->sin_port = htons(PMAPPORT);
+	client = clnttcp_create(address, PMAPPROG,
+	    PMAPVERS, &socket, 50, 500);
+	if (client != (CLIENT *)NULL) {
+		if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist,
+		    &head, minutetimeout) != RPC_SUCCESS) {
+			clnt_perror(client, "pmap_getmaps rpc problem");
+		}
+		CLNT_DESTROY(client);
+	}
+#ifdef WIN32
+	(void)closesocket(socket);
+#else
+	(void)close(socket);
+#endif
+	address->sin_port = 0;
+	return (head);
+}
diff --git a/external/rpc_win32/LIBRPC/pmap_pr.c b/external/rpc_win32/LIBRPC/pmap_pr.c
new file mode 100644
index 0000000..c9c6474
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/pmap_pr.c
@@ -0,0 +1,72 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)pmap_prot.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_prot.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#ifdef WIN32
+#include <rpc/pmap_pro.h>
+#else
+#include <rpc/pmap_prot.h>
+#endif
+
+
+bool_t
+xdr_pmap(xdrs, regs)
+	XDR *xdrs;
+	struct pmap *regs;
+{
+
+	if (xdr_u_long(xdrs, &regs->pm_prog) && 
+		xdr_u_long(xdrs, &regs->pm_vers) && 
+		xdr_u_long(xdrs, &regs->pm_prot))
+		return (xdr_u_long(xdrs, &regs->pm_port));
+	return (FALSE);
+}
diff --git a/external/rpc_win32/LIBRPC/pmap_pro.c b/external/rpc_win32/LIBRPC/pmap_pro.c
new file mode 100644
index 0000000..687f44e
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/pmap_pro.c
@@ -0,0 +1,130 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)pmap_prot2.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_prot2.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#ifdef WIN32
+#include <rpc/pmap_pro.h>
+#else
+#include <rpc/pmap_prot.h>
+#endif
+
+/* 
+ * What is going on with linked lists? (!)
+ * First recall the link list declaration from pmap_prot.h:
+ *
+ * struct pmaplist {
+ *	struct pmap pml_map;
+ *	struct pmaplist *pml_map;
+ * };
+ *
+ * Compare that declaration with a corresponding xdr declaration that 
+ * is (a) pointer-less, and (b) recursive:
+ *
+ * typedef union switch (bool_t) {
+ * 
+ *	case TRUE: struct {
+ *		struct pmap;
+ * 		pmaplist_t foo;
+ *	};
+ *
+ *	case FALSE: struct {};
+ * } pmaplist_t;
+ *
+ * Notice that the xdr declaration has no nxt pointer while
+ * the C declaration has no bool_t variable.  The bool_t can be
+ * interpreted as ``more data follows me''; if FALSE then nothing
+ * follows this bool_t; if TRUE then the bool_t is followed by
+ * an actual struct pmap, and then (recursively) by the 
+ * xdr union, pamplist_t.  
+ *
+ * This could be implemented via the xdr_union primitive, though this
+ * would cause a one recursive call per element in the list.  Rather than do
+ * that we can ``unwind'' the recursion
+ * into a while loop and do the union arms in-place.
+ *
+ * The head of the list is what the C programmer wishes to past around
+ * the net, yet is the data that the pointer points to which is interesting;
+ * this sounds like a job for xdr_reference!
+ */
+bool_t
+xdr_pmaplist(xdrs, rp)
+	register XDR *xdrs;
+	register struct pmaplist **rp;
+{
+	/*
+	 * more_elements is pre-computed in case the direction is
+	 * XDR_ENCODE or XDR_FREE.  more_elements is overwritten by
+	 * xdr_bool when the direction is XDR_DECODE.
+	 */
+	bool_t more_elements;
+	register int freeing = (xdrs->x_op == XDR_FREE);
+	register struct pmaplist **next;
+
+	while (TRUE) {
+		more_elements = (bool_t)(*rp != NULL);
+		if (! xdr_bool(xdrs, &more_elements))
+			return (FALSE);
+		if (! more_elements)
+			return (TRUE);  /* we are done */
+		/*
+		 * the unfortunate side effect of non-recursion is that in
+		 * the case of freeing we must remember the next object
+		 * before we free the current object ...
+		 */
+		if (freeing)
+			next = &((*rp)->pml_next); 
+		if (! xdr_reference(xdrs, (caddr_t *)rp,
+		    (u_int)sizeof(struct pmaplist), xdr_pmap))
+			return (FALSE);
+		rp = (freeing) ? next : &((*rp)->pml_next);
+	}
+}
diff --git a/external/rpc_win32/LIBRPC/pmap_rmt.c b/external/rpc_win32/LIBRPC/pmap_rmt.c
new file mode 100644
index 0000000..ccd3f8e
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/pmap_rmt.c
@@ -0,0 +1,443 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+/* @(#)pmap_rmt.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * pmap_rmt.c
+ * Client interface to pmap rpc service.
+ * remote call and broadcast service
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+#ifdef WIN32
+#include <rpc/pmap_pro.h>
+#include <rpc/pmap_cln.h>
+#include <rpc/pmap_rmt.h>
+#include <stdio.h>
+#include <errno.h>
+#define MAX_BROADCAST_SIZE 1400
+#else
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <rpc/pmap_rmt.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#define MAX_BROADCAST_SIZE 1400
+
+extern int errno;
+#endif
+static struct timeval timeout = { 3, 0 };
+
+
+/*
+ * pmapper remote-call-service interface.
+ * This routine is used to call the pmapper remote call service
+ * which will look up a service program in the port maps, and then
+ * remotely call that routine with the given parameters.  This allows
+ * programs to do a lookup and call in one step.
+*/
+enum clnt_stat
+pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr)
+	struct sockaddr_in *addr;
+	u_long prog, vers, proc;
+	xdrproc_t xdrargs, xdrres;
+	caddr_t argsp, resp;
+	struct timeval tout;
+	u_long *port_ptr;
+{
+	int socket = -1;
+	register CLIENT *client;
+	struct rmtcallargs a;
+	struct rmtcallres r;
+	enum clnt_stat stat;
+
+	addr->sin_port = htons(PMAPPORT);
+	client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket);
+	if (client != (CLIENT *)NULL) {
+		a.prog = prog;
+		a.vers = vers;
+		a.proc = proc;
+		a.args_ptr = argsp;
+		a.xdr_args = xdrargs;
+		r.port_ptr = port_ptr;
+		r.results_ptr = resp;
+		r.xdr_results = xdrres;
+		stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a,
+		    xdr_rmtcallres, &r, tout);
+		CLNT_DESTROY(client);
+	} else {
+		stat = RPC_FAILED;
+	}
+#ifdef WIN32
+	(void)closesocket(socket);
+#else
+	(void)close(socket);
+#endif
+	addr->sin_port = 0;
+	return (stat);
+}
+
+
+/*
+ * XDR remote call arguments
+ * written for XDR_ENCODE direction only
+ */
+bool_t
+xdr_rmtcall_args(xdrs, cap)
+	register XDR *xdrs;
+	register struct rmtcallargs *cap;
+{
+	u_int lenposition, argposition, position;
+
+	if (xdr_u_long(xdrs, &(cap->prog)) &&
+	    xdr_u_long(xdrs, &(cap->vers)) &&
+	    xdr_u_long(xdrs, &(cap->proc))) {
+		lenposition = XDR_GETPOS(xdrs);
+		if (! xdr_u_long(xdrs, &(cap->arglen)))
+		    return (FALSE);
+		argposition = XDR_GETPOS(xdrs);
+		if (! (*(cap->xdr_args))(xdrs, cap->args_ptr))
+		    return (FALSE);
+		position = XDR_GETPOS(xdrs);
+		cap->arglen = (u_long)position - (u_long)argposition;
+		XDR_SETPOS(xdrs, lenposition);
+		if (! xdr_u_long(xdrs, &(cap->arglen)))
+		    return (FALSE);
+		XDR_SETPOS(xdrs, position);
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+/*
+ * XDR remote call results
+ * written for XDR_DECODE direction only
+ */
+bool_t
+xdr_rmtcallres(xdrs, crp)
+	register XDR *xdrs;
+	register struct rmtcallres *crp;
+{
+	caddr_t port_ptr;
+
+	port_ptr = (caddr_t)crp->port_ptr;
+	if (xdr_reference(xdrs, &port_ptr, sizeof (u_long),
+	    xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) {
+		crp->port_ptr = (u_long *)port_ptr;
+		return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
+	}
+	return (FALSE);
+}
+
+
+/*
+ * The following is kludged-up support for simple rpc broadcasts.
+ * Someday a large, complicated system will replace these trivial
+ * routines which only support udp/ip .
+ */
+
+static int
+getbroadcastnets(addrs, sock, buf)
+	struct in_addr *addrs;
+	int sock;  /* any valid socket will do */
+	char *buf;  /* why allocxate more when we can use existing... */
+{
+#ifdef WIN32
+	/* try to do a global broadcast, this is not a clean solution */
+	addrs[0].s_addr = INADDR_BROADCAST;
+	return 1;
+
+	/* was return 0 in version 1.04 */
+
+#else
+	struct ifconf ifc;
+        struct ifreq ifreq, *ifr;
+	struct sockaddr_in *sin;
+        int n, i;
+
+        ifc.ifc_len = UDPMSGSIZE;
+        ifc.ifc_buf = buf;
+        if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
+                perror("broadcast: ioctl (get interface configuration)");
+                return (0);
+        }
+        ifr = ifc.ifc_req;
+        for (i = 0, n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) {
+                ifreq = *ifr;
+                if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
+                        perror("broadcast: ioctl (get interface flags)");
+                        continue;
+                }
+                if ((ifreq.ifr_flags & IFF_BROADCAST) &&
+		    (ifreq.ifr_flags & IFF_UP) &&
+		    ifr->ifr_addr.sa_family == AF_INET) {
+			sin = (struct sockaddr_in *)&ifr->ifr_addr;
+#ifdef SIOCGIFBRDADDR   /* 4.3BSD */
+			if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
+				addrs[i++] = inet_makeaddr(inet_netof
+			    (sin->sin_addr.s_addr), INADDR_ANY);
+			} else {
+				addrs[i++] = ((struct sockaddr_in*)
+				  &ifreq.ifr_addr)->sin_addr;
+			}
+#else /* 4.2 BSD */
+			addrs[i++] = inet_makeaddr(inet_netof
+			  (sin->sin_addr.s_addr), INADDR_ANY);
+#endif
+		}
+	}
+	return (i);
+#endif
+}
+
+typedef bool_t (*resultproc_t)();
+
+enum clnt_stat
+clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
+	u_long		prog;		/* program number */
+	u_long		vers;		/* version number */
+	u_long		proc;		/* procedure number */
+	xdrproc_t	xargs;		/* xdr routine for args */
+	caddr_t		argsp;		/* pointer to args */
+	xdrproc_t	xresults;	/* xdr routine for results */
+	caddr_t		resultsp;	/* pointer to results */
+	resultproc_t	eachresult;	/* call with each result obtained */
+{
+	enum clnt_stat stat;
+	AUTH *unix_auth = authunix_create_default();
+	XDR xdr_stream;
+	register XDR *xdrs = &xdr_stream;
+	int outlen, inlen, fromlen, nets;
+	register int sock;
+	int on = 1;
+#ifdef FD_SETSIZE
+	fd_set mask;
+	fd_set readfds;
+#else
+	int readfds;
+	register int mask;
+#endif /* def FD_SETSIZE */
+	register int i;
+	bool_t done = FALSE;
+	register u_long xid;
+	u_long port;
+	struct in_addr addrs[20];
+	struct sockaddr_in baddr, raddr; /* broadcast and response addresses */
+	struct rmtcallargs a;
+	struct rmtcallres r;
+	struct rpc_msg msg;
+	struct timeval t;
+	char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
+
+	/*
+	 * initialization: create a socket, a broadcast address, and
+	 * preserialize the arguments into a send buffer.
+	 */
+#ifdef WIN32
+	if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
+#else
+	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+#endif
+		perror("Cannot create socket for broadcast rpc");
+		stat = RPC_CANTSEND;
+		goto done_broad;
+	}
+#ifdef SO_BROADCAST
+	if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) {
+		perror("Cannot set socket option SO_BROADCAST");
+		stat = RPC_CANTSEND;
+		goto done_broad;
+	}
+#endif /* def SO_BROADCAST */
+#ifdef FD_SETSIZE
+	FD_ZERO(&mask);
+	FD_SET(sock, &mask);
+#else
+	mask = (1 << sock);
+#endif /* def FD_SETSIZE */
+	nets = getbroadcastnets(addrs, sock, inbuf);
+	bzero((char *)&baddr, sizeof (baddr));
+	baddr.sin_family = AF_INET;
+	baddr.sin_port = htons(PMAPPORT);
+	baddr.sin_addr.s_addr = htonl(INADDR_ANY);
+/*	baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */
+	(void)gettimeofday(&t, (struct timezone *)0);
+	msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec;
+	t.tv_usec = 0;
+	msg.rm_direction = CALL;
+	msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
+	msg.rm_call.cb_prog = PMAPPROG;
+	msg.rm_call.cb_vers = PMAPVERS;
+	msg.rm_call.cb_proc = PMAPPROC_CALLIT;
+	msg.rm_call.cb_cred = unix_auth->ah_cred;
+	msg.rm_call.cb_verf = unix_auth->ah_verf;
+	a.prog = prog;
+	a.vers = vers;
+	a.proc = proc;
+	a.xdr_args = xargs;
+	a.args_ptr = argsp;
+	r.port_ptr = &port;
+	r.xdr_results = xresults;
+	r.results_ptr = resultsp;
+	xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE);
+	if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) {
+		stat = RPC_CANTENCODEARGS;
+		goto done_broad;
+	}
+	outlen = (int)xdr_getpos(xdrs);
+	xdr_destroy(xdrs);
+	/*
+	 * Basic loop: broadcast a packet and wait a while for response(s).
+	 * The response timeout grows larger per iteration.
+	 */
+	for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) {
+		for (i = 0; i < nets; i++) {
+			baddr.sin_addr = addrs[i];
+			if (sendto(sock, outbuf, outlen, 0,
+				(struct sockaddr *)&baddr,
+				sizeof (struct sockaddr)) != outlen) {
+				perror("Cannot send broadcast packet");
+				stat = RPC_CANTSEND;
+				goto done_broad;
+			}
+		}
+		if (eachresult == NULL) {
+			stat = RPC_SUCCESS;
+			goto done_broad;
+		}
+	recv_again:
+		msg.acpted_rply.ar_verf = _null_auth;
+		msg.acpted_rply.ar_results.where = (caddr_t)&r;
+                msg.acpted_rply.ar_results.proc = xdr_rmtcallres;
+		readfds = mask;
+#ifdef WIN32
+		switch (select(0 /* unused in winsock */, &readfds, (int *)NULL,
+#else
+		switch (select(_rpc_dtablesize(), &readfds, (int *)NULL, 
+#endif
+			       (int *)NULL, &t)) {
+		case 0:  /* timed out */
+			stat = RPC_TIMEDOUT;
+			continue;
+
+		case -1:  /* some kind of error */
+#ifdef WIN32
+			if (WSAerrno == EINTR)
+#else
+			if (errno == EINTR)
+#endif
+				goto recv_again;
+			perror("Broadcast select problem");
+			stat = RPC_CANTRECV;
+			goto done_broad;
+
+		}  /* end of select results switch */
+	try_again:
+		fromlen = sizeof(struct sockaddr);
+		inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0,
+			(struct sockaddr *)&raddr, &fromlen);
+		if (inlen < 0) {
+#ifdef WIN32
+			if (WSAerrno == EINTR)
+#else
+			if (errno == EINTR)
+#endif
+				goto try_again;
+			perror("Cannot receive reply to broadcast");
+			stat = RPC_CANTRECV;
+			goto done_broad;
+		}
+		if (inlen < sizeof(u_long))
+			goto recv_again;
+		/*
+		 * see if reply transaction id matches sent id.
+		 * If so, decode the results.
+		 */
+		xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE);
+		if (xdr_replymsg(xdrs, &msg)) {
+			if ((msg.rm_xid == xid) &&
+				(msg.rm_reply.rp_stat == MSG_ACCEPTED) &&
+				(msg.acpted_rply.ar_stat == SUCCESS)) {
+				raddr.sin_port = htons((u_short)port);
+				done = (*eachresult)(resultsp, &raddr);
+			}
+			/* otherwise, we just ignore the errors ... */
+		} else {
+#ifdef notdef
+			/* some kind of deserialization problem ... */
+			if (msg.rm_xid == xid)
+#ifdef WIN32
+				nt_rpc_report("Broadcast deserialization problem");
+#else
+				fprintf(stderr, "Broadcast deserialization problem");
+#endif
+			/* otherwise, just random garbage */
+#endif
+		}
+		xdrs->x_op = XDR_FREE;
+		msg.acpted_rply.ar_results.proc = xdr_void;
+		(void)xdr_replymsg(xdrs, &msg);
+		(void)(*xresults)(xdrs, resultsp);
+		xdr_destroy(xdrs);
+		if (done) {
+			stat = RPC_SUCCESS;
+			goto done_broad;
+		} else {
+			goto recv_again;
+		}
+	}
+done_broad:
+#ifdef WIN32
+	(void)closesocket(sock);
+#else
+	(void)close(sock);
+#endif
+	AUTH_DESTROY(unix_auth);
+	return (stat);
+}
+
diff --git a/external/rpc_win32/LIBRPC/portmap.c b/external/rpc_win32/LIBRPC/portmap.c
new file mode 100644
index 0000000..34ae8eb
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/portmap.c
@@ -0,0 +1,458 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+#if !defined(lint) && !defined(_NOIDENT)
+static char rcsid[] = "@(#)$RCSfile: portmap.c,v $ $Revision: 1.1.1.1 $ (OSF) $Date: 2000/10/29 20:54:58 $";
+#endif
+#ifndef lint
+static	char sccsid[] = "@(#)portmap.c 1.2 85/03/13 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * Copyright (c) 1984 by Sun Microsystems, Inc.
+ */
+
+/*
+ * portmap.c, Implements the program,version to port number mapping for
+ * rpc.
+ * Modified to debug based on global var. "debug" so that you can twiddle
+ * it with adb and to use syslog for errors. rick macklem
+ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_pro.h>
+#include <stdio.h>
+
+#ifdef SMARTHEAP
+#include <smrtheap.h>
+unsigned MemDefaultPoolFlags = MEM_POOL_SERIALIZE;
+#endif
+
+int reg_service();
+static callit();
+
+#ifdef DEBUG
+#define	syslog(e, s)	fprintf(stderr, (s))
+static int debug = 1;
+#else
+static int debug = 0;
+#endif
+
+main()
+{
+	SVCXPRT *xprt;
+	int sock, pid, t;
+	struct sockaddr_in addr;
+	int len = sizeof(struct sockaddr_in);
+
+#if 0
+	if (!debug) {
+		pid = daemon(0,0);	/* from libutil */
+		if (pid < 0) {
+			perror("portmap: fork");
+			exit(1);
+		}
+	}
+
+	openlog("portmap:", LOG_PID, LOG_DAEMON);
+#endif
+
+	if (rpc_nt_init() != 0) {
+		fprintf(stderr, "cannot init WinSock\n");
+		exit(1);
+	}
+	
+
+	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
+		fprintf(stderr, "cannot create socket\n");
+		exit(1);
+	}
+
+	addr.sin_addr.s_addr = 0;
+	addr.sin_family = AF_INET;
+	addr.sin_port = htons(PMAPPORT);
+	if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
+		fprintf(stderr, "cannot bind\n");
+		exit(1);
+	}
+
+	if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) {
+		fprintf(stderr, "couldn't do udp_create\n");
+		exit(1);
+	}
+
+	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+		fprintf(stderr, "cannot create socket\n");
+		exit(1);
+	}
+	if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
+		fprintf(stderr, "cannot bind\n");
+		exit(1);
+	}
+	if ((xprt = svctcp_create(sock, 0, 0)) == (SVCXPRT *)NULL) {
+		fprintf(stderr, "couldn't do tcp_create\n");
+		exit(1);
+	}
+
+        (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE);
+	svc_run();
+	fprintf(stderr, "run_svc returned unexpectedly\n");
+
+	rpc_nt_exit();
+
+	abort();
+}
+
+struct pmaplist *pmaplist;
+
+static struct pmaplist *
+find_service(prog, vers, prot)
+	u_long prog;
+	u_long vers;
+{
+	register struct pmaplist *hit = NULL;
+	register struct pmaplist *pml;
+
+	for (pml = pmaplist; pml != NULL; pml = pml->pml_next) {
+		if ((pml->pml_map.pm_prog != prog) ||
+			(pml->pml_map.pm_prot != prot))
+			continue;
+		hit = pml;
+		if (pml->pml_map.pm_vers == vers)
+		    break;
+	}
+
+	return (hit);
+}
+
+/* 
+ * 1 OK, 0 not
+ */
+reg_service(rqstp, xprt)
+	struct svc_req *rqstp;
+	SVCXPRT *xprt;
+{
+	struct pmap reg;
+	struct pmaplist *pml, *prevpml, *fnd;
+	int ans, port;
+	caddr_t t;
+	
+	if (debug)
+		fprintf(stderr, "server: about do a switch\n");
+	switch (rqstp->rq_proc) {
+
+	case PMAPPROC_NULL:
+		/*
+		 * Null proc call
+		 */
+		if ((!svc_sendreply(xprt, xdr_void, NULL)) && debug) {
+			abort();
+		}
+		break;
+
+	case PMAPPROC_SET:
+		/*
+		 * Set a program,version to port mapping
+		 */
+		if (!svc_getargs(xprt, xdr_pmap, &reg))
+			svcerr_decode(xprt);
+		else {
+			/*
+			 * check to see if already used
+			 * find_service returns a hit even if
+			 * the versions don't match, so check for it
+			 */
+			fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
+			if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) {
+				if (fnd->pml_map.pm_port == reg.pm_port) {
+					ans = 1;
+					goto done;
+				}
+				else {
+					ans = 0;
+					goto done;
+				}
+			} else {
+				/* 
+				 * add to list
+				 */
+				pml = (struct pmaplist *)
+				    malloc((u_int)sizeof(struct pmaplist));
+				pml->pml_map = reg;
+				pml->pml_next = pmaplist;
+				pmaplist = pml;
+				ans = 1;
+			}
+		done:
+			if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
+			    debug) {
+				fprintf(stderr, "svc_sendreply\n");
+				abort();
+			}
+		}
+		break;
+
+	case PMAPPROC_UNSET:
+		/*
+		 * Remove a program,version to port mapping.
+		 */
+		if (!svc_getargs(xprt, xdr_pmap, &reg))
+			svcerr_decode(xprt);
+		else {
+			ans = 0;
+			for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {
+				if ((pml->pml_map.pm_prog != reg.pm_prog) ||
+					(pml->pml_map.pm_vers != reg.pm_vers)) {
+					/* both pml & prevpml move forwards */
+					prevpml = pml;
+					pml = pml->pml_next;
+					continue;
+				}
+				/* found it; pml moves forward, prevpml stays */
+				ans = 1;
+				t = (caddr_t)pml;
+				pml = pml->pml_next;
+				if (prevpml == NULL)
+					pmaplist = pml;
+				else
+					prevpml->pml_next = pml;
+				free(t);
+			}
+			if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&ans)) &&
+			    debug) {
+				fprintf(stderr, "svc_sendreply\n");
+				abort();
+			}
+		}
+		break;
+
+	case PMAPPROC_GETPORT:
+		/*
+		 * Lookup the mapping for a program,version and return its port
+		 */
+		if (!svc_getargs(xprt, xdr_pmap, &reg))
+			svcerr_decode(xprt);
+		else {
+			fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
+			if (fnd)
+				port = fnd->pml_map.pm_port;
+			else
+				port = 0;
+			if ((!svc_sendreply(xprt, xdr_long, (caddr_t)&port)) &&
+			    debug) {
+				fprintf(stderr, "svc_sendreply\n");
+				abort();
+			}
+		}
+		break;
+
+	case PMAPPROC_DUMP:
+		/*
+		 * Return the current set of mapped program,version
+		 */
+		if (!svc_getargs(xprt, xdr_void, NULL))
+			svcerr_decode(xprt);
+		else {
+			if ((!svc_sendreply(xprt, xdr_pmaplist,
+			    (caddr_t)&pmaplist)) && debug) {
+				fprintf(stderr, "svc_sendreply\n");
+				abort();
+			}
+		}
+		break;
+
+	case PMAPPROC_CALLIT:
+		/*
+		 * Calls a procedure on the local machine.  If the requested
+		 * procedure is not registered this procedure does not return
+		 * error information!!
+		 * This procedure is only supported on rpc/udp and calls via 
+		 * rpc/udp.  It passes null authentication parameters.
+		 */
+		callit(rqstp, xprt);
+		break;
+
+	default:
+		svcerr_noproc(xprt);
+		break;
+	}
+}
+
+
+/*
+ * Stuff for the rmtcall service
+ */
+#define ARGSIZE 9000
+
+typedef struct encap_parms {
+	u_long arglen;
+	char *args;
+} encap_parms_t;
+
+static bool_t
+xdr_encap_parms(xdrs, epp)
+	XDR *xdrs;
+	struct encap_parms *epp;
+{
+
+	return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE));
+}
+
+typedef struct rmtcallargs {
+	u_long	rmt_prog;
+	u_long	rmt_vers;
+	u_long	rmt_port;
+	u_long	rmt_proc;
+	struct encap_parms rmt_args;
+} rmtcallargs_t;
+
+static bool_t
+xdr_rmtcall_args(xdrs, cap)
+	register XDR *xdrs;
+	register struct rmtcallargs *cap;
+{
+
+	/* does not get a port number */
+	if (xdr_u_long(xdrs, &(cap->rmt_prog)) &&
+	    xdr_u_long(xdrs, &(cap->rmt_vers)) &&
+	    xdr_u_long(xdrs, &(cap->rmt_proc))) {
+		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
+	}
+	return (FALSE);
+}
+
+static bool_t
+xdr_rmtcall_result(xdrs, cap)
+	register XDR *xdrs;
+	register struct rmtcallargs *cap;
+{
+	if (xdr_u_long(xdrs, &(cap->rmt_port)))
+		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
+	return (FALSE);
+}
+
+/*
+ * only worries about the struct encap_parms part of struct rmtcallargs.
+ * The arglen must already be set!!
+ */
+static bool_t
+xdr_opaque_parms(xdrs, cap)
+	XDR *xdrs;
+	struct rmtcallargs *cap;
+{
+
+	return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen));
+}
+
+/*
+ * This routine finds and sets the length of incoming opaque paraters
+ * and then calls xdr_opaque_parms.
+ */
+static bool_t
+xdr_len_opaque_parms(xdrs, cap)
+	register XDR *xdrs;
+	struct rmtcallargs *cap;
+{
+	register u_int beginpos, lowpos, highpos, currpos, pos;
+
+	beginpos = lowpos = pos = xdr_getpos(xdrs);
+	highpos = lowpos + ARGSIZE;
+	while ((int)(highpos - lowpos) >= 0) {
+		currpos = (lowpos + highpos) / 2;
+		if (xdr_setpos(xdrs, currpos)) {
+			pos = currpos;
+			lowpos = currpos + 1;
+		} else {
+			highpos = currpos - 1;
+		}
+	}
+	xdr_setpos(xdrs, beginpos);
+	cap->rmt_args.arglen = pos - beginpos;
+	return (xdr_opaque_parms(xdrs, cap));
+}
+
+/*
+ * Call a remote procedure service
+ * This procedure is very quiet when things go wrong.
+ * The proc is written to support broadcast rpc.  In the broadcast case,
+ * a machine should shut-up instead of complain, less the requestor be
+ * overrun with complaints at the expense of not hearing a valid reply ...
+ */
+static
+callit(rqstp, xprt)
+	struct svc_req *rqstp;
+	SVCXPRT *xprt;
+{
+	char buf[2000];
+	struct rmtcallargs a;
+	struct pmaplist *pml;
+	u_short port;
+	struct sockaddr_in me;
+	int socket = -1;
+	CLIENT *client;
+	struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;
+	struct timeval timeout;
+
+	timeout.tv_sec = 5;
+	timeout.tv_usec = 0;
+	a.rmt_args.args = buf;
+	if (!svc_getargs(xprt, xdr_rmtcall_args, &a))
+	    return;
+	if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL)
+	    return;
+	port = pml->pml_map.pm_port;
+	get_myaddress(&me);
+	me.sin_port = htons(port);
+	client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket);
+	if (client != (CLIENT *)NULL) {
+		if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
+			client->cl_auth = authunix_create(au->aup_machname,
+			   au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids);
+		}
+		a.rmt_port = (u_long)port;
+		if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a,
+		    xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) {
+			svc_sendreply(xprt, xdr_rmtcall_result, &a);
+		}
+		AUTH_DESTROY(client->cl_auth);
+		clnt_destroy(client);
+	}
+	(void)closesocket(socket);
+}
diff --git a/external/rpc_win32/LIBRPC/rpc.def b/external/rpc_win32/LIBRPC/rpc.def
new file mode 100644
index 0000000..844b5bb
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/rpc.def
@@ -0,0 +1,88 @@
+LIBRARY rpc
+
+CODE      PRELOAD MOVEABLE DISCARDABLE
+DATA      PRELOAD SINGLE
+
+EXPORTS
+
+	authnone_create
+	authunix_create
+	authunix_create_default
+	bcopy
+	bzero
+	bcmp
+	clnt_broadcast
+	clnt_create
+	clnt_pcreateerror
+	clnt_perror
+	clnt_sperrno
+	clntraw_create
+	clnttcp_create
+	clntudp_bufcreate
+	clntudp_create
+	get_myaddress
+	getrpcbyname
+	getrpcbynumber
+	pmap_getmaps
+	pmap_getport
+	pmap_set
+	pmap_unset
+	rpc_nt_exit
+	rpc_nt_init
+	svc_getreq
+	svc_getreqset
+	svc_register
+	svc_run
+	svc_sendreply
+	svc_unregister
+	svcerr_auth
+	svcerr_decode
+	svcerr_noproc
+	svcerr_noprog
+	svcerr_progvers
+	svcerr_systemerr
+	svcerr_weakauth
+	svcraw_create
+	svctcp_create
+	svcudp_bufcreate
+	svcudp_create
+	xdr_array
+	xdr_authunix_parms
+	xdr_bool
+	xdr_bytes
+	xdr_callhdr
+	xdr_callmsg
+	xdr_char
+	xdr_des_block
+	xdr_double
+	xdr_enum
+	xdr_float
+	xdr_free
+	xdr_int
+	xdr_long
+	xdr_netobj
+	xdr_opaque
+	xdr_opaque_auth
+	xdr_pmap
+	xdr_pmaplist
+	xdr_pointer
+	xdr_reference
+	xdr_replymsg
+	xdr_short
+	xdr_string
+	xdr_u_char
+	xdr_u_int
+	xdr_u_long
+	xdr_u_short
+	xdr_union
+	xdr_vector
+	xdr_void
+	xdr_wrapstring
+	xdrmem_create
+	xdrrec_create
+	xdrrec_endofrecord
+	xdrrec_eof
+	xdrrec_skiprecord
+	xdrstdio_create
+	xprt_register
+	xprt_unregister
diff --git a/external/rpc_win32/LIBRPC/rpc_call.c b/external/rpc_win32/LIBRPC/rpc_call.c
new file mode 100644
index 0000000..4eee78d
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/rpc_call.c
@@ -0,0 +1,201 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+/* @(#)rpc_callmsg.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * rpc_callmsg.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+
+#ifndef WIN32
+#include <sys/param.h>
+#endif
+#include <rpc/rpc.h>
+
+/*
+ * XDR a call message
+ */
+bool_t
+xdr_callmsg(xdrs, cmsg)
+	register XDR *xdrs;
+	register struct rpc_msg *cmsg;
+{
+	register long *buf;
+	register struct opaque_auth *oa;
+
+	if (xdrs->x_op == XDR_ENCODE) {
+		if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
+			return (FALSE);
+		}
+		if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) {
+			return (FALSE);
+		}
+		buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT
+			+ RNDUP(cmsg->rm_call.cb_cred.oa_length)
+			+ 2 * BYTES_PER_XDR_UNIT
+			+ RNDUP(cmsg->rm_call.cb_verf.oa_length));
+		if (buf != NULL) {
+			IXDR_PUT_LONG(buf, cmsg->rm_xid);
+			IXDR_PUT_ENUM(buf, cmsg->rm_direction);
+			if (cmsg->rm_direction != CALL) {
+				return (FALSE);
+			}
+			IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers);
+			if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
+				return (FALSE);
+			}
+			IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog);
+			IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers);
+			IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc);
+			oa = &cmsg->rm_call.cb_cred;
+			IXDR_PUT_ENUM(buf, oa->oa_flavor);
+			IXDR_PUT_LONG(buf, oa->oa_length);
+			if (oa->oa_length) {
+				bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length);
+				buf += RNDUP(oa->oa_length) / sizeof (long);
+			}
+			oa = &cmsg->rm_call.cb_verf;
+			IXDR_PUT_ENUM(buf, oa->oa_flavor);
+			IXDR_PUT_LONG(buf, oa->oa_length);
+			if (oa->oa_length) {
+				bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length);
+				/* no real need....
+				buf += RNDUP(oa->oa_length) / sizeof (long);
+				*/
+			}
+			return (TRUE);
+		}
+	}
+	if (xdrs->x_op == XDR_DECODE) {
+		buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
+		if (buf != NULL) {
+			cmsg->rm_xid = IXDR_GET_LONG(buf);
+			cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
+			if (cmsg->rm_direction != CALL) {
+				return (FALSE);
+			}
+			cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf);
+			if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
+				return (FALSE);
+			}
+			cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf);
+			cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf);
+			cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf);
+			oa = &cmsg->rm_call.cb_cred;
+			oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
+			oa->oa_length = IXDR_GET_LONG(buf);
+			if (oa->oa_length) {
+				if (oa->oa_length > MAX_AUTH_BYTES) {
+					return (FALSE);
+				}
+				if (oa->oa_base == NULL) {
+					oa->oa_base = (caddr_t)
+						mem_alloc(oa->oa_length);
+				}
+				buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+				if (buf == NULL) {
+					if (xdr_opaque(xdrs, oa->oa_base,
+					    oa->oa_length) == FALSE) {
+						return (FALSE);
+					}
+				} else {
+					bcopy((caddr_t)buf, oa->oa_base,
+					    oa->oa_length);
+					/* no real need....
+					buf += RNDUP(oa->oa_length) /
+						sizeof (long);
+					*/
+				}
+			}
+			oa = &cmsg->rm_call.cb_verf;
+			buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
+			if (buf == NULL) {
+				if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
+				    xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
+					return (FALSE);
+				}
+			} else {
+				oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
+				oa->oa_length = IXDR_GET_LONG(buf);
+			}
+			if (oa->oa_length) {
+				if (oa->oa_length > MAX_AUTH_BYTES) {
+					return (FALSE);
+				}
+				if (oa->oa_base == NULL) {
+					oa->oa_base = (caddr_t)
+						mem_alloc(oa->oa_length);
+				}
+				buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+				if (buf == NULL) {
+					if (xdr_opaque(xdrs, oa->oa_base,
+					    oa->oa_length) == FALSE) {
+						return (FALSE);
+					}
+				} else {
+					bcopy((caddr_t)buf, oa->oa_base,
+					    oa->oa_length);
+					/* no real need...
+					buf += RNDUP(oa->oa_length) /
+						sizeof (long);
+					*/
+				}
+			}
+			return (TRUE);
+		}
+	}
+	if (
+	    xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
+	    xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
+	    (cmsg->rm_direction == CALL) &&
+	    xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+	    (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) &&
+	    xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) &&
+	    xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) &&
+	    xdr_u_long(xdrs, &(cmsg->rm_call.cb_proc)) &&
+	    xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) )
+	    return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf)));
+	return (FALSE);
+}
+
diff --git a/external/rpc_win32/LIBRPC/rpc_comm.c b/external/rpc_win32/LIBRPC/rpc_comm.c
new file mode 100644
index 0000000..bc87d16
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/rpc_comm.c
@@ -0,0 +1,52 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)rpc_commondata.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#include <rpc/rpc.h>
+/*
+ * This file should only contain common data (global data) that is exported
+ * by public interfaces 
+ */
+struct opaque_auth _null_auth;
+#ifdef FD_SETSIZE
+fd_set svc_fdset;
+#else
+int svc_fds;
+#endif /* def FD_SETSIZE */
+struct rpc_createerr rpc_createerr;
diff --git a/external/rpc_win32/LIBRPC/rpc_prot.c b/external/rpc_win32/LIBRPC/rpc_prot.c
new file mode 100644
index 0000000..4240a37
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/rpc_prot.c
@@ -0,0 +1,302 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)rpc_prot.c	2.3 88/08/07 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * rpc_prot.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements the rpc message definition,
+ * its serializer and some common rpc utility routines.
+ * The routines are meant for various implementations of rpc -
+ * they are NOT for the rpc client or rpc service implementations!
+ * Because authentication stuff is easy and is part of rpc, the opaque
+ * routines are also in this program.
+ */
+
+#ifndef WIN32
+#include <sys/param.h>
+#endif
+
+#include <rpc/rpc.h>
+
+/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */
+
+struct opaque_auth _null_auth;
+
+/*
+ * XDR an opaque authentication struct
+ * (see auth.h)
+ */
+bool_t
+xdr_opaque_auth(xdrs, ap)
+	register XDR *xdrs;
+	register struct opaque_auth *ap;
+{
+
+	if (xdr_enum(xdrs, &(ap->oa_flavor)))
+		return (xdr_bytes(xdrs, &ap->oa_base,
+			&ap->oa_length, MAX_AUTH_BYTES));
+	return (FALSE);
+}
+
+/*
+ * XDR a DES block
+ */
+bool_t
+xdr_des_block(xdrs, blkp)
+	register XDR *xdrs;
+	register des_block *blkp;
+{
+	return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block)));
+}
+
+/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */
+
+/*
+ * XDR the MSG_ACCEPTED part of a reply message union
+ */
+bool_t 
+xdr_accepted_reply(xdrs, ar)
+	register XDR *xdrs;   
+	register struct accepted_reply *ar;
+{
+
+	/* personalized union, rather than calling xdr_union */
+	if (! xdr_opaque_auth(xdrs, &(ar->ar_verf)))
+		return (FALSE);
+	if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat)))
+		return (FALSE);
+	switch (ar->ar_stat) {
+
+	case SUCCESS:
+		return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where));
+
+	case PROG_MISMATCH:
+		if (! xdr_u_long(xdrs, &(ar->ar_vers.low)))
+			return (FALSE);
+		return (xdr_u_long(xdrs, &(ar->ar_vers.high)));
+	}
+	return (TRUE);  /* TRUE => open ended set of problems */
+}
+
+/*
+ * XDR the MSG_DENIED part of a reply message union
+ */
+bool_t 
+xdr_rejected_reply(xdrs, rr)
+	register XDR *xdrs;
+	register struct rejected_reply *rr;
+{
+
+	/* personalized union, rather than calling xdr_union */
+	if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat)))
+		return (FALSE);
+	switch (rr->rj_stat) {
+
+	case RPC_MISMATCH:
+		if (! xdr_u_long(xdrs, &(rr->rj_vers.low)))
+			return (FALSE);
+		return (xdr_u_long(xdrs, &(rr->rj_vers.high)));
+
+	case AUTH_ERROR:
+		return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why)));
+	}
+	return (FALSE);
+}
+
+static struct xdr_discrim reply_dscrm[3] = {
+	{ (int)MSG_ACCEPTED, xdr_accepted_reply },
+	{ (int)MSG_DENIED, xdr_rejected_reply },
+	{ __dontcare__, NULL_xdrproc_t } };
+
+/*
+ * XDR a reply message
+ */
+bool_t
+xdr_replymsg(xdrs, rmsg)
+	register XDR *xdrs;
+	register struct rpc_msg *rmsg;
+{
+	if (
+	    xdr_u_long(xdrs, &(rmsg->rm_xid)) && 
+	    xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) &&
+	    (rmsg->rm_direction == REPLY) )
+		return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat),
+		   (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t));
+	return (FALSE);
+}
+
+
+/*
+ * Serializes the "static part" of a call message header.
+ * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers.
+ * The rm_xid is not really static, but the user can easily munge on the fly.
+ */
+bool_t
+xdr_callhdr(xdrs, cmsg)
+	register XDR *xdrs;
+	register struct rpc_msg *cmsg;
+{
+
+	cmsg->rm_direction = CALL;
+	cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION;
+	if (
+	    (xdrs->x_op == XDR_ENCODE) &&
+	    xdr_u_long(xdrs, &(cmsg->rm_xid)) &&
+	    xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) &&
+	    xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) &&
+	    xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) )
+	    return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)));
+	return (FALSE);
+}
+
+/* ************************** Client utility routine ************* */
+
+static void
+accepted(acpt_stat, error)
+	register enum accept_stat acpt_stat;
+	register struct rpc_err *error;
+{
+
+	switch (acpt_stat) {
+
+	case PROG_UNAVAIL:
+		error->re_status = RPC_PROGUNAVAIL;
+		return;
+
+	case PROG_MISMATCH:
+		error->re_status = RPC_PROGVERSMISMATCH;
+		return;
+
+	case PROC_UNAVAIL:
+		error->re_status = RPC_PROCUNAVAIL;
+		return;
+
+	case GARBAGE_ARGS:
+		error->re_status = RPC_CANTDECODEARGS;
+		return;
+
+	case SYSTEM_ERR:
+		error->re_status = RPC_SYSTEMERROR;
+		return;
+
+	case SUCCESS:
+		error->re_status = RPC_SUCCESS;
+		return;
+	}
+	/* something's wrong, but we don't know what ... */
+	error->re_status = RPC_FAILED;
+	error->re_lb.s1 = (long)MSG_ACCEPTED;
+	error->re_lb.s2 = (long)acpt_stat;
+}
+
+static void 
+rejected(rjct_stat, error)
+	register enum reject_stat rjct_stat;
+	register struct rpc_err *error;
+{
+
+	switch (rjct_stat) {
+
+	case RPC_VERSMISMATCH:
+		error->re_status = RPC_VERSMISMATCH;
+		return;
+
+	case AUTH_ERROR:
+		error->re_status = RPC_AUTHERROR;
+		return;
+	}
+	/* something's wrong, but we don't know what ... */
+	error->re_status = RPC_FAILED;
+	error->re_lb.s1 = (long)MSG_DENIED;
+	error->re_lb.s2 = (long)rjct_stat;
+}
+
+/*
+ * given a reply message, fills in the error
+ */
+void
+_seterr_reply(msg, error)
+	register struct rpc_msg *msg;
+	register struct rpc_err *error;
+{
+
+	/* optimized for normal, SUCCESSful case */
+	switch (msg->rm_reply.rp_stat) {
+
+	case MSG_ACCEPTED:
+		if (msg->acpted_rply.ar_stat == SUCCESS) {
+			error->re_status = RPC_SUCCESS;
+			return;
+		};
+		accepted(msg->acpted_rply.ar_stat, error);
+		break;
+
+	case MSG_DENIED:
+		rejected(msg->rjcted_rply.rj_stat, error);
+		break;
+
+	default:
+		error->re_status = RPC_FAILED;
+		error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
+		break;
+	}
+	switch (error->re_status) {
+
+	case RPC_VERSMISMATCH:
+		error->re_vers.low = msg->rjcted_rply.rj_vers.low;
+		error->re_vers.high = msg->rjcted_rply.rj_vers.high;
+		break;
+
+	case RPC_AUTHERROR:
+		error->re_why = msg->rjcted_rply.rj_why;
+		break;
+
+	case RPC_PROGVERSMISMATCH:
+		error->re_vers.low = msg->acpted_rply.ar_vers.low;
+		error->re_vers.high = msg->acpted_rply.ar_vers.high;
+		break;
+	}
+}
diff --git a/external/rpc_win32/LIBRPC/rpcinfo.c b/external/rpc_win32/LIBRPC/rpcinfo.c
new file mode 100644
index 0000000..e5de319
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/rpcinfo.c
@@ -0,0 +1,676 @@
+/* @(#)rpcinfo.c	2.2 88/08/11 4.0 RPCSRC */
+#ifndef lint
+static	char sccsid[] = "@(#)rpcinfo.c 1.22 87/08/12 SMI";
+#endif
+
+/*
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+/*
+ * rpcinfo: ping a particular rpc program
+ *     or dump the portmapper
+ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#include <rpc/rpc.h>
+#include <stdio.h>
+#include <sys/socket.h>
+#ifdef WIN32
+#include <rpc/pmap_pro.h>
+#include <rpc/pmap_cln.h>
+#else
+#include <netdb.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#define closesocket(x) close(x)
+#endif
+#include <signal.h>
+#include <ctype.h>
+
+#define MAXHOSTLEN 256
+
+#define	MIN_VERS	((u_long) 0)
+#define	MAX_VERS	((u_long) 4294967295L)
+
+static void	udpping(/*u_short portflag, int argc, char **argv*/);
+static void	tcpping(/*u_short portflag, int argc, char **argv*/);
+static int	pstatus(/*CLIENT *client, u_long prognum, u_long vers*/);
+static void	pmapdump(/*int argc, char **argv*/);
+static bool_t	reply_proc(/*void *res, struct sockaddr_in *who*/);
+static void	brdcst(/*int argc, char **argv*/);
+static void	deletereg(/* int argc, char **argv */) ;
+static void	usage(/*void*/);
+static u_long	getprognum(/*char *arg*/);
+static u_long	getvers(/*char *arg*/);
+static void	get_inet_address(/*struct sockaddr_in *addr, char *host*/);
+#if 0
+extern u_long inet_addr();  /* in 4.2BSD, arpa/inet.h called that a in_addr */
+extern char *inet_ntoa();
+#endif
+
+/*
+ * Functions to be performed.
+ */
+#define	NONE		0	/* no function */
+#define	PMAPDUMP	1	/* dump portmapper registrations */
+#define	TCPPING		2	/* ping TCP service */
+#define	UDPPING		3	/* ping UDP service */
+#define	BRDCST		4	/* ping broadcast UDP service */
+#define DELETES		5	/* delete registration for the service */
+
+int
+main(argc, argv)
+	int argc;
+	char **argv;
+{
+	register int c;
+	extern char *optarg;
+	extern int optind;
+	int errflg;
+	int function;
+	u_short portnum;
+
+	function = NONE;
+	portnum = 0;
+	errflg = 0;
+	while ((c = getopt(argc, argv, "ptubdn:")) != -1) {
+		switch (c) {
+
+		case 'p':
+			if (function != NONE)
+				errflg = 1;
+			else
+				function = PMAPDUMP;
+			break;
+
+		case 't':
+			if (function != NONE)
+				errflg = 1;
+			else
+				function = TCPPING;
+			break;
+
+		case 'u':
+			if (function != NONE)
+				errflg = 1;
+			else
+				function = UDPPING;
+			break;
+
+		case 'b':
+			if (function != NONE)
+				errflg = 1;
+			else
+				function = BRDCST;
+			break;
+
+		case 'n':
+			portnum = (u_short) atoi(optarg);   /* hope we don't get bogus # */
+			break;
+
+		case 'd':
+			if (function != NONE)
+				errflg = 1;
+			else
+				function = DELETES;
+			break;
+
+		case '?':
+			errflg = 1;
+		}
+	}
+
+	if (errflg || function == NONE) {
+		usage();
+		return (1);
+	}
+
+	switch (function) {
+
+	case PMAPDUMP:
+		if (portnum != 0) {
+			usage();
+			return (1);
+		}
+		pmapdump(argc - optind, argv + optind);
+		break;
+
+	case UDPPING:
+		udpping(portnum, argc - optind, argv + optind);
+		break;
+
+	case TCPPING:
+		tcpping(portnum, argc - optind, argv + optind);
+		break;
+
+	case BRDCST:
+		if (portnum != 0) {
+			usage();
+			return (1);
+		}
+		brdcst(argc - optind, argv + optind);
+		break;
+
+	case DELETES:
+		deletereg(argc - optind, argv + optind);
+		break;
+	}
+
+	return (0);
+}
+
+static void
+udpping(portnum, argc, argv)
+	u_short portnum;
+	int argc;
+	char **argv;
+{
+	struct timeval to;
+	struct sockaddr_in addr;
+	enum clnt_stat rpc_stat;
+	CLIENT *client;
+	u_long prognum, vers, minvers, maxvers;
+	int sock = RPC_ANYSOCK;
+	struct rpc_err rpcerr;
+	int failure;
+
+	if (argc < 2 || argc > 3) {
+		usage();
+		exit(1);
+	}
+	prognum = getprognum(argv[1]);
+	get_inet_address(&addr, argv[0]);
+	/* Open the socket here so it will survive calls to clnt_destroy */
+	sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	if (sock < 0) {
+		perror("rpcinfo: socket");
+		exit(1);
+	}
+	failure = 0;
+	if (argc == 2) {
+		/*
+		 * A call to version 0 should fail with a program/version
+		 * mismatch, and give us the range of versions supported.
+		 */
+		addr.sin_port = htons(portnum);
+		to.tv_sec = 5;
+		to.tv_usec = 0;
+		if ((client = clntudp_create(&addr, prognum, (u_long)0,
+		    to, &sock)) == NULL) {
+			clnt_pcreateerror("rpcinfo");
+			printf("program %lu is not available\n",
+			    prognum);
+			exit(1);
+		}
+		to.tv_sec = 10;
+		to.tv_usec = 0;
+		rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL,
+		    xdr_void, (char *)NULL, to);
+		if (rpc_stat == RPC_PROGVERSMISMATCH) {
+			clnt_geterr(client, &rpcerr);
+			minvers = rpcerr.re_vers.low;
+			maxvers = rpcerr.re_vers.high;
+		} else if (rpc_stat == RPC_SUCCESS) {
+			/*
+			 * Oh dear, it DOES support version 0.
+			 * Let's try version MAX_VERS.
+			 */
+			addr.sin_port = htons(portnum);
+			to.tv_sec = 5;
+			to.tv_usec = 0;
+			if ((client = clntudp_create(&addr, prognum, MAX_VERS,
+			    to, &sock)) == NULL) {
+				clnt_pcreateerror("rpcinfo");
+				printf("program %lu version %lu is not available\n",
+				    prognum, MAX_VERS);
+				exit(1);
+			}
+			to.tv_sec = 10;
+			to.tv_usec = 0;
+			rpc_stat = clnt_call(client, NULLPROC, xdr_void,
+			    (char *)NULL, xdr_void, (char *)NULL, to);
+			if (rpc_stat == RPC_PROGVERSMISMATCH) {
+				clnt_geterr(client, &rpcerr);
+				minvers = rpcerr.re_vers.low;
+				maxvers = rpcerr.re_vers.high;
+			} else if (rpc_stat == RPC_SUCCESS) {
+				/*
+				 * It also supports version MAX_VERS.
+				 * Looks like we have a wise guy.
+				 * OK, we give them information on all
+				 * 4 billion versions they support...
+				 */
+				minvers = 0;
+				maxvers = MAX_VERS;
+			} else {
+				(void) pstatus(client, prognum, MAX_VERS);
+				exit(1);
+			}
+		} else {
+			(void) pstatus(client, prognum, (u_long)0);
+			exit(1);
+		}
+		clnt_destroy(client);
+		for (vers = minvers; vers <= maxvers; vers++) {
+			addr.sin_port = htons(portnum);
+			to.tv_sec = 5;
+			to.tv_usec = 0;
+			if ((client = clntudp_create(&addr, prognum, vers,
+			    to, &sock)) == NULL) {
+				clnt_pcreateerror("rpcinfo");
+				printf("program %lu version %lu is not available\n",
+				    prognum, vers);
+				exit(1);
+			}
+			to.tv_sec = 10;
+			to.tv_usec = 0;
+			rpc_stat = clnt_call(client, NULLPROC, xdr_void,
+			    (char *)NULL, xdr_void, (char *)NULL, to);
+			if (pstatus(client, prognum, vers) < 0)
+				failure = 1;
+			clnt_destroy(client);
+		}
+	}
+	else {
+		vers = getvers(argv[2]);
+		addr.sin_port = htons(portnum);
+		to.tv_sec = 5;
+		to.tv_usec = 0;
+		if ((client = clntudp_create(&addr, prognum, vers,
+		    to, &sock)) == NULL) {
+			clnt_pcreateerror("rpcinfo");
+			printf("program %lu version %lu is not available\n",
+			    prognum, vers);
+			exit(1);
+		}
+		to.tv_sec = 10;
+		to.tv_usec = 0;
+		rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
+		    xdr_void, (char *)NULL, to);
+		if (pstatus(client, prognum, vers) < 0)
+			failure = 1;
+	}
+	(void) closesocket(sock); /* Close it up again */
+	if (failure)
+		exit(1);
+}
+
+static void
+tcpping(portnum, argc, argv)
+	u_short portnum;
+	int argc;
+	char **argv;
+{
+	struct timeval to;
+	struct sockaddr_in addr;
+	enum clnt_stat rpc_stat;
+	CLIENT *client;
+	u_long prognum, vers, minvers, maxvers;
+	int sock = RPC_ANYSOCK;
+	struct rpc_err rpcerr;
+	int failure;
+
+	if (argc < 2 || argc > 3) {
+		usage();
+		exit(1);
+	}
+	prognum = getprognum(argv[1]);
+	get_inet_address(&addr, argv[0]);
+	failure = 0;
+	if (argc == 2) {
+		/*
+		 * A call to version 0 should fail with a program/version
+		 * mismatch, and give us the range of versions supported.
+		 */
+		addr.sin_port = htons(portnum);
+		if ((client = clnttcp_create(&addr, prognum, MIN_VERS,
+		    &sock, 0, 0)) == NULL) {
+			clnt_pcreateerror("rpcinfo");
+			printf("program %lu is not available\n",
+			    prognum);
+			exit(1);
+		}
+		to.tv_sec = 10;
+		to.tv_usec = 0;
+		rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL,
+		    xdr_void, (char *)NULL, to);
+		if (rpc_stat == RPC_PROGVERSMISMATCH) {
+			clnt_geterr(client, &rpcerr);
+			minvers = rpcerr.re_vers.low;
+			maxvers = rpcerr.re_vers.high;
+		} else if (rpc_stat == RPC_SUCCESS) {
+			/*
+			 * Oh dear, it DOES support version 0.
+			 * Let's try version MAX_VERS.
+			 */
+			addr.sin_port = htons(portnum);
+			if ((client = clnttcp_create(&addr, prognum, MAX_VERS,
+			    &sock, 0, 0)) == NULL) {
+				clnt_pcreateerror("rpcinfo");
+				printf("program %lu version %lu is not available\n",
+				    prognum, MAX_VERS);
+				exit(1);
+			}
+			to.tv_sec = 10;
+			to.tv_usec = 0;
+			rpc_stat = clnt_call(client, NULLPROC, xdr_void,
+			    (char *)NULL, xdr_void, (char *)NULL, to);
+			if (rpc_stat == RPC_PROGVERSMISMATCH) {
+				clnt_geterr(client, &rpcerr);
+				minvers = rpcerr.re_vers.low;
+				maxvers = rpcerr.re_vers.high;
+			} else if (rpc_stat == RPC_SUCCESS) {
+				/*
+				 * It also supports version MAX_VERS.
+				 * Looks like we have a wise guy.
+				 * OK, we give them information on all
+				 * 4 billion versions they support...
+				 */
+				minvers = 0;
+				maxvers = MAX_VERS;
+			} else {
+				(void) pstatus(client, prognum, MAX_VERS);
+				exit(1);
+			}
+		} else {
+			(void) pstatus(client, prognum, MIN_VERS);
+			exit(1);
+		}
+		clnt_destroy(client);
+		(void) closesocket(sock);
+		sock = RPC_ANYSOCK; /* Re-initialize it for later */
+		for (vers = minvers; vers <= maxvers; vers++) {
+			addr.sin_port = htons(portnum);
+			if ((client = clnttcp_create(&addr, prognum, vers,
+			    &sock, 0, 0)) == NULL) {
+				clnt_pcreateerror("rpcinfo");
+				printf("program %lu version %lu is not available\n",
+				    prognum, vers);
+				exit(1);
+			}
+			to.tv_usec = 0;
+			to.tv_sec = 10;
+			rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
+			    xdr_void, (char *)NULL, to);
+			if (pstatus(client, prognum, vers) < 0)
+				failure = 1;
+			clnt_destroy(client);
+			(void) closesocket(sock);
+			sock = RPC_ANYSOCK;
+		}
+	}
+	else {
+		vers = getvers(argv[2]);
+		addr.sin_port = htons(portnum);
+		if ((client = clnttcp_create(&addr, prognum, vers, &sock,
+		    0, 0)) == NULL) {
+			clnt_pcreateerror("rpcinfo");
+			printf("program %lu version %lu is not available\n",
+			    prognum, vers);
+			exit(1);
+		}
+		to.tv_usec = 0;
+		to.tv_sec = 10;
+		rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL,
+		    xdr_void, (char *)NULL, to);
+		if (pstatus(client, prognum, vers) < 0)
+			failure = 1;
+	}
+	if (failure)
+		exit(1);
+}
+
+/*
+ * This routine should take a pointer to an "rpc_err" structure, rather than
+ * a pointer to a CLIENT structure, but "clnt_perror" takes a pointer to
+ * a CLIENT structure rather than a pointer to an "rpc_err" structure.
+ * As such, we have to keep the CLIENT structure around in order to print
+ * a good error message.
+ */
+static int
+pstatus(client, prognum, vers)
+	register CLIENT *client;
+	u_long prognum;
+	u_long vers;
+{
+	struct rpc_err rpcerr;
+
+	clnt_geterr(client, &rpcerr);
+	if (rpcerr.re_status != RPC_SUCCESS) {
+		clnt_perror(client, "rpcinfo");
+		printf("program %lu version %lu is not available\n",
+		    prognum, vers);
+		return (-1);
+	} else {
+		printf("program %lu version %lu ready and waiting\n",
+		    prognum, vers);
+		return (0);
+	}
+}
+
+static void
+pmapdump(argc, argv)
+	int argc;
+	char **argv;
+{
+	struct sockaddr_in server_addr;
+	register struct hostent *hp;
+	struct pmaplist *head = NULL;
+	int socket = RPC_ANYSOCK;
+	struct timeval minutetimeout;
+	register CLIENT *client;
+	struct rpcent *rpc;
+
+	if (argc > 1) {
+		usage();
+		exit(1);
+	}
+	if (argc == 1)
+		get_inet_address(&server_addr, argv[0]);
+	else {
+		bzero((char *)&server_addr, sizeof server_addr);
+		server_addr.sin_family = AF_INET;
+		if ((hp = gethostbyname("localhost")) != NULL)
+			bcopy(hp->h_addr, (caddr_t)&server_addr.sin_addr,
+			    hp->h_length);
+		else
+			server_addr.sin_addr.s_addr = inet_addr("0.0.0.0");
+	}
+	minutetimeout.tv_sec = 60;
+	minutetimeout.tv_usec = 0;
+	server_addr.sin_port = htons(PMAPPORT);
+	if ((client = clnttcp_create(&server_addr, PMAPPROG,
+	    PMAPVERS, &socket, 50, 500)) == NULL) {
+		clnt_pcreateerror("rpcinfo: can't contact portmapper");
+		exit(1);
+	}
+	if (clnt_call(client, PMAPPROC_DUMP, xdr_void, NULL,
+	    xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) {
+		fprintf(stderr, "rpcinfo: can't contact portmapper: ");
+		clnt_perror(client, "rpcinfo");
+		exit(1);
+	}
+	if (head == NULL) {
+		printf("No remote programs registered.\n");
+	} else {
+		printf("   program vers proto   port\n");
+		for (; head != NULL; head = head->pml_next) {
+			printf("%10ld%5ld",
+			    head->pml_map.pm_prog,
+			    head->pml_map.pm_vers);
+			if (head->pml_map.pm_prot == IPPROTO_UDP)
+				printf("%6s",  "udp");
+			else if (head->pml_map.pm_prot == IPPROTO_TCP)
+				printf("%6s", "tcp");
+			else
+				printf("%6ld",  head->pml_map.pm_prot);
+			printf("%7ld",  head->pml_map.pm_port);
+			rpc = getrpcbynumber(head->pml_map.pm_prog);
+			if (rpc)
+				printf("  %s\n", rpc->r_name);
+			else
+				printf("\n");
+		}
+	}
+}
+
+/*
+ * reply_proc collects replies from the broadcast.
+ * to get a unique list of responses the output of rpcinfo should
+ * be piped through sort(1) and then uniq(1).
+ */
+
+/*ARGSUSED*/
+static bool_t
+reply_proc(res, who)
+	void *res;		/* Nothing comes back */
+	struct sockaddr_in *who; /* Who sent us the reply */
+{
+	register struct hostent *hp;
+
+	hp = gethostbyaddr((char *) &who->sin_addr, sizeof who->sin_addr,
+	    AF_INET);
+	printf("%s %s\n", inet_ntoa(who->sin_addr),
+	    (hp == NULL) ? "(unknown)" : hp->h_name);
+	return(FALSE);
+}
+
+static void
+brdcst(argc, argv)
+	int argc;
+	char **argv;
+{
+	enum clnt_stat rpc_stat;
+	u_long prognum, vers;
+
+	if (argc != 2) {
+		usage();
+		exit(1);
+	}
+	prognum = getprognum(argv[0]);
+	vers = getvers(argv[1]);
+	rpc_stat = clnt_broadcast(prognum, vers, NULLPROC, xdr_void,
+	    (char *)NULL, xdr_void, (char *)NULL, reply_proc);
+	if ((rpc_stat != RPC_SUCCESS) && (rpc_stat != RPC_TIMEDOUT)) {
+		fprintf(stderr, "rpcinfo: broadcast failed: %s\n",
+		    clnt_sperrno(rpc_stat));
+		exit(1);
+	}
+	exit(0);
+}
+
+static void
+deletereg(argc, argv)
+	int argc;
+	char **argv;
+{	u_long prog_num, version_num ;
+
+	if (argc != 2) {
+		usage() ;
+		exit(1) ;
+	}
+#ifndef WIN32
+	if (getuid()) { /* This command allowed only to root */
+		fprintf(stderr, "Sorry. You are not root\n") ;
+		exit(1) ;
+	}
+#endif
+	prog_num = getprognum(argv[0]);
+	version_num = getvers(argv[1]);
+	if ((pmap_unset(prog_num, version_num)) == 0) {
+		fprintf(stderr, "rpcinfo: Could not delete registration for prog %s version %s\n",
+			argv[0], argv[1]) ;
+		exit(1) ;
+	}
+}
+
+static void
+usage()
+{
+	fprintf(stderr, "Usage: rpcinfo [ -n portnum ] -u host prognum [ versnum ]\n");
+	fprintf(stderr, "       rpcinfo [ -n portnum ] -t host prognum [ versnum ]\n");
+	fprintf(stderr, "       rpcinfo -p [ host ]\n");
+	fprintf(stderr, "       rpcinfo -b prognum versnum\n");
+	fprintf(stderr, "       rpcinfo -d prognum versnum\n") ;
+}
+
+static u_long
+getprognum(arg)
+	char *arg;
+{
+	register struct rpcent *rpc;
+	register u_long prognum;
+
+	if (isalpha(*arg)) {
+		rpc = getrpcbyname(arg);
+		if (rpc == NULL) {
+			fprintf(stderr, "rpcinfo: %s is unknown service\n",
+			    arg);
+			exit(1);
+		}
+		prognum = rpc->r_number;
+	} else {
+		prognum = (u_long) atoi(arg);
+	}
+
+	return (prognum);
+}
+
+static u_long
+getvers(arg)
+	char *arg;
+{
+	register u_long vers;
+
+	vers = (int) atoi(arg);
+	return (vers);
+}
+
+static void
+get_inet_address(addr, host)
+	struct sockaddr_in *addr;
+	char *host;
+{
+	register struct hostent *hp;
+
+	bzero((char *)addr, sizeof *addr);
+	addr->sin_addr.s_addr = (u_long) inet_addr(host);
+	if (addr->sin_addr.s_addr == -1 || addr->sin_addr.s_addr == 0) {
+		if ((hp = gethostbyname(host)) == NULL) {
+			fprintf(stderr, "rpcinfo: %s is unknown host\n",
+				host);
+			exit(1);
+		}
+		bcopy(hp->h_addr, (char *)&addr->sin_addr, hp->h_length);
+	}
+	addr->sin_family = AF_INET;
+}
diff --git a/external/rpc_win32/LIBRPC/svc.c b/external/rpc_win32/LIBRPC/svc.c
new file mode 100644
index 0000000..aadccbd
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/svc.c
@@ -0,0 +1,575 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)svc.c	2.4 88/08/11 4.0 RPCSRC; from 1.44 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc.c 1.41 87/10/13 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc.c, Server-side remote procedure call interface.
+ *
+ * There are two sets of procedures here.  The xprt routines are
+ * for handling transport handles.  The svc routines handle the
+ * list of service routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <string.h>
+#ifdef WIN32
+#include <rpc/rpc.h>
+#include <rpc/pmap_cln.h>
+#include <stdio.h>
+#else
+#include <sys/errno.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+
+extern int errno;
+#endif
+
+#ifdef FD_SETSIZE
+static SVCXPRT **xports;
+#ifdef WIN32
+static int sizeof_xports = FD_SETSIZE;
+#endif
+#else
+#define NOFILE 32
+
+static SVCXPRT *xports[NOFILE];
+#endif /* def FD_SETSIZE */
+
+#define NULL_SVC ((struct svc_callout *)0)
+#define	RQCRED_SIZE	400		/* this size is excessive */
+
+/*
+ * The services list
+ * Each entry represents a set of procedures (an rpc program).
+ * The dispatch routine takes request structs and runs the
+ * apropriate procedure.
+ */
+static struct svc_callout {
+	struct svc_callout *sc_next;
+	u_long		    sc_prog;
+	u_long		    sc_vers;
+	void		    (*sc_dispatch)();
+} *svc_head;
+
+static struct svc_callout *svc_find();
+
+/* ***************  SVCXPRT related stuff **************** */
+
+/*
+ * Activate a transport handle.
+ */
+void
+xprt_register(xprt)
+	SVCXPRT *xprt;
+{
+	register int sock = xprt->xp_sock;
+
+#ifdef FD_SETSIZE
+	if (xports == NULL) {
+		xports = (SVCXPRT **)
+			mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *));
+		/*
+		 * Set the newly allocated memory to 0 so Purify won't
+		 * complain when we decide to do copies as the array runs
+		 * out of space.
+		 */
+		memset(xports, 0, FD_SETSIZE * sizeof(SVCXPRT *));
+	}
+#ifdef WIN32
+	/*
+	 * XXX: Note: The handling of sockets as a simple index array on
+	 * Win32 is a really, really bad idea.  Since you do not know that
+	 * socket handles used by Win32 are going to be reasonably small
+	 * numbers, you should not do it.  Since this is already done
+	 * and I don't want to track down problems caused by changing it,
+	 * I thought I'd note it here in case a problem shows up later.
+	 * -- Gordon
+	 */
+	while (sock >= sizeof_xports) {
+		SVCXPRT **old_xports;
+
+		old_xports = xports;
+		xports = (SVCXPRT **)
+			mem_alloc(2 * sizeof_xports * sizeof(SVCXPRT *));
+		bcopy(old_xports, xports, sizeof_xports * sizeof(SVCXPRT *));
+
+		/*
+		 * Set the newly allocated memory to 0 so Purify won't
+		 * complain when we decide to do copies as the array runs
+		 * out of space.
+		 */
+		memset(&xports[sizeof_xports], 0, FD_SETSIZE * sizeof(SVCXPRT *));
+		mem_free(old_xports, sizeof_xports * sizeof(SVCXPRT *));
+
+		sizeof_xports = 2 * sizeof_xports;
+	}
+
+
+	if (svc_fdset.fd_count < FD_SETSIZE) {
+		xports[sock] = xprt;
+		FD_SET(sock, &svc_fdset);
+	} else {
+		char str[256];
+		
+		sprintf(str, "too many connections (%d), compilation constant FD_SETSIZE was only %d", sock, FD_SETSIZE);
+		nt_rpc_report(str);
+	}
+#else
+	if (sock < _rpc_dtablesize()) {
+		xports[sock] = xprt;
+		FD_SET(sock, &svc_fdset);
+	}
+#endif
+#else
+	if (sock < NOFILE) {
+		xports[sock] = xprt;
+		svc_fds |= (1 << sock);
+	}
+#endif /* def FD_SETSIZE */
+
+}
+
+/*
+ * De-activate a transport handle. 
+ */
+void
+xprt_unregister(xprt) 
+	SVCXPRT *xprt;
+{ 
+	register int sock = xprt->xp_sock;
+
+#ifdef FD_SETSIZE
+#ifdef WIN32
+	if ((xports[sock] == xprt)) {
+		xports[sock] = (SVCXPRT *)0;
+		FD_CLR((unsigned)sock, &svc_fdset);
+#else
+	if ((sock < _rpc_dtablesize()) && (xports[sock] == xprt)) {
+		xports[sock] = (SVCXPRT *)0;
+		FD_CLR(sock, &svc_fdset);
+#endif
+	}
+#else
+	if ((sock < NOFILE) && (xports[sock] == xprt)) {
+		xports[sock] = (SVCXPRT *)0;
+		svc_fds &= ~(1 << sock);
+	}
+#endif /* def FD_SETSIZE */
+}
+
+
+/* ********************** CALLOUT list related stuff ************* */
+
+/*
+ * Add a service program to the callout list.
+ * The dispatch routine will be called when a rpc request for this
+ * program number comes in.
+ */
+bool_t
+svc_register(xprt, prog, vers, dispatch, protocol)
+	SVCXPRT *xprt;
+	u_long prog;
+	u_long vers;
+	void (*dispatch)();
+	int protocol;
+{
+	struct svc_callout *prev;
+	register struct svc_callout *s;
+
+	if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) {
+		if (s->sc_dispatch == dispatch)
+			goto pmap_it;  /* he is registering another xptr */
+		return (FALSE);
+	}
+	s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout));
+	if (s == (struct svc_callout *)0) {
+		return (FALSE);
+	}
+	s->sc_prog = prog;
+	s->sc_vers = vers;
+	s->sc_dispatch = dispatch;
+	s->sc_next = svc_head;
+	svc_head = s;
+pmap_it:
+	/* now register the information with the local binder service */
+	if (protocol) {
+		return (pmap_set(prog, vers, protocol, xprt->xp_port));
+	}
+	return (TRUE);
+}
+
+/*
+ * Remove a service program from the callout list.
+ */
+void
+svc_unregister(prog, vers)
+	u_long prog;
+	u_long vers;
+{
+	struct svc_callout *prev;
+	register struct svc_callout *s;
+
+	if ((s = svc_find(prog, vers, &prev)) == NULL_SVC)
+		return;
+	if (prev == NULL_SVC) {
+		svc_head = s->sc_next;
+	} else {
+		prev->sc_next = s->sc_next;
+	}
+	s->sc_next = NULL_SVC;
+	mem_free((char *) s, (u_int) sizeof(struct svc_callout));
+	/* now unregister the information with the local binder service */
+	(void)pmap_unset(prog, vers);
+}
+
+/*
+ * Search the callout list for a program number, return the callout
+ * struct.
+ */
+static struct svc_callout *
+svc_find(prog, vers, prev)
+	u_long prog;
+	u_long vers;
+	struct svc_callout **prev;
+{
+	register struct svc_callout *s, *p;
+
+	p = NULL_SVC;
+	for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
+		if ((s->sc_prog == prog) && (s->sc_vers == vers))
+			goto done;
+		p = s;
+	}
+done:
+	*prev = p;
+	return (s);
+}
+
+/* ******************* REPLY GENERATION ROUTINES  ************ */
+
+/*
+ * Send a reply to an rpc request
+ */
+bool_t
+svc_sendreply(xprt, xdr_results, xdr_location)
+	register SVCXPRT *xprt;
+	xdrproc_t xdr_results;
+	caddr_t xdr_location;
+{
+	struct rpc_msg rply; 
+
+	rply.rm_direction = REPLY;  
+	rply.rm_reply.rp_stat = MSG_ACCEPTED; 
+	rply.acpted_rply.ar_verf = xprt->xp_verf; 
+	rply.acpted_rply.ar_stat = SUCCESS;
+	rply.acpted_rply.ar_results.where = xdr_location;
+	rply.acpted_rply.ar_results.proc = xdr_results;
+	return (SVC_REPLY(xprt, &rply)); 
+}
+
+/*
+ * No procedure error reply
+ */
+void
+svcerr_noproc(xprt)
+	register SVCXPRT *xprt;
+{
+	struct rpc_msg rply;
+
+	rply.rm_direction = REPLY;
+	rply.rm_reply.rp_stat = MSG_ACCEPTED;
+	rply.acpted_rply.ar_verf = xprt->xp_verf;
+	rply.acpted_rply.ar_stat = PROC_UNAVAIL;
+	SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Can't decode args error reply
+ */
+void
+svcerr_decode(xprt)
+	register SVCXPRT *xprt;
+{
+	struct rpc_msg rply; 
+
+	rply.rm_direction = REPLY; 
+	rply.rm_reply.rp_stat = MSG_ACCEPTED; 
+	rply.acpted_rply.ar_verf = xprt->xp_verf;
+	rply.acpted_rply.ar_stat = GARBAGE_ARGS;
+	SVC_REPLY(xprt, &rply); 
+}
+
+/*
+ * Some system error
+ */
+void
+svcerr_systemerr(xprt)
+	register SVCXPRT *xprt;
+{
+	struct rpc_msg rply; 
+
+	rply.rm_direction = REPLY; 
+	rply.rm_reply.rp_stat = MSG_ACCEPTED; 
+	rply.acpted_rply.ar_verf = xprt->xp_verf;
+	rply.acpted_rply.ar_stat = SYSTEM_ERR;
+	SVC_REPLY(xprt, &rply); 
+}
+
+/*
+ * Authentication error reply
+ */
+void
+svcerr_auth(xprt, why)
+	SVCXPRT *xprt;
+	enum auth_stat why;
+{
+	struct rpc_msg rply;
+
+	rply.rm_direction = REPLY;
+	rply.rm_reply.rp_stat = MSG_DENIED;
+	rply.rjcted_rply.rj_stat = AUTH_ERROR;
+	rply.rjcted_rply.rj_why = why;
+	SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Auth too weak error reply
+ */
+void
+svcerr_weakauth(xprt)
+	SVCXPRT *xprt;
+{
+
+	svcerr_auth(xprt, AUTH_TOOWEAK);
+}
+
+/*
+ * Program unavailable error reply
+ */
+void 
+svcerr_noprog(xprt)
+	register SVCXPRT *xprt;
+{
+	struct rpc_msg rply;  
+
+	rply.rm_direction = REPLY;   
+	rply.rm_reply.rp_stat = MSG_ACCEPTED;  
+	rply.acpted_rply.ar_verf = xprt->xp_verf;  
+	rply.acpted_rply.ar_stat = PROG_UNAVAIL;
+	SVC_REPLY(xprt, &rply);
+}
+
+/*
+ * Program version mismatch error reply
+ */
+void  
+svcerr_progvers(xprt, low_vers, high_vers)
+	register SVCXPRT *xprt; 
+	u_long low_vers;
+	u_long high_vers;
+{
+	struct rpc_msg rply;
+
+	rply.rm_direction = REPLY;
+	rply.rm_reply.rp_stat = MSG_ACCEPTED;
+	rply.acpted_rply.ar_verf = xprt->xp_verf;
+	rply.acpted_rply.ar_stat = PROG_MISMATCH;
+	rply.acpted_rply.ar_vers.low = low_vers;
+	rply.acpted_rply.ar_vers.high = high_vers;
+	SVC_REPLY(xprt, &rply);
+}
+
+/* ******************* SERVER INPUT STUFF ******************* */
+
+/*
+ * Get server side input from some transport.
+ *
+ * Statement of authentication parameters management:
+ * This function owns and manages all authentication parameters, specifically
+ * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and
+ * the "cooked" credentials (rqst->rq_clntcred).
+ * However, this function does not know the structure of the cooked
+ * credentials, so it make the following assumptions: 
+ *   a) the structure is contiguous (no pointers), and
+ *   b) the cred structure size does not exceed RQCRED_SIZE bytes. 
+ * In all events, all three parameters are freed upon exit from this routine.
+ * The storage is trivially management on the call stack in user land, but
+ * is mallocated in kernel land.
+ */
+
+void
+svc_getreq(rdfds)
+	int rdfds;
+{
+#ifdef FD_SETSIZE
+#ifdef WIN32
+int i;
+#endif
+	fd_set readfds;
+
+	FD_ZERO(&readfds);
+
+#ifdef WIN32
+	i = 0;
+	while (rdfds) {
+		if (rdfds & 1)
+			FD_SET(i, &readfds);
+		rdfds = rdfds >> 1;
+		i++;
+	}
+#else
+	readfds.fds_bits[0] = rdfds;
+#endif
+	svc_getreqset(&readfds);
+#else
+	int readfds = rdfds & svc_fds;
+
+	svc_getreqset(&readfds);
+#endif /* def FD_SETSIZE */
+}
+
+void
+svc_getreqset(readfds)
+#ifdef FD_SETSIZE
+	fd_set *readfds;
+{
+#else
+	int *readfds;
+{
+    int readfds_local = *readfds;
+#endif /* def FD_SETSIZE */
+	enum xprt_stat stat;
+	struct rpc_msg msg;
+	int prog_found;
+	u_long low_vers;
+	u_long high_vers;
+	struct svc_req r;
+	register SVCXPRT *xprt;
+	register u_long mask;
+	register int bit;
+	register u_long *maskp;
+	register int setsize;
+	register int sock;
+	char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE];
+	int i;
+
+	msg.rm_call.cb_cred.oa_base = cred_area;
+	msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]);
+	r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]);
+
+#ifdef FD_SETSIZE
+#ifdef WIN32
+	/* Loop through the sockets that have input ready */
+	for ( i=0; i<readfds->fd_count; i++ ) {
+		sock = readfds->fd_array[i];
+		/* sock has input waiting */
+		xprt = xports[sock];
+#else
+	setsize = _rpc_dtablesize();	
+	maskp = (u_long *)readfds->fds_bits;
+	for (sock = 0; sock < setsize; sock += NFDBITS) {
+	    for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) {
+		/* sock has input waiting */
+		xprt = xports[sock + bit - 1];
+#endif
+#else
+	for (sock = 0; readfds_local != 0; sock++, readfds_local >>= 1) {
+	    if ((readfds_local & 1) != 0) {
+		/* sock has input waiting */
+		xprt = xports[sock];
+#endif /* def FD_SETSIZE */
+		/* now receive msgs from xprtprt (support batch calls) */
+		do {
+			if (SVC_RECV(xprt, &msg)) {
+
+				/* now find the exported program and call it */
+				register struct svc_callout *s;
+				enum auth_stat why;
+
+				r.rq_xprt = xprt;
+				r.rq_prog = msg.rm_call.cb_prog;
+				r.rq_vers = msg.rm_call.cb_vers;
+				r.rq_proc = msg.rm_call.cb_proc;
+				r.rq_cred = msg.rm_call.cb_cred;
+				/* first authenticate the message */
+				if ((why= _authenticate(&r, &msg)) != AUTH_OK) {
+					svcerr_auth(xprt, why);
+					goto call_done;
+				}
+				/* now match message with a registered service*/
+				prog_found = FALSE;
+				low_vers = 0 - 1;
+				high_vers = 0;
+				for (s = svc_head; s != NULL_SVC; s = s->sc_next) {
+					if (s->sc_prog == r.rq_prog) {
+						if (s->sc_vers == r.rq_vers) {
+							(*s->sc_dispatch)(&r, xprt);
+							goto call_done;
+						}  /* found correct version */
+						prog_found = TRUE;
+						if (s->sc_vers < low_vers)
+							low_vers = s->sc_vers;
+						if (s->sc_vers > high_vers)
+							high_vers = s->sc_vers;
+					}   /* found correct program */
+				}
+				/*
+				 * if we got here, the program or version
+				 * is not served ...
+				 */
+				if (prog_found)
+					svcerr_progvers(xprt,
+					low_vers, high_vers);
+				else
+					 svcerr_noprog(xprt);
+				/* Fall through to ... */
+			}
+		call_done:
+			if ((stat = SVC_STAT(xprt)) == XPRT_DIED){
+				SVC_DESTROY(xprt);
+				break;
+			}
+		} while (stat == XPRT_MOREREQS);
+	}
+}
diff --git a/external/rpc_win32/LIBRPC/svc_auth.c b/external/rpc_win32/LIBRPC/svc_auth.c
new file mode 100644
index 0000000..c563d12
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/svc_auth.c
@@ -0,0 +1,125 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_auth.c	2.1 88/08/07 4.0 RPCSRC; from 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * svc_auth_nodes.c, Server-side rpc authenticator interface,
+ * *WITHOUT* DES authentication.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+
+/*
+ * svcauthsw is the bdevsw of server side authentication. 
+ * 
+ * Server side authenticators are called from authenticate by
+ * using the client auth struct flavor field to index into svcauthsw.
+ * The server auth flavors must implement a routine that looks  
+ * like: 
+ * 
+ *	enum auth_stat
+ *	flavorx_auth(rqst, msg)
+ *		register struct svc_req *rqst; 
+ *		register struct rpc_msg *msg;
+ *
+ */
+
+enum auth_stat _svcauth_null();		/* no authentication */
+enum auth_stat _svcauth_unix();		/* unix style (uid, gids) */
+enum auth_stat _svcauth_short();	/* short hand unix style */
+
+static struct {
+	enum auth_stat (*authenticator)();
+} svcauthsw[] = {
+	_svcauth_null,			/* AUTH_NULL */
+	_svcauth_unix,			/* AUTH_UNIX */
+	_svcauth_short,			/* AUTH_SHORT */
+};
+#define	AUTH_MAX	2		/* HIGHEST AUTH NUMBER */
+
+
+/*
+ * The call rpc message, msg has been obtained from the wire.  The msg contains
+ * the raw form of credentials and verifiers.  authenticate returns AUTH_OK
+ * if the msg is successfully authenticated.  If AUTH_OK then the routine also
+ * does the following things:
+ * set rqst->rq_xprt->verf to the appropriate response verifier;
+ * sets rqst->rq_client_cred to the "cooked" form of the credentials.
+ *
+ * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
+ * its length is set appropriately.
+ *
+ * The caller still owns and is responsible for msg->u.cmb.cred and
+ * msg->u.cmb.verf.  The authentication system retains ownership of
+ * rqst->rq_client_cred, the cooked credentials.
+ *
+ * There is an assumption that any flavour less than AUTH_NULL is
+ * invalid.
+ */
+enum auth_stat
+_authenticate(rqst, msg)
+	register struct svc_req *rqst;
+	struct rpc_msg *msg;
+{
+	register int cred_flavor;
+
+	rqst->rq_cred = msg->rm_call.cb_cred;
+	rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
+	rqst->rq_xprt->xp_verf.oa_length = 0;
+	cred_flavor = rqst->rq_cred.oa_flavor;
+	if ((cred_flavor <= AUTH_MAX) && (cred_flavor >= AUTH_NULL)) {
+		return ((*(svcauthsw[cred_flavor].authenticator))(rqst, msg));
+	}
+
+	return (AUTH_REJECTEDCRED);
+}
+
+enum auth_stat
+_svcauth_null(/*rqst, msg*/)
+	/*struct svc_req *rqst;
+	struct rpc_msg *msg;*/
+{
+
+	return (AUTH_OK);
+}
diff --git a/external/rpc_win32/LIBRPC/svc_autu.c b/external/rpc_win32/LIBRPC/svc_autu.c
new file mode 100644
index 0000000..d9d2004
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/svc_autu.c
@@ -0,0 +1,152 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)svc_auth_unix.c	2.3 88/08/01 4.0 RPCSRC; from 1.28 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_auth_unix.c
+ * Handles UNIX flavor authentication parameters on the service side of rpc.
+ * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT.
+ * _svcauth_unix does full blown unix style uid,gid+gids auth,
+ * _svcauth_short uses a shorthand auth to index into a cache of longhand auths.
+ * Note: the shorthand has been gutted for efficiency.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+
+/*
+ * Unix longhand authenticator
+ */
+enum auth_stat
+_svcauth_unix(rqst, msg)
+	register struct svc_req *rqst;
+	register struct rpc_msg *msg;
+{
+	register enum auth_stat stat;
+	XDR xdrs;
+	register struct authunix_parms *aup;
+	register long *buf;
+	struct area {
+		struct authunix_parms area_aup;
+		char area_machname[MAX_MACHINE_NAME+1];
+		int area_gids[NGRPS];
+	} *area;
+	u_int auth_len;
+	int str_len, gid_len;
+	register int i;
+
+	area = (struct area *) rqst->rq_clntcred;
+	aup = &area->area_aup;
+	aup->aup_machname = area->area_machname;
+	aup->aup_gids = area->area_gids;
+	auth_len = (u_int)msg->rm_call.cb_cred.oa_length;
+	xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE);
+	buf = XDR_INLINE(&xdrs, auth_len);
+	if (buf != NULL) {
+		aup->aup_time = IXDR_GET_LONG(buf);
+		str_len = IXDR_GET_U_LONG(buf);
+		if (str_len > MAX_MACHINE_NAME) {
+			stat = AUTH_BADCRED;
+			goto done;
+		}
+		bcopy((caddr_t)buf, aup->aup_machname, (u_int)str_len);
+		aup->aup_machname[str_len] = 0;
+		str_len = RNDUP(str_len);
+		buf += str_len / sizeof (long);
+		aup->aup_uid = IXDR_GET_LONG(buf);
+		aup->aup_gid = IXDR_GET_LONG(buf);
+		gid_len = IXDR_GET_U_LONG(buf);
+		if (gid_len > NGRPS) {
+			stat = AUTH_BADCRED;
+			goto done;
+		}
+		aup->aup_len = gid_len;
+		for (i = 0; i < gid_len; i++) {
+			aup->aup_gids[i] = IXDR_GET_LONG(buf);
+		}
+		/*
+		 * five is the smallest unix credentials structure -
+		 * timestamp, hostname len (0), uid, gid, and gids len (0).
+		 */
+		if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
+#ifdef WIN32
+			char str[256];
+			sprintf(str, "bad auth_len gid %d str %d auth %d\n",
+			    gid_len, str_len, auth_len);
+			nt_rpc_report(str);
+#else
+			(void) printf("bad auth_len gid %d str %d auth %d\n",
+			    gid_len, str_len, auth_len);
+#endif
+			stat = AUTH_BADCRED;
+			goto done;
+		}
+	} else if (! xdr_authunix_parms(&xdrs, aup)) {
+		xdrs.x_op = XDR_FREE;
+		(void)xdr_authunix_parms(&xdrs, aup);
+		stat = AUTH_BADCRED;
+		goto done;
+	}
+	rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
+	rqst->rq_xprt->xp_verf.oa_length = 0;
+	stat = AUTH_OK;
+done:
+	XDR_DESTROY(&xdrs);
+	return (stat);
+}
+
+
+/*
+ * Shorthand unix authenticator
+ * Looks up longhand in a cache.
+ */
+/*ARGSUSED*/
+enum auth_stat 
+_svcauth_short(rqst, msg)
+	struct svc_req *rqst;
+	struct rpc_msg *msg;
+{
+	return (AUTH_REJECTEDCRED);
+}
diff --git a/external/rpc_win32/LIBRPC/svc_raw.c b/external/rpc_win32/LIBRPC/svc_raw.c
new file mode 100644
index 0000000..15e6e88
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/svc_raw.c
@@ -0,0 +1,177 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)svc_raw.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_raw.c,   This a toy for simple testing and timing.
+ * Interface to create an rpc client and server in the same UNIX process.
+ * This lets us similate rpc and get rpc (round trip) overhead, without
+ * any interference from the kernal.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <rpc/rpc.h>
+
+
+/*
+ * This is the "network" that we will be moving data over
+ */
+static struct svcraw_private {
+	char	_raw_buf[UDPMSGSIZE];
+	SVCXPRT	server;
+	XDR	xdr_stream;
+	char	verf_body[MAX_AUTH_BYTES];
+} *svcraw_private;
+
+static bool_t		svcraw_recv();
+static enum xprt_stat 	svcraw_stat();
+static bool_t		svcraw_getargs();
+static bool_t		svcraw_reply();
+static bool_t		svcraw_freeargs();
+static void		svcraw_destroy();
+
+static struct xp_ops server_ops = {
+	svcraw_recv,
+	svcraw_stat,
+	svcraw_getargs,
+	svcraw_reply,
+	svcraw_freeargs,
+	svcraw_destroy
+};
+
+SVCXPRT *
+svcraw_create()
+{
+	register struct svcraw_private *srp = svcraw_private;
+
+	if (srp == 0) {
+		srp = (struct svcraw_private *)calloc(1, sizeof (*srp));
+		if (srp == 0)
+			return (0);
+	}
+	srp->server.xp_sock = 0;
+	srp->server.xp_port = 0;
+	srp->server.xp_ops = &server_ops;
+	srp->server.xp_verf.oa_base = srp->verf_body;
+	xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE);
+	return (&srp->server);
+}
+
+static enum xprt_stat
+svcraw_stat()
+{
+
+	return (XPRT_IDLE);
+}
+
+static bool_t
+svcraw_recv(xprt, msg)
+	SVCXPRT *xprt;
+	struct rpc_msg *msg;
+{
+	register struct svcraw_private *srp = svcraw_private;
+	register XDR *xdrs;
+
+	if (srp == 0)
+		return (0);
+	xdrs = &srp->xdr_stream;
+	xdrs->x_op = XDR_DECODE;
+	XDR_SETPOS(xdrs, 0);
+	if (! xdr_callmsg(xdrs, msg))
+	       return (FALSE);
+	return (TRUE);
+}
+
+static bool_t
+svcraw_reply(xprt, msg)
+	SVCXPRT *xprt;
+	struct rpc_msg *msg;
+{
+	register struct svcraw_private *srp = svcraw_private;
+	register XDR *xdrs;
+
+	if (srp == 0)
+		return (FALSE);
+	xdrs = &srp->xdr_stream;
+	xdrs->x_op = XDR_ENCODE;
+	XDR_SETPOS(xdrs, 0);
+	if (! xdr_replymsg(xdrs, msg))
+	       return (FALSE);
+	(void)XDR_GETPOS(xdrs);  /* called just for overhead */
+	return (TRUE);
+}
+
+static bool_t
+svcraw_getargs(xprt, xdr_args, args_ptr)
+	SVCXPRT *xprt;
+	xdrproc_t xdr_args;
+	caddr_t args_ptr;
+{
+	register struct svcraw_private *srp = svcraw_private;
+
+	if (srp == 0)
+		return (FALSE);
+	return ((*xdr_args)(&srp->xdr_stream, args_ptr));
+}
+
+static bool_t
+svcraw_freeargs(xprt, xdr_args, args_ptr)
+	SVCXPRT *xprt;
+	xdrproc_t xdr_args;
+	caddr_t args_ptr;
+{ 
+	register struct svcraw_private *srp = svcraw_private;
+	register XDR *xdrs;
+
+	if (srp == 0)
+		return (FALSE);
+	xdrs = &srp->xdr_stream;
+	xdrs->x_op = XDR_FREE;
+	return ((*xdr_args)(xdrs, args_ptr));
+} 
+
+static void
+svcraw_destroy()
+{
+}
diff --git a/external/rpc_win32/LIBRPC/svc_run.c b/external/rpc_win32/LIBRPC/svc_run.c
new file mode 100644
index 0000000..fb5ab6a
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/svc_run.c
@@ -0,0 +1,97 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)svc_run.c	2.1 88/07/29 4.0 RPCSRC */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * This is the rpc server side idle loop
+ * Wait for input, call server program.
+ */
+#include <rpc/rpc.h>
+#ifdef WIN32
+#include <errno.h>
+#else
+#include <sys/errno.h>
+#endif
+
+void
+svc_run()
+{
+#ifdef FD_SETSIZE
+	fd_set readfds;
+#else
+      int readfds;
+#endif /* def FD_SETSIZE */
+#ifndef WIN32
+	extern int errno;
+#endif
+
+	for (;;) {
+#ifdef FD_SETSIZE
+		readfds = svc_fdset;
+#else
+		readfds = svc_fds;
+#endif /* def FD_SETSIZE */
+#ifdef WIN32
+		switch (select(0 /* unused in winsock */, &readfds, (int *)0, (int *)0,
+#else
+		switch (select(_rpc_dtablesize(), &readfds, (int *)0, (int *)0,
+#endif
+			       (struct timeval *)0)) {
+		case -1:
+#ifdef WIN32
+			if (WSAerrno == EINTR) {
+#else
+			if (errno == EINTR) {
+#endif
+				continue;
+			}
+			perror("svc_run: - select failed");
+			return;
+		case 0:
+			continue;
+		default:
+			svc_getreqset(&readfds);
+		}
+	}
+}
diff --git a/external/rpc_win32/LIBRPC/svc_simp.c b/external/rpc_win32/LIBRPC/svc_simp.c
new file mode 100644
index 0000000..47524f9
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/svc_simp.c
@@ -0,0 +1,187 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)svc_simple.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#ifndef WIN32
+#include <sys/socket.h>
+#include <netdb.h>
+#endif
+
+static struct proglst {
+	char *(*p_progname)();
+	int  p_prognum;
+	int  p_procnum;
+	xdrproc_t p_inproc, p_outproc;
+	struct proglst *p_nxt;
+} *proglst;
+static void universal();
+static SVCXPRT *transp;
+struct proglst *pl;
+
+registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
+	char *(*progname)();
+	xdrproc_t inproc, outproc;
+{
+
+	if (procnum == NULLPROC) {
+#ifdef WIN32
+		nt_rpc_report(
+		    "can't reassign procedure number 0\n");
+#else
+		(void) fprintf(stderr,
+		    "can't reassign procedure number %d\n", NULLPROC);
+#endif
+		return (-1);
+	}
+	if (transp == 0) {
+		transp = svcudp_create(RPC_ANYSOCK);
+		if (transp == NULL) {
+#ifdef WIN32
+			nt_rpc_report("couldn't create an rpc server\n");
+#else
+			(void) fprintf(stderr, "couldn't create an rpc server\n");
+#endif
+			return (-1);
+		}
+	}
+	(void) pmap_unset((u_long)prognum, (u_long)versnum);
+	if (!svc_register(transp, (u_long)prognum, (u_long)versnum,
+	    universal, IPPROTO_UDP)) {
+#ifdef WIN32
+	    	nt_rpc_report("couldn't register prog");
+#else
+	    	(void) fprintf(stderr, "couldn't register prog %d vers %d\n",
+		    prognum, versnum);
+#endif
+		return (-1);
+	}
+	pl = (struct proglst *)malloc(sizeof(struct proglst));
+	if (pl == NULL) {
+#ifdef WIN32
+		nt_rpc_report("registerrpc: out of memory\n");
+#else
+		(void) fprintf(stderr, "registerrpc: out of memory\n");
+#endif
+		return (-1);
+	}
+	pl->p_progname = progname;
+	pl->p_prognum = prognum;
+	pl->p_procnum = procnum;
+	pl->p_inproc = inproc;
+	pl->p_outproc = outproc;
+	pl->p_nxt = proglst;
+	proglst = pl;
+	return (0);
+}
+
+static void
+universal(rqstp, transp)
+	struct svc_req *rqstp;
+	SVCXPRT *transp;
+{
+	int prog, proc;
+	char *outdata;
+	char xdrbuf[UDPMSGSIZE];
+	struct proglst *pl;
+
+	/*
+	 * enforce "procnum 0 is echo" convention
+	 */
+	if (rqstp->rq_proc == NULLPROC) {
+		if (svc_sendreply(transp, xdr_void, (char *)NULL) == FALSE) {
+#ifdef WIN32
+			nt_rpc_report(stderr, "xxx\n");
+#else
+			(void) fprintf(stderr, "xxx\n");
+#endif
+			exit(1);
+		}
+		return;
+	}
+	prog = rqstp->rq_prog;
+	proc = rqstp->rq_proc;
+	for (pl = proglst; pl != NULL; pl = pl->p_nxt)
+		if (pl->p_prognum == prog && pl->p_procnum == proc) {
+			/* decode arguments into a CLEAN buffer */
+			bzero(xdrbuf, sizeof(xdrbuf)); /* required ! */
+			if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) {
+				svcerr_decode(transp);
+				return;
+			}
+			outdata = (*(pl->p_progname))(xdrbuf);
+			if (outdata == NULL && pl->p_outproc != xdr_void)
+				/* there was an error */
+				return;
+			if (!svc_sendreply(transp, pl->p_outproc, outdata)) {
+#ifdef WIN32
+				nt_rpc_report(
+				    "trouble replying to prog\n"
+				    /*, pl->p_prognum*/);
+#else
+				(void) fprintf(stderr,
+				    "trouble replying to prog %d\n",
+				    pl->p_prognum);
+#endif
+				exit(1);
+			}
+			/* free the decoded arguments */
+			(void)svc_freeargs(transp, pl->p_inproc, xdrbuf);
+			return;
+		}
+#ifdef WIN32
+	nt_rpc_report("never registered prog %d\n"/*, prog*/);
+#else
+	(void) fprintf(stderr, "never registered prog %d\n", prog);
+#endif
+	exit(1);
+}
+
diff --git a/external/rpc_win32/LIBRPC/svc_tcp.c b/external/rpc_win32/LIBRPC/svc_tcp.c
new file mode 100644
index 0000000..9b0feff
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/svc_tcp.c
@@ -0,0 +1,498 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)svc_tcp.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_tcp.c, Server side for TCP/IP based RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Actually implements two flavors of transporter -
+ * a tcp rendezvouser (a listner and connection establisher)
+ * and a record/tcp stream.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include <errno.h>
+#ifndef WIN32
+#include <sys/socket.h>
+#endif
+#include <errno.h>
+#ifdef WIN32
+int xabort();
+#else
+extern bool_t abort();
+extern errno;
+#endif
+
+/*
+ * Ops vector for TCP/IP based rpc service handle
+ */
+static bool_t		svctcp_recv();
+static enum xprt_stat	svctcp_stat();
+static bool_t		svctcp_getargs();
+static bool_t		svctcp_reply();
+static bool_t		svctcp_freeargs();
+static void		svctcp_destroy();
+
+static struct xp_ops svctcp_op = {
+	svctcp_recv,
+	svctcp_stat,
+	svctcp_getargs,
+	svctcp_reply,
+	svctcp_freeargs,
+	svctcp_destroy
+};
+
+/*
+ * Ops vector for TCP/IP rendezvous handler
+ */
+static bool_t		rendezvous_request();
+static enum xprt_stat	rendezvous_stat();
+
+static struct xp_ops svctcp_rendezvous_op = {
+	rendezvous_request,
+	rendezvous_stat,
+#ifdef WIN32
+	xabort,
+	xabort,
+	xabort,
+#else
+	abort,
+	abort,
+	abort,
+#endif
+	svctcp_destroy
+};
+
+static int readtcp(), writetcp();
+static SVCXPRT *makefd_xprt();
+
+struct tcp_rendezvous { /* kept in xprt->xp_p1 */
+	u_int sendsize;
+	u_int recvsize;
+};
+
+struct tcp_conn {  /* kept in xprt->xp_p1 */
+	enum xprt_stat strm_stat;
+	u_long x_id;
+	XDR xdrs;
+	char verf_body[MAX_AUTH_BYTES];
+};
+
+/*
+ * Usage:
+ *	xprt = svctcp_create(sock, send_buf_size, recv_buf_size);
+ *
+ * Creates, registers, and returns a (rpc) tcp based transporter.
+ * Once *xprt is initialized, it is registered as a transporter
+ * see (svc.h, xprt_register).  This routine returns
+ * a NULL if a problem occurred.
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svctcp_create
+ * binds it to an arbitrary port.  The routine then starts a tcp
+ * listener on the socket's associated port.  In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ *
+ * Since tcp streams do buffered io similar to stdio, the caller can specify
+ * how big the send and receive buffers are via the second and third parms;
+ * 0 => use the system default.
+ */
+SVCXPRT *
+svctcp_create(sock, sendsize, recvsize)
+	register int sock;
+	u_int sendsize;
+	u_int recvsize;
+{
+	bool_t madesock = FALSE;
+	register SVCXPRT *xprt;
+	register struct tcp_rendezvous *r;
+	struct sockaddr_in addr;
+	int len = sizeof(struct sockaddr_in);
+
+	if (sock == RPC_ANYSOCK) {
+#ifdef WIN32
+		if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
+#else
+		if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+#endif
+			perror("svctcp_.c - udp socket creation problem");
+			return ((SVCXPRT *)NULL);
+		}
+		madesock = TRUE;
+	}
+	bzero((char *)&addr, sizeof (addr));
+	addr.sin_family = AF_INET;
+	if (bindresvport(sock, &addr)) {
+		addr.sin_port = 0;
+		(void)bind(sock, (struct sockaddr *)&addr, len);
+	}
+	if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0)  ||
+	    (listen(sock, 2) != 0)) {
+		perror("svctcp_.c - cannot getsockname or listen");
+		if (madesock)
+#ifdef WIN32
+		       (void)closesocket(sock);
+#else
+		       (void)close(sock);
+#endif
+		return ((SVCXPRT *)NULL);
+	}
+	r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r));
+	if (r == NULL) {
+#ifdef WIN32
+		nt_rpc_report("svctcp_create: out of memory\n");
+#else
+		(void) fprintf(stderr, "svctcp_create: out of memory\n");
+#endif
+		return (NULL);
+	}
+	r->sendsize = sendsize;
+	r->recvsize = recvsize;
+	xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+	if (xprt == NULL) {
+#ifdef WIN32
+		nt_rpc_report("svctcp_create: out of memory\n");
+#else
+		(void) fprintf(stderr, "svctcp_create: out of memory\n");
+#endif
+		return (NULL);
+	}
+	xprt->xp_p2 = NULL;
+	xprt->xp_p1 = (caddr_t)r;
+	xprt->xp_verf = _null_auth;
+	xprt->xp_ops = &svctcp_rendezvous_op;
+	xprt->xp_port = ntohs(addr.sin_port);
+	xprt->xp_sock = sock;
+	xprt_register(xprt);
+	return (xprt);
+}
+
+/*
+ * Like svtcp_create(), except the routine takes any *open* UNIX file
+ * descriptor as its first input.
+ */
+SVCXPRT *
+svcfd_create(fd, sendsize, recvsize)
+	int fd;
+	u_int sendsize;
+	u_int recvsize;
+{
+
+	return (makefd_xprt(fd, sendsize, recvsize));
+}
+
+static SVCXPRT *
+makefd_xprt(fd, sendsize, recvsize)
+	int fd;
+	u_int sendsize;
+	u_int recvsize;
+{
+	register SVCXPRT *xprt;
+	register struct tcp_conn *cd;
+
+	xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+	if (xprt == (SVCXPRT *)NULL) {
+#ifdef WIN32
+		nt_rpc_report("svc_tcp: makefd_xprt: out of memory\n");
+#else
+		(void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+#endif
+		goto done;
+	}
+	cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn));
+	if (cd == (struct tcp_conn *)NULL) {
+#ifdef WIN32
+		nt_rpc_report("svc_tcp: makefd_xprt: out of memory\n");
+#else
+		(void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
+#endif
+		mem_free((char *) xprt, sizeof(SVCXPRT));
+		xprt = (SVCXPRT *)NULL;
+		goto done;
+	}
+	cd->strm_stat = XPRT_IDLE;
+	xdrrec_create(&(cd->xdrs), sendsize, recvsize,
+	    (caddr_t)xprt, readtcp, writetcp);
+	xprt->xp_p2 = NULL;
+	xprt->xp_p1 = (caddr_t)cd;
+	xprt->xp_verf.oa_base = cd->verf_body;
+	xprt->xp_addrlen = 0;
+	xprt->xp_ops = &svctcp_op;  /* truely deals with calls */
+	xprt->xp_port = 0;  /* this is a connection, not a rendezvouser */
+	xprt->xp_sock = fd;
+	xprt_register(xprt);
+    done:
+	return (xprt);
+}
+
+static bool_t
+rendezvous_request(xprt)
+	register SVCXPRT *xprt;
+{
+	int sock;
+	struct tcp_rendezvous *r;
+	struct sockaddr_in addr;
+	int len;
+
+	r = (struct tcp_rendezvous *)xprt->xp_p1;
+    again:
+	len = sizeof(struct sockaddr_in);
+	if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr,
+	    &len)) < 0) {
+#ifdef WIN32
+		if (WSAerrno == WSAEINTR)
+#else
+		if (errno == EINTR)
+#endif
+			goto again;
+	       return (FALSE);
+	}
+	/*
+	 * make a new transporter (re-uses xprt)
+	 */
+	xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
+	xprt->xp_raddr = addr;
+	xprt->xp_addrlen = len;
+	return (FALSE); /* there is never an rpc msg to be processed */
+}
+
+static enum xprt_stat
+rendezvous_stat()
+{
+
+	return (XPRT_IDLE);
+}
+
+static void
+svctcp_destroy(xprt)
+	register SVCXPRT *xprt;
+{
+	register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1;
+
+	xprt_unregister(xprt);
+#ifdef WIN32
+	(void)closesocket(xprt->xp_sock);
+#else
+	(void)close(xprt->xp_sock);
+#endif
+	if (xprt->xp_port != 0) {
+		/* a rendezvouser socket */
+		xprt->xp_port = 0;
+	} else {
+		/* an actual connection socket */
+		XDR_DESTROY(&(cd->xdrs));
+	}
+	mem_free((caddr_t)cd, sizeof(struct tcp_conn));
+	mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+/*
+ * All read operations timeout after 35 seconds.
+ * A timeout is fatal for the connection.
+ */
+static struct timeval wait_per_try = { 35, 0 };
+
+/*
+ * reads data from the tcp conection.
+ * any error is fatal and the connection is closed.
+ * (And a read of zero bytes is a half closed stream => error.)
+ */
+static int
+readtcp(xprt, buf, len)
+	register SVCXPRT *xprt;
+	caddr_t buf;
+	register int len;
+{
+	register int sock = xprt->xp_sock;
+#ifdef FD_SETSIZE
+	fd_set mask;
+	fd_set readfds;
+
+	FD_ZERO(&mask);
+	FD_SET(sock, &mask);
+#else
+	register int mask = 1 << sock;
+	int readfds;
+#endif /* def FD_SETSIZE */
+	do {
+		readfds = mask;
+#ifdef WIN32
+		if (select(0 /* unused in winsock */, &readfds, (int*)NULL, (int*)NULL,
+#else
+		if (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL, 
+#endif
+			   &wait_per_try) <= 0) {
+#ifdef WIN32
+			if (WSAerrno == WSAEINTR) {
+#else
+			if (errno == EINTR) {
+#endif
+				continue;
+			}
+			goto fatal_err;
+		}
+#ifdef FD_SETSIZE
+	} while (!FD_ISSET(sock, &readfds));
+#else
+	} while (readfds != mask);
+#endif /* def FD_SETSIZE */
+#ifdef WIN32
+	if ((len = recv(sock, buf, len, 0)) > 0) {
+#else
+	if ((len = read(sock, buf, len)) > 0) {
+#endif
+		return (len);
+	}
+fatal_err:
+	((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
+	return (-1);
+}
+
+/*
+ * writes data to the tcp connection.
+ * Any error is fatal and the connection is closed.
+ */
+static int
+writetcp(xprt, buf, len)
+	register SVCXPRT *xprt;
+	caddr_t buf;
+	int len;
+{
+	register int i, cnt;
+
+	for (cnt = len; cnt > 0; cnt -= i, buf += i) {
+#ifdef WIN32
+		if ((i = send(xprt->xp_sock, buf, cnt, 0)) < 0) {
+#else
+		if ((i = write(xprt->xp_sock, buf, cnt)) < 0) {
+#endif
+			((struct tcp_conn *)(xprt->xp_p1))->strm_stat =
+			    XPRT_DIED;
+			return (-1);
+		}
+	}
+	return (len);
+}
+
+static enum xprt_stat
+svctcp_stat(xprt)
+	SVCXPRT *xprt;
+{
+	register struct tcp_conn *cd =
+	    (struct tcp_conn *)(xprt->xp_p1);
+
+	if (cd->strm_stat == XPRT_DIED)
+		return (XPRT_DIED);
+	if (! xdrrec_eof(&(cd->xdrs)))
+		return (XPRT_MOREREQS);
+	return (XPRT_IDLE);
+}
+
+static bool_t
+svctcp_recv(xprt, msg)
+	SVCXPRT *xprt;
+	register struct rpc_msg *msg;
+{
+	register struct tcp_conn *cd =
+	    (struct tcp_conn *)(xprt->xp_p1);
+	register XDR *xdrs = &(cd->xdrs);
+
+	xdrs->x_op = XDR_DECODE;
+	(void)xdrrec_skiprecord(xdrs);
+	if (xdr_callmsg(xdrs, msg)) {
+		cd->x_id = msg->rm_xid;
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+static bool_t
+svctcp_getargs(xprt, xdr_args, args_ptr)
+	SVCXPRT *xprt;
+	xdrproc_t xdr_args;
+	caddr_t args_ptr;
+{
+
+	return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr));
+}
+
+static bool_t
+svctcp_freeargs(xprt, xdr_args, args_ptr)
+	SVCXPRT *xprt;
+	xdrproc_t xdr_args;
+	caddr_t args_ptr;
+{
+	register XDR *xdrs =
+	    &(((struct tcp_conn *)(xprt->xp_p1))->xdrs);
+
+	xdrs->x_op = XDR_FREE;
+	return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static bool_t
+svctcp_reply(xprt, msg)
+	SVCXPRT *xprt;
+	register struct rpc_msg *msg;
+{
+	register struct tcp_conn *cd =
+	    (struct tcp_conn *)(xprt->xp_p1);
+	register XDR *xdrs = &(cd->xdrs);
+	register bool_t stat;
+
+	xdrs->x_op = XDR_ENCODE;
+	msg->rm_xid = cd->x_id;
+	stat = xdr_replymsg(xdrs, msg);
+	(void)xdrrec_endofrecord(xdrs, TRUE);
+	return (stat);
+}
+
+#ifdef WIN32
+int xabort()
+{
+	abort();
+}
+#endif
diff --git a/external/rpc_win32/LIBRPC/svc_udp.c b/external/rpc_win32/LIBRPC/svc_udp.c
new file mode 100644
index 0000000..0921797
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/svc_udp.c
@@ -0,0 +1,527 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)svc_udp.c	2.2 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * svc_udp.c,
+ * Server side for UDP/IP based RPC.  (Does some caching in the hopes of
+ * achieving execute-at-most-once semantics.)
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <stdio.h>
+#include <rpc/rpc.h>
+#ifndef WIN32
+#include <sys/socket.h>
+#endif
+#include <errno.h>
+
+
+#define rpc_buffer(xprt) ((xprt)->xp_p1)
+#define MAX(a, b)     ((a > b) ? a : b)
+
+static bool_t		svcudp_recv();
+static bool_t		svcudp_reply();
+static enum xprt_stat	svcudp_stat();
+static bool_t		svcudp_getargs();
+static bool_t		svcudp_freeargs();
+static void		svcudp_destroy();
+
+static struct xp_ops svcudp_op = {
+	svcudp_recv,
+	svcudp_stat,
+	svcudp_getargs,
+	svcudp_reply,
+	svcudp_freeargs,
+	svcudp_destroy
+};
+
+#ifndef WIN32
+extern int errno;
+#endif
+
+/*
+ * kept in xprt->xp_p2
+ */
+struct svcudp_data {
+	u_int   su_iosz;	/* byte size of send.recv buffer */
+	u_long	su_xid;		/* transaction id */
+	XDR	su_xdrs;	/* XDR handle */
+	char	su_verfbody[MAX_AUTH_BYTES];	/* verifier body */
+	char * 	su_cache;	/* cached data, NULL if no cache */
+};
+#define	su_data(xprt)	((struct svcudp_data *)(xprt->xp_p2))
+
+/*
+ * Usage:
+ *	xprt = svcudp_create(sock);
+ *
+ * If sock<0 then a socket is created, else sock is used.
+ * If the socket, sock is not bound to a port then svcudp_create
+ * binds it to an arbitrary port.  In any (successful) case,
+ * xprt->xp_sock is the registered socket number and xprt->xp_port is the
+ * associated port number.
+ * Once *xprt is initialized, it is registered as a transporter;
+ * see (svc.h, xprt_register).
+ * The routines returns NULL if a problem occurred.
+ */
+SVCXPRT *
+svcudp_bufcreate(sock, sendsz, recvsz)
+	register int sock;
+	u_int sendsz, recvsz;
+{
+	bool_t madesock = FALSE;
+	register SVCXPRT *xprt;
+	register struct svcudp_data *su;
+	struct sockaddr_in addr;
+	int len = sizeof(struct sockaddr_in);
+
+	if (sock == RPC_ANYSOCK) {
+#ifdef WIN32
+		if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET) {
+#else
+		if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
+#endif
+			perror("svcudp_create: socket creation problem");
+			return ((SVCXPRT *)NULL);
+		}
+		madesock = TRUE;
+	}
+	bzero((char *)&addr, sizeof (addr));
+	addr.sin_family = AF_INET;
+	if (bindresvport(sock, &addr)) {
+		addr.sin_port = 0;
+		(void)bind(sock, (struct sockaddr *)&addr, len);
+	}
+	if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) {
+		perror("svcudp_create - cannot getsockname");
+		if (madesock)
+#ifdef WIN32
+			(void)closesocket(sock);
+#else
+			(void)close(sock);
+#endif
+		return ((SVCXPRT *)NULL);
+	}
+	xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
+	if (xprt == NULL) {
+#ifdef WIN32
+		nt_rpc_report("svcudp_create: out of memory\n");
+#else
+		(void)fprintf(stderr, "svcudp_create: out of memory\n");
+#endif
+		return (NULL);
+	}
+	su = (struct svcudp_data *)mem_alloc(sizeof(*su));
+	if (su == NULL) {
+#ifdef WIN32
+		nt_rpc_report("svcudp_create: out of memory\n");
+#else
+		(void)fprintf(stderr, "svcudp_create: out of memory\n");
+#endif
+		return (NULL);
+	}
+	su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
+	if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) {
+#ifdef WIN32
+		nt_rpc_report("svcudp_create: out of memory\n");
+#else
+		(void)fprintf(stderr, "svcudp_create: out of memory\n");
+#endif
+		return (NULL);
+	}
+	xdrmem_create(
+	    &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE);
+	su->su_cache = NULL;
+	xprt->xp_p2 = (caddr_t)su;
+	xprt->xp_verf.oa_base = su->su_verfbody;
+	xprt->xp_ops = &svcudp_op;
+	xprt->xp_port = ntohs(addr.sin_port);
+	xprt->xp_sock = sock;
+	xprt_register(xprt);
+	return (xprt);
+}
+
+SVCXPRT *
+svcudp_create(sock)
+	int sock;
+{
+
+	return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE));
+}
+
+static enum xprt_stat
+svcudp_stat(xprt)
+	SVCXPRT *xprt;
+{
+
+	return (XPRT_IDLE);
+}
+
+static bool_t
+svcudp_recv(xprt, msg)
+	register SVCXPRT *xprt;
+	struct rpc_msg *msg;
+{
+	register struct svcudp_data *su = su_data(xprt);
+	register XDR *xdrs = &(su->su_xdrs);
+	register int rlen;
+	char *reply;
+	u_long replylen;
+
+    again:
+	xprt->xp_addrlen = sizeof(struct sockaddr_in);
+	rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz,
+	    0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen));
+#ifdef WIN32
+	if (rlen == -1 && WSAerrno == WSAEINTR)
+#else
+	if (rlen == -1 && errno == EINTR)
+#endif
+		goto again;
+	if (rlen < 4*sizeof(u_long))
+		return (FALSE);
+	xdrs->x_op = XDR_DECODE;
+	XDR_SETPOS(xdrs, 0);
+	if (! xdr_callmsg(xdrs, msg))
+		return (FALSE);
+	su->su_xid = msg->rm_xid;
+	if (su->su_cache != NULL) {
+		if (cache_get(xprt, msg, &reply, &replylen)) {
+#ifdef WIN32
+			  sendto(xprt->xp_sock, reply, (int) replylen, 0,
+#else
+			(void) sendto(xprt->xp_sock, reply, (int) replylen, 0,
+#endif
+			  (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen);
+			return (TRUE);
+		}
+	}
+	return (TRUE);
+}
+
+static bool_t
+svcudp_reply(xprt, msg)
+	register SVCXPRT *xprt;
+	struct rpc_msg *msg;
+{
+	register struct svcudp_data *su = su_data(xprt);
+	register XDR *xdrs = &(su->su_xdrs);
+	register int slen;
+	register bool_t stat = FALSE;
+
+	xdrs->x_op = XDR_ENCODE;
+	XDR_SETPOS(xdrs, 0);
+	msg->rm_xid = su->su_xid;
+	if (xdr_replymsg(xdrs, msg)) {
+		slen = (int)XDR_GETPOS(xdrs);
+		if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
+		    (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
+		    == slen) {
+			stat = TRUE;
+			if (su->su_cache && slen >= 0) {
+				cache_set(xprt, (u_long) slen);
+			}
+		}
+	}
+	return (stat);
+}
+
+static bool_t
+svcudp_getargs(xprt, xdr_args, args_ptr)
+	SVCXPRT *xprt;
+	xdrproc_t xdr_args;
+	caddr_t args_ptr;
+{
+
+	return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr));
+}
+
+static bool_t
+svcudp_freeargs(xprt, xdr_args, args_ptr)
+	SVCXPRT *xprt;
+	xdrproc_t xdr_args;
+	caddr_t args_ptr;
+{
+	register XDR *xdrs = &(su_data(xprt)->su_xdrs);
+
+	xdrs->x_op = XDR_FREE;
+	return ((*xdr_args)(xdrs, args_ptr));
+}
+
+static void
+svcudp_destroy(xprt)
+	register SVCXPRT *xprt;
+{
+	register struct svcudp_data *su = su_data(xprt);
+
+	xprt_unregister(xprt);
+#ifdef WIN32
+	(void)closesocket(xprt->xp_sock);
+#else
+	(void)close(xprt->xp_sock);
+#endif
+	XDR_DESTROY(&(su->su_xdrs));
+	mem_free(rpc_buffer(xprt), su->su_iosz);
+	mem_free((caddr_t)su, sizeof(struct svcudp_data));
+	mem_free((caddr_t)xprt, sizeof(SVCXPRT));
+}
+
+
+/***********this could be a separate file*********************/
+
+/*
+ * Fifo cache for udp server
+ * Copies pointers to reply buffers into fifo cache
+ * Buffers are sent again if retransmissions are detected.
+ */
+
+#define SPARSENESS 4	/* 75% sparse */
+
+#ifdef WIN32
+#define CACHE_PERROR(msg)	\
+	nt_rpc_report(msg)
+#else
+#define CACHE_PERROR(msg)	\
+	(void) fprintf(stderr,"%s\n", msg)
+#endif
+
+#define ALLOC(type, size)	\
+	(type *) mem_alloc((unsigned) (sizeof(type) * (size)))
+
+#define BZERO(addr, type, size)	 \
+	bzero((char *) addr, sizeof(type) * (int) (size))
+
+/*
+ * An entry in the cache
+ */
+typedef struct cache_node *cache_ptr;
+struct cache_node {
+	/*
+	 * Index into cache is xid, proc, vers, prog and address
+	 */
+	u_long cache_xid;
+	u_long cache_proc;
+	u_long cache_vers;
+	u_long cache_prog;
+	struct sockaddr_in cache_addr;
+	/*
+	 * The cached reply and length
+	 */
+	char * cache_reply;
+	u_long cache_replylen;
+	/*
+ 	 * Next node on the list, if there is a collision
+	 */
+	cache_ptr cache_next;
+};
+
+
+
+/*
+ * The entire cache
+ */
+struct udp_cache {
+	u_long uc_size;		/* size of cache */
+	cache_ptr *uc_entries;	/* hash table of entries in cache */
+	cache_ptr *uc_fifo;	/* fifo list of entries in cache */
+	u_long uc_nextvictim;	/* points to next victim in fifo list */
+	u_long uc_prog;		/* saved program number */
+	u_long uc_vers;		/* saved version number */
+	u_long uc_proc;		/* saved procedure number */
+	struct sockaddr_in uc_addr; /* saved caller's address */
+};
+
+
+/*
+ * the hashing function
+ */
+#define CACHE_LOC(transp, xid)	\
+ (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size))
+
+
+/*
+ * Enable use of the cache.
+ * Note: there is no disable.
+ */
+svcudp_enablecache(transp, size)
+	SVCXPRT *transp;
+	u_long size;
+{
+	struct svcudp_data *su = su_data(transp);
+	struct udp_cache *uc;
+
+	if (su->su_cache != NULL) {
+		CACHE_PERROR("enablecache: cache already enabled");
+		return(0);
+	}
+	uc = ALLOC(struct udp_cache, 1);
+	if (uc == NULL) {
+		CACHE_PERROR("enablecache: could not allocate cache");
+		return(0);
+	}
+	uc->uc_size = size;
+	uc->uc_nextvictim = 0;
+	uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS);
+	if (uc->uc_entries == NULL) {
+		CACHE_PERROR("enablecache: could not allocate cache data");
+		return(0);
+	}
+	BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS);
+	uc->uc_fifo = ALLOC(cache_ptr, size);
+	if (uc->uc_fifo == NULL) {
+		CACHE_PERROR("enablecache: could not allocate cache fifo");
+		return(0);
+	}
+	BZERO(uc->uc_fifo, cache_ptr, size);
+	su->su_cache = (char *) uc;
+	return(1);
+}
+
+
+/*
+ * Set an entry in the cache
+ */
+static
+cache_set(xprt, replylen)
+	SVCXPRT *xprt;
+	u_long replylen;
+{
+	register cache_ptr victim;
+	register cache_ptr *vicp;
+	register struct svcudp_data *su = su_data(xprt);
+	struct udp_cache *uc = (struct udp_cache *) su->su_cache;
+	u_int loc;
+	char *newbuf;
+
+	/*
+ 	 * Find space for the new entry, either by
+	 * reusing an old entry, or by mallocing a new one
+	 */
+	victim = uc->uc_fifo[uc->uc_nextvictim];
+	if (victim != NULL) {
+		loc = CACHE_LOC(xprt, victim->cache_xid);
+		for (vicp = &uc->uc_entries[loc];
+		  *vicp != NULL && *vicp != victim;
+		  vicp = &(*vicp)->cache_next)
+				;
+		if (*vicp == NULL) {
+			CACHE_PERROR("cache_set: victim not found");
+			return;
+		}
+		*vicp = victim->cache_next;	/* remote from cache */
+		newbuf = victim->cache_reply;
+	} else {
+		victim = ALLOC(struct cache_node, 1);
+		if (victim == NULL) {
+			CACHE_PERROR("cache_set: victim alloc failed");
+			return;
+		}
+		newbuf = mem_alloc(su->su_iosz);
+		if (newbuf == NULL) {
+			CACHE_PERROR("cache_set: could not allocate new rpc_buffer");
+			return;
+		}
+	}
+
+	/*
+	 * Store it away
+	 */
+	victim->cache_replylen = replylen;
+	victim->cache_reply = rpc_buffer(xprt);
+	rpc_buffer(xprt) = newbuf;
+	xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE);
+	victim->cache_xid = su->su_xid;
+	victim->cache_proc = uc->uc_proc;
+	victim->cache_vers = uc->uc_vers;
+	victim->cache_prog = uc->uc_prog;
+	victim->cache_addr = uc->uc_addr;
+	loc = CACHE_LOC(xprt, victim->cache_xid);
+	victim->cache_next = uc->uc_entries[loc];
+	uc->uc_entries[loc] = victim;
+	uc->uc_fifo[uc->uc_nextvictim++] = victim;
+	uc->uc_nextvictim %= uc->uc_size;
+}
+
+/*
+ * Try to get an entry from the cache
+ * return 1 if found, 0 if not found
+ */
+static
+cache_get(xprt, msg, replyp, replylenp)
+	SVCXPRT *xprt;
+	struct rpc_msg *msg;
+	char **replyp;
+	u_long *replylenp;
+{
+	u_int loc;
+	register cache_ptr ent;
+	register struct svcudp_data *su = su_data(xprt);
+	register struct udp_cache *uc = (struct udp_cache *) su->su_cache;
+
+#	define EQADDR(a1, a2)	(bcmp((char*)&a1, (char*)&a2, sizeof(a1)) == 0)
+
+	loc = CACHE_LOC(xprt, su->su_xid);
+	for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) {
+		if (ent->cache_xid == su->su_xid &&
+		  ent->cache_proc == uc->uc_proc &&
+		  ent->cache_vers == uc->uc_vers &&
+		  ent->cache_prog == uc->uc_prog &&
+		  EQADDR(ent->cache_addr, uc->uc_addr)) {
+			*replyp = ent->cache_reply;
+			*replylenp = ent->cache_replylen;
+			return(1);
+		}
+	}
+	/*
+	 * Failed to find entry
+	 * Remember a few things so we can do a set later
+	 */
+	uc->uc_proc = msg->rm_call.cb_proc;
+	uc->uc_vers = msg->rm_call.cb_vers;
+	uc->uc_prog = msg->rm_call.cb_prog;
+	uc->uc_addr = xprt->xp_raddr;
+	return(0);
+}
+
diff --git a/external/rpc_win32/LIBRPC/xdr.c b/external/rpc_win32/LIBRPC/xdr.c
new file mode 100644
index 0000000..fc6bab4
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/xdr.c
@@ -0,0 +1,596 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)xdr.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
+#endif
+
+/*
+ * xdr.c, Generic XDR routines implementation.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ *
+ * These are the "generic" xdr routines used to serialize and de-serialize
+ * most common data items.  See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#include <stdio.h>
+char *malloc();
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+/*
+ * constants specific to the xdr "protocol"
+ */
+#define XDR_FALSE	((long) 0)
+#define XDR_TRUE	((long) 1)
+#define LASTUNSIGNED	((u_int) 0-1)
+
+/*
+ * for unit alignment
+ */
+static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
+
+/*
+ * Free a data structure using XDR
+ * Not a filter, but a convenient utility nonetheless
+ */
+void
+xdr_free(proc, objp)
+	xdrproc_t proc;
+	char *objp;
+{
+	XDR x;
+
+	x.x_op = XDR_FREE;
+	(*proc)(&x, objp);
+}
+
+/*
+ * XDR nothing
+ */
+bool_t
+xdr_void(/* xdrs, addr */)
+	/* XDR *xdrs; */
+	/* caddr_t addr; */
+{
+
+	return (TRUE);
+}
+
+/*
+ * XDR integers
+ */
+bool_t
+xdr_int(xdrs, ip)
+	XDR *xdrs;
+	int *ip;
+{
+
+#ifdef lint
+	(void) (xdr_short(xdrs, (short *)ip));
+	return (xdr_long(xdrs, (long *)ip));
+#else
+	if (sizeof (int) == sizeof (long)) {
+		return (xdr_long(xdrs, (long *)ip));
+	} else {
+		return (xdr_short(xdrs, (short *)ip));
+	}
+#endif
+}
+
+/*
+ * XDR unsigned integers
+ */
+bool_t
+xdr_u_int(xdrs, up)
+	XDR *xdrs;
+	u_int *up;
+{
+
+#ifdef lint
+	(void) (xdr_short(xdrs, (short *)up));
+	return (xdr_u_long(xdrs, (u_long *)up));
+#else
+	if (sizeof (u_int) == sizeof (u_long)) {
+		return (xdr_u_long(xdrs, (u_long *)up));
+	} else {
+		return (xdr_short(xdrs, (short *)up));
+	}
+#endif
+}
+
+/*
+ * XDR long integers
+ * same as xdr_u_long - open coded to save a proc call!
+ */
+bool_t
+xdr_long(xdrs, lp)
+	register XDR *xdrs;
+	long *lp;
+{
+
+	if (xdrs->x_op == XDR_ENCODE)
+		return (XDR_PUTLONG(xdrs, lp));
+
+	if (xdrs->x_op == XDR_DECODE)
+		return (XDR_GETLONG(xdrs, lp));
+
+	if (xdrs->x_op == XDR_FREE)
+		return (TRUE);
+
+	return (FALSE);
+}
+
+/*
+ * XDR unsigned long integers
+ * same as xdr_long - open coded to save a proc call!
+ */
+bool_t
+xdr_u_long(xdrs, ulp)
+	register XDR *xdrs;
+	u_long *ulp;
+{
+
+	if (xdrs->x_op == XDR_DECODE)
+		return (XDR_GETLONG(xdrs, (long *)ulp));
+	if (xdrs->x_op == XDR_ENCODE)
+		return (XDR_PUTLONG(xdrs, (long *)ulp));
+	if (xdrs->x_op == XDR_FREE)
+		return (TRUE);
+	return (FALSE);
+}
+
+/*
+ * XDR short integers
+ */
+bool_t
+xdr_short(xdrs, sp)
+	register XDR *xdrs;
+	short *sp;
+{
+	long l;
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		l = (long) *sp;
+		return (XDR_PUTLONG(xdrs, &l));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, &l)) {
+			return (FALSE);
+		}
+		*sp = (short) l;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+/*
+ * XDR unsigned short integers
+ */
+bool_t
+xdr_u_short(xdrs, usp)
+	register XDR *xdrs;
+	u_short *usp;
+{
+	u_long l;
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		l = (u_long) *usp;
+		return (XDR_PUTLONG(xdrs, &l));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, &l)) {
+			return (FALSE);
+		}
+		*usp = (u_short) l;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+
+/*
+ * XDR a char
+ */
+bool_t
+xdr_char(xdrs, cp)
+	XDR *xdrs;
+	char *cp;
+{
+	int i;
+
+	i = (*cp);
+	if (!xdr_int(xdrs, &i)) {
+		return (FALSE);
+	}
+	*cp = i;
+	return (TRUE);
+}
+
+/*
+ * XDR an unsigned char
+ */
+bool_t
+xdr_u_char(xdrs, cp)
+	XDR *xdrs;
+	char *cp;
+{
+	u_int u;
+
+	u = (*cp);
+	if (!xdr_u_int(xdrs, &u)) {
+		return (FALSE);
+	}
+	*cp = u;
+	return (TRUE);
+}
+
+/*
+ * XDR booleans
+ */
+bool_t
+xdr_bool(xdrs, bp)
+	register XDR *xdrs;
+	bool_t *bp;
+{
+	long lb;
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		lb = *bp ? XDR_TRUE : XDR_FALSE;
+		return (XDR_PUTLONG(xdrs, &lb));
+
+	case XDR_DECODE:
+		if (!XDR_GETLONG(xdrs, &lb)) {
+			return (FALSE);
+		}
+		*bp = (lb == XDR_FALSE) ? FALSE : TRUE;
+		return (TRUE);
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+/*
+ * XDR enumerations
+ */
+bool_t
+xdr_enum(xdrs, ep)
+	XDR *xdrs;
+	enum_t *ep;
+{
+#ifndef lint
+	enum sizecheck { SIZEVAL };	/* used to find the size of an enum */
+
+	/*
+	 * enums are treated as ints
+	 */
+	if (sizeof (enum sizecheck) == sizeof (long)) {
+		return (xdr_long(xdrs, (long *)ep));
+	} else if (sizeof (enum sizecheck) == sizeof (short)) {
+		return (xdr_short(xdrs, (short *)ep));
+	} else {
+		return (FALSE);
+	}
+#else
+	(void) (xdr_short(xdrs, (short *)ep));
+	return (xdr_long(xdrs, (long *)ep));
+#endif
+}
+
+/*
+ * XDR opaque data
+ * Allows the specification of a fixed size sequence of opaque bytes.
+ * cp points to the opaque object and cnt gives the byte length.
+ */
+bool_t
+xdr_opaque(xdrs, cp, cnt)
+	register XDR *xdrs;
+	caddr_t cp;
+	register u_int cnt;
+{
+	register u_int rndup;
+	static crud[BYTES_PER_XDR_UNIT];
+
+	/*
+	 * if no data we are done
+	 */
+	if (cnt == 0)
+		return (TRUE);
+
+	/*
+	 * round byte count to full xdr units
+	 */
+	rndup = cnt % BYTES_PER_XDR_UNIT;
+	if (rndup > 0)
+		rndup = BYTES_PER_XDR_UNIT - rndup;
+
+	if (xdrs->x_op == XDR_DECODE) {
+		if (!XDR_GETBYTES(xdrs, cp, cnt)) {
+			return (FALSE);
+		}
+		if (rndup == 0)
+			return (TRUE);
+		return (XDR_GETBYTES(xdrs, crud, rndup));
+	}
+
+	if (xdrs->x_op == XDR_ENCODE) {
+		if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
+			return (FALSE);
+		}
+		if (rndup == 0)
+			return (TRUE);
+		return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
+	}
+
+	if (xdrs->x_op == XDR_FREE) {
+		return (TRUE);
+	}
+
+	return (FALSE);
+}
+
+/*
+ * XDR counted bytes
+ * *cpp is a pointer to the bytes, *sizep is the count.
+ * If *cpp is NULL maxsize bytes are allocated
+ */
+bool_t
+xdr_bytes(xdrs, cpp, sizep, maxsize)
+	register XDR *xdrs;
+	char **cpp;
+	register u_int *sizep;
+	u_int maxsize;
+{
+	register char *sp = *cpp;  /* sp is the actual string pointer */
+	register u_int nodesize;
+
+	/*
+	 * first deal with the length since xdr bytes are counted
+	 */
+	if (! xdr_u_int(xdrs, sizep)) {
+		return (FALSE);
+	}
+	nodesize = *sizep;
+	if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
+		return (FALSE);
+	}
+
+	/*
+	 * now deal with the actual bytes
+	 */
+	switch (xdrs->x_op) {
+
+	case XDR_DECODE:
+		if (nodesize == 0) {
+			return (TRUE);
+		}
+		if (sp == NULL) {
+			*cpp = sp = (char *)mem_alloc(nodesize);
+		}
+		if (sp == NULL) {
+#ifdef WIN32
+			nt_rpc_report("xdr_bytes: out of memory\n");
+#else
+			(void) fprintf(stderr, "xdr_bytes: out of memory\n");
+#endif
+			return (FALSE);
+		}
+		/* fall into ... */
+
+	case XDR_ENCODE:
+		return (xdr_opaque(xdrs, sp, nodesize));
+
+	case XDR_FREE:
+		if (sp != NULL) {
+			mem_free(sp, nodesize);
+			*cpp = NULL;
+		}
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+/*
+ * Implemented here due to commonality of the object.
+ */
+bool_t
+xdr_netobj(xdrs, np)
+	XDR *xdrs;
+	struct netobj *np;
+{
+
+	return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
+}
+
+/*
+ * XDR a descriminated union
+ * Support routine for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * an entry with a null procedure pointer.  The routine gets
+ * the discriminant value and then searches the array of xdrdiscrims
+ * looking for that value.  It calls the procedure given in the xdrdiscrim
+ * to handle the discriminant.  If there is no specific routine a default
+ * routine may be called.
+ * If there is no specific or default routine an error is returned.
+ */
+bool_t
+xdr_union(xdrs, dscmp, unp, choices, dfault)
+	register XDR *xdrs;
+	enum_t *dscmp;		/* enum to decide which arm to work on */
+	char *unp;		/* the union itself */
+	struct xdr_discrim *choices;	/* [value, xdr proc] for each arm */
+	xdrproc_t dfault;	/* default xdr routine */
+{
+	register enum_t dscm;
+
+	/*
+	 * we deal with the discriminator;  it's an enum
+	 */
+	if (! xdr_enum(xdrs, dscmp)) {
+		return (FALSE);
+	}
+	dscm = *dscmp;
+
+	/*
+	 * search choices for a value that matches the discriminator.
+	 * if we find one, execute the xdr routine for that value.
+	 */
+	for (; choices->proc != NULL_xdrproc_t; choices++) {
+		if (choices->value == dscm)
+			return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
+	}
+
+	/*
+	 * no match - execute the default xdr routine if there is one
+	 */
+	return ((dfault == NULL_xdrproc_t) ? FALSE :
+	    (*dfault)(xdrs, unp, LASTUNSIGNED));
+}
+
+
+/*
+ * Non-portable xdr primitives.
+ * Care should be taken when moving these routines to new architectures.
+ */
+
+
+/*
+ * XDR null terminated ASCII strings
+ * xdr_string deals with "C strings" - arrays of bytes that are
+ * terminated by a NULL character.  The parameter cpp references a
+ * pointer to storage; If the pointer is null, then the necessary
+ * storage is allocated.  The last parameter is the max allowed length
+ * of the string as specified by a protocol.
+ */
+bool_t
+xdr_string(xdrs, cpp, maxsize)
+	register XDR *xdrs;
+	char **cpp;
+	u_int maxsize;
+{
+	register char *sp = *cpp;  /* sp is the actual string pointer */
+	u_int size;
+	u_int nodesize;
+
+	/*
+	 * first deal with the length since xdr strings are counted-strings
+	 */
+	switch (xdrs->x_op) {
+	case XDR_FREE:
+		if (sp == NULL) {
+			return(TRUE);	/* already free */
+		}
+		/* fall through... */
+	case XDR_ENCODE:
+		size = strlen(sp);
+		break;
+	}
+	if (! xdr_u_int(xdrs, &size)) {
+		return (FALSE);
+	}
+	if (size > maxsize) {
+		return (FALSE);
+	}
+	nodesize = size + 1;
+
+	/*
+	 * now deal with the actual bytes
+	 */
+	switch (xdrs->x_op) {
+
+	case XDR_DECODE:
+		if (nodesize == 0) {
+			return (TRUE);
+		}
+		if (sp == NULL)
+			*cpp = sp = (char *)mem_alloc(nodesize);
+		if (sp == NULL) {
+#ifdef WIN32
+			nt_rpc_report("xdr_string: out of memory\n");
+#else
+			(void) fprintf(stderr, "xdr_string: out of memory\n");
+#endif
+			return (FALSE);
+		}
+		sp[size] = 0;
+		/* fall into ... */
+
+	case XDR_ENCODE:
+		return (xdr_opaque(xdrs, sp, size));
+
+	case XDR_FREE:
+		mem_free(sp, nodesize);
+		*cpp = NULL;
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+/*
+ * Wrapper for xdr_string that can be called directly from
+ * routines like clnt_call
+ */
+bool_t
+xdr_wrapstring(xdrs, cpp)
+	XDR *xdrs;
+	char **cpp;
+{
+	if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
+		return (TRUE);
+	}
+	return (FALSE);
+}
diff --git a/external/rpc_win32/LIBRPC/xdr_arra.c b/external/rpc_win32/LIBRPC/xdr_arra.c
new file mode 100644
index 0000000..fd51554
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/xdr_arra.c
@@ -0,0 +1,168 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)xdr_array.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_array.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * arrays.  See xdr.h for more info on the interface to xdr.
+ */
+
+#include <stdio.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#define LASTUNSIGNED	((u_int)0-1)
+
+
+/*
+ * XDR an array of arbitrary elements
+ * *addrp is a pointer to the array, *sizep is the number of elements.
+ * If addrp is NULL (*sizep * elsize) bytes are allocated.
+ * elsize is the size (in bytes) of each element, and elproc is the
+ * xdr procedure to call to handle each element of the array.
+ */
+bool_t
+xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc)
+	register XDR *xdrs;
+	caddr_t *addrp;		/* array pointer */
+	u_int *sizep;		/* number of elements */
+	u_int maxsize;		/* max numberof elements */
+	u_int elsize;		/* size in bytes of each element */
+	xdrproc_t elproc;	/* xdr routine to handle each element */
+{
+	register u_int i;
+	register caddr_t target = *addrp;
+	register u_int c;  /* the actual element count */
+	register bool_t stat = TRUE;
+	register u_int nodesize;
+
+	/* like strings, arrays are really counted arrays */
+	if (! xdr_u_int(xdrs, sizep)) {
+		return (FALSE);
+	}
+	c = *sizep;
+	if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) {
+		return (FALSE);
+	}
+	nodesize = c * elsize;
+
+	/*
+	 * if we are deserializing, we may need to allocate an array.
+	 * We also save time by checking for a null array if we are freeing.
+	 */
+	if (target == NULL)
+		switch (xdrs->x_op) {
+		case XDR_DECODE:
+			if (c == 0)
+				return (TRUE);
+			*addrp = target = mem_alloc(nodesize);
+			if (target == NULL) {
+#ifdef WIN32
+				nt_rpc_report(
+#else
+				(void) fprintf(stderr, 
+#endif
+					"xdr_array: out of memory\n");
+				return (FALSE);
+			}
+			bzero(target, nodesize);
+			break;
+
+		case XDR_FREE:
+			return (TRUE);
+	}
+
+	/*
+	 * now we xdr each element of array
+	 */
+	for (i = 0; (i < c) && stat; i++) {
+		stat = (*elproc)(xdrs, target, LASTUNSIGNED);
+		target += elsize;
+	}
+
+	/*
+	 * the array may need freeing
+	 */
+	if (xdrs->x_op == XDR_FREE) {
+		mem_free(*addrp, nodesize);
+		*addrp = NULL;
+	}
+	return (stat);
+}
+
+/*
+ * xdr_vector():
+ *
+ * XDR a fixed length array. Unlike variable-length arrays,
+ * the storage of fixed length arrays is static and unfreeable.
+ * > basep: base of the array
+ * > size: size of the array
+ * > elemsize: size of each element
+ * > xdr_elem: routine to XDR each element
+ */
+bool_t
+xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem)
+	register XDR *xdrs;
+	register char *basep;
+	register u_int nelem;
+	register u_int elemsize;
+	register xdrproc_t xdr_elem;
+{
+	register u_int i;
+	register char *elptr;
+
+	elptr = basep;
+	for (i = 0; i < nelem; i++) {
+		if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) {
+			return(FALSE);
+		}
+		elptr += elemsize;
+	}
+	return(TRUE);
+}
+
diff --git a/external/rpc_win32/LIBRPC/xdr_floa.c b/external/rpc_win32/LIBRPC/xdr_floa.c
new file mode 100644
index 0000000..f920870
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/xdr_floa.c
@@ -0,0 +1,289 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)xdr_float.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_float.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "floating point" xdr routines used to (de)serialize
+ * most common data items.  See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#include <stdio.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#if defined(_M_IX86) || defined(_M_X64)
+#define _X86_
+#endif
+
+/*
+ * NB: Not portable.
+ * This routine works on Suns (Sky / 68000's) and Vaxen.
+ */
+
+#ifdef vax
+
+/* What IEEE single precision floating point looks like on a Vax */
+struct	ieee_single {
+	unsigned int	mantissa: 23;
+	unsigned int	exp     : 8;
+	unsigned int	sign    : 1;
+};
+
+/* Vax single precision floating point */
+struct	vax_single {
+	unsigned int	mantissa1 : 7;
+	unsigned int	exp       : 8;
+	unsigned int	sign      : 1;
+	unsigned int	mantissa2 : 16;
+};
+
+#define VAX_SNG_BIAS	0x81
+#define IEEE_SNG_BIAS	0x7f
+
+static struct sgl_limits {
+	struct vax_single s;
+	struct ieee_single ieee;
+} sgl_limits[2] = {
+	{{ 0x7f, 0xff, 0x0, 0xffff },	/* Max Vax */
+	{ 0x0, 0xff, 0x0 }},		/* Max IEEE */
+	{{ 0x0, 0x0, 0x0, 0x0 },	/* Min Vax */
+	{ 0x0, 0x0, 0x0 }}		/* Min IEEE */
+};
+#endif /* vax */
+
+bool_t
+xdr_float(xdrs, fp)
+	register XDR *xdrs;
+	register float *fp;
+{
+
+#if !defined(mc68000) && !defined(sparc) && !defined(mips) && !defined(mmax) && !defined(_X86_) && !defined(_AMD64_)
+	struct ieee_single is;
+	struct vax_single vs, *vsp;
+	struct sgl_limits *lim;
+	int i;
+#endif
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+#if defined(mc68000) || defined(sparc) || defined(mips) || defined(mmax) || defined(_X86_) || defined(_AMD64_)
+		return (XDR_PUTLONG(xdrs, (long *)fp));
+#else
+		vs = *((struct vax_single *)fp);
+		for (i = 0, lim = sgl_limits;
+			i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
+			i++, lim++) {
+			if ((vs.mantissa2 == lim->s.mantissa2) &&
+				(vs.exp == lim->s.exp) &&
+				(vs.mantissa1 == lim->s.mantissa1)) {
+				is = lim->ieee;
+				goto shipit;
+			}
+		}
+		is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
+		is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
+	shipit:
+		is.sign = vs.sign;
+		return (XDR_PUTLONG(xdrs, (long *)&is));
+#endif
+
+	case XDR_DECODE:
+#if defined(mc68000) || defined(sparc) || defined(mips) || defined(mmax) || defined(_X86_) || defined(_AMD64_)
+		return (XDR_GETLONG(xdrs, (long *)fp));
+#else
+		vsp = (struct vax_single *)fp;
+		if (!XDR_GETLONG(xdrs, (long *)&is))
+			return (FALSE);
+		for (i = 0, lim = sgl_limits;
+			i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
+			i++, lim++) {
+			if ((is.exp == lim->ieee.exp) &&
+				(is.mantissa == lim->ieee.mantissa)) {
+				*vsp = lim->s;
+				goto doneit;
+			}
+		}
+		vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
+		vsp->mantissa2 = is.mantissa;
+		vsp->mantissa1 = (is.mantissa >> 16);
+	doneit:
+		vsp->sign = is.sign;
+		return (TRUE);
+#endif
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	return (FALSE);
+}
+
+/*
+ * This routine works on Suns (Sky / 68000's) and Vaxen.
+ */
+
+#ifdef vax
+/* What IEEE double precision floating point looks like on a Vax */
+struct	ieee_double {
+	unsigned int	mantissa1 : 20;
+	unsigned int	exp       : 11;
+	unsigned int	sign      : 1;
+	unsigned int	mantissa2 : 32;
+};
+
+/* Vax double precision floating point */
+struct  vax_double {
+	unsigned int	mantissa1 : 7;
+	unsigned int	exp       : 8;
+	unsigned int	sign      : 1;
+	unsigned int	mantissa2 : 16;
+	unsigned int	mantissa3 : 16;
+	unsigned int	mantissa4 : 16;
+};
+
+#define VAX_DBL_BIAS	0x81
+#define IEEE_DBL_BIAS	0x3ff
+#define MASK(nbits)	((1 << nbits) - 1)
+
+static struct dbl_limits {
+	struct	vax_double d;
+	struct	ieee_double ieee;
+} dbl_limits[2] = {
+	{{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },	/* Max Vax */
+	{ 0x0, 0x7ff, 0x0, 0x0 }},			/* Max IEEE */
+	{{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},		/* Min Vax */
+	{ 0x0, 0x0, 0x0, 0x0 }}				/* Min IEEE */
+};
+
+#endif /* vax */
+
+
+bool_t
+xdr_double(xdrs, dp)
+	register XDR *xdrs;
+	double *dp;
+{
+	register long *lp;
+#if !defined(mc68000) && !defined(sparc) && !defined(mips) && !defined(mmax) && !defined(_X86_) && !defined(_AMD64_)
+	struct	ieee_double id;
+	struct	vax_double vd;
+	register struct dbl_limits *lim;
+	int i;
+#endif
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+#if defined(mc68000) || defined(sparc) || defined(mips) || defined(mmax) || defined(_X86_) || defined(_AMD64_)
+		lp = (long *)dp;
+#else
+		vd = *((struct vax_double *)dp);
+		for (i = 0, lim = dbl_limits;
+			i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
+			i++, lim++) {
+			if ((vd.mantissa4 == lim->d.mantissa4) &&
+				(vd.mantissa3 == lim->d.mantissa3) &&
+				(vd.mantissa2 == lim->d.mantissa2) &&
+				(vd.mantissa1 == lim->d.mantissa1) &&
+				(vd.exp == lim->d.exp)) {
+				id = lim->ieee;
+				goto shipit;
+			}
+		}
+		id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
+		id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
+		id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
+				(vd.mantissa3 << 13) |
+				((vd.mantissa4 >> 3) & MASK(13));
+	shipit:
+		id.sign = vd.sign;
+		lp = (long *)&id;
+#endif
+#if defined(_X86_) || defined(_AMD64_)
+		return (XDR_PUTLONG(xdrs, lp+1) && XDR_PUTLONG(xdrs, lp));
+#else
+		return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
+#endif
+	case XDR_DECODE:
+#if defined(mc68000) || defined(sparc) || defined(mips) || defined(mmax) || defined(_X86_) || defined(_AMD64_)
+		lp = (long *)dp;
+#if defined(_X86_) || defined(_AMD64_)
+		return (XDR_GETLONG(xdrs, lp+1) && XDR_GETLONG(xdrs, lp));
+#else
+		return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
+#endif
+#else
+		lp = (long *)&id;
+		if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
+			return (FALSE);
+		for (i = 0, lim = dbl_limits;
+			i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
+			i++, lim++) {
+			if ((id.mantissa2 == lim->ieee.mantissa2) &&
+				(id.mantissa1 == lim->ieee.mantissa1) &&
+				(id.exp == lim->ieee.exp)) {
+				vd = lim->d;
+				goto doneit;
+			}
+		}
+		vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
+		vd.mantissa1 = (id.mantissa1 >> 13);
+		vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
+				(id.mantissa2 >> 29);
+		vd.mantissa3 = (id.mantissa2 >> 13);
+		vd.mantissa4 = (id.mantissa2 << 3);
+	doneit:
+		vd.sign = id.sign;
+		*dp = *((double *)&vd);
+		return (TRUE);
+#endif
+
+	case XDR_FREE:
+		return (TRUE);
+	}
+	return (FALSE);
+}
diff --git a/external/rpc_win32/LIBRPC/xdr_mem.c b/external/rpc_win32/LIBRPC/xdr_mem.c
new file mode 100644
index 0000000..d5b4b22
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/xdr_mem.c
@@ -0,0 +1,200 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)xdr_mem.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_mem.h, XDR implementation using memory buffers.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * If you have some data to be interpreted as external data representation
+ * or to be converted to external data representation in a memory buffer,
+ * then this is the package for you.
+ *
+ */
+
+
+#ifdef WIN32
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#else
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+#endif
+
+static bool_t	xdrmem_getlong();
+static bool_t	xdrmem_putlong();
+static bool_t	xdrmem_getbytes();
+static bool_t	xdrmem_putbytes();
+static u_int	xdrmem_getpos();
+static bool_t	xdrmem_setpos();
+static long *	xdrmem_inline();
+static void	xdrmem_destroy();
+
+static struct	xdr_ops xdrmem_ops = {
+	xdrmem_getlong,
+	xdrmem_putlong,
+	xdrmem_getbytes,
+	xdrmem_putbytes,
+	xdrmem_getpos,
+	xdrmem_setpos,
+	xdrmem_inline,
+	xdrmem_destroy
+};
+
+/*
+ * The procedure xdrmem_create initializes a stream descriptor for a
+ * memory buffer.  
+ */
+void
+xdrmem_create(xdrs, addr, size, op)
+	register XDR *xdrs;
+	caddr_t addr;
+	u_int size;
+	enum xdr_op op;
+{
+
+	xdrs->x_op = op;
+	xdrs->x_ops = &xdrmem_ops;
+	xdrs->x_private = xdrs->x_base = addr;
+	xdrs->x_handy = size;
+}
+
+static void
+xdrmem_destroy(/*xdrs*/)
+	/*XDR *xdrs;*/
+{
+}
+
+static bool_t
+xdrmem_getlong(xdrs, lp)
+	register XDR *xdrs;
+	long *lp;
+{
+
+	if ((xdrs->x_handy -= sizeof(long)) < 0)
+		return (FALSE);
+	*lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private))));
+	xdrs->x_private += sizeof(long);
+	return (TRUE);
+}
+
+static bool_t
+xdrmem_putlong(xdrs, lp)
+	register XDR *xdrs;
+	long *lp;
+{
+
+	if ((xdrs->x_handy -= sizeof(long)) < 0)
+		return (FALSE);
+	*(long *)xdrs->x_private = (long)htonl((u_long)(*lp));
+	xdrs->x_private += sizeof(long);
+	return (TRUE);
+}
+
+static bool_t
+xdrmem_getbytes(xdrs, addr, len)
+	register XDR *xdrs;
+	caddr_t addr;
+	register u_int len;
+{
+
+	if ((xdrs->x_handy -= len) < 0)
+		return (FALSE);
+	bcopy(xdrs->x_private, addr, len);
+	xdrs->x_private += len;
+	return (TRUE);
+}
+
+static bool_t
+xdrmem_putbytes(xdrs, addr, len)
+	register XDR *xdrs;
+	caddr_t addr;
+	register u_int len;
+{
+
+	if ((xdrs->x_handy -= len) < 0)
+		return (FALSE);
+	bcopy(addr, xdrs->x_private, len);
+	xdrs->x_private += len;
+	return (TRUE);
+}
+
+static u_int
+xdrmem_getpos(xdrs)
+	register XDR *xdrs;
+{
+
+	return ((u_int)xdrs->x_private - (u_int)xdrs->x_base);
+}
+
+static bool_t
+xdrmem_setpos(xdrs, pos)
+	register XDR *xdrs;
+	u_int pos;
+{
+	register caddr_t newaddr = xdrs->x_base + pos;
+	register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy;
+
+	if ((long)newaddr > (long)lastaddr)
+		return (FALSE);
+	xdrs->x_private = newaddr;
+	xdrs->x_handy = (int)lastaddr - (int)newaddr;
+	return (TRUE);
+}
+
+static long *
+xdrmem_inline(xdrs, len)
+	register XDR *xdrs;
+	int len;
+{
+	long *buf = 0;
+
+	if (xdrs->x_handy >= len) {
+		xdrs->x_handy -= len;
+		buf = (long *) xdrs->x_private;
+		xdrs->x_private += len;
+	}
+	return (buf);
+}
diff --git a/external/rpc_win32/LIBRPC/xdr_rec.c b/external/rpc_win32/LIBRPC/xdr_rec.c
new file mode 100644
index 0000000..7711eb5
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/xdr_rec.c
@@ -0,0 +1,605 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)xdr_rec.c	2.2 88/08/01 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
+ * layer above tcp (for rpc's use).
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These routines interface XDRSTREAMS to a tcp/ip connection.
+ * There is a record marking layer between the xdr stream
+ * and the tcp transport level.  A record is composed on one or more
+ * record fragments.  A record fragment is a thirty-two bit header followed
+ * by n bytes of data, where n is contained in the header.  The header
+ * is represented as a htonl(u_long).  Thegh order bit encodes
+ * whether or not the fragment is the last fragment of the record
+ * (1 => fragment is last, 0 => more fragments to follow.
+ * The other 31 bits encode the byte length of the fragment.
+ */
+
+#include <stdio.h>
+#ifdef WIN32
+#include <io.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#else
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+extern long	lseek();
+#endif
+
+static u_int	fix_buf_size();
+
+static bool_t	xdrrec_getlong();
+static bool_t	xdrrec_putlong();
+static bool_t	xdrrec_getbytes();
+static bool_t	xdrrec_putbytes();
+static u_int	xdrrec_getpos();
+static bool_t	xdrrec_setpos();
+static long *	xdrrec_inline();
+static void	xdrrec_destroy();
+
+static struct  xdr_ops xdrrec_ops = {
+	xdrrec_getlong,
+	xdrrec_putlong,
+	xdrrec_getbytes,
+	xdrrec_putbytes,
+	xdrrec_getpos,
+	xdrrec_setpos,
+	xdrrec_inline,
+	xdrrec_destroy
+};
+
+/*
+ * A record is composed of one or more record fragments.
+ * A record fragment is a two-byte header followed by zero to
+ * 2**32-1 bytes.  The header is treated as a long unsigned and is
+ * encode/decoded to the network via htonl/ntohl.  The low order 31 bits
+ * are a byte count of the fragment.  The highest order bit is a boolean:
+ * 1 => this fragment is the last fragment of the record,
+ * 0 => this fragment is followed by more fragment(s).
+ *
+ * The fragment/record machinery is not general;  it is constructed to
+ * meet the needs of xdr and rpc based on tcp.
+ */
+
+#define LAST_FRAG ((u_long)(1 << 31))
+
+typedef struct rec_strm {
+	caddr_t tcp_handle;
+	caddr_t the_buffer;
+	/*
+	 * out-goung bits
+	 */
+	int (*writeit)();
+	caddr_t out_base;	/* output buffer (points to frag header) */
+	caddr_t out_finger;	/* next output position */
+	caddr_t out_boundry;	/* data cannot up to this address */
+	u_long *frag_header;	/* beginning of curren fragment */
+	bool_t frag_sent;	/* true if buffer sent in middle of record */
+	/*
+	 * in-coming bits
+	 */
+	int (*readit)();
+	u_long in_size;	/* fixed size of the input buffer */
+	caddr_t in_base;
+	caddr_t in_finger;	/* location of next byte to be had */
+	caddr_t in_boundry;	/* can read up to this location */
+	long fbtbc;		/* fragment bytes to be consumed */
+	bool_t last_frag;
+	u_int sendsize;
+	u_int recvsize;
+} RECSTREAM;
+
+
+/*
+ * Create an xdr handle for xdrrec
+ * xdrrec_create fills in xdrs.  Sendsize and recvsize are
+ * send and recv buffer sizes (0 => use default).
+ * tcp_handle is an opaque handle that is passed as the first parameter to
+ * the procedures readit and writeit.  Readit and writeit are read and
+ * write respectively.   They are like the system
+ * calls expect that they take an opaque handle rather than an fd.
+ */
+void
+xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit)
+	register XDR *xdrs;
+	register u_int sendsize;
+	register u_int recvsize;
+	caddr_t tcp_handle;
+	int (*readit)();  /* like read, but pass it a tcp_handle, not sock */
+	int (*writeit)();  /* like write, but pass it a tcp_handle, not sock */
+{
+	register RECSTREAM *rstrm =
+		(RECSTREAM *)mem_alloc(sizeof(RECSTREAM));
+
+	if (rstrm == NULL) {
+#ifdef WIN32
+		nt_rpc_report("xdrrec_create: out of memory\n");
+#else
+		(void)fprintf(stderr, "xdrrec_create: out of memory\n");
+#endif
+		/*
+		 *  This is bad.  Should rework xdrrec_create to
+		 *  return a handle, and in this case return NULL
+		 */
+		return;
+	}
+	/*
+	 * adjust sizes and allocate buffer quad byte aligned
+	 */
+	rstrm->sendsize = sendsize = fix_buf_size(sendsize);
+	rstrm->recvsize = recvsize = fix_buf_size(recvsize);
+	rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT);
+	if (rstrm->the_buffer == NULL) {
+#ifdef WIN32
+		nt_rpc_report("xdrrec_create: out of memory\n");
+#else
+		(void)fprintf(stderr, "xdrrec_create: out of memory\n");
+#endif
+		return;
+	}
+	for (rstrm->out_base = rstrm->the_buffer;
+		(u_int)rstrm->out_base % BYTES_PER_XDR_UNIT != 0;
+		rstrm->out_base++);
+	rstrm->in_base = rstrm->out_base + sendsize;
+	/*
+	 * now the rest ...
+	 */
+	xdrs->x_ops = &xdrrec_ops;
+	xdrs->x_private = (caddr_t)rstrm;
+	rstrm->tcp_handle = tcp_handle;
+	rstrm->readit = readit;
+	rstrm->writeit = writeit;
+	rstrm->out_finger = rstrm->out_boundry = rstrm->out_base;
+	rstrm->frag_header = (u_long *)rstrm->out_base;
+	rstrm->out_finger += sizeof(u_long);
+	rstrm->out_boundry += sendsize;
+	rstrm->frag_sent = FALSE;
+	rstrm->in_size = recvsize;
+	rstrm->in_boundry = rstrm->in_base;
+	rstrm->in_finger = (rstrm->in_boundry += recvsize);
+	rstrm->fbtbc = 0;
+	rstrm->last_frag = TRUE;
+}
+
+
+/*
+ * The reoutines defined below are the xdr ops which will go into the
+ * xdr handle filled in by xdrrec_create.
+ */
+
+static bool_t
+xdrrec_getlong(xdrs, lp)
+	XDR *xdrs;
+	long *lp;
+{
+	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+	register long *buflp = (long *)(rstrm->in_finger);
+	long mylong;
+
+	/* first try the inline, fast case */
+	if ((rstrm->fbtbc >= sizeof(long)) &&
+		(((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) {
+		*lp = (long)ntohl((u_long)(*buflp));
+		rstrm->fbtbc -= sizeof(long);
+		rstrm->in_finger += sizeof(long);
+	} else {
+		if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long)))
+			return (FALSE);
+		*lp = (long)ntohl((u_long)mylong);
+	}
+	return (TRUE);
+}
+
+static bool_t
+xdrrec_putlong(xdrs, lp)
+	XDR *xdrs;
+	long *lp;
+{
+	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+	register long *dest_lp = ((long *)(rstrm->out_finger));
+
+	if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) {
+		/*
+		 * this case should almost never happen so the code is
+		 * inefficient
+		 */
+		rstrm->out_finger -= sizeof(long);
+		rstrm->frag_sent = TRUE;
+		if (! flush_out(rstrm, FALSE))
+			return (FALSE);
+		dest_lp = ((long *)(rstrm->out_finger));
+		rstrm->out_finger += sizeof(long);
+	}
+	*dest_lp = (long)htonl((u_long)(*lp));
+	return (TRUE);
+}
+
+static bool_t  /* must manage buffers, fragments, and records */
+xdrrec_getbytes(xdrs, addr, len)
+	XDR *xdrs;
+	register caddr_t addr;
+	register u_int len;
+{
+	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+	register int current;
+
+	while (len > 0) {
+		current = rstrm->fbtbc;
+		if (current == 0) {
+			if (rstrm->last_frag)
+				return (FALSE);
+			if (! set_input_fragment(rstrm))
+				return (FALSE);
+			continue;
+		}
+		current = (len < current) ? len : current;
+		if (! get_input_bytes(rstrm, addr, current))
+			return (FALSE);
+		addr += current;
+		rstrm->fbtbc -= current;
+		len -= current;
+	}
+	return (TRUE);
+}
+
+static bool_t
+xdrrec_putbytes(xdrs, addr, len)
+	XDR *xdrs;
+	register caddr_t addr;
+	register u_int len;
+{
+	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+	register int current;
+
+	while (len > 0) {
+		current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger;
+		current = (len < current) ? len : current;
+		bcopy(addr, rstrm->out_finger, current);
+		rstrm->out_finger += current;
+		addr += current;
+		len -= current;
+		if (rstrm->out_finger == rstrm->out_boundry) {
+			rstrm->frag_sent = TRUE;
+			if (! flush_out(rstrm, FALSE))
+				return (FALSE);
+		}
+	}
+	return (TRUE);
+}
+
+static u_int
+xdrrec_getpos(xdrs)
+	register XDR *xdrs;
+{
+	register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+	register long pos;
+
+	pos = lseek((int)rstrm->tcp_handle, (long) 0, 1);
+	if (pos != -1)
+		switch (xdrs->x_op) {
+
+		case XDR_ENCODE:
+			pos += rstrm->out_finger - rstrm->out_base;
+			break;
+
+		case XDR_DECODE:
+			pos -= rstrm->in_boundry - rstrm->in_finger;
+			break;
+
+		default:
+			pos = (u_int) -1;
+			break;
+		}
+	return ((u_int) pos);
+}
+
+static bool_t
+xdrrec_setpos(xdrs, pos)
+	register XDR *xdrs;
+	u_int pos;
+{
+	register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+	u_int currpos = xdrrec_getpos(xdrs);
+	int delta = currpos - pos;
+	caddr_t newpos;
+
+	if ((int)currpos != -1)
+		switch (xdrs->x_op) {
+
+		case XDR_ENCODE:
+			newpos = rstrm->out_finger - delta;
+			if ((newpos > (caddr_t)(rstrm->frag_header)) &&
+				(newpos < rstrm->out_boundry)) {
+				rstrm->out_finger = newpos;
+				return (TRUE);
+			}
+			break;
+
+		case XDR_DECODE:
+			newpos = rstrm->in_finger - delta;
+			if ((delta < (int)(rstrm->fbtbc)) &&
+				(newpos <= rstrm->in_boundry) &&
+				(newpos >= rstrm->in_base)) {
+				rstrm->in_finger = newpos;
+				rstrm->fbtbc -= delta;
+				return (TRUE);
+			}
+			break;
+		}
+	return (FALSE);
+}
+
+static long *
+xdrrec_inline(xdrs, len)
+	register XDR *xdrs;
+	int len;
+{
+	register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+	long * buf = NULL;
+
+	switch (xdrs->x_op) {
+
+	case XDR_ENCODE:
+		if ((rstrm->out_finger + len) <= rstrm->out_boundry) {
+			buf = (long *) rstrm->out_finger;
+			rstrm->out_finger += len;
+		}
+		break;
+
+	case XDR_DECODE:
+		if ((len <= rstrm->fbtbc) &&
+			((rstrm->in_finger + len) <= rstrm->in_boundry)) {
+			buf = (long *) rstrm->in_finger;
+			rstrm->fbtbc -= len;
+			rstrm->in_finger += len;
+		}
+		break;
+	}
+	return (buf);
+}
+
+static void
+xdrrec_destroy(xdrs)
+	register XDR *xdrs;
+{
+	register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
+
+	mem_free(rstrm->the_buffer,
+		rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT);
+	mem_free((caddr_t)rstrm, sizeof(RECSTREAM));
+}
+
+
+/*
+ * Exported routines to manage xdr records
+ */
+
+/*
+ * Before reading (deserializing from the stream, one should always call
+ * this procedure to guarantee proper record alignment.
+ */
+bool_t
+xdrrec_skiprecord(xdrs)
+	XDR *xdrs;
+{
+	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+
+	while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
+		if (! skip_input_bytes(rstrm, rstrm->fbtbc))
+			return (FALSE);
+		rstrm->fbtbc = 0;
+		if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
+			return (FALSE);
+	}
+	rstrm->last_frag = FALSE;
+	return (TRUE);
+}
+
+/*
+ * Look ahead fuction.
+ * Returns TRUE iff there is no more input in the buffer
+ * after consuming the rest of the current record.
+ */
+bool_t
+xdrrec_eof(xdrs)
+	XDR *xdrs;
+{
+	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+
+	while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) {
+		if (! skip_input_bytes(rstrm, rstrm->fbtbc))
+			return (TRUE);
+		rstrm->fbtbc = 0;
+		if ((! rstrm->last_frag) && (! set_input_fragment(rstrm)))
+			return (TRUE);
+	}
+	if (rstrm->in_finger == rstrm->in_boundry)
+		return (TRUE);
+	return (FALSE);
+}
+
+/*
+ * The client must tell the package when an end-of-record has occurred.
+ * The second paraemters tells whether the record should be flushed to the
+ * (output) tcp stream.  (This let's the package support batched or
+ * pipelined procedure calls.)  TRUE => immmediate flush to tcp connection.
+ */
+bool_t
+xdrrec_endofrecord(xdrs, sendnow)
+	XDR *xdrs;
+	bool_t sendnow;
+{
+	register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
+	register u_long len;  /* fragment length */
+
+	if (sendnow || rstrm->frag_sent ||
+		((u_long)rstrm->out_finger + sizeof(u_long) >=
+		(u_long)rstrm->out_boundry)) {
+		rstrm->frag_sent = FALSE;
+		return (flush_out(rstrm, TRUE));
+	}
+	len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) -
+	   sizeof(u_long);
+	*(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG);
+	rstrm->frag_header = (u_long *)rstrm->out_finger;
+	rstrm->out_finger += sizeof(u_long);
+	return (TRUE);
+}
+
+
+/*
+ * Internal useful routines
+ */
+static bool_t
+flush_out(rstrm, eor)
+	register RECSTREAM *rstrm;
+	bool_t eor;
+{
+	register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0;
+	register u_long len = (u_long)(rstrm->out_finger) -
+		(u_long)(rstrm->frag_header) - sizeof(u_long);
+
+	*(rstrm->frag_header) = htonl(len | eormask);
+	len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base);
+	if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
+		!= (int)len)
+		return (FALSE);
+	rstrm->frag_header = (u_long *)rstrm->out_base;
+	rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long);
+	return (TRUE);
+}
+
+static bool_t  /* knows nothing about records!  Only about input buffers */
+fill_input_buf(rstrm)
+	register RECSTREAM *rstrm;
+{
+	register caddr_t where;
+	u_int i;
+	register int len;
+
+	where = rstrm->in_base;
+	i = (u_int)rstrm->in_boundry % BYTES_PER_XDR_UNIT;
+	where += i;
+	len = rstrm->in_size - i;
+	if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
+		return (FALSE);
+	rstrm->in_finger = where;
+	where += len;
+	rstrm->in_boundry = where;
+	return (TRUE);
+}
+
+static bool_t  /* knows nothing about records!  Only about input buffers */
+get_input_bytes(rstrm, addr, len)
+	register RECSTREAM *rstrm;
+	register caddr_t addr;
+	register int len;
+{
+	register int current;
+
+	while (len > 0) {
+		current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
+		if (current == 0) {
+			if (! fill_input_buf(rstrm))
+				return (FALSE);
+			continue;
+		}
+		current = (len < current) ? len : current;
+		bcopy(rstrm->in_finger, addr, current);
+		rstrm->in_finger += current;
+		addr += current;
+		len -= current;
+	}
+	return (TRUE);
+}
+
+static bool_t  /* next two bytes of the input stream are treated as a header */
+set_input_fragment(rstrm)
+	register RECSTREAM *rstrm;
+{
+	u_long header;
+
+	if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header)))
+		return (FALSE);
+	header = (long)ntohl(header);
+	rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE;
+	rstrm->fbtbc = header & (~LAST_FRAG);
+	return (TRUE);
+}
+
+static bool_t  /* consumes input bytes; knows nothing about records! */
+skip_input_bytes(rstrm, cnt)
+	register RECSTREAM *rstrm;
+	long cnt;
+{
+	register int current;
+
+	while (cnt > 0) {
+		current = (int)rstrm->in_boundry - (int)rstrm->in_finger;
+		if (current == 0) {
+			if (! fill_input_buf(rstrm))
+				return (FALSE);
+			continue;
+		}
+		current = (cnt < current) ? cnt : current;
+		rstrm->in_finger += current;
+		cnt -= current;
+	}
+	return (TRUE);
+}
+
+static u_int
+fix_buf_size(s)
+	register u_int s;
+{
+
+	if (s < 100)
+		s = 4000;
+	return (RNDUP(s));
+}
diff --git a/external/rpc_win32/LIBRPC/xdr_refe.c b/external/rpc_win32/LIBRPC/xdr_refe.c
new file mode 100644
index 0000000..7c95dd0
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/xdr_refe.c
@@ -0,0 +1,147 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)xdr_reference.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_reference.c 1.11 87/08/11 SMI";
+#endif
+
+/*
+ * xdr_reference.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * "pointers".  See xdr.h for more info on the interface to xdr.
+ */
+
+#include <stdio.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#define LASTUNSIGNED	((u_int)0-1)
+
+/*
+ * XDR an indirect pointer
+ * xdr_reference is for recursively translating a structure that is
+ * referenced by a pointer inside the structure that is currently being
+ * translated.  pp references a pointer to storage. If *pp is null
+ * the  necessary storage is allocated.
+ * size is the sizeof the referneced structure.
+ * proc is the routine to handle the referenced structure.
+ */
+bool_t
+xdr_reference(xdrs, pp, size, proc)
+	register XDR *xdrs;
+	caddr_t *pp;		/* the pointer to work on */
+	u_int size;		/* size of the object pointed to */
+	xdrproc_t proc;		/* xdr routine to handle the object */
+{
+	register caddr_t loc = *pp;
+	register bool_t stat;
+
+	if (loc == NULL)
+		switch (xdrs->x_op) {
+		case XDR_FREE:
+			return (TRUE);
+
+		case XDR_DECODE:
+			*pp = loc = (caddr_t) mem_alloc(size);
+			if (loc == NULL) {
+#ifdef WIN32
+				(void) nt_rpc_report(
+#else
+				(void) fprintf(stderr,
+#endif
+				    "xdr_reference: out of memory\n");
+				return (FALSE);
+			}
+			bzero(loc, (int)size);
+			break;
+	}
+
+	stat = (*proc)(xdrs, loc, LASTUNSIGNED);
+
+	if (xdrs->x_op == XDR_FREE) {
+		mem_free(loc, size);
+		*pp = NULL;
+	}
+	return (stat);
+}
+
+
+/*
+ * xdr_pointer():
+ *
+ * XDR a pointer to a possibly recursive data structure. This
+ * differs with xdr_reference in that it can serialize/deserialiaze
+ * trees correctly.
+ *
+ *  What's sent is actually a union:
+ *
+ *  union object_pointer switch (boolean b) {
+ *  case TRUE: object_data data;
+ *  case FALSE: void nothing;
+ *  }
+ *
+ * > objpp: Pointer to the pointer to the object.
+ * > obj_size: size of the object.
+ * > xdr_obj: routine to XDR an object.
+ *
+ */
+bool_t
+xdr_pointer(xdrs,objpp,obj_size,xdr_obj)
+	register XDR *xdrs;
+	char **objpp;
+	u_int obj_size;
+	xdrproc_t xdr_obj;
+{
+
+	bool_t more_data;
+
+	more_data = (*objpp != NULL);
+	if (! xdr_bool(xdrs,&more_data)) {
+		return (FALSE);
+	}
+	if (! more_data) {
+		*objpp = NULL;
+		return (TRUE);
+	}
+	return (xdr_reference(xdrs,objpp,obj_size,xdr_obj));
+}
diff --git a/external/rpc_win32/LIBRPC/xdr_stdi.c b/external/rpc_win32/LIBRPC/xdr_stdi.c
new file mode 100644
index 0000000..8abc505
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/xdr_stdi.c
@@ -0,0 +1,204 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)xdr_stdio.c	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static char sccsid[] = "@(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_stdio.c, XDR implementation on standard i/o file.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements a XDR on a stdio stream.
+ * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
+ * from the stream.
+ */
+
+#ifdef WIN32
+#include <rpc/rpc.h>
+#else
+#include <rpc/types.h>
+#endif
+#include <stdio.h>
+#include <rpc/xdr.h>
+
+static bool_t	xdrstdio_getlong();
+static bool_t	xdrstdio_putlong();
+static bool_t	xdrstdio_getbytes();
+static bool_t	xdrstdio_putbytes();
+static u_int	xdrstdio_getpos();
+static bool_t	xdrstdio_setpos();
+static long *	xdrstdio_inline();
+static void	xdrstdio_destroy();
+
+/*
+ * Ops vector for stdio type XDR
+ */
+static struct xdr_ops	xdrstdio_ops = {
+	xdrstdio_getlong,	/* deseraialize a long int */
+	xdrstdio_putlong,	/* seraialize a long int */
+	xdrstdio_getbytes,	/* deserialize counted bytes */
+	xdrstdio_putbytes,	/* serialize counted bytes */
+	xdrstdio_getpos,	/* get offset in the stream */
+	xdrstdio_setpos,	/* set offset in the stream */
+	xdrstdio_inline,	/* prime stream for inline macros */
+	xdrstdio_destroy	/* destroy stream */
+};
+
+/*
+ * Initialize a stdio xdr stream.
+ * Sets the xdr stream handle xdrs for use on the stream file.
+ * Operation flag is set to op.
+ */
+void
+xdrstdio_create(xdrs, file, op)
+	register XDR *xdrs;
+	FILE *file;
+	enum xdr_op op;
+{
+
+	xdrs->x_op = op;
+	xdrs->x_ops = &xdrstdio_ops;
+	xdrs->x_private = (caddr_t)file;
+	xdrs->x_handy = 0;
+	xdrs->x_base = 0;
+}
+
+/*
+ * Destroy a stdio xdr stream.
+ * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
+ */
+static void
+xdrstdio_destroy(xdrs)
+	register XDR *xdrs;
+{
+	(void)fflush((FILE *)xdrs->x_private);
+	/* xx should we close the file ?? */
+};
+
+static bool_t
+xdrstdio_getlong(xdrs, lp)
+	XDR *xdrs;
+	register long *lp;
+{
+
+	if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
+		return (FALSE);
+#ifndef mc68000
+	*lp = ntohl(*lp);
+#endif
+	return (TRUE);
+}
+
+static bool_t
+xdrstdio_putlong(xdrs, lp)
+	XDR *xdrs;
+	long *lp;
+{
+
+#ifndef mc68000
+	long mycopy = htonl(*lp);
+	lp = &mycopy;
+#endif
+	if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1)
+		return (FALSE);
+	return (TRUE);
+}
+
+static bool_t
+xdrstdio_getbytes(xdrs, addr, len)
+	XDR *xdrs;
+	caddr_t addr;
+	u_int len;
+{
+
+	if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
+		return (FALSE);
+	return (TRUE);
+}
+
+static bool_t
+xdrstdio_putbytes(xdrs, addr, len)
+	XDR *xdrs;
+	caddr_t addr;
+	u_int len;
+{
+
+	if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1))
+		return (FALSE);
+	return (TRUE);
+}
+
+static u_int
+xdrstdio_getpos(xdrs)
+	XDR *xdrs;
+{
+
+	return ((u_int) ftell((FILE *)xdrs->x_private));
+}
+
+static bool_t
+xdrstdio_setpos(xdrs, pos) 
+	XDR *xdrs;
+	u_int pos;
+{ 
+
+	return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
+		FALSE : TRUE);
+}
+
+static long *
+xdrstdio_inline(xdrs, len)
+	XDR *xdrs;
+	u_int len;
+{
+
+	/*
+	 * Must do some work to implement this: must insure
+	 * enough data in the underlying stdio buffer,
+	 * that the buffer is aligned so that we can indirect through a
+	 * long *, and stuff this pointer in xdrs->x_buf.  Doing
+	 * a fread or fwrite to a scratch buffer would defeat
+	 * most of the gains to be had here and require storage
+	 * management on this buffer, so we don't do this.
+	 */
+	return (NULL);
+}
diff --git a/external/rpc_win32/LIBRPC/xdrrefer.c b/external/rpc_win32/LIBRPC/xdrrefer.c
new file mode 100644
index 0000000..d5de4e5
--- /dev/null
+++ b/external/rpc_win32/LIBRPC/xdrrefer.c
@@ -0,0 +1,102 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#ifndef lint
+static char sccsid[] = "@(#)xdr_reference.c 1.2 85/02/26 Copyr 1984 Sun Micro";
+#endif
+
+/*
+ * xdr_reference.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * "pointers".  See xdr.h for more info on the interface to xdr.
+ */
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <stdio.h>
+#define LASTUNSIGNED	((u_int)0-1)
+
+char *mem_alloc();
+
+/*
+ * XDR an indirect pointer
+ * xdr_reference is for recursively translating a structure that is
+ * referenced by a pointer inside the structure that is currently being
+ * translated.  pp references a pointer to storage. If *pp is null
+ * the  necessary storage is allocated.
+ * size is the sizeof the referneced structure.
+ * proc is the routine to handle the referenced structure.
+ */
+bool_t
+xdr_reference(xdrs, pp, size, proc)
+	register XDR *xdrs;
+	caddr_t *pp;		/* the pointer to work on */
+	u_int size;		/* size of the object pointed to */
+	xdrproc_t proc;		/* xdr routine to handle the object */
+{
+	register caddr_t loc = *pp;
+	register bool_t stat;
+
+	if (loc == NULL)
+		switch (xdrs->x_op) {
+		case XDR_FREE:
+			return (TRUE);
+
+		case XDR_DECODE:
+			*pp = loc = mem_alloc(size);
+			if (loc == NULL) {
+				nt_rpc_report(
+				    "xdr_reference: out of memory\n");
+				return (FALSE);
+			}
+			bzero(loc, (int)size);
+			break;
+	}
+
+	stat = (*proc)(xdrs, loc, LASTUNSIGNED);
+
+	if (xdrs->x_op == XDR_FREE) {
+		mem_free(loc, size);
+		*pp = NULL;
+	}
+	return (stat);
+}
diff --git a/external/rpc_win32/RPC/AUTH.H b/external/rpc_win32/RPC/AUTH.H
new file mode 100644
index 0000000..84a6324
--- /dev/null
+++ b/external/rpc_win32/RPC/AUTH.H
@@ -0,0 +1,190 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)auth.h	2.3 88/08/07 4.0 RPCSRC; from 1.17 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * auth.h, Authentication interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The data structures are completely opaque to the client.  The client
+ * is required to pass a AUTH * to routines that create rpc
+ * "sessions".
+ */
+
+#ifndef __AUTH_HEADER__
+#define __AUTH_HEADER__
+
+#define MAX_AUTH_BYTES	400
+#define MAXNETNAMELEN	255	/* maximum length of network user's name */
+
+/*
+ * Status returned from authentication check
+ */
+enum auth_stat {
+	AUTH_OK=0,
+	/*
+	 * failed at remote end
+	 */
+	AUTH_BADCRED=1,			/* bogus credentials (seal broken) */
+	AUTH_REJECTEDCRED=2,		/* client should begin new session */
+	AUTH_BADVERF=3,			/* bogus verifier (seal broken) */
+	AUTH_REJECTEDVERF=4,		/* verifier expired or was replayed */
+	AUTH_TOOWEAK=5,			/* rejected due to security reasons */
+	/*
+	 * failed locally
+	*/
+	AUTH_INVALIDRESP=6,		/* bogus response verifier */
+	AUTH_FAILED=7			/* some unknown reason */
+};
+
+#if (mc68000 || sparc || vax || i386)
+typedef u_long u_int32;	/* 32-bit unsigned integers */
+
+union des_block {
+	struct {
+		u_int32 high;
+		u_int32 low;
+	} key;
+	char c[8];
+};
+#else
+union des_block {
+        struct {
+                u_long high;
+                u_long low;
+        } key;
+        char c[8];
+};
+#endif
+typedef union des_block des_block;
+extern bool_t xdr_des_block();
+
+/*
+ * Authentication info.  Opaque to client.
+ */
+struct opaque_auth {
+	enum_t	oa_flavor;		/* flavor of auth */
+	caddr_t	oa_base;		/* address of more auth stuff */
+	u_int	oa_length;		/* not to exceed MAX_AUTH_BYTES */
+};
+
+
+/*
+ * Auth handle, interface to client side authenticators.
+ */
+typedef struct {
+	struct	opaque_auth	ah_cred;
+	struct	opaque_auth	ah_verf;
+	union	des_block	ah_key;
+	struct auth_ops {
+		void	(*ah_nextverf)();
+		int	(*ah_marshal)();	/* nextverf & serialize */
+		int	(*ah_validate)();	/* validate varifier */
+		int	(*ah_refresh)();	/* refresh credentials */
+		void	(*ah_destroy)();	/* destroy this structure */
+	} *ah_ops;
+	caddr_t ah_private;
+} AUTH;
+
+
+/*
+ * Authentication ops.
+ * The ops and the auth handle provide the interface to the authenticators.
+ *
+ * AUTH	*auth;
+ * XDR	*xdrs;
+ * struct opaque_auth verf;
+ */
+#define AUTH_NEXTVERF(auth)		\
+		((*((auth)->ah_ops->ah_nextverf))(auth))
+#define auth_nextverf(auth)		\
+		((*((auth)->ah_ops->ah_nextverf))(auth))
+
+#define AUTH_MARSHALL(auth, xdrs)	\
+		((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+#define auth_marshall(auth, xdrs)	\
+		((*((auth)->ah_ops->ah_marshal))(auth, xdrs))
+
+#define AUTH_VALIDATE(auth, verfp)	\
+		((*((auth)->ah_ops->ah_validate))((auth), verfp))
+#define auth_validate(auth, verfp)	\
+		((*((auth)->ah_ops->ah_validate))((auth), verfp))
+
+#define AUTH_REFRESH(auth)		\
+		((*((auth)->ah_ops->ah_refresh))(auth))
+#define auth_refresh(auth)		\
+		((*((auth)->ah_ops->ah_refresh))(auth))
+
+#define AUTH_DESTROY(auth)		\
+		((*((auth)->ah_ops->ah_destroy))(auth))
+#define auth_destroy(auth)		\
+		((*((auth)->ah_ops->ah_destroy))(auth))
+
+
+extern struct opaque_auth _null_auth;
+
+
+/*
+ * These are the various implementations of client side authenticators.
+ */
+
+/*
+ * Unix style authentication
+ * AUTH *authunix_create(machname, uid, gid, len, aup_gids)
+ *	char *machname;
+ *	int uid;
+ *	int gid;
+ *	int len;
+ *	int *aup_gids;
+ */
+extern AUTH *authunix_create();
+extern AUTH *authunix_create_default();	/* takes no parameters */
+extern AUTH *authnone_create();		/* takes no parameters */
+extern AUTH *authdes_create();
+
+#define AUTH_NONE	0		/* no authentication */
+#define	AUTH_NULL	0		/* backward compatibility */
+#define	AUTH_UNIX	1		/* unix style (uid, gids) */
+#define	AUTH_SHORT	2		/* short hand unix style */
+#define AUTH_DES	3		/* des style (encrypted timestamps) */
+
+#endif	/* __AUTH_HEADER__ */
+
diff --git a/external/rpc_win32/RPC/AUTH_UNI.H b/external/rpc_win32/RPC/AUTH_UNI.H
new file mode 100644
index 0000000..f4fbaf0
--- /dev/null
+++ b/external/rpc_win32/RPC/AUTH_UNI.H
@@ -0,0 +1,89 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)auth_unix.h	2.2 88/07/29 4.0 RPCSRC; from 1.8 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)auth_unix.h 1.5 86/07/16 SMI      */
+
+/*
+ * auth_unix.h, Protocol for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * The system is very weak.  The client uses no encryption for  it
+ * credentials and only sends null verifiers.  The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ */
+
+#ifndef __AUTH_UNIX_HEADER__
+#define __AUTH_UNIX_HEADER__
+
+/* The machine name is part of a credential; it may not exceed 255 bytes */
+#define MAX_MACHINE_NAME 255
+
+/* gids compose part of a credential; there may not be more than 16 of them */
+#define NGRPS 16
+
+/*
+ * Unix style credentials.
+ */
+struct authunix_parms {
+	u_long	 aup_time;
+	char	*aup_machname;
+	int	 aup_uid;
+	int	 aup_gid;
+	u_int	 aup_len;
+	int	*aup_gids;
+};
+
+extern bool_t xdr_authunix_parms();
+
+/* 
+ * If a response verifier has flavor AUTH_SHORT, 
+ * then the body of the response verifier encapsulates the following structure;
+ * again it is serialized in the obvious fashion.
+ */
+struct short_hand_verf {
+	struct opaque_auth new_cred;
+};
+
+#endif	/* __AUTH_UNIX_HEADER__ */
+
diff --git a/external/rpc_win32/RPC/BCOPY.H b/external/rpc_win32/RPC/BCOPY.H
new file mode 100644
index 0000000..b4d0d8d
--- /dev/null
+++ b/external/rpc_win32/RPC/BCOPY.H
@@ -0,0 +1,14 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+void bcopy(char *,char*,int);
+void bcopy_nf(char *,char *,int);
+void bcopy_fn(char *,char *,int);
+void bcopy_ff(char *,char *,int);
+void bzero(char*,int);
diff --git a/external/rpc_win32/RPC/CLNT.H b/external/rpc_win32/RPC/CLNT.H
new file mode 100644
index 0000000..4fbb10b
--- /dev/null
+++ b/external/rpc_win32/RPC/CLNT.H
@@ -0,0 +1,342 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)clnt.h	2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * clnt.h - Client side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _CLNT_
+#define _CLNT_
+
+/*
+ * Rpc calls return an enum clnt_stat.  This should be looked at more,
+ * since each implementation is required to live with this (implementation
+ * independent) list of errors.
+ */
+enum clnt_stat {
+	RPC_SUCCESS=0,			/* call succeeded */
+	/*
+	 * local errors
+	 */
+	RPC_CANTENCODEARGS=1,		/* can't encode arguments */
+	RPC_CANTDECODERES=2,		/* can't decode results */
+	RPC_CANTSEND=3,			/* failure in sending call */
+	RPC_CANTRECV=4,			/* failure in receiving result */
+	RPC_TIMEDOUT=5,			/* call timed out */
+	/*
+	 * remote errors
+	 */
+	RPC_VERSMISMATCH=6,		/* rpc versions not compatible */
+	RPC_AUTHERROR=7,		/* authentication error */
+	RPC_PROGUNAVAIL=8,		/* program not available */
+	RPC_PROGVERSMISMATCH=9,		/* program version mismatched */
+	RPC_PROCUNAVAIL=10,		/* procedure unavailable */
+	RPC_CANTDECODEARGS=11,		/* decode arguments error */
+	RPC_SYSTEMERROR=12,		/* generic "other problem" */
+
+	/*
+	 * callrpc & clnt_create errors
+	 */
+	RPC_UNKNOWNHOST=13,		/* unknown host name */
+	RPC_UNKNOWNPROTO=17,		/* unkown protocol */
+
+	/*
+	 * _ create errors
+	 */
+	RPC_PMAPFAILURE=14,		/* the pmapper failed in its call */
+	RPC_PROGNOTREGISTERED=15,	/* remote program is not registered */
+	/*
+	 * unspecified error
+	 */
+	RPC_FAILED=16
+};
+
+
+/*
+ * Error info.
+ */
+struct rpc_err {
+	enum clnt_stat re_status;
+	union {
+		int RE_errno;		/* realated system error */
+		enum auth_stat RE_why;	/* why the auth error occurred */
+		struct {
+			u_long low;	/* lowest verion supported */
+			u_long high;	/* highest verion supported */
+		} RE_vers;
+		struct {		/* maybe meaningful if RPC_FAILED */
+			long s1;
+			long s2;
+		} RE_lb;		/* life boot & debugging only */
+	} ru;
+#define	re_errno	ru.RE_errno
+#define	re_why		ru.RE_why
+#define	re_vers		ru.RE_vers
+#define	re_lb		ru.RE_lb
+};
+
+
+/*
+ * Client rpc handle.
+ * Created by individual implementations, see e.g. rpc_udp.c.
+ * Client is responsible for initializing auth, see e.g. auth_none.c.
+ */
+typedef struct {
+	AUTH	*cl_auth;			/* authenticator */
+	struct clnt_ops {
+		enum clnt_stat	(*cl_call)();	/* call remote procedure */
+		void		(*cl_abort)();	/* abort a call */
+		void		(*cl_geterr)();	/* get specific error code */
+		bool_t		(*cl_freeres)(); /* frees results */
+		void		(*cl_destroy)();/* destroy this structure */
+		bool_t          (*cl_control)();/* the ioctl() of rpc */
+	} *cl_ops;
+	caddr_t			cl_private;	/* private stuff */
+} CLIENT;
+
+
+/*
+ * client side rpc interface ops
+ *
+ * Parameter types are:
+ *
+ */
+
+/*
+ * enum clnt_stat
+ * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
+ * 	CLIENT *rh;
+ *	u_long proc;
+ *	xdrproc_t xargs;
+ *	caddr_t argsp;
+ *	xdrproc_t xres;
+ *	caddr_t resp;
+ *	struct timeval timeout;
+ */
+#define	CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs)	\
+	((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+#define	clnt_call(rh, proc, xargs, argsp, xres, resp, secs)	\
+	((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs))
+
+/*
+ * void
+ * CLNT_ABORT(rh);
+ * 	CLIENT *rh;
+ */
+#define	CLNT_ABORT(rh)	((*(rh)->cl_ops->cl_abort)(rh))
+#define	clnt_abort(rh)	((*(rh)->cl_ops->cl_abort)(rh))
+
+/*
+ * struct rpc_err
+ * CLNT_GETERR(rh);
+ * 	CLIENT *rh;
+ */
+#define	CLNT_GETERR(rh,errp)	((*(rh)->cl_ops->cl_geterr)(rh, errp))
+#define	clnt_geterr(rh,errp)	((*(rh)->cl_ops->cl_geterr)(rh, errp))
+
+
+/*
+ * bool_t
+ * CLNT_FREERES(rh, xres, resp);
+ * 	CLIENT *rh;
+ *	xdrproc_t xres;
+ *	caddr_t resp;
+ */
+#define	CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+#define	clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp))
+
+/*
+ * bool_t
+ * CLNT_CONTROL(cl, request, info)
+ *      CLIENT *cl;
+ *      u_int request;
+ *      char *info;
+ */
+#define	CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+#define	clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in))
+
+/*
+ * control operations that apply to both udp and tcp transports
+ */
+#define CLSET_TIMEOUT       1   /* set timeout (timeval) */
+#define CLGET_TIMEOUT       2   /* get timeout (timeval) */
+#define CLGET_SERVER_ADDR   3   /* get server's address (sockaddr) */
+/*
+ * udp only control operations
+ */
+#define CLSET_RETRY_TIMEOUT 4   /* set retry timeout (timeval) */
+#define CLGET_RETRY_TIMEOUT 5   /* get retry timeout (timeval) */
+
+/*
+ * void
+ * CLNT_DESTROY(rh);
+ * 	CLIENT *rh;
+ */
+#define	CLNT_DESTROY(rh)	((*(rh)->cl_ops->cl_destroy)(rh))
+#define	clnt_destroy(rh)	((*(rh)->cl_ops->cl_destroy)(rh))
+
+
+/*
+ * RPCTEST is a test program which is accessable on every rpc
+ * transport/port.  It is used for testing, performance evaluation,
+ * and network administration.
+ */
+
+#define RPCTEST_PROGRAM		((u_long)1)
+#define RPCTEST_VERSION		((u_long)1)
+#define RPCTEST_NULL_PROC	((u_long)2)
+#define RPCTEST_NULL_BATCH_PROC	((u_long)3)
+
+/*
+ * By convention, procedure 0 takes null arguments and returns them
+ */
+
+#define NULLPROC ((u_long)0)
+
+/*
+ * Below are the client handle creation routines for the various
+ * implementations of client side rpc.  They can return NULL if a 
+ * creation failure occurs.
+ */
+
+/*
+ * Memory based rpc (for speed check and testing)
+ * CLIENT *
+ * clntraw_create(prog, vers)
+ *	u_long prog;
+ *	u_long vers;
+ */
+extern CLIENT *clntraw_create();
+
+
+/*
+ * Generic client creation routine. Supported protocols are "udp" and "tcp"
+ */
+extern CLIENT *
+clnt_create(/*host, prog, vers, prot*/); /*
+	char *host; 	-- hostname
+	u_long prog;	-- program number
+	u_long vers;	-- version number
+	char *prot;	-- protocol
+*/
+
+
+
+
+/*
+ * TCP based rpc
+ * CLIENT *
+ * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+ *	struct sockaddr_in *raddr;
+ *	u_long prog;
+ *	u_long version;
+ *	register int *sockp;
+ *	u_int sendsz;
+ *	u_int recvsz;
+ */
+extern CLIENT *clnttcp_create();
+
+/*
+ * UDP based rpc.
+ * CLIENT *
+ * clntudp_create(raddr, program, version, wait, sockp)
+ *	struct sockaddr_in *raddr;
+ *	u_long program;
+ *	u_long version;
+ *	struct timeval wait;
+ *	int *sockp;
+ *
+ * Same as above, but you specify max packet sizes.
+ * CLIENT *
+ * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+ *	struct sockaddr_in *raddr;
+ *	u_long program;
+ *	u_long version;
+ *	struct timeval wait;
+ *	int *sockp;
+ *	u_int sendsz;
+ *	u_int recvsz;
+ */
+extern CLIENT *clntudp_create();
+extern CLIENT *clntudp_bufcreate();
+
+/*
+ * Print why creation failed
+ */
+void clnt_pcreateerror(/* char *msg */);	/* stderr */
+char *clnt_spcreateerror(/* char *msg */);	/* string */
+
+/*
+ * Like clnt_perror(), but is more verbose in its output
+ */ 
+void clnt_perrno(/* enum clnt_stat num */);	/* stderr */
+
+/*
+ * Print an English error message, given the client error code
+ */
+void clnt_perror(/* CLIENT *clnt, char *msg */); 	/* stderr */
+char *clnt_sperror(/* CLIENT *clnt, char *msg */);	/* string */
+
+/* 
+ * If a creation fails, the following allows the user to figure out why.
+ */
+struct rpc_createerr {
+	enum clnt_stat cf_stat;
+	struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */
+};
+
+extern struct rpc_createerr rpc_createerr;
+
+
+
+/*
+ * Copy error message to buffer.
+ */
+char *clnt_sperrno(/* enum clnt_stat num */);	/* string */
+
+
+
+#define UDPMSGSIZE	8800	/* rpc imposed limit on udp msg size */
+#define RPCSMALLMSGSIZE	400	/* a more reasonable packet size */
+
+#endif /*!_CLNT_*/
diff --git a/external/rpc_win32/RPC/NETDB.H b/external/rpc_win32/RPC/NETDB.H
new file mode 100644
index 0000000..ec7b4dc
--- /dev/null
+++ b/external/rpc_win32/RPC/NETDB.H
@@ -0,0 +1,51 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)netdb.h	2.1 88/07/29 3.9 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*	@(#)rpc.h 1.8 87/07/24 SMI	*/
+
+/* Really belongs in <netdb.h> */
+
+struct rpcent {
+      char    *r_name;        /* name of server for this rpc program */
+      char    **r_aliases;    /* alias list */
+      int     r_number;       /* rpc program number */
+};
+
+struct rpcent *getrpcbyname(), *getrpcbynumber(), *getrpcent();
diff --git a/external/rpc_win32/RPC/PMAP_CLN.H b/external/rpc_win32/RPC/PMAP_CLN.H
new file mode 100644
index 0000000..718bc43
--- /dev/null
+++ b/external/rpc_win32/RPC/PMAP_CLN.H
@@ -0,0 +1,76 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)pmap_clnt.h	2.1 88/07/29 4.0 RPCSRC; from 1.11 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * pmap_clnt.h
+ * Supplies C routines to get to portmap services.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * Usage:
+ *	success = pmap_set(program, version, protocol, port);
+ *	success = pmap_unset(program, version);
+ *	port = pmap_getport(address, program, version, protocol);
+ *	head = pmap_getmaps(address);
+ *	clnt_stat = pmap_rmtcall(address, program, version, procedure,
+ *		xdrargs, argsp, xdrres, resp, tout, port_ptr)
+ *		(works for udp only.) 
+ * 	clnt_stat = clnt_broadcast(program, version, procedure,
+ *		xdrargs, argsp,	xdrres, resp, eachresult)
+ *		(like pmap_rmtcall, except the call is broadcasted to all
+ *		locally connected nets.  For each valid response received,
+ *		the procedure eachresult is called.  Its form is:
+ *	done = eachresult(resp, raddr)
+ *		bool_t done;
+ *		caddr_t resp;
+ *		struct sockaddr_in raddr;
+ *		where resp points to the results of the call and raddr is the
+ *		address if the responder to the broadcast.
+ */
+
+extern bool_t		pmap_set();
+extern bool_t		pmap_unset();
+extern struct pmaplist	*pmap_getmaps();
+enum clnt_stat		pmap_rmtcall();
+enum clnt_stat		clnt_broadcast();
+extern u_short		pmap_getport();
diff --git a/external/rpc_win32/RPC/PMAP_PRO.H b/external/rpc_win32/RPC/PMAP_PRO.H
new file mode 100644
index 0000000..0a71429
--- /dev/null
+++ b/external/rpc_win32/RPC/PMAP_PRO.H
@@ -0,0 +1,105 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)pmap_prot.h	2.1 88/07/29 4.0 RPCSRC; from 1.14 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * pmap_prot.h
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The following procedures are supported by the protocol:
+ *
+ * PMAPPROC_NULL() returns ()
+ * 	takes nothing, returns nothing
+ *
+ * PMAPPROC_SET(struct pmap) returns (bool_t)
+ * 	TRUE is success, FALSE is failure.  Registers the tuple
+ *	[prog, vers, prot, port].
+ *
+ * PMAPPROC_UNSET(struct pmap) returns (bool_t)
+ *	TRUE is success, FALSE is failure.  Un-registers pair
+ *	[prog, vers].  prot and port are ignored.
+ *
+ * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
+ *	0 is failure.  Otherwise returns the port number where the pair
+ *	[prog, vers] is registered.  It may lie!
+ *
+ * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
+ *
+ * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
+ * 	RETURNS (port, string<>);
+ * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
+ * 	Calls the procedure on the local machine.  If it is not registered,
+ *	this procedure is quite; ie it does not return error information!!!
+ *	This procedure only is supported on rpc/udp and calls via
+ *	rpc/udp.  This routine only passes null authentication parameters.
+ *	This file has no interface to xdr routines for PMAPPROC_CALLIT.
+ *
+ * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
+ */
+
+#define PMAPPORT		((u_short)111)
+#define PMAPPROG		((u_long)100000)
+#define PMAPVERS		((u_long)2)
+#define PMAPVERS_PROTO		((u_long)2)
+#define PMAPVERS_ORIG		((u_long)1)
+#define PMAPPROC_NULL		((u_long)0)
+#define PMAPPROC_SET		((u_long)1)
+#define PMAPPROC_UNSET		((u_long)2)
+#define PMAPPROC_GETPORT	((u_long)3)
+#define PMAPPROC_DUMP		((u_long)4)
+#define PMAPPROC_CALLIT		((u_long)5)
+
+struct pmap {
+	long unsigned pm_prog;
+	long unsigned pm_vers;
+	long unsigned pm_prot;
+	long unsigned pm_port;
+};
+
+extern bool_t xdr_pmap();
+
+struct pmaplist {
+	struct pmap	pml_map;
+	struct pmaplist *pml_next;
+};
+
+extern bool_t xdr_pmaplist();
diff --git a/external/rpc_win32/RPC/PMAP_RMT.H b/external/rpc_win32/RPC/PMAP_RMT.H
new file mode 100644
index 0000000..cfc82f5
--- /dev/null
+++ b/external/rpc_win32/RPC/PMAP_RMT.H
@@ -0,0 +1,64 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)pmap_rmt.h	2.1 88/07/29 4.0 RPCSRC; from 1.2 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * Structures and XDR routines for parameters to and replies from
+ * the portmapper remote-call-service.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+struct rmtcallargs {
+	u_long prog, vers, proc, arglen;
+	caddr_t args_ptr;
+	xdrproc_t xdr_args;
+};
+
+bool_t xdr_rmtcall_args();
+
+struct rmtcallres {
+	u_long *port_ptr;
+	u_long resultslen;
+	caddr_t results_ptr;
+	xdrproc_t xdr_results;
+};
+
+bool_t xdr_rmtcallres();
diff --git a/external/rpc_win32/RPC/RPC.H b/external/rpc_win32/RPC/RPC.H
new file mode 100644
index 0000000..b1728bd
--- /dev/null
+++ b/external/rpc_win32/RPC/RPC.H
@@ -0,0 +1,108 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)rpc.h	2.3 88/08/10 4.0 RPCSRC; from 1.9 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * rpc.h, Just includes the billions of rpc header files necessary to
+ * do remote procedure calling.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+#ifndef __RPC_HEADER__
+#define __RPC_HEADER__
+
+#ifdef WIN32
+#define FD_SETSIZE	128
+
+#include <stdlib.h>
+#include <winsock.h>
+#include <rpc/types.h>		/* some typedefs */
+#include <process.h>
+
+#define WSAerrno (WSAGetLastError())
+#define gettimeofday(tv,tz) ((tv)->tv_sec = time(0), (tv)->tv_usec = 0)
+
+extern int rpc_nt_init(void);
+extern int rpc_nt_exit(void);
+extern void nt_rpc_report();
+
+#include <rpc/bcopy.h>
+extern int xdr_opaque_auth();
+
+#else
+#include <rpc/types.h>		/* some typedefs */
+#include <netinet/in.h>
+#endif
+
+/* external data representation interfaces */
+#include <rpc/xdr.h>		/* generic (de)serializer */
+
+/* Client side only authentication */
+#include <rpc/auth.h>		/* generic authenticator (client side) */
+
+/* Client side (mostly) remote procedure call */
+#include <rpc/clnt.h>		/* generic rpc stuff */
+
+/* semi-private protocol headers */
+#include <rpc/rpc_msg.h>	/* protocol for rpc messages */
+#ifdef WIN32
+#include <rpc/auth_uni.h>	/* protocol for unix style cred */
+#else
+#include <rpc/auth_unix.h>	/* protocol for unix style cred */
+#endif
+/*
+ *  Uncomment-out the next line if you are building the rpc library with
+ *  DES Authentication (see the README file in the secure_rpc/ directory).
+ */
+/*#include <rpc/auth_des.h>	/* protocol for des style cred */
+
+/* Server side only remote procedure callee */
+#include <rpc/svc.h>		/* service manager and multiplexer */
+#include <rpc/svc_auth.h>	/* service side authenticator */
+
+/*
+ * COMMENT OUT THE NEXT INCLUDE IF RUNNING ON SUN OS OR ON A VERSION
+ * OF UNIX BASED ON NFSSRC.  These systems will already have the structures
+ * defined by <rpc/netdb.h> included in <netdb.h>.
+ */
+/* routines for parsing /etc/rpc */
+#include <rpc/netdb.h>		/* structures and routines to parse /etc/rpc */
+
+#endif /* ndef __RPC_HEADER__ */
diff --git a/external/rpc_win32/RPC/RPC_MSG.H b/external/rpc_win32/RPC/RPC_MSG.H
new file mode 100644
index 0000000..dddd6c6
--- /dev/null
+++ b/external/rpc_win32/RPC/RPC_MSG.H
@@ -0,0 +1,204 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)rpc_msg.h	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)rpc_msg.h 1.7 86/07/16 SMI      */
+
+/*
+ * rpc_msg.h
+ * rpc message definition
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef __RPC_MSG_HEADER__
+#define __RPC_MSG_HEADER__
+
+#define RPC_MSG_VERSION		((u_long) 2)
+#define RPC_SERVICE_PORT	((u_short) 2048)
+
+/*
+ * Bottom up definition of an rpc message.
+ * NOTE: call and reply use the same overall stuct but
+ * different parts of unions within it.
+ */
+
+enum msg_type {
+	CALL=0,
+	REPLY=1
+};
+
+enum reply_stat {
+	MSG_ACCEPTED=0,
+	MSG_DENIED=1
+};
+
+enum accept_stat {
+	SUCCESS=0,
+	PROG_UNAVAIL=1,
+	PROG_MISMATCH=2,
+	PROC_UNAVAIL=3,
+	GARBAGE_ARGS=4,
+	SYSTEM_ERR=5
+};
+
+enum reject_stat {
+	RPC_MISMATCH=0,
+	AUTH_ERROR=1
+};
+
+/*
+ * Reply part of an rpc exchange
+ */
+
+/*
+ * Reply to an rpc request that was accepted by the server.
+ * Note: there could be an error even though the request was
+ * accepted.
+ */
+struct accepted_reply {
+	struct opaque_auth	ar_verf;
+	enum accept_stat	ar_stat;
+	union {
+		struct {
+			u_long	low;
+			u_long	high;
+		} AR_versions;
+		struct {
+			caddr_t	where;
+			xdrproc_t proc;
+		} AR_results;
+		/* and many other null cases */
+	} ru;
+#define	ar_results	ru.AR_results
+#define	ar_vers		ru.AR_versions
+};
+
+/*
+ * Reply to an rpc request that was rejected by the server.
+ */
+struct rejected_reply {
+	enum reject_stat rj_stat;
+	union {
+		struct {
+			u_long low;
+			u_long high;
+		} RJ_versions;
+		enum auth_stat RJ_why;  /* why authentication did not work */
+	} ru;
+#define	rj_vers	ru.RJ_versions
+#define	rj_why	ru.RJ_why
+};
+
+/*
+ * Body of a reply to an rpc request.
+ */
+struct reply_body {
+	enum reply_stat rp_stat;
+	union {
+		struct accepted_reply RP_ar;
+		struct rejected_reply RP_dr;
+	} ru;
+#define	rp_acpt	ru.RP_ar
+#define	rp_rjct	ru.RP_dr
+};
+
+/*
+ * Body of an rpc request call.
+ */
+struct call_body {
+	u_long cb_rpcvers;	/* must be equal to two */
+	u_long cb_prog;
+	u_long cb_vers;
+	u_long cb_proc;
+	struct opaque_auth cb_cred;
+	struct opaque_auth cb_verf; /* protocol specific - provided by client */
+};
+
+/*
+ * The rpc message
+ */
+struct rpc_msg {
+	u_long			rm_xid;
+	enum msg_type		rm_direction;
+	union {
+		struct call_body RM_cmb;
+		struct reply_body RM_rmb;
+	} ru;
+#define	rm_call		ru.RM_cmb
+#define	rm_reply	ru.RM_rmb
+};
+#define	acpted_rply	ru.RM_rmb.ru.RP_ar
+#define	rjcted_rply	ru.RM_rmb.ru.RP_dr
+
+
+/*
+ * XDR routine to handle a rpc message.
+ * xdr_callmsg(xdrs, cmsg)
+ * 	XDR *xdrs;
+ * 	struct rpc_msg *cmsg;
+ */
+extern bool_t	xdr_callmsg();
+
+/*
+ * XDR routine to pre-serialize the static part of a rpc message.
+ * xdr_callhdr(xdrs, cmsg)
+ * 	XDR *xdrs;
+ * 	struct rpc_msg *cmsg;
+ */
+extern bool_t	xdr_callhdr();
+
+/*
+ * XDR routine to handle a rpc reply.
+ * xdr_replymsg(xdrs, rmsg)
+ * 	XDR *xdrs;
+ * 	struct rpc_msg *rmsg;
+ */
+extern bool_t	xdr_replymsg();
+
+/*
+ * Fills in the error part of a reply message.
+ * _seterr_reply(msg, error)
+ * 	struct rpc_msg *msg;
+ * 	struct rpc_err *error;
+ */
+extern void	_seterr_reply();
+
+#endif	/*  __RPC_MSG_HEADER__ */
+
diff --git a/external/rpc_win32/RPC/SVC.H b/external/rpc_win32/RPC/SVC.H
new file mode 100644
index 0000000..0b91861
--- /dev/null
+++ b/external/rpc_win32/RPC/SVC.H
@@ -0,0 +1,291 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)svc.h	2.2 88/07/29 4.0 RPCSRC; from 1.20 88/02/08 SMI */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * svc.h, Server-side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef __SVC_HEADER__
+#define __SVC_HEADER__
+
+/*
+ * This interface must manage two items concerning remote procedure calling:
+ *
+ * 1) An arbitrary number of transport connections upon which rpc requests
+ * are received.  The two most notable transports are TCP and UDP;  they are
+ * created and registered by routines in svc_tcp.c and svc_udp.c, respectively;
+ * they in turn call xprt_register and xprt_unregister.
+ *
+ * 2) An arbitrary number of locally registered services.  Services are
+ * described by the following four data: program number, version number,
+ * "service dispatch" function, a transport handle, and a boolean that
+ * indicates whether or not the exported program should be registered with a
+ * local binder service;  if true the program's number and version and the
+ * port number from the transport handle are registered with the binder.
+ * These data are registered with the rpc svc system via svc_register.
+ *
+ * A service's dispatch function is called whenever an rpc request comes in
+ * on a transport.  The request's program and version numbers must match
+ * those of the registered service.  The dispatch function is passed two
+ * parameters, struct svc_req * and SVCXPRT *, defined below.
+ */
+
+enum xprt_stat {
+	XPRT_DIED,
+	XPRT_MOREREQS,
+	XPRT_IDLE
+};
+
+/*
+ * Server side transport handle
+ */
+typedef struct {
+	int		xp_sock;
+	u_short		xp_port;	 /* associated port number */
+	struct xp_ops {
+	    bool_t	(*xp_recv)();	 /* receive incomming requests */
+	    enum xprt_stat (*xp_stat)(); /* get transport status */
+	    bool_t	(*xp_getargs)(); /* get arguments */
+	    bool_t	(*xp_reply)();	 /* send reply */
+	    bool_t	(*xp_freeargs)();/* free mem allocated for args */
+	    void	(*xp_destroy)(); /* destroy this struct */
+	} *xp_ops;
+	int		xp_addrlen;	 /* length of remote address */
+	struct sockaddr_in xp_raddr;	 /* remote address */
+	struct opaque_auth xp_verf;	 /* raw response verifier */
+	caddr_t		xp_p1;		 /* private */
+	caddr_t		xp_p2;		 /* private */
+} SVCXPRT;
+
+/*
+ *  Approved way of getting address of caller
+ */
+#define svc_getcaller(x) (&(x)->xp_raddr)
+
+/*
+ * Operations defined on an SVCXPRT handle
+ *
+ * SVCXPRT		*xprt;
+ * struct rpc_msg	*msg;
+ * xdrproc_t		 xargs;
+ * caddr_t		 argsp;
+ */
+#define SVC_RECV(xprt, msg)				\
+	(*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+#define svc_recv(xprt, msg)				\
+	(*(xprt)->xp_ops->xp_recv)((xprt), (msg))
+
+#define SVC_STAT(xprt)					\
+	(*(xprt)->xp_ops->xp_stat)(xprt)
+#define svc_stat(xprt)					\
+	(*(xprt)->xp_ops->xp_stat)(xprt)
+
+#define SVC_GETARGS(xprt, xargs, argsp)			\
+	(*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+#define svc_getargs(xprt, xargs, argsp)			\
+	(*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
+
+#define SVC_REPLY(xprt, msg)				\
+	(*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+#define svc_reply(xprt, msg)				\
+	(*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
+
+#define SVC_FREEARGS(xprt, xargs, argsp)		\
+	(*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+#define svc_freeargs(xprt, xargs, argsp)		\
+	(*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
+
+#define SVC_DESTROY(xprt)				\
+	(*(xprt)->xp_ops->xp_destroy)(xprt)
+#define svc_destroy(xprt)				\
+	(*(xprt)->xp_ops->xp_destroy)(xprt)
+
+
+/*
+ * Service request
+ */
+struct svc_req {
+	u_long		rq_prog;	/* service program number */
+	u_long		rq_vers;	/* service protocol version */
+	u_long		rq_proc;	/* the desired procedure */
+	struct opaque_auth rq_cred;	/* raw creds from the wire */
+	caddr_t		rq_clntcred;	/* read only cooked cred */
+	SVCXPRT	*rq_xprt;		/* associated transport */
+};
+
+
+/*
+ * Service registration
+ *
+ * svc_register(xprt, prog, vers, dispatch, protocol)
+ *	SVCXPRT *xprt;
+ *	u_long prog;
+ *	u_long vers;
+ *	void (*dispatch)();
+ *	int protocol;  /* like TCP or UDP, zero means do not register 
+ */
+extern bool_t	svc_register();
+
+/*
+ * Service un-registration
+ *
+ * svc_unregister(prog, vers)
+ *	u_long prog;
+ *	u_long vers;
+ */
+extern void	svc_unregister();
+
+/*
+ * Transport registration.
+ *
+ * xprt_register(xprt)
+ *	SVCXPRT *xprt;
+ */
+extern void	xprt_register();
+
+/*
+ * Transport un-register
+ *
+ * xprt_unregister(xprt)
+ *	SVCXPRT *xprt;
+ */
+extern void	xprt_unregister();
+
+
+
+
+/*
+ * When the service routine is called, it must first check to see if it
+ * knows about the procedure;  if not, it should call svcerr_noproc
+ * and return.  If so, it should deserialize its arguments via 
+ * SVC_GETARGS (defined above).  If the deserialization does not work,
+ * svcerr_decode should be called followed by a return.  Successful
+ * decoding of the arguments should be followed the execution of the
+ * procedure's code and a call to svc_sendreply.
+ *
+ * Also, if the service refuses to execute the procedure due to too-
+ * weak authentication parameters, svcerr_weakauth should be called.
+ * Note: do not confuse access-control failure with weak authentication!
+ *
+ * NB: In pure implementations of rpc, the caller always waits for a reply
+ * msg.  This message is sent when svc_sendreply is called.  
+ * Therefore pure service implementations should always call
+ * svc_sendreply even if the function logically returns void;  use
+ * xdr.h - xdr_void for the xdr routine.  HOWEVER, tcp based rpc allows
+ * for the abuse of pure rpc via batched calling or pipelining.  In the
+ * case of a batched call, svc_sendreply should NOT be called since
+ * this would send a return message, which is what batching tries to avoid.
+ * It is the service/protocol writer's responsibility to know which calls are
+ * batched and which are not.  Warning: responding to batch calls may
+ * deadlock the caller and server processes!
+ */
+
+extern bool_t	svc_sendreply();
+extern void	svcerr_decode();
+extern void	svcerr_weakauth();
+extern void	svcerr_noproc();
+extern void	svcerr_progvers();
+extern void	svcerr_auth();
+extern void	svcerr_noprog();
+extern void	svcerr_systemerr();
+    
+/*
+ * Lowest level dispatching -OR- who owns this process anyway.
+ * Somebody has to wait for incoming requests and then call the correct
+ * service routine.  The routine svc_run does infinite waiting; i.e.,
+ * svc_run never returns.
+ * Since another (co-existant) package may wish to selectively wait for
+ * incoming calls or other events outside of the rpc architecture, the
+ * routine svc_getreq is provided.  It must be passed readfds, the
+ * "in-place" results of a select system call (see select, section 2).
+ */
+
+/*
+ * Global keeper of rpc service descriptors in use
+ * dynamic; must be inspected before each call to select 
+ */
+#ifdef FD_SETSIZE
+extern fd_set svc_fdset;
+#define svc_fds svc_fdset.fds_bits[0]	/* compatibility */
+#else
+extern int svc_fds;
+#endif /* def FD_SETSIZE */
+
+/*
+ * a small program implemented by the svc_rpc implementation itself;
+ * also see clnt.h for protocol numbers.
+ */
+extern void rpctest_service();
+
+extern void	svc_getreq();
+extern void	svc_getreqset();	/* takes fdset instead of int */
+extern void	svc_run(); 	 /* never returns */
+
+/*
+ * Socket to use on svcxxx_create call to get default socket
+ */
+#define	RPC_ANYSOCK	-1
+
+/*
+ * These are the existing service side transport implementations
+ */
+
+/*
+ * Memory based rpc for testing and timing.
+ */
+extern SVCXPRT *svcraw_create();
+
+/*
+ * Udp based rpc.
+ */
+extern SVCXPRT *svcudp_create();
+extern SVCXPRT *svcudp_bufcreate();
+
+/*
+ * Tcp based rpc.
+ */
+extern SVCXPRT *svctcp_create();
+
+
+
+#endif /* __SVC_HEADER__ */
diff --git a/external/rpc_win32/RPC/SVC_AUTH.H b/external/rpc_win32/RPC/SVC_AUTH.H
new file mode 100644
index 0000000..94f044f
--- /dev/null
+++ b/external/rpc_win32/RPC/SVC_AUTH.H
@@ -0,0 +1,53 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)svc_auth.h	2.1 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)svc_auth.h 1.6 86/07/16 SMI      */
+
+/*
+ * svc_auth.h, Service side of rpc authentication.
+ * 
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+
+/*
+ * Server side authenticator
+ */
+extern enum auth_stat _authenticate();
diff --git a/external/rpc_win32/RPC/TYPES.H b/external/rpc_win32/RPC/TYPES.H
new file mode 100644
index 0000000..699be58
--- /dev/null
+++ b/external/rpc_win32/RPC/TYPES.H
@@ -0,0 +1,87 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)types.h	2.3 88/08/15 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)types.h 1.18 87/07/24 SMI      */
+
+/*
+ * Rpc additions to <sys/types.h>
+ */
+#ifndef __TYPES_RPC_HEADER__
+#define __TYPES_RPC_HEADER__
+
+#define	bool_t	int
+#define	enum_t	int
+#ifndef FALSE
+#define	FALSE	(0)
+#endif
+#ifndef TRUE
+#define	TRUE	(1)
+#endif
+#define __dontcare__	-1
+#ifndef NULL
+#	define NULL 0
+#endif
+
+#ifndef WIN32
+extern char *malloc();
+#endif
+#define mem_alloc	malloc
+#define mem_free(ptr, bsize)	free(ptr)
+
+#ifndef makedev /* ie, we haven't already included it */
+#include <sys/types.h>
+#endif
+#ifndef WIN32
+#include <sys/time.h>
+#endif
+
+#ifndef INADDR_LOOPBACK
+#define       INADDR_LOOPBACK         (u_long)0x7F000001
+#endif
+#ifndef MAXHOSTNAMELEN
+#define        MAXHOSTNAMELEN  64
+#endif
+
+typedef char *caddr_t;
+typedef unsigned int u_int;
+typedef unsigned long u_long;
+typedef unsigned short u_short;
+
+#endif /* ndef __TYPES_RPC_HEADER__ */
diff --git a/external/rpc_win32/RPC/XDR.H b/external/rpc_win32/RPC/XDR.H
new file mode 100644
index 0000000..6f02ca0
--- /dev/null
+++ b/external/rpc_win32/RPC/XDR.H
@@ -0,0 +1,281 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/* @(#)xdr.h	2.2 88/07/29 4.0 RPCSRC */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+/*      @(#)xdr.h 1.19 87/04/22 SMI      */
+
+/*
+ * xdr.h, External Data Representation Serialization Routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef __XDR_HEADER__
+#define __XDR_HEADER__
+
+/*
+ * XDR provides a conventional way for converting between C data
+ * types and an external bit-string representation.  Library supplied
+ * routines provide for the conversion on built-in C data types.  These
+ * routines and utility routines defined here are used to help implement
+ * a type encode/decode routine for each user-defined type.
+ *
+ * Each data type provides a single procedure which takes two arguments:
+ *
+ *	bool_t
+ *	xdrproc(xdrs, argresp)
+ *		XDR *xdrs;
+ *		<type> *argresp;
+ *
+ * xdrs is an instance of a XDR handle, to which or from which the data
+ * type is to be converted.  argresp is a pointer to the structure to be
+ * converted.  The XDR handle contains an operation field which indicates
+ * which of the operations (ENCODE, DECODE * or FREE) is to be performed.
+ *
+ * XDR_DECODE may allocate space if the pointer argresp is null.  This
+ * data can be freed with the XDR_FREE operation.
+ *
+ * We write only one procedure per data type to make it easy
+ * to keep the encode and decode procedures for a data type consistent.
+ * In many cases the same code performs all operations on a user defined type,
+ * because all the hard work is done in the component type routines.
+ * decode as a series of calls on the nested data types.
+ */
+
+/*
+ * Xdr operations.  XDR_ENCODE causes the type to be encoded into the
+ * stream.  XDR_DECODE causes the type to be extracted from the stream.
+ * XDR_FREE can be used to release the space allocated by an XDR_DECODE
+ * request.
+ */
+enum xdr_op {
+	XDR_ENCODE=0,
+	XDR_DECODE=1,
+	XDR_FREE=2
+};
+
+/*
+ * This is the number of bytes per unit of external data.
+ */
+#define BYTES_PER_XDR_UNIT	(4)
+#define RNDUP(x)  ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \
+		    * BYTES_PER_XDR_UNIT)
+
+/*
+ * A xdrproc_t exists for each data type which is to be encoded or decoded.
+ *
+ * The second argument to the xdrproc_t is a pointer to an opaque pointer.
+ * The opaque pointer generally points to a structure of the data type
+ * to be decoded.  If this pointer is 0, then the type routines should
+ * allocate dynamic storage of the appropriate size and return it.
+ * bool_t	(*xdrproc_t)(XDR *, caddr_t *);
+ */
+typedef	bool_t (*xdrproc_t)();
+
+/*
+ * The XDR handle.
+ * Contains operation which is being applied to the stream,
+ * an operations vector for the paticular implementation (e.g. see xdr_mem.c),
+ * and two private fields for the use of the particular impelementation.
+ */
+typedef struct {
+	enum xdr_op	x_op;		/* operation; fast additional param */
+	struct xdr_ops {
+		bool_t	(*x_getlong)();	/* get a long from underlying stream */
+		bool_t	(*x_putlong)();	/* put a long to " */
+		bool_t	(*x_getbytes)();/* get some bytes from " */
+		bool_t	(*x_putbytes)();/* put some bytes to " */
+		u_int	(*x_getpostn)();/* returns bytes off from beginning */
+		bool_t  (*x_setpostn)();/* lets you reposition the stream */
+		long *	(*x_inline)();	/* buf quick ptr to buffered data */
+		void	(*x_destroy)();	/* free privates of this xdr_stream */
+	} *x_ops;
+	caddr_t 	x_public;	/* users' data */
+	caddr_t		x_private;	/* pointer to private data */
+	caddr_t 	x_base;		/* private used for position info */
+	int		x_handy;	/* extra private word */
+} XDR;
+
+/*
+ * Operations defined on a XDR handle
+ *
+ * XDR		*xdrs;
+ * long		*longp;
+ * caddr_t	 addr;
+ * u_int	 len;
+ * u_int	 pos;
+ */
+#define XDR_GETLONG(xdrs, longp)			\
+	(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+#define xdr_getlong(xdrs, longp)			\
+	(*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+
+#define XDR_PUTLONG(xdrs, longp)			\
+	(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+#define xdr_putlong(xdrs, longp)			\
+	(*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+
+#define XDR_GETBYTES(xdrs, addr, len)			\
+	(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+#define xdr_getbytes(xdrs, addr, len)			\
+	(*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+
+#define XDR_PUTBYTES(xdrs, addr, len)			\
+	(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+#define xdr_putbytes(xdrs, addr, len)			\
+	(*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+
+#define XDR_GETPOS(xdrs)				\
+	(*(xdrs)->x_ops->x_getpostn)(xdrs)
+#define xdr_getpos(xdrs)				\
+	(*(xdrs)->x_ops->x_getpostn)(xdrs)
+
+#define XDR_SETPOS(xdrs, pos)				\
+	(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+#define xdr_setpos(xdrs, pos)				\
+	(*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+
+#define	XDR_INLINE(xdrs, len)				\
+	(*(xdrs)->x_ops->x_inline)(xdrs, len)
+#define	xdr_inline(xdrs, len)				\
+	(*(xdrs)->x_ops->x_inline)(xdrs, len)
+
+#define	XDR_DESTROY(xdrs)				\
+	if ((xdrs)->x_ops->x_destroy) 			\
+		(*(xdrs)->x_ops->x_destroy)(xdrs)
+#define	xdr_destroy(xdrs)				\
+	if ((xdrs)->x_ops->x_destroy) 			\
+		(*(xdrs)->x_ops->x_destroy)(xdrs)
+
+/*
+ * Support struct for discriminated unions.
+ * You create an array of xdrdiscrim structures, terminated with
+ * a entry with a null procedure pointer.  The xdr_union routine gets
+ * the discriminant value and then searches the array of structures
+ * for a matching value.  If a match is found the associated xdr routine
+ * is called to handle that part of the union.  If there is
+ * no match, then a default routine may be called.
+ * If there is no match and no default routine it is an error.
+ */
+#define NULL_xdrproc_t ((xdrproc_t)0)
+struct xdr_discrim {
+	int	value;
+	xdrproc_t proc;
+};
+
+/*
+ * In-line routines for fast encode/decode of primitve data types.
+ * Caveat emptor: these use single memory cycles to get the
+ * data from the underlying buffer, and will fail to operate
+ * properly if the data is not aligned.  The standard way to use these
+ * is to say:
+ *	if ((buf = XDR_INLINE(xdrs, count)) == NULL)
+ *		return (FALSE);
+ *	<<< macro calls >>>
+ * where ``count'' is the number of bytes of data occupied
+ * by the primitive data types.
+ *
+ * N.B. and frozen for all time: each data type here uses 4 bytes
+ * of external representation.
+ */
+#define IXDR_GET_LONG(buf)		((long)ntohl((u_long)*(buf)++))
+#define IXDR_PUT_LONG(buf, v)		(*(buf)++ = (long)htonl((u_long)v))
+
+#define IXDR_GET_BOOL(buf)		((bool_t)IXDR_GET_LONG(buf))
+#define IXDR_GET_ENUM(buf, t)		((t)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_LONG(buf)		((u_long)IXDR_GET_LONG(buf))
+#define IXDR_GET_SHORT(buf)		((short)IXDR_GET_LONG(buf))
+#define IXDR_GET_U_SHORT(buf)		((u_short)IXDR_GET_LONG(buf))
+
+#define IXDR_PUT_BOOL(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_ENUM(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_U_LONG(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_SHORT(buf, v)		IXDR_PUT_LONG((buf), ((long)(v)))
+#define IXDR_PUT_U_SHORT(buf, v)	IXDR_PUT_LONG((buf), ((long)(v)))
+
+/*
+ * These are the "generic" xdr routines.
+ */
+extern bool_t	xdr_void();
+extern bool_t	xdr_int();
+extern bool_t	xdr_u_int();
+extern bool_t	xdr_long();
+extern bool_t	xdr_u_long();
+extern bool_t	xdr_short();
+extern bool_t	xdr_u_short();
+extern bool_t	xdr_bool();
+extern bool_t	xdr_enum();
+extern bool_t	xdr_array();
+extern bool_t	xdr_bytes();
+extern bool_t	xdr_opaque();
+extern bool_t	xdr_string();
+extern bool_t	xdr_union();
+extern bool_t	xdr_char();
+extern bool_t	xdr_u_char();
+extern bool_t	xdr_vector();
+extern bool_t	xdr_float();
+extern bool_t	xdr_double();
+extern bool_t	xdr_reference();
+extern bool_t	xdr_pointer();
+extern bool_t	xdr_wrapstring();
+
+/*
+ * Common opaque bytes objects used by many rpc protocols;
+ * declared here due to commonality.
+ */
+#define MAX_NETOBJ_SZ 1024 
+struct netobj {
+	u_int	n_len;
+	char	*n_bytes;
+};
+typedef struct netobj netobj;
+extern bool_t   xdr_netobj();
+
+/*
+ * These are the public routines for the various implementations of
+ * xdr streams.
+ */
+extern void   xdrmem_create();		/* XDR using memory buffers */
+extern void   xdrstdio_create();	/* XDR using stdio library */
+extern void   xdrrec_create();		/* XDR pseudo records for tcp */
+extern bool_t xdrrec_endofrecord();	/* make end of xdr record */
+extern bool_t xdrrec_skiprecord();	/* move to beginning of next record */
+extern bool_t xdrrec_eof();		/* true if no more input */
+
+#endif /* __XDR_HEADER__ */
diff --git a/external/rpc_win32/RPCGEN/makefile b/external/rpc_win32/RPCGEN/makefile
new file mode 100644
index 0000000..3c887d9
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/makefile
@@ -0,0 +1,48 @@
+#
+#  Zlib compression library makefile
+#
+# Copyright (C) 1996 Logiciels et Applications Scientifiques (L.A.S.) Inc
+# Permission to use, copy, modify and distribute this software and
+# its documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies, that
+# both the copyright notice and this permission notice appear in
+# supporting documentation, and that the name of L.A.S. Inc not be used 
+# in advertising or publicity pertaining to distribution of the software 
+# without specific, written prior permission. L.A.S. Inc. makes no
+# representations about the suitability of this software for any purpose.
+# It is provided "as is" without express or implied warranty.
+#
+
+#
+# The names of the targets to build
+#
+TOBEGEN		= rpcgen
+TARGETGEN	= $(PROGGEN)
+
+#
+# Source files
+#
+SOURCES = rpc_main.c rpc_hout.c rpc_cout.c rpc_parse.c rpc_scan.c \
+	rpc_util.c rpc_svcout.c rpc_clntout.c rpc_tblout.c rpc_sample.c
+
+#
+# Compilation flags
+#
+INCLUDES = $(CURRENT_INCLUDE) $(OGDI_INCLUDE) $(PROJ_INCLUDE)\
+	   $(ZLIB_INCLUDE) $(GENERAL_INCLUDE) $(TCLTK_INCLUDE)
+CFLAGS 	= $(INCLUDES) $(COMMON_CFLAGS) $(FLAGS_X86DEF)
+LINK_LIBS= $(WIN_LINKLIB) $(RPC_LINKLIB)
+
+#
+# Include the common configuration
+#
+include $(TOPDIR)/config/common.mak
+
+#
+# Primary target
+#
+all: MKOBJECTDIR
+	@echo "making $(TARGETGEN)"
+	$(MAKE) --directory $(OBJDIR) -f ../makefile PASS='depend' $(TARGETGEN)
+
+clean: default-clean
diff --git a/external/rpc_win32/RPCGEN/proto.h b/external/rpc_win32/RPCGEN/proto.h
new file mode 100644
index 0000000..ed010f8
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/proto.h
@@ -0,0 +1,53 @@
+/****** rpc_clntout.c ******/
+
+void write_stubs(void);
+void printarglist(proc_list *proc, 
+		  const char *addargname, const char *addargtype);
+
+/****** rpc_cout.c ******/
+
+void emit(definition *def);
+void emit_inline(declaration *decl, int flag);
+void emit_single_in_line(declaration *decl, int flag, relation rel);
+
+/****** rpc_hout.c ******/
+
+void print_datadef(definition *def);
+void print_funcdef(definition *def);
+void pxdrfuncdecl(const char *name, int pointerp);
+void pprocdef(proc_list *proc, version_list *vp, 
+	      const char *addargtype, int server_p, int mode);
+void pdeclaration(const char *name, declaration *dec, int tab, 
+		  const char *separator);
+
+/****** rpc_main.c ******/
+	/* nil */
+
+/****** rpc_parse.c ******/
+definition *get_definition(void);
+
+/****** rpc_sample.c ******/
+void write_sample_svc(definition *def);
+int write_sample_clnt(definition *def);
+void add_sample_msg(void);
+void write_sample_clnt_main(void);
+
+/****** rpc_scan.c ******/
+   /* see rpc_scan.h */
+
+/****** rpc_svcout.c ******/
+int nullproc(proc_list *proc);
+void write_svc_aux(int nomain);
+void write_msg_out(void);
+
+/****** rpc_tblout.c ******/
+void write_tables(void);
+
+/****** rpc_util.c ******/
+void reinitialize(void);
+int streq(const char *a, const char *b);
+void error(const char *msg);
+void crash(void);
+void tabify(FILE *f, int tab);
+char *make_argname(const char *pname, const char *vname);
+void add_type(int len, const char *type);
diff --git a/external/rpc_win32/RPCGEN/rpc_clntout.c b/external/rpc_win32/RPCGEN/rpc_clntout.c
new file mode 100644
index 0000000..37c52e2
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_clntout.c
@@ -0,0 +1,223 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * From: @(#)rpc_clntout.c 1.11 89/02/22 (C) 1987 SMI
+ */
+char clntout_rcsid[] =
+  "$Id: rpc_clntout.c,v 1.1.1.1 2000/10/29 20:55:02 warmerda Exp $";
+
+/*
+ * rpc_clntout.c, Client-stub outputter for the RPC protocol compiler
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <rpc/types.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+#define DEFAULT_TIMEOUT 25	/* in seconds */
+static char RESULT[] = "clnt_res";
+
+static void write_program(definition *def);
+static void printbody(proc_list *proc);
+static const char *ampr(const char *type);
+static void printbody(proc_list *proc);
+
+
+void
+write_stubs(void)
+{
+	list *l;
+	definition *def;
+
+	f_print(fout,
+		"\n/* Default timeout can be changed using clnt_control() */\n");
+	f_print(fout, "static struct timeval TIMEOUT = { %d, 0 };\n",
+		DEFAULT_TIMEOUT);
+	for (l = defined; l != NULL; l = l->next) {
+		def = (definition *) l->val;
+		if (def->def_kind == DEF_PROGRAM) {
+			write_program(def);
+		}
+	}
+}
+
+static void
+write_program(definition *def)
+{
+	version_list *vp;
+	proc_list *proc;
+
+	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+		for (proc = vp->procs; proc != NULL; proc = proc->next) {
+			f_print(fout, "\n");
+			ptype(proc->res_prefix, proc->res_type, 1);
+			f_print(fout, "*\n");
+			pvname(proc->proc_name, vp->vers_num);
+			printarglist( proc, "clnt", "CLIENT *" );
+			f_print(fout, "{\n");
+			printbody(proc);
+			f_print(fout, "}\n");
+		}
+	}
+}
+
+/* Writes out declarations of procedure's argument list.
+   In either ANSI C style, in one of old rpcgen style (pass by reference),
+   or new rpcgen style (multiple arguments, pass by value);
+   */
+
+/* sample addargname = "clnt"; sample addargtype = "CLIENT * " */
+
+void printarglist(proc_list *proc,
+		  const char *addargname, const char *addargtype)
+{
+
+  decl_list *l;
+
+  if (!newstyle) {    /* old style: always pass argument by reference */
+    if (Cflag) {      /* C++ style heading */
+      f_print(fout, "(");
+      ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
+      f_print(fout, "*argp, %s%s)\n", addargtype, addargname );
+    }
+    else {
+      f_print(fout, "(argp, %s)\n", addargname);
+      f_print(fout, "\t");
+      ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
+      f_print(fout, "*argp;\n");
+    }
+  } else if (streq( proc->args.decls->decl.type, "void")) {
+    /* newstyle, 0 argument */
+    if( Cflag )
+      f_print(fout, "(%s%s)\n", addargtype, addargname );
+    else
+      f_print(fout, "(%s)\n", addargname);
+  } else {
+    /* new style, 1 or multiple arguments */
+    if( !Cflag ) {
+      f_print(fout, "(");
+      for (l = proc->args.decls;  l != NULL; l = l->next)
+	f_print(fout, "%s, ", l->decl.name);
+      f_print(fout, "%s)\n", addargname );
+      for (l = proc->args.decls; l != NULL; l = l->next) {
+	pdeclaration(proc->args.argname, &l->decl, 1, ";\n" );
+      }
+    } else {  /* C++ style header */
+      f_print(fout, "(");
+      for(l = proc->args.decls; l != NULL; l = l->next) {
+	pdeclaration(proc->args.argname, &l->decl, 0, ", " );
+      }
+      f_print(fout, " %s%s)\n", addargtype, addargname );
+    }
+  }
+
+  if( !Cflag )
+    f_print(fout, "\t%s%s;\n", addargtype, addargname );
+}
+
+
+
+static
+const char *
+ampr(const char *type)
+{
+	if (isvectordef(type, REL_ALIAS)) {
+		return ("");
+	} else {
+		return ("&");
+	}
+}
+
+static void
+printbody(proc_list *proc)
+{
+  decl_list *l;
+  bool_t args2 = (proc->arg_num > 1);
+/*  int i; */
+
+  /* For new style with multiple arguments, need a structure in which
+     to stuff the arguments. */
+	if ( newstyle && args2) {
+		f_print(fout, "\t%s", proc->args.argname);
+		f_print(fout, " arg;\n");
+	}
+	f_print(fout, "\tstatic ");
+	if (streq(proc->res_type, "void")) {
+		f_print(fout, "char ");
+	} else {
+		ptype(proc->res_prefix, proc->res_type, 0);
+	}
+	f_print(fout, "%s;\n",RESULT);
+	f_print(fout, "\n");
+        f_print(fout, "\tmemset((char *)%s%s, 0, sizeof(%s));\n",
+		ampr(proc->res_type ), RESULT, RESULT);
+	if (newstyle && !args2 && (streq( proc->args.decls->decl.type, "void"))) {
+	  /* newstyle, 0 arguments */
+	  f_print(fout,
+		    "\tif (clnt_call(clnt, %s, xdr_void", proc->proc_name);
+	  f_print(fout,
+ 		  ", NULL, xdr_%s, %s,%s, TIMEOUT) != RPC_SUCCESS) {\n",
+ 		  stringfix(proc->res_type), ampr(proc->res_type), RESULT);
+
+	} else if ( newstyle && args2) {
+	  /* newstyle, multiple arguments:  stuff arguments into structure */
+	  for (l = proc->args.decls;  l != NULL; l = l->next) {
+	    f_print(fout, "\targ.%s = %s;\n",
+		    l->decl.name, l->decl.name);
+	  }
+	  f_print(fout,
+		  "\tif (clnt_call(clnt, %s, xdr_%s", proc->proc_name,
+		  proc->args.argname);
+	  f_print(fout,
+ 		      ", &arg, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS) {\n",
+ 		  stringfix(proc->res_type), ampr(proc->res_type), RESULT);
+	} else {  /* single argument, new or old style */
+	      f_print(fout,
+ 		      "\tif (clnt_call(clnt, %s, xdr_%s, %s%s, xdr_%s, %s%s, TIMEOUT) != RPC_SUCCESS) {\n",
+		      proc->proc_name,
+		      stringfix(proc->args.decls->decl.type),
+		      (newstyle ? "&" : ""),
+		      (newstyle ? proc->args.decls->decl.name : "argp"),
+		      stringfix(proc->res_type), ampr(proc->res_type),RESULT);
+	    }
+	f_print(fout, "\t\treturn (NULL);\n");
+	f_print(fout, "\t}\n");
+	if (streq(proc->res_type, "void")) {
+		f_print(fout, "\treturn ((void *)%s%s);\n",
+			ampr(proc->res_type),RESULT);
+	} else {
+		f_print(fout, "\treturn (%s%s);\n", ampr(proc->res_type),RESULT);
+	}
+}
diff --git a/external/rpc_win32/RPCGEN/rpc_cout.c b/external/rpc_win32/RPCGEN/rpc_cout.c
new file mode 100644
index 0000000..8ce794f
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_cout.c
@@ -0,0 +1,716 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * From: @(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI
+ */
+char cout_rcsid[] =
+  "$Id: rpc_cout.c,v 1.1.1.1 2000/10/29 20:55:03 warmerda Exp $";
+
+/*
+ * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
+ */
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+static void emit_enum(definition *def);
+static void emit_program(definition *def);
+static void emit_union(definition *def);
+static void emit_struct(definition *def);
+static void emit_typedef(definition *def);
+static int findtype(const definition *def, const char *type);
+static int undefined(const char *type);
+static void print_generic_header(const char *procname, int pointerp);
+static void print_ifopen(int indent, const char *name);
+static void print_ifarg(const char *arg);
+static void print_ifsizeof(const char *prefix, const char *type);
+static void print_ifclose(int indent);
+static void print_ifstat(int indent, const char *prefix, const char *type,
+			 relation rel, const char *amax,
+			 const char *objname, const char *name);
+static void print_stat(int indent, declaration *dec);
+static void print_header(definition *def);
+static void print_trailer(void);
+static char *upcase(const char *str);
+
+/*
+ * Emit the C-routine for the given definition
+ */
+void
+emit(definition *def)
+{
+	if (def->def_kind == DEF_CONST) {
+		return;
+	}
+	if (def->def_kind == DEF_PROGRAM) {
+		emit_program(def);
+		return;
+	}
+	if(def->def_kind == DEF_TYPEDEF)
+	  {
+	  /* now we need to handle declarations like
+   struct typedef foo foo;
+   since we don't want this to be expanded into 2 calls to xdr_foo */
+
+ 	if(strcmp(def->def.ty.old_type,def->def_name)==0)
+	  return;
+      };
+
+	print_header(def);
+	switch (def->def_kind) {
+	case DEF_UNION:
+		emit_union(def);
+		break;
+	case DEF_ENUM:
+		emit_enum(def);
+		break;
+	case DEF_STRUCT:
+		emit_struct(def);
+		break;
+	case DEF_TYPEDEF:
+		emit_typedef(def);
+		break;
+	default:
+	  /* can't happen */
+		;
+	}
+	print_trailer();
+}
+
+static int
+findtype(const definition *def, const char *type)
+{
+
+	if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
+		return (0);
+	} else {
+		return (streq(def->def_name, type));
+	}
+}
+
+static int
+undefined(const char *type)
+{
+	definition *def;
+
+	def = (definition *) FINDVAL(defined, type, findtype);
+
+
+	return (def == NULL);
+}
+
+
+static void
+print_generic_header(const char *procname, int pointerp)
+{
+	f_print(fout, "\n");
+	f_print(fout, "bool_t\n");
+	if (Cflag) {
+	   f_print(fout, "xdr_%s(", procname);
+	   f_print(fout, "XDR *xdrs, ");
+	   f_print(fout, "%s ", procname);
+	   if( pointerp )
+	     f_print(fout, "*");
+	   f_print(fout, "objp)\n{\n\n");
+	} else {
+	  f_print(fout, "xdr_%s(xdrs, objp)\n", procname);
+	  f_print(fout, "\tXDR *xdrs;\n");
+	  f_print(fout, "\t%s ", procname);
+	  if( pointerp )
+	    f_print(fout, "*");
+	  f_print(fout, "objp;\n{\n\n");
+	}
+}
+
+static void
+print_header(definition *def)
+{
+
+/*
+  decl_list *dl;
+  bas_type *ptr;
+  int i;
+ */
+
+  print_generic_header( def->def_name,
+		       def->def_kind != DEF_TYPEDEF ||
+		       !isvectordef(def->def.ty.old_type, def->def.ty.rel));
+
+  /* Now add Inline support */
+
+
+  if(inlineflag == 0 )
+    return;
+  /*May cause lint to complain. but  ... */
+f_print(fout, "\t register long *buf;\n\n");
+
+}
+
+static void
+print_prog_header(proc_list *plist)
+{
+  print_generic_header( plist->args.argname, 1 );
+}
+
+static void
+print_trailer(void)
+{
+	f_print(fout, "\treturn (TRUE);\n");
+	f_print(fout, "}\n");
+}
+
+
+static void
+print_ifopen(int indent, const char *name)
+{
+	tabify(fout, indent);
+	f_print(fout, " if (!xdr_%s(xdrs", name);
+}
+
+static void
+print_ifarg(const char *arg)
+{
+	f_print(fout, ", %s", arg);
+}
+
+static void
+print_ifsizeof(const char *prefix, const char *type)
+{
+	if (streq(type, "bool")) {
+		f_print(fout, ", sizeof(bool_t), (xdrproc_t)xdr_bool");
+	}
+	else {
+		f_print(fout, ", sizeof(");
+		if (undefined(type) && prefix) {
+			f_print(fout, "%s ", prefix);
+		}
+		f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type);
+	}
+}
+
+static void
+print_ifclose(int indent)
+{
+	f_print(fout, ")) {\n");
+	tabify(fout, indent);
+	f_print(fout, "\t return (FALSE);\n");
+	tabify(fout, indent);
+	f_print(fout, " }\n");
+}
+
+static void
+print_ifstat(int indent, const char *prefix, const char *type, relation rel,
+	     const char *amax, const char *objname, const char *name)
+{
+	const char *alt = NULL;
+
+	switch (rel) {
+	case REL_POINTER:
+		print_ifopen(indent, "pointer");
+		print_ifarg("(char **)");
+		f_print(fout, "%s", objname);
+		print_ifsizeof(prefix, type);
+		break;
+	case REL_VECTOR:
+		if (streq(type, "string")) {
+			alt = "string";
+		} else if (streq(type, "opaque")) {
+			alt = "opaque";
+		}
+		if (alt) {
+			print_ifopen(indent, alt);
+			print_ifarg(objname);
+		} else {
+			print_ifopen(indent, "vector");
+			print_ifarg("(char *)");
+			f_print(fout, "%s", objname);
+		}
+		print_ifarg(amax);
+		if (!alt) {
+			print_ifsizeof(prefix, type);
+		}
+		break;
+	case REL_ARRAY:
+		if (streq(type, "string")) {
+			alt = "string";
+		} else if (streq(type, "opaque")) {
+			alt = "bytes";
+		}
+		if (streq(type, "string")) {
+			print_ifopen(indent, alt);
+			print_ifarg(objname);
+		} else {
+			if (alt) {
+				print_ifopen(indent, alt);
+			} else {
+				print_ifopen(indent, "array");
+			}
+			print_ifarg("(char **)");
+			if (*objname == '&') {
+				f_print(fout, "%s.%s_val, (u_int *)%s.%s_len",
+					objname, name, objname, name);
+			} else {
+				f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len",
+					objname, name, objname, name);
+			}
+		}
+		print_ifarg(amax);
+		if (!alt) {
+			print_ifsizeof(prefix, type);
+		}
+		break;
+	case REL_ALIAS:
+		print_ifopen(indent, type);
+		print_ifarg(objname);
+		break;
+	}
+	print_ifclose(indent);
+}
+
+static void
+emit_enum(definition *def)
+{
+	(void)def;
+
+	print_ifopen(1, "enum");
+	print_ifarg("(enum_t *)objp");
+	print_ifclose(1);
+}
+
+static void
+emit_program(definition *def)
+{
+	decl_list *dl;
+	version_list *vlist;
+	proc_list *plist;
+
+	for (vlist = def->def.pr.versions; vlist != NULL;vlist = vlist->next)
+	  for(plist = vlist->procs; plist != NULL; plist = plist->next) {
+		  if (!newstyle || plist->arg_num < 2)
+		    continue; /* old style, or single argument */
+		  print_prog_header(plist);
+		  for (dl = plist->args.decls; dl != NULL;
+		       dl = dl->next)
+			  print_stat(1,&dl->decl);
+		  print_trailer();
+	  }
+}
+
+static void
+emit_union(definition *def)
+{
+  declaration *dflt;
+  case_list *cl;
+  declaration *cs;
+  char *object;
+  const char *vecformat = "objp->%s_u.%s";
+  const char *format = "&objp->%s_u.%s";
+
+  print_stat(1,&def->def.un.enum_decl);
+  f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
+  for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
+
+    f_print(fout, "\tcase %s:\n", cl->case_name);
+    if(cl->contflag == 1)	/* a continued case statement */
+      continue;
+    cs = &cl->case_decl;
+    if (!streq(cs->type, "void")) {
+      object = alloc(strlen(def->def_name) + strlen(format) +
+		     strlen(cs->name) + 1);
+      if (isvectordef(cs->type, cs->rel)) {
+	s_print(object, vecformat, def->def_name,
+		cs->name);
+      } else {
+	s_print(object, format, def->def_name,
+		cs->name);
+      }
+      print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
+		   object, cs->name);
+      free(object);
+    }
+    f_print(fout, "\t\tbreak;\n");
+  }
+  dflt = def->def.un.default_decl;
+  if (dflt != NULL) {
+    if (!streq(dflt->type, "void")) {
+      f_print(fout, "\tdefault:\n");
+      object = alloc(strlen(def->def_name) + strlen(format) +
+		     strlen(dflt->name) + 1);
+      if (isvectordef(dflt->type, dflt->rel)) {
+	s_print(object, vecformat, def->def_name,
+		dflt->name);
+      } else {
+	s_print(object, format, def->def_name,
+		dflt->name);
+      }
+
+      print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
+		   dflt->array_max, object, dflt->name);
+      free(object);
+      f_print(fout, "\t\tbreak;\n");
+    }
+#ifdef __GNU_LIBRARY__
+    else {
+      f_print(fout, "\tdefault:\n");
+      f_print(fout, "\t\tbreak;\n");
+    }
+#endif
+  } else {
+    f_print(fout, "\tdefault:\n");
+    f_print(fout, "\t\treturn (FALSE);\n");
+  }
+
+  f_print(fout, "\t}\n");
+}
+
+static void
+emit_struct(definition *def)
+{
+	decl_list *dl;
+	int i,j,size,flag;
+	decl_list *cur = NULL,*psav;
+	bas_type *ptr;
+	char *sizestr;
+	const char *plus;
+	char ptemp[256];
+	int can_inline;
+
+
+	if(inlineflag  == 0)	{
+		for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+			print_stat(1,&dl->decl);
+	}
+
+	else	{
+
+		for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+			if(dl->decl.rel == REL_VECTOR){
+				f_print(fout,"\t int i;\n");
+				break;
+			}
+
+		size=0;can_inline=0;
+		for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+			if((dl->decl.prefix == NULL) && ((ptr=find_type(dl->decl.type))!= NULL) && 		 ((dl->decl.rel == REL_ALIAS)||(dl->decl.rel == REL_VECTOR))){
+
+				if(dl->decl.rel == REL_ALIAS)
+					size+=ptr->length;
+				else {
+					can_inline=1;
+					break; /* can be inlined */
+				};
+			}
+			else {
+				if(size >= inlineflag){
+					can_inline=1;
+					break; /* can be inlined */
+				}
+				size=0;
+			}
+		if(size > inlineflag)
+			can_inline=1;
+
+		if(can_inline == 0){ /* can not inline, drop back to old mode */
+			for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+				print_stat(1,&dl->decl);
+			return;
+		};
+
+
+
+
+		flag=PUT;
+		for(j=0; j<2; j++){
+
+			if(flag == PUT)
+				f_print(fout,"\n\t if (xdrs->x_op == XDR_ENCODE) {\n");
+			else
+				f_print(fout,"\n \t return (TRUE);\n\t} else if (xdrs->x_op == XDR_DECODE) {\n");
+
+
+			i=0;
+			size=0;
+			sizestr=NULL;
+			for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */
+
+				/* now walk down the list and check for basic types */
+				if((dl->decl.prefix == NULL) && ((ptr=find_type(dl->decl.type))!= NULL) && 		 ((dl->decl.rel == REL_ALIAS)||(dl->decl.rel == REL_VECTOR))){
+					if(i ==0 )
+						cur=dl;
+					i++;
+
+					if(dl->decl.rel == REL_ALIAS)
+						size+=ptr->length;
+					else {
+						/* this is required to handle arrays */
+
+						if(sizestr == NULL)
+							plus = " ";
+						else
+							plus = "+";
+
+						if(ptr->length != 1)
+							s_print(ptemp," %s %s * %d",plus,dl->decl.array_max,ptr->length);
+						else
+							s_print(ptemp," %s %s ",plus,dl->decl.array_max);
+
+						/*now concatenate to sizestr !!!! */
+						if (sizestr == NULL)
+							sizestr=strdup(ptemp);
+						else{
+							sizestr=realloc(sizestr,strlen(sizestr)+strlen(ptemp)+1);
+							if(sizestr == NULL){
+
+								f_print(stderr, "Fatal error : no memory \n");
+								crash();
+							};
+							sizestr=strcat(sizestr,ptemp); /*build up length of array */
+
+						}
+					}
+
+				}
+				else{
+					if(i > 0 )
+						if(sizestr == NULL && size < inlineflag){
+							/* don't expand into inline code if size < inlineflag */
+							while(cur != dl){
+								print_stat(1,&cur->decl);
+								cur=cur->next;
+							}
+						}
+						else{
+
+
+
+							/* were already looking at a xdr_inlineable structure */
+							if(sizestr == NULL)
+								f_print(fout,"\t buf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);",
+									size);
+							else
+								if(size == 0)
+									f_print(fout,
+										"\t buf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
+										sizestr);
+								else
+									f_print(fout,
+										"\t buf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
+										size,sizestr);
+
+							f_print(fout,"\n\t   if (buf == NULL) {\n");
+
+							psav=cur;
+							while(cur != dl){
+								print_stat(2,&cur->decl);
+								cur=cur->next;
+							}
+
+							f_print(fout,"\n\t  }\n\t  else {\n");
+
+							cur=psav;
+							while(cur != dl){
+								emit_inline(&cur->decl,flag);
+								cur=cur->next;
+							}
+
+							f_print(fout,"\t  }\n");
+						}
+					size=0;i=0;sizestr=NULL;
+					print_stat(1,&dl->decl);
+				}
+
+			}
+			if(i > 0 )
+				if(sizestr == NULL && size < inlineflag){
+					/* don't expand into inline code if size < inlineflag */
+					while(cur != dl){
+						print_stat(1,&cur->decl);
+						cur=cur->next;
+					}
+				}
+				else{
+
+					/* were already looking at a xdr_inlineable structure */
+					if(sizestr == NULL)
+						f_print(fout,"\t\tbuf = XDR_INLINE(xdrs,%d * BYTES_PER_XDR_UNIT);",
+							size);
+					else
+						if(size == 0)
+							f_print(fout,
+								"\t\tbuf = XDR_INLINE(xdrs,%s * BYTES_PER_XDR_UNIT);",
+								sizestr);
+						else
+							f_print(fout,
+								"\t\tbuf = XDR_INLINE(xdrs,(%d + %s)* BYTES_PER_XDR_UNIT);",
+								size,sizestr);
+
+					f_print(fout,"\n\t\tif (buf == NULL) {\n");
+
+					psav=cur;
+					while(cur != NULL){
+						print_stat(2,&cur->decl);
+						cur=cur->next;
+					}
+					f_print(fout,"\n\t  }\n\t  else {\n");
+
+					cur=psav;
+					while(cur != dl){
+						emit_inline(&cur->decl,flag);
+						cur=cur->next;
+					}
+
+					f_print(fout,"\t  }\n");
+
+				}
+			flag=GET;
+		}
+		f_print(fout,"\t return(TRUE);\n\t}\n\n");
+
+		/* now take care of XDR_FREE case */
+
+		for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
+			print_stat(1,&dl->decl);
+	}
+}
+
+
+static void
+emit_typedef(definition *def)
+{
+	const char *prefix = def->def.ty.old_prefix;
+	const char *type = def->def.ty.old_type;
+	const char *amax = def->def.ty.array_max;
+	relation rel = def->def.ty.rel;
+
+
+	print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
+}
+
+static void
+print_stat(int indent, declaration *dec)
+{
+	const char *prefix = dec->prefix;
+	const char *type = dec->type;
+	const char *amax = dec->array_max;
+	relation rel = dec->rel;
+	char name[256];
+
+	if (isvectordef(type, rel)) {
+		s_print(name, "objp->%s", dec->name);
+	} else {
+		s_print(name, "&objp->%s", dec->name);
+	}
+	print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
+}
+
+
+void
+emit_inline(declaration *decl, int flag)
+{
+
+/*check whether an array or not */
+
+switch(decl->rel)
+  {
+ case  REL_ALIAS :
+  emit_single_in_line(decl,flag,REL_ALIAS);
+  break;
+ case REL_VECTOR :
+   f_print(fout,"\t\t{ register %s *genp; \n",decl->type);
+   f_print(fout,"\t\t  for ( i = 0,genp=objp->%s;\n \t\t\ti < %s; i++){\n\t\t",
+	   decl->name,decl->array_max);
+  emit_single_in_line(decl,flag,REL_VECTOR);
+    f_print(fout,"\t\t   }\n\t\t };\n");
+
+  default:
+    /* ?... do nothing I guess */
+	  ;
+  }
+}
+
+void
+emit_single_in_line(declaration *decl, int flag, relation rel)
+{
+	char *upp_case1;
+	const char *upp_case;
+
+	if (flag == PUT) {
+	    f_print(fout,"\t\t IXDR_PUT_");
+	}
+	else {
+	    if(rel== REL_ALIAS) {
+		f_print(fout, "\t\t objp->%s = IXDR_GET_", decl->name);
+	    }
+	    else {
+		f_print(fout,"\t\t *genp++ = IXDR_GET_");
+	    }
+	}
+
+	upp_case1 = upcase(decl->type);
+	upp_case = upp_case1;
+
+	/* hack  - XX */
+	if (!strcmp(upp_case, "INT")) upp_case="LONG";
+	if (!strcmp(upp_case, "U_INT")) upp_case="U_LONG";
+
+	if (flag == PUT) {
+	    if (rel==REL_ALIAS) {
+		f_print(fout,"%s(buf,objp->%s);\n",upp_case,decl->name);
+	    }
+	    else {
+		f_print(fout,"%s(buf,*genp++);\n",upp_case);
+	    }
+	}
+	else {
+	    f_print(fout,"%s(buf);\n",upp_case);
+	}
+
+	free(upp_case1);
+}
+
+
+static char *upcase(const char *str) {
+    char *ptr, *hptr;
+    ptr = malloc(strlen(str));
+    if (ptr == NULL) {
+	f_print(stderr,"malloc failed\n");
+	exit(1);
+    }
+    hptr=ptr;
+    while (*str != 0) {
+	*ptr++ = toupper(*str++);
+    }
+    *ptr=0;
+    return hptr;
+}
diff --git a/external/rpc_win32/RPCGEN/rpc_hout.c b/external/rpc_win32/RPCGEN/rpc_hout.c
new file mode 100644
index 0000000..f3707dd
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_hout.c
@@ -0,0 +1,499 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * From: @(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI
+ */
+char hout_rcsid[] = 
+  "$Id: rpc_hout.c,v 1.1.1.1 2000/10/29 20:55:03 warmerda Exp $";
+
+/*
+ * rpc_hout.c, Header file outputter for the RPC protocol compiler 
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+static void pconstdef(definition *def);
+static void pargdef(definition *def);
+static void pstructdef(definition *def);
+static void puniondef(definition *def);
+static void pdefine(const char *name, const char *num);
+static void puldefine(const char *name, const char *num);
+static int define_printed(proc_list *stop, version_list *start);
+static void pprogramdef(definition *def);
+static void parglist(proc_list *proc, const char *addargtype);
+static void penumdef(definition *def);
+static void ptypedef(definition *def);
+static int undefined2(const char *type, const char *stop);
+
+/*
+ * Print the C-version of an xdr definition 
+ */
+void
+print_datadef(definition *def)
+{
+
+	if (def->def_kind == DEF_PROGRAM )  /* handle data only */
+	        return;
+
+	if (def->def_kind != DEF_CONST) {
+		f_print(fout, "\n");
+	}
+	switch (def->def_kind) {
+	case DEF_STRUCT:
+		pstructdef(def);
+		break;
+	case DEF_UNION:
+		puniondef(def);
+		break;
+	case DEF_ENUM:
+		penumdef(def);
+		break;
+	case DEF_TYPEDEF:
+		ptypedef(def);
+		break;
+	case DEF_PROGRAM:
+		pprogramdef(def);
+		break;
+	case DEF_CONST:
+		pconstdef(def);
+		break;
+	}
+	if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
+	  pxdrfuncdecl( def->def_name,
+		       def->def_kind != DEF_TYPEDEF ||
+		       !isvectordef(def->def.ty.old_type, def->def.ty.rel));
+
+	}
+}
+
+
+void
+print_funcdef(definition *def)
+{
+	switch (def->def_kind) {
+	  case DEF_PROGRAM:
+		f_print(fout, "\n");
+		pprogramdef(def);
+		break;
+	  default:
+	    /* ?... shouldn't happen I guess */
+		  ;
+	}
+}
+
+void
+pxdrfuncdecl(const char *name, int pointerp)
+{
+
+  f_print(fout,"#ifdef __cplusplus \n");
+    f_print(fout, "extern \"C\" bool_t xdr_%s(XDR *, %s%s);\n", name, name, pointerp ? "*" : "");
+  f_print(fout,"#elif __STDC__ \n");
+    f_print(fout, "extern  bool_t xdr_%s(XDR *, %s%s);\n", name, name, pointerp ? "*" : "");
+  f_print(fout,"#else /* Old Style C */ \n");
+    f_print(fout, "bool_t xdr_%s();\n", name);
+  f_print(fout,"#endif /* Old Style C */ \n\n");
+}
+
+
+static void
+pconstdef(definition *def)
+{
+	pdefine(def->def_name, def->def.co);
+}
+
+/* print out the definitions for the arguments of functions in the 
+   header file 
+*/
+static void
+pargdef(definition *def)
+{
+	decl_list *l;
+	version_list *vers;
+	const char *name;
+	proc_list *plist;
+
+	
+	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
+			for(plist = vers->procs; plist != NULL; 
+			    plist = plist->next) {
+				
+				if (!newstyle || plist->arg_num < 2) {
+					continue; /* old style or single args */
+				}
+				name = plist->args.argname;
+				f_print(fout, "struct %s {\n", name);
+				for (l = plist->args.decls; 
+				     l != NULL; l = l->next) {
+					pdeclaration(name, &l->decl, 1, ";\n" );
+				}
+				f_print(fout, "};\n");
+				f_print(fout, "typedef struct %s %s;\n", name, name);
+				pxdrfuncdecl(name, 0);
+				f_print( fout, "\n" );
+			}
+		}
+
+}
+
+
+static void
+pstructdef(definition *def)
+{
+	decl_list *l;
+	const char *name = def->def_name;
+
+	f_print(fout, "struct %s {\n", name);
+	for (l = def->def.st.decls; l != NULL; l = l->next) {
+		pdeclaration(name, &l->decl, 1, ";\n");
+	}
+	f_print(fout, "};\n");
+	f_print(fout, "typedef struct %s %s;\n", name, name);
+}
+
+static void
+puniondef(definition *def)
+{
+	case_list *l;
+	const char *name = def->def_name;
+	declaration *decl;
+
+	f_print(fout, "struct %s {\n", name);
+	decl = &def->def.un.enum_decl;
+	if (streq(decl->type, "bool")) {
+		f_print(fout, "\tbool_t %s;\n", decl->name);
+	} else {
+		f_print(fout, "\t%s %s;\n", decl->type, decl->name);
+	}
+	f_print(fout, "\tunion {\n");
+	for (l = def->def.un.cases; l != NULL; l = l->next) {
+	  if(l->contflag == 0)
+		pdeclaration(name, &l->case_decl, 2, ";\n" );
+	}
+	decl = def->def.un.default_decl;
+	if (decl && !streq(decl->type, "void")) {
+		pdeclaration(name, decl, 2, ";\n" );
+	}
+	f_print(fout, "\t} %s_u;\n", name);
+	f_print(fout, "};\n");
+	f_print(fout, "typedef struct %s %s;\n", name, name);
+}
+
+static void
+pdefine(const char *name, const char *num)
+{
+	f_print(fout, "#define %s %s\n", name, num);
+}
+
+static void
+puldefine(const char *name, const char *num)
+{
+	f_print(fout, "#define %s ((u_long)%s)\n", name, num);
+}
+
+static int
+define_printed(proc_list *stop, version_list *start)
+{
+	version_list *vers;
+	proc_list *proc;
+
+	for (vers = start; vers != NULL; vers = vers->next) {
+		for (proc = vers->procs; proc != NULL; proc = proc->next) {
+			if (proc == stop) {
+				return (0);
+			} else if (streq(proc->proc_name, stop->proc_name)) {
+				return (1);
+			}
+		}
+	}
+	abort();
+	/* NOTREACHED */
+}
+
+static void
+pprogramdef(definition *def)
+{
+	version_list *vers;
+	proc_list *proc;
+	int i;
+	const char *ext;
+	
+	pargdef(def);
+
+	puldefine(def->def_name, def->def.pr.prog_num);
+	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
+		if (tblflag) {
+			f_print(fout, "extern struct rpcgen_table %s_%s_table[];\n",
+				locase(def->def_name), vers->vers_num);
+			f_print(fout, "extern %s_%s_nproc;\n",
+				locase(def->def_name), vers->vers_num);
+		}
+		puldefine(vers->vers_name, vers->vers_num);
+
+		/* 
+		 * Print out 3 definitions, one for ANSI-C, another for C++, 
+		 * a third for old style C 
+		 */
+		   
+		for (i=0;i<3;i++) {
+			if (i==0) {
+				f_print(fout,"\n#ifdef __cplusplus\n");
+				ext="extern \"C\" ";
+			} 
+			else if (i==1) {
+				f_print(fout,"\n#elif __STDC__\n");
+				ext="extern  "  ;
+			} 
+			else {
+				f_print(fout,"\n#else /* Old Style C */ \n");
+				ext="extern  ";
+			}
+			
+			
+			for (proc = vers->procs; proc != NULL; proc = proc->next) {
+				if (!define_printed(proc, def->def.pr.versions)) {
+					puldefine(proc->proc_name, proc->proc_num);
+				}
+				f_print(fout,"%s",ext);
+				pprocdef(proc, vers, "CLIENT *", 0,i);
+				f_print(fout,"%s",ext);
+				pprocdef(proc, vers, "struct svc_req *", 1,i);
+				
+			}
+
+		}
+		f_print(fout,"#endif /* Old Style C */ \n");
+	}
+}
+
+void
+pprocdef(proc_list *proc, version_list *vp, 
+	 const char *addargtype, int server_p, int mode)
+{
+
+
+
+
+		ptype( proc->res_prefix, proc->res_type, 1 );
+		f_print( fout, "* " );
+		if( server_p )
+			pvname_svc(proc->proc_name, vp->vers_num);
+		else
+			pvname(proc->proc_name, vp->vers_num);
+
+		/*
+		 * mode  0 == cplusplus, mode  1 = ANSI-C, mode 2 = old style C 
+		 */
+		if(mode == 0 || mode ==1) 
+			parglist(proc, addargtype);
+		else
+			f_print(fout, "();\n");
+
+
+
+}
+
+
+
+/* print out argument list of procedure */
+static void
+parglist(proc_list *proc, const char *addargtype)
+{
+	decl_list *dl;
+
+		f_print(fout,"(");
+
+		if( proc->arg_num < 2 && newstyle &&
+		   streq( proc->args.decls->decl.type, "void")) {
+			/* 0 argument in new style:  do nothing */
+		} else {
+			for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
+				ptype( dl->decl.prefix, dl->decl.type, 1 );
+				if( !newstyle )
+					f_print( fout, "*" ); /* old style passes by reference */
+	
+				f_print( fout, ", " );
+			}
+		}
+    
+		f_print(fout, "%s);\n", addargtype);
+
+}
+
+static void
+penumdef(definition *def)
+{
+	const char *name = def->def_name;
+	enumval_list *l;
+	const char *last = NULL;
+	int count = 0;
+
+	f_print(fout, "enum %s {\n", name);
+	for (l = def->def.en.vals; l != NULL; l = l->next) {
+		f_print(fout, "\t%s", l->name);
+		if (l->assignment) {
+			f_print(fout, " = %s", l->assignment);
+			last = l->assignment;
+			count = 1;
+		} else {
+			if (last == NULL) {
+				f_print(fout, " = %d", count++);
+			} else {
+				f_print(fout, " = %s + %d", last, count++);
+			}
+		}
+		f_print(fout, ",\n");
+	}
+	f_print(fout, "};\n");
+	f_print(fout, "typedef enum %s %s;\n", name, name);
+}
+
+static void
+ptypedef(definition *def)
+{
+	const char *name = def->def_name;
+	const char *old = def->def.ty.old_type;
+	char prefix[8];	/* enough to contain "struct ", including NUL */
+	relation rel = def->def.ty.rel;
+
+
+	if (!streq(name, old)) {
+		if (streq(old, "string")) {
+			old = "char";
+			rel = REL_POINTER;
+		} else if (streq(old, "opaque")) {
+			old = "char";
+		} else if (streq(old, "bool")) {
+			old = "bool_t";
+		}
+		if (undefined2(old, name) && def->def.ty.old_prefix) {
+			s_print(prefix, "%s ", def->def.ty.old_prefix);
+		} else {
+			prefix[0] = 0;
+		}
+		f_print(fout, "typedef ");
+		switch (rel) {
+		case REL_ARRAY:
+			f_print(fout, "struct {\n");
+			f_print(fout, "\tu_int %s_len;\n", name);
+			f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name);
+			f_print(fout, "} %s", name);
+			break;
+		case REL_POINTER:
+			f_print(fout, "%s%s *%s", prefix, old, name);
+			break;
+		case REL_VECTOR:
+			f_print(fout, "%s%s %s[%s]", prefix, old, name,
+				def->def.ty.array_max);
+			break;
+		case REL_ALIAS:
+			f_print(fout, "%s%s %s", prefix, old, name);
+			break;
+		}
+		f_print(fout, ";\n");
+	}
+}
+
+void
+pdeclaration(const char *name, declaration *dec, int tab, 
+	     const char *separator)
+{
+	char buf[8];	/* enough to hold "struct ", include NUL */
+	const char *prefix;
+	const char *type;
+
+	if (streq(dec->type, "void")) {
+		return;
+	}
+	tabify(fout, tab);
+	if (streq(dec->type, name) && !dec->prefix) {
+		f_print(fout, "struct ");
+	}
+	if (streq(dec->type, "string")) {
+		f_print(fout, "char *%s", dec->name);
+	} else {
+		prefix = "";
+		if (streq(dec->type, "bool")) {
+			type = "bool_t";
+		} else if (streq(dec->type, "opaque")) {
+			type = "char";
+		} else {
+			if (dec->prefix) {
+				s_print(buf, "%s ", dec->prefix);
+				prefix = buf;
+			}
+			type = dec->type;
+		}
+		switch (dec->rel) {
+		case REL_ALIAS:
+			f_print(fout, "%s%s %s", prefix, type, dec->name);
+			break;
+		case REL_VECTOR:
+			f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
+				dec->array_max);
+			break;
+		case REL_POINTER:
+			f_print(fout, "%s%s *%s", prefix, type, dec->name);
+			break;
+		case REL_ARRAY:
+			f_print(fout, "struct {\n");
+			tabify(fout, tab);
+			f_print(fout, "\tu_int %s_len;\n", dec->name);
+			tabify(fout, tab);
+			f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
+			tabify(fout, tab);
+			f_print(fout, "} %s", dec->name);
+			break;
+		}
+	}
+	f_print(fout, separator );
+}
+
+static int
+undefined2(const char *type, const char *stop)
+{
+	list *l;
+	definition *def;
+
+	for (l = defined; l != NULL; l = l->next) {
+		def = (definition *) l->val;
+		if (def->def_kind != DEF_PROGRAM) {
+			if (streq(def->def_name, stop)) {
+				return (1);
+			} else if (streq(def->def_name, type)) {
+				return (0);
+			}
+		}
+	}
+	return (1);
+}
diff --git a/external/rpc_win32/RPCGEN/rpc_main.c b/external/rpc_win32/RPCGEN/rpc_main.c
new file mode 100644
index 0000000..11fa108
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_main.c
@@ -0,0 +1,1159 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * From @(#)rpc_main.c 1.30 89/03/30 (C) 1987 SMI;
+ */
+char main_rcsid[] =
+  "$Id: rpc_main.c,v 1.1.1.1 2000/10/29 20:55:04 warmerda Exp $";
+
+/*
+ * rpc_main.c, Top level of the RPC protocol compiler.
+ */
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/types.h>
+#ifdef WIN32
+#include <process.h>
+#include <io.h>
+#else
+#include <sys/param.h>
+#include <sys/file.h>
+#endif
+#include <fcntl.h>
+#include <sys/stat.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "rpc_scan.h"
+#include "proto.h"
+
+
+#define EXTEND	1		/* alias for TRUE */
+#define DONT_EXTEND	0		/* alias for FALSE */
+
+#ifdef WIN32
+#define USE_CPP "cl.exe"
+#define USE_CPP_FLAGS "-EP /nologo"
+/* Use a deep pipe because all output from compile must fit in it */
+#define pipe(x) _pipe(x, 0x40000, O_TEXT)
+#define MAXPATHLEN 1024
+#else
+#define SVR4_CPP "/usr/ccs/lib/cpp"
+#define SUNOS_CPP "/lib/cpp"
+#define USE_CPP SUNOS_CPP
+#define USE_CPP_FLAGS "-C"
+#endif
+static int cppDefined = 0;          /* explicit path for C preprocessor */
+
+struct commandline {
+	int cflag;		/* xdr C routines */
+	int hflag;		/* header file */
+	int lflag;		/* client side stubs */
+	int mflag;		/* server side stubs */
+	int nflag;		/* netid flag */
+	int sflag;		/* server stubs for the given transport */
+	int tflag;		/* dispatch Table file */
+	int Ssflag;		/* produce server sample code */
+	int Scflag;		/* produce client sample code */
+	const char *infile;	/* input module name */
+	const char *outfile;	/* output module name */
+};
+
+
+static const char *cmdname;
+
+static const char *svcclosetime = "120";
+static const char *CPP = USE_CPP;
+static const char *CPPFLAGS = USE_CPP_FLAGS;
+static char pathbuf[MAXPATHLEN + 1];
+static const char *allv[] = {
+	"rpcgen", "-s", "udp", "-s", "tcp",
+};
+static int allc = sizeof(allv)/sizeof(allv[0]);
+static const char *allnv[] = {
+	"rpcgen", "-s", "netpath",
+};
+static int allnc = sizeof(allnv)/sizeof(allnv[0]);
+
+/*
+ * machinations for handling expanding argument list
+ */
+static void addarg(const char *);       /* add another argument to the list */
+static void putarg(int, const char *); /* put argument at specified location */
+static void clear_args(void);	        /* clear argument list */
+static void checkfiles(const char *, const char *);
+                                        /* check if out file already exists */
+
+static void clear_args(void);
+static char *extendfile(const char *file, const char *ext);
+static void open_output(const char *infile, const char *outfile);
+static void add_warning(void);
+static void clear_args(void);
+static void find_cpp(void);
+static void open_input(const char *infile, const char *define);
+static int check_nettype(const char *name, const char *list_to_check[]);
+static void c_output(const char *infile, const char *define,
+		     int extend, const char *outfile);
+static void h_output(const char *infile, const char *define,
+		     int extend, const char *outfile);
+static void s_output(int argc, const char *argv[], const char *infile,
+		     const char *define, int extend,
+		     const char *outfile, int nomain, int netflag);
+static void l_output(const char *infile, const char *define,
+		     int extend, const char *outfile);
+static void t_output(const char *infile, const char *define,
+		     int extend, const char *outfile);
+static void svc_output(const char *infile, const char *define,
+		       int extend, const char *outfile);
+static void clnt_output(const char *infile, const char *define,
+			int extend, const char *outfile);
+static int do_registers(int argc, const char *argv[]);
+static void addarg(const char *cp);
+static void putarg(int whereto, const char *cp);
+static void checkfiles(const char *infile, const char *outfile);
+static int parseargs(int argc, const char *argv[], struct commandline *cmd);
+static void usage(void);
+static void options_usage(void);
+static void c_initialize(void);
+static char *generate_guard(const char *pathname);
+
+
+#define ARGLISTLEN	20
+#define FIXEDARGS         2
+
+static const char *arglist[ARGLISTLEN];
+static int argcount = FIXEDARGS;
+
+
+int nonfatalerrors;	/* errors */
+int inetdflag/* = 1*/;	/* Support for inetd */ /* is now the default */
+int pmflag;		/* Support for port monitors */
+int logflag;		/* Use syslog instead of fprintf for errors */
+int tblflag;		/* Support for dispatch table file */
+
+#define INLINE 3
+/*length at which to start doing an inline */
+
+int inlineflag=INLINE; /* length at which to start doing an inline. 3 = default
+		if 0, no xdr_inline code */
+
+int indefinitewait;	/* If started by port monitors, hang till it wants */
+int exitnow;		/* If started by port monitors, exit after the call */
+int timerflag;		/* TRUE if !indefinite && !exitnow */
+int newstyle;           /* newstyle of passing arguments (by value) */
+#ifdef __GNU_LIBRARY__
+int Cflag = 1 ;         /* ANSI C syntax */
+#else
+int Cflag = 0 ;         /* ANSI C syntax */
+#endif
+static int allfiles;   /* generate all files */
+#ifdef __GNU_LIBRARY__
+int tirpcflag = 0;       /* generating code for tirpc, by default */
+#else
+int tirpcflag = 1;       /* generating code for tirpc, by default */
+#endif
+
+int
+main(int argc, const char *argv[])
+{
+	struct commandline cmd;
+
+	(void) memset((char *)&cmd, 0, sizeof (struct commandline));
+	clear_args();
+	if (!parseargs(argc, argv, &cmd))
+		usage();
+
+	if (cmd.cflag || cmd.hflag || cmd.lflag || cmd.tflag || cmd.sflag ||
+		cmd.mflag || cmd.nflag || cmd.Ssflag || cmd.Scflag ) {
+	  checkfiles(cmd.infile, cmd.outfile);
+	}
+	else
+	  checkfiles(cmd.infile,NULL);
+
+	if (cmd.cflag) {
+		c_output(cmd.infile, "-DRPC_XDR", DONT_EXTEND, cmd.outfile);
+	} else if (cmd.hflag) {
+		h_output(cmd.infile, "-DRPC_HDR", DONT_EXTEND, cmd.outfile);
+	} else if (cmd.lflag) {
+		l_output(cmd.infile, "-DRPC_CLNT", DONT_EXTEND, cmd.outfile);
+	} else if (cmd.sflag || cmd.mflag || (cmd.nflag)) {
+		s_output(argc, argv, cmd.infile, "-DRPC_SVC", DONT_EXTEND,
+			 cmd.outfile, cmd.mflag, cmd.nflag);
+	} else if (cmd.tflag) {
+		t_output(cmd.infile, "-DRPC_TBL", DONT_EXTEND, cmd.outfile);
+	} else if  (cmd.Ssflag) {
+		  svc_output(cmd.infile, "-DRPC_SERVER", DONT_EXTEND, cmd.outfile);
+	} else if (cmd.Scflag) {
+		  clnt_output(cmd.infile, "-DRPC_CLIENT", DONT_EXTEND, cmd.outfile);
+	} else {
+		/* the rescans are required, since cpp may effect input */
+		c_output(cmd.infile, "-DRPC_XDR", EXTEND, "_xdr.c");
+		reinitialize();
+		h_output(cmd.infile, "-DRPC_HDR", EXTEND, ".h");
+		reinitialize();
+		l_output(cmd.infile, "-DRPC_CLNT", EXTEND, "_clnt.c");
+		reinitialize();
+		if (inetdflag || !tirpcflag )
+			s_output(allc, allv, cmd.infile, "-DRPC_SVC", EXTEND,
+				 "_svc.c", cmd.mflag, cmd.nflag);
+		else
+			s_output(allnc, allnv, cmd.infile, "-DRPC_SVC",
+				 EXTEND, "_svc.c", cmd.mflag, cmd.nflag);
+		if (tblflag) {
+			reinitialize();
+			t_output(cmd.infile, "-DRPC_TBL", EXTEND, "_tbl.i");
+		}
+		if (allfiles) {
+		  reinitialize();
+		  svc_output(cmd.infile, "-DRPC_SERVER", EXTEND, "_server.c");
+		}
+		if (allfiles) {
+		  reinitialize();
+		  clnt_output(cmd.infile, "-DRPC_CLIENT", EXTEND, "_client.c");
+		}
+	}
+	exit(nonfatalerrors);
+	/* NOTREACHED */
+	return 0;
+}
+
+/*
+ * add extension to filename
+ */
+static char *
+extendfile(const char *file, const char *ext)
+{
+	char *res;
+	const char *p;
+
+	res = alloc(strlen(file) + strlen(ext) + 1);
+	if (res == NULL) {
+		abort();
+	}
+	p = strrchr(file, '.');
+	if (p == NULL) {
+		p = file + strlen(file);
+	}
+	(void) strcpy(res, file);
+	(void) strcpy(res + (p - file), ext);
+	return (res);
+}
+
+/*
+ * Open output file with given extension
+ */
+static void
+open_output(const char *infile, const char *outfile)
+{
+
+	if (outfile == NULL) {
+		fout = stdout;
+		return;
+	}
+
+	if (infile != NULL && streq(outfile, infile)) {
+		f_print(stderr, "%s: output would overwrite %s\n", cmdname,
+			infile);
+		crash();
+	}
+	fout = fopen(outfile, "wb");
+	if (fout == NULL) {
+		f_print(stderr, "%s: unable to open ", cmdname);
+		perror(outfile);
+		crash();
+	}
+	record_open(outfile);
+}
+
+static void
+add_warning(void)
+{
+	f_print(fout, "/*\n");
+	f_print(fout, " * Please do not edit this file.\n");
+	f_print(fout, " * It was generated using rpcgen.\n");
+	f_print(fout, " */\n\n");
+}
+
+static void
+add_stdheaders(void)
+{
+	f_print(fout, "#include <rpc/types.h>\n");
+	f_print(fout, "#include <rpc/xdr.h>\n\n");
+}
+
+/* clear list of arguments */
+static void clear_args(void)
+{
+  int i;
+  for( i=FIXEDARGS; i<ARGLISTLEN; i++ )
+    arglist[i] = NULL;
+  argcount = FIXEDARGS;
+}
+
+/* make sure that a CPP exists */
+static void find_cpp(void)
+{
+  struct stat buf;
+
+  if (stat(CPP, &buf) < 0 )  {	/* SVR4 or explicit cpp does not exist */
+    if (cppDefined) {
+      fprintf( stderr, "cannot find C preprocessor: %s \n", CPP );
+      crash();
+    } else {			/* try the other one */
+      CPP = USE_CPP;
+      if( stat( CPP, &buf ) < 0 ) { /* can't find any cpp */
+	fprintf( stderr, "cannot find any C preprocessor (cpp)\n" );
+	crash();
+      }
+    }
+  }
+}
+
+/*
+ * Open input file with given define for C-preprocessor
+ */
+static void
+open_input(const char *infile, const char *define)
+{
+	int pd[2];
+
+	infilename = (infile == NULL) ? "<stdin>" : infile;
+	(void) pipe(pd);
+
+#ifdef WIN32
+	{
+		int old;
+		char fullPath[MAXPATHLEN];
+
+		strcpy(fullPath, CPP);
+		if (SearchPath(NULL, fullPath, NULL, MAXPATHLEN, fullPath, NULL) == 0) {
+			putarg(0, CPP);
+		} else {
+			putarg(0, fullPath);
+		}
+
+		putarg(1, CPPFLAGS);
+		addarg(define);
+		addarg(infile);
+		addarg((char *)NULL);
+
+		old = dup(1);
+		(void) dup2(pd[1], 1);
+
+		if (_spawnv(_P_WAIT, arglist[0], (char **)arglist) < 0) {
+			f_print(stderr, "%s: unable to open ", arglist[0]);
+			perror(CPP);
+			crash();
+		}
+		(void) dup2(old, 1);
+	}
+
+#else
+
+	switch (fork()) {
+	case 0:
+		find_cpp();
+		putarg(0, CPP);
+		putarg(1, CPPFLAGS);
+		addarg(define);
+		addarg(infile);
+		addarg((char *)NULL);
+		(void) close(1);
+		(void) dup2(pd[1], 1);
+		(void) close(pd[0]);
+		execv(arglist[0], (char **)arglist);
+		perror("execv");
+		exit(1);
+	case -1:
+		perror("fork");
+		exit(1);
+	}
+#endif
+
+	(void) close(pd[1]);
+	fin = fdopen(pd[0], "r");
+	if (fin == NULL) {
+		f_print(stderr, "%s: ", cmdname);
+		perror(infilename);
+		crash();
+	}
+}
+
+/* valid tirpc nettypes */
+static const char *valid_ti_nettypes[] =
+{
+  "netpath",
+  "visible",
+  "circuit_v",
+  "datagram_v",
+  "circuit_n",
+  "datagram_n",
+  "udp",
+  "tcp",
+  "raw",
+  NULL
+  };
+
+/* valid inetd nettypes */
+static const char *valid_i_nettypes[] =
+{
+  "udp",
+  "tcp",
+  NULL
+};
+
+static int check_nettype(const char *name, const char *list_to_check[]) {
+  int i;
+  for( i = 0; list_to_check[i] != NULL; i++ ) {
+	  if( strcmp( name, list_to_check[i] ) == 0 ) {
+	    return 1;
+	  }
+  }
+  f_print( stderr, "illegal nettype :\'%s\'\n", name );
+  return 0;
+}
+
+/*
+ * Compile into an XDR routine output file
+ */
+
+static void
+c_output(const char *infile, const char *define, int extend,
+	 const char *outfile)
+{
+	definition *def;
+	char *include;
+	const char *outfilename;
+	long tell;
+
+	c_initialize();
+	open_input(infile, define);
+	outfilename = extend ? extendfile(infile, outfile) : outfile;
+	open_output(infile, outfilename);
+	add_warning();
+	add_stdheaders();
+	if (infile && (include = extendfile(infile, ".h"))) {
+		f_print(fout, "#include \"%s\"\n", include);
+		free(include);
+		/* .h file already contains rpc/rpc.h */
+	} else
+	  f_print(fout, "#include <rpc/rpc.h>\n");
+	tell = ftell(fout);
+	while ((def = get_definition())!=NULL) {
+		emit(def);
+	}
+	if (extend && tell == ftell(fout)) {
+		(void) unlink(outfilename);
+	}
+}
+
+void
+c_initialize(void)
+{
+
+  /* add all the starting basic types */
+
+  add_type(1,"int");
+  add_type(1,"long");
+  add_type(1,"short");
+  add_type(1,"bool");
+
+  add_type(1,"u_int");
+  add_type(1,"u_long");
+  add_type(1,"u_short");
+
+}
+
+char rpcgen_table_dcl[] = "struct rpcgen_table {\n\
+	char	*(*proc)();\n\
+	xdrproc_t	xdr_arg;\n\
+	unsigned	len_arg;\n\
+	xdrproc_t	xdr_res;\n\
+	unsigned	len_res;\n\
+};\n";
+
+
+static char *generate_guard(const char *pathname) {
+        const char *filename;
+	char *guard, *tmp;
+
+	filename = strrchr(pathname, '/' );  /* find last component */
+	filename = ((filename == NULL) ? pathname : filename+1);
+	guard = strdup(filename);
+	/* convert to upper case */
+	tmp = guard;
+	while (*tmp) {
+		if (islower(*tmp))
+			*tmp = toupper(*tmp);
+		tmp++;
+	}
+
+	guard = extendfile(guard, "_H_RPCGEN");
+	return guard;
+}
+
+/*
+ * Compile into an XDR header file
+ */
+
+
+static void
+h_output(const char *infile, const char *define, int extend,
+	 const char *outfile)
+{
+	definition *def;
+	const char *ifilename;
+	const char *outfilename;
+	long tell;
+	char *guard;
+	list *l;
+
+	open_input(infile, define);
+	outfilename =  extend ? extendfile(infile, outfile) : outfile;
+	open_output(infile, outfilename);
+	add_warning();
+	ifilename = (infile == NULL) ? "STDIN" : infile;
+	guard = generate_guard(  outfilename ? outfilename: ifilename );
+
+	f_print(fout,"#ifndef _%s\n#define _%s\n\n", guard,
+		guard);
+
+	f_print(fout, "#include <rpc/rpc.h>\n\n");
+
+	tell = ftell(fout);
+	/* print data definitions */
+	while ((def = get_definition())!=NULL) {
+		print_datadef(def);
+	}
+
+	/* print function declarations.
+	   Do this after data definitions because they might be used as
+	   arguments for functions */
+	for (l = defined; l != NULL; l = l->next) {
+		print_funcdef(l->val);
+	}
+	if (extend && tell == ftell(fout)) {
+		(void) unlink(outfilename);
+	} else if (tblflag) {
+		f_print(fout, rpcgen_table_dcl);
+	}
+	f_print(fout, "\n#endif /* !_%s */\n", guard);
+}
+
+/*
+ * Compile into an RPC service
+ */
+static void
+s_output(int argc, const char *argv[], const char *infile, const char *define,
+	 int extend, const char *outfile, int nomain, int netflag)
+{
+	char *include;
+	definition *def;
+	int foundprogram = 0;
+	const char *outfilename;
+
+	open_input(infile, define);
+	outfilename = extend ? extendfile(infile, outfile) : outfile;
+	open_output(infile, outfilename);
+	add_warning();
+	if (infile && (include = extendfile(infile, ".h"))) {
+		f_print(fout, "#include \"%s\"\n", include);
+		free(include);
+	} else
+	  f_print(fout, "#include <rpc/rpc.h>\n");
+
+	f_print(fout, "#include <stdio.h>\n");
+	f_print(fout, "#include <stdlib.h>/* getenv, exit */\n");
+	if (Cflag) {
+		f_print (fout, "#include <rpc/pmap_clnt.h> /* for pmap_unset */\n");
+		f_print (fout, "#include <string.h> /* strcmp */ \n");
+	}
+	if (strcmp(svcclosetime, "-1") == 0)
+		indefinitewait = 1;
+	else if (strcmp(svcclosetime, "0") == 0)
+		exitnow = 1;
+	else if (inetdflag || pmflag) {
+		f_print(fout, "#include <signal.h>\n");
+	  timerflag = 1;
+	}
+
+	if( !tirpcflag && inetdflag )
+#ifdef __GNU_LIBRARY__
+	  f_print(fout, "#include <sys/ioctl.h> /* ioctl, TIOCNOTTY */\n");
+#else
+	  f_print(fout, "#include <sys/ttycom.h>/* TIOCNOTTY */\n");
+#endif
+	if( Cflag && (inetdflag || pmflag ) ) {
+#ifdef __GNU_LIBRARY__
+	  f_print(fout, "#include <sys/types.h> /* open */\n");
+	  f_print(fout, "#include <sys/stat.h> /* open */\n");
+	  f_print(fout, "#include <fcntl.h> /* open */\n");
+	  f_print(fout, "#include <unistd.h> /* getdtablesize */\n");
+#else
+	  f_print(fout, "#ifdef __cplusplus\n");
+	  f_print(fout, "#include <sysent.h> /* getdtablesize, open */\n");
+	  f_print(fout, "#endif /* __cplusplus */\n");
+#endif
+	  if( tirpcflag )
+	    f_print(fout, "#include <unistd.h> /* setsid */\n");
+	}
+	if( tirpcflag )
+	  f_print(fout, "#include <sys/types.h>\n");
+
+	f_print(fout, "#include <memory.h>\n");
+#ifndef __GNU_LIBRARY__
+	f_print(fout, "#include <stropts.h>\n");
+#endif
+	if (inetdflag || !tirpcflag ) {
+		f_print(fout, "#include <sys/socket.h>\n");
+		f_print(fout, "#include <netinet/in.h>\n");
+	}
+
+	if ( (netflag || pmflag) && tirpcflag ) {
+		f_print(fout, "#include <netconfig.h>\n");
+	}
+	if (/*timerflag &&*/ tirpcflag)
+		f_print(fout, "#include <sys/resource.h> /* rlimit */\n");
+	if (logflag || inetdflag || pmflag) {
+#ifdef __GNU_LIBRARY__
+		f_print(fout, "#include <syslog.h>\n");
+#else
+		f_print(fout, "#ifdef SYSLOG\n");
+		f_print(fout, "#include <syslog.h>\n");
+		f_print(fout, "#else\n");
+		f_print(fout, "#define LOG_ERR 1\n");
+		f_print(fout, "#define openlog(a, b, c)\n");
+		f_print(fout, "#endif\n");
+#endif
+	}
+
+	/* for ANSI-C */
+	f_print(fout, "\n#ifdef __STDC__\n#define SIG_PF void(*)(int)\n#endif\n");
+
+#ifndef __GNU_LIBRARY__
+	f_print(fout, "\n#ifdef DEBUG\n#define RPC_SVC_FG\n#endif\n");
+#endif
+	if (timerflag)
+		f_print(fout, "\n#define _RPCSVC_CLOSEDOWN %s\n", svcclosetime);
+	while ((def = get_definition())!=NULL) {
+		foundprogram |= (def->def_kind == DEF_PROGRAM);
+	}
+	if (extend && !foundprogram) {
+		(void) unlink(outfilename);
+		return;
+	}
+	write_most(infile, netflag, nomain);
+	if (!nomain) {
+		if( !do_registers(argc, argv) ) {
+		  if (outfilename)
+		    (void) unlink(outfilename);
+		  usage();
+		}
+		write_rest();
+	}
+}
+
+/*
+ * generate client side stubs
+ */
+static void
+l_output(const char *infile, const char *define, int extend,
+	 const char *outfile)
+{
+	char *include;
+	definition *def;
+	int foundprogram = 0;
+	const char *outfilename;
+
+	open_input(infile, define);
+	outfilename = extend ? extendfile(infile, outfile) : outfile;
+	open_output(infile, outfilename);
+	add_warning();
+	if (Cflag)
+	  f_print (fout, "#include <memory.h> /* for memset */\n");
+	if (infile && (include = extendfile(infile, ".h"))) {
+		f_print(fout, "#include \"%s\"\n", include);
+		free(include);
+	} else
+	  f_print(fout, "#include <rpc/rpc.h>\n");
+	while ((def = get_definition())!=NULL) {
+		foundprogram |= (def->def_kind == DEF_PROGRAM);
+	}
+	if (extend && !foundprogram) {
+		(void) unlink(outfilename);
+		return;
+	}
+	write_stubs();
+}
+
+/*
+ * generate the dispatch table
+ */
+static void
+t_output(const char *infile, const char *define, int extend,
+	 const char *outfile)
+{
+	definition *def;
+	int foundprogram = 0;
+	const char *outfilename;
+
+	open_input(infile, define);
+	outfilename = extend ? extendfile(infile, outfile) : outfile;
+	open_output(infile, outfilename);
+	add_warning();
+	while ((def = get_definition())!=NULL) {
+		foundprogram |= (def->def_kind == DEF_PROGRAM);
+	}
+	if (extend && !foundprogram) {
+		(void) unlink(outfilename);
+		return;
+	}
+	write_tables();
+}
+
+/* sample routine for the server template */
+static void
+svc_output(const char *infile, const char *define, int extend,
+	   const char *outfile)
+{
+  definition *def;
+  char *include;
+  const char *outfilename;
+  long tell;
+
+  open_input(infile, define);
+  outfilename = extend ? extendfile(infile, outfile) : outfile;
+  checkfiles(infile,outfilename); /*check if outfile already exists.
+				  if so, print an error message and exit*/
+  open_output(infile, outfilename);
+  add_sample_msg();
+
+  if (infile && (include = extendfile(infile, ".h"))) {
+    f_print(fout, "#include \"%s\"\n", include);
+    free(include);
+  } else
+    f_print(fout, "#include <rpc/rpc.h>\n");
+
+  tell = ftell(fout);
+  while ((def = get_definition())!=NULL) {
+	  write_sample_svc(def);
+  }
+  if (extend && tell == ftell(fout)) {
+	  (void) unlink(outfilename);
+  }
+}
+
+
+/* sample main routine for client */
+static void
+clnt_output(const char *infile, const char *define, int extend,
+	    const char *outfile)
+{
+  definition *def;
+  char *include;
+  const char *outfilename;
+  long tell;
+  int has_program = 0;
+
+  open_input(infile, define);
+  outfilename = extend ? extendfile(infile, outfile) : outfile;
+  checkfiles(infile,outfilename); /*check if outfile already exists.
+				  if so, print an error message and exit*/
+
+  open_output(infile, outfilename);
+  add_sample_msg();
+  if (infile && (include = extendfile(infile, ".h"))) {
+    f_print(fout, "#include \"%s\"\n", include);
+    free(include);
+  } else
+    f_print(fout, "#include <rpc/rpc.h>\n");
+  tell = ftell(fout);
+  while ((def = get_definition())!=NULL) {
+    has_program += write_sample_clnt(def);
+  }
+
+  if( has_program )
+    write_sample_clnt_main();
+
+  if (extend && tell == ftell(fout)) {
+    (void) unlink(outfilename);
+  }
+}
+
+/*
+ * Perform registrations for service output
+ * Return 0 if failed; 1 otherwise.
+ */
+static int do_registers(int argc, const char *argv[])
+{
+	int i;
+
+	if ( inetdflag || !tirpcflag) {
+		for (i = 1; i < argc; i++) {
+			if (streq(argv[i], "-s")) {
+			        if(!check_nettype( argv[i + 1], valid_i_nettypes ))
+				  return 0;
+				write_inetd_register(argv[i + 1]);
+				i++;
+			}
+		}
+	} else {
+		for (i = 1; i < argc; i++)
+		        if (streq(argv[i], "-s")) {
+			        if(!check_nettype( argv[i + 1], valid_ti_nettypes ))
+				  return 0;
+				write_nettype_register(argv[i + 1]);
+				i++;
+			} else if (streq(argv[i], "-n")) {
+				write_netid_register(argv[i + 1]);
+				i++;
+			}
+	}
+	return 1;
+}
+
+/*
+ * Add another argument to the arg list
+ */
+static void
+addarg(const char *cp)
+{
+	if (argcount >= ARGLISTLEN) {
+		f_print(stderr, "rpcgen: too many defines\n");
+		crash();
+		/*NOTREACHED*/
+	}
+	arglist[argcount++] = cp;
+
+}
+
+static void
+putarg(int whereto, const char *cp)
+{
+	if (whereto >= ARGLISTLEN) {
+		f_print(stderr, "rpcgen: arglist coding error\n");
+		crash();
+		/*NOTREACHED*/
+	}
+	arglist[whereto] = cp;
+}
+
+/*
+ * if input file is stdin and an output file is specified then complain
+ * if the file already exists. Otherwise the file may get overwritten
+ * If input file does not exist, exit with an error
+ */
+
+static void
+checkfiles(const char *infile, const char *outfile)
+{
+
+  struct stat buf;
+
+  if(infile)			/* infile ! = NULL */
+    if(stat(infile,&buf) < 0)
+      {
+	perror(infile);
+	crash();
+      };
+  if (outfile) {
+    if (stat(outfile, &buf) < 0)
+      return;			/* file does not exist */
+    else {
+      f_print(stderr,
+	      "file '%s' already exists and may be overwritten\n", outfile);
+      crash();
+    }
+  }
+}
+
+/*
+ * Parse command line arguments
+ */
+static int
+parseargs(int argc, const char *argv[], struct commandline *cmd)
+{
+	int i;
+	int j;
+	int c;
+	char flag[(1 << 8 * sizeof(char))];
+	int nflags;
+
+	cmdname = argv[0];
+	cmd->infile = cmd->outfile = NULL;
+	if (argc < 2) {
+		return (0);
+	}
+	allfiles = 0;
+	flag['c'] = 0;
+	flag['h'] = 0;
+	flag['l'] = 0;
+	flag['m'] = 0;
+	flag['o'] = 0;
+	flag['s'] = 0;
+	flag['n'] = 0;
+	flag['t'] = 0;
+	flag['S'] = 0;
+	flag['C'] = 0;
+	for (i = 1; i < argc; i++) {
+		if (argv[i][0] != '-') {
+			if (cmd->infile) {
+			        f_print( stderr, "Cannot specify more than one input file!\n");
+
+				return (0);
+			}
+			cmd->infile = argv[i];
+		} else {
+			for (j = 1; argv[i][j] != 0; j++) {
+				c = argv[i][j];
+				switch (c) {
+				case 'a':
+					allfiles = 1;
+					break;
+				case 'c':
+				case 'h':
+				case 'l':
+				case 'm':
+				case 't':
+					if (flag[c]) {
+						return (0);
+					}
+					flag[c] = 1;
+					break;
+				case 'S':
+					/* sample flag: Ss or Sc.
+					   Ss means set flag['S'];
+					   Sc means set flag['C']; */
+					c = argv[i][++j];  /* get next char */
+					if( c == 's' )
+					  c = 'S';
+					else if( c == 'c' )
+					  c = 'C';
+					else
+					  return( 0 );
+
+					if (flag[c]) {
+						return (0);
+					}
+					flag[c] = 1;
+					break;
+				case 'C':  /* ANSI C syntax */
+					Cflag = 1;
+					break;
+
+#ifdef __GNU_LIBRARY__
+				case 'k':  /* K&R C syntax */
+					Cflag = 0;
+					break;
+
+#endif
+				case 'b':  /* turn TIRPC flag off for
+					    generating backward compatible
+					    */
+					tirpcflag = 0;
+					break;
+
+#ifdef __GNU_LIBRARY__
+				case '5':  /* turn TIRPC flag on for
+					    generating SysVr4 compatible
+					    */
+					tirpcflag = 1;
+					break;
+
+#endif
+				case 'I':
+					inetdflag = 1;
+					break;
+				case 'N':
+					newstyle = 1;
+					break;
+				case 'L':
+					logflag = 1;
+					break;
+				case 'K':
+					if (++i == argc) {
+						return (0);
+					}
+					svcclosetime = argv[i];
+					goto nextarg;
+				case 'T':
+					tblflag = 1;
+					break;
+				case 'i' :
+				  	if (++i == argc) {
+						return (0);
+					}
+					inlineflag = atoi(argv[i]);
+					goto nextarg;
+				case 'n':
+				case 'o':
+				case 's':
+					if (argv[i][j - 1] != '-' ||
+					    argv[i][j + 1] != 0) {
+						return (0);
+					}
+					flag[c] = 1;
+					if (++i == argc) {
+						return (0);
+					}
+					if (c == 's') {
+						if (!streq(argv[i], "udp") &&
+						    !streq(argv[i], "tcp")) {
+							return (0);
+						}
+					} else if (c == 'o') {
+						if (cmd->outfile) {
+							return (0);
+						}
+						cmd->outfile = argv[i];
+					}
+					goto nextarg;
+				case 'D':
+					if (argv[i][j - 1] != '-') {
+						return (0);
+					}
+					(void) addarg(argv[i]);
+					goto nextarg;
+				case 'Y':
+					if (++i == argc) {
+						return (0);
+					}
+					(void) strcpy(pathbuf, argv[i]);
+					(void) strcat(pathbuf, "/cpp");
+					CPP = pathbuf;
+					cppDefined = 1;
+					goto nextarg;
+
+
+
+				default:
+					return (0);
+				}
+			}
+	nextarg:
+			;
+		}
+	}
+
+	cmd->cflag = flag['c'];
+	cmd->hflag = flag['h'];
+	cmd->lflag = flag['l'];
+	cmd->mflag = flag['m'];
+	cmd->nflag = flag['n'];
+	cmd->sflag = flag['s'];
+	cmd->tflag = flag['t'];
+	cmd->Ssflag = flag['S'];
+	cmd->Scflag = flag['C'];
+
+	if( tirpcflag ) {
+	  pmflag = inetdflag ? 0 : 1;	  /* pmflag or inetdflag is always TRUE */
+	  if( (inetdflag && cmd->nflag)) { /* netid not allowed with inetdflag */
+	    f_print(stderr, "Cannot use netid flag with inetd flag!\n");
+	    return (0);
+	  }
+	} else {  /* 4.1 mode */
+	  pmflag = 0;               /* set pmflag only in tirpcmode */
+#ifndef __GNU_LIBRARY__
+	  inetdflag = 1;            /* inetdflag is TRUE by default */
+#endif
+	  if( cmd->nflag ) {          /* netid needs TIRPC */
+	    f_print( stderr, "Cannot use netid flag without TIRPC!\n");
+	    return( 0 );
+	  }
+	}
+
+	if( newstyle && ( tblflag || cmd->tflag) ) {
+	  f_print( stderr, "Cannot use table flags with newstyle!\n");
+	  return( 0 );
+	}
+
+	/* check no conflicts with file generation flags */
+	nflags = cmd->cflag + cmd->hflag + cmd->lflag + cmd->mflag +
+		cmd->sflag + cmd->nflag + cmd->tflag + cmd->Ssflag + cmd->Scflag;
+
+	if (nflags == 0) {
+		if (cmd->outfile != NULL || cmd->infile == NULL) {
+			return (0);
+		}
+	} else if (nflags > 1) {
+	        f_print( stderr, "Cannot have more than one file generation flag!\n");
+		return (0);
+	}
+	return (1);
+}
+
+static void
+usage(void)
+{
+	f_print(stderr, "usage:  %s infile\n", cmdname);
+	f_print(stderr, "\t%s [-a][-b][-C][-Dname[=value]] -i size  [-I [-K seconds]] [-L][-N][-T] infile\n",
+			cmdname);
+	f_print(stderr, "\t%s [-c | -h | -l | -m | -t | -Sc | -Ss] [-o outfile] [infile]\n",
+			cmdname);
+	f_print(stderr, "\t%s [-s nettype]* [-o outfile] [infile]\n", cmdname);
+	f_print(stderr, "\t%s [-n netid]* [-o outfile] [infile]\n", cmdname);
+	options_usage();
+	exit(1);
+}
+
+static void
+options_usage(void)
+{
+	f_print(stderr, "options:\n");
+	f_print(stderr, "-a\t\tgenerate all files, including samples\n");
+	f_print(stderr, "-b\t\tbackward compatibility mode (generates code for SunOS 4.1)\n");
+	f_print(stderr, "-c\t\tgenerate XDR routines\n");
+	f_print(stderr, "-C\t\tANSI C mode\n");
+	f_print(stderr, "-Dname[=value]\tdefine a symbol (same as #define)\n");
+	f_print(stderr, "-h\t\tgenerate header file\n");
+	f_print(stderr, "-i size\t\tsize at which to start generating inline code\n");
+	f_print(stderr, "-I\t\tgenerate code for inetd support in server (for SunOS 4.1)\n");
+	f_print(stderr, "-K seconds\tserver exits after K seconds of inactivity\n");
+	f_print(stderr, "-l\t\tgenerate client side stubs\n");
+	f_print(stderr, "-L\t\tserver errors will be printed to syslog\n");
+	f_print(stderr, "-m\t\tgenerate server side stubs\n");
+	f_print(stderr, "-n netid\tgenerate server code that supports named netid\n");
+	f_print(stderr, "-N\t\tsupports multiple arguments and call-by-value\n");
+	f_print(stderr, "-o outfile\tname of the output file\n");
+	f_print(stderr, "-s nettype\tgenerate server code that supports named nettype\n");
+	f_print(stderr, "-Sc\t\tgenerate sample client code that uses remote procedures\n");
+	f_print(stderr, "-Ss\t\tgenerate sample server code that defines remote procedures\n");
+	f_print(stderr, "-t\t\tgenerate RPC dispatch table\n");
+	f_print(stderr, "-T\t\tgenerate code to support RPC dispatch tables\n");
+	f_print(stderr, "-Y path\t\tdirectory name to find C preprocessor (cpp)\n");
+
+	exit(1);
+}
diff --git a/external/rpc_win32/RPCGEN/rpc_parse.c b/external/rpc_win32/RPCGEN/rpc_parse.c
new file mode 100644
index 0000000..29c553b
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_parse.c
@@ -0,0 +1,622 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * From: @(#)rpc_parse.c 1.8 89/02/22 (C) 1987 SMI
+ */
+char parse_rcsid[] = 
+  "$Id: rpc_parse.c,v 1.1.1.1 2000/10/29 20:55:04 warmerda Exp $";
+
+/*
+ * rpc_parse.c, Parser for the RPC protocol compiler 
+ * Copyright (C) 1987 Sun Microsystems, Inc.
+ */
+#include <stdio.h>
+#include <string.h>
+#include "rpc/types.h"
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+#define ARGNAME "arg"
+
+static void isdefined(definition *defp);
+static void def_struct(definition *defp);
+static void def_program(definition *defp);
+static void def_enum(definition *defp);
+static void def_const(definition *defp);
+static void def_union(definition *defp);
+static void check_type_name(const char *name, int new_type);
+static void def_typedef(definition *defp);
+static void get_declaration(declaration *dec, defkind dkind);
+static void get_prog_declaration(declaration *dec, defkind dkind, int num);
+static void get_type(const char **prefixp, const char **typep, defkind dkind);
+static void unsigned_dec(const char **typep);
+
+/*
+ * return the next definition you see
+ */
+definition *
+get_definition(void)
+{
+	definition *defp;
+	token tok;
+
+	defp = ALLOC(definition);
+	get_token(&tok);
+	switch (tok.kind) {
+	case TOK_STRUCT:
+		def_struct(defp);
+		break;
+	case TOK_UNION:
+		def_union(defp);
+		break;
+	case TOK_TYPEDEF:
+		def_typedef(defp);
+		break;
+	case TOK_ENUM:
+		def_enum(defp);
+		break;
+	case TOK_PROGRAM:
+		def_program(defp);
+		break;
+	case TOK_CONST:
+		def_const(defp);
+		break;
+	case TOK_EOF:
+		return (NULL);
+	default:
+		error("definition keyword expected");
+	}
+	scan(TOK_SEMICOLON, &tok);
+	isdefined(defp);
+	return (defp);
+}
+
+static void
+isdefined(definition *defp)
+{
+	STOREVAL(&defined, defp);
+}
+
+static void
+def_struct(definition *defp)
+{
+	token tok;
+	declaration dec;
+	decl_list *decls;
+	decl_list **tailp;
+
+	defp->def_kind = DEF_STRUCT;
+
+	scan(TOK_IDENT, &tok);
+	defp->def_name = tok.str;
+	scan(TOK_LBRACE, &tok);
+	tailp = &defp->def.st.decls;
+	do {
+		get_declaration(&dec, DEF_STRUCT);
+		decls = ALLOC(decl_list);
+		decls->decl = dec;
+		*tailp = decls;
+		tailp = &decls->next;
+		scan(TOK_SEMICOLON, &tok);
+		peek(&tok);
+	} while (tok.kind != TOK_RBRACE);
+	get_token(&tok);
+	*tailp = NULL;
+}
+
+static void
+def_program(definition *defp)
+{
+	token tok;
+	declaration dec;
+	decl_list *decls;
+	decl_list **tailp;
+	version_list *vlist;
+	version_list **vtailp;
+	proc_list *plist;
+	proc_list **ptailp;
+	int num_args;
+	bool_t isvoid = FALSE; /* whether first argument is void */
+	defp->def_kind = DEF_PROGRAM;
+	scan(TOK_IDENT, &tok);
+	defp->def_name = tok.str;
+	scan(TOK_LBRACE, &tok);
+	vtailp = &defp->def.pr.versions;
+	tailp = &defp->def.st.decls;
+	scan(TOK_VERSION, &tok);
+	do {
+		scan(TOK_IDENT, &tok);
+		vlist = ALLOC(version_list);
+		vlist->vers_name = tok.str;
+		scan(TOK_LBRACE, &tok);
+		ptailp = &vlist->procs;
+		do {
+			/* get result type */
+			plist = ALLOC(proc_list);
+			get_type(&plist->res_prefix, &plist->res_type, 
+				 DEF_PROGRAM);
+			if (streq(plist->res_type, "opaque")) {
+				error("illegal result type");
+			}
+			scan(TOK_IDENT, &tok);
+			plist->proc_name = tok.str;
+			scan(TOK_LPAREN, &tok);
+			/* get args - first one*/
+			num_args = 1;
+			isvoid = FALSE;
+			/* type of DEF_PROGRAM in the first 
+			 * get_prog_declaration and DEF_STURCT in the next
+			 * allows void as argument if it is the only argument
+			 */
+			get_prog_declaration(&dec, DEF_PROGRAM, num_args);
+			if (streq(dec.type, "void"))
+			  isvoid = TRUE;
+			decls = ALLOC(decl_list);
+			plist->args.decls = decls;
+			decls->decl = dec;
+			tailp = &decls->next;
+			/* get args */
+			while(peekscan(TOK_COMMA, &tok)) {
+			  num_args++;
+			  get_prog_declaration(&dec, DEF_STRUCT, 
+					       num_args);
+			  decls = ALLOC(decl_list);
+			  decls->decl = dec;
+			  *tailp = decls;
+			  if (streq(dec.type, "void"))
+			    isvoid = TRUE;
+			  tailp = &decls->next;
+			}
+			/* multiple arguments are only allowed in newstyle */
+			if( !newstyle && num_args > 1 ) {
+			  error("only one argument is allowed" );
+			}
+			if (isvoid && num_args > 1) { 
+			  error("illegal use of void in program definition");
+			}
+			*tailp = NULL;
+			scan(TOK_RPAREN, &tok);
+			scan(TOK_EQUAL, &tok);
+			scan_num(&tok);
+			scan(TOK_SEMICOLON, &tok);
+			plist->proc_num = tok.str;
+			plist->arg_num = num_args;
+			*ptailp = plist;
+			ptailp = &plist->next;
+			peek(&tok);
+		} while (tok.kind != TOK_RBRACE);
+		*ptailp = NULL;
+		*vtailp = vlist;
+		vtailp = &vlist->next;
+		scan(TOK_RBRACE, &tok);
+		scan(TOK_EQUAL, &tok);
+		scan_num(&tok);
+		vlist->vers_num = tok.str;
+		/* make the argument structure name for each arg*/
+		for(plist = vlist->procs; plist != NULL; 
+		    plist = plist->next) {
+			plist->args.argname = make_argname(plist->proc_name,
+							   vlist->vers_num); 
+			/* free the memory ??*/
+		}
+		scan(TOK_SEMICOLON, &tok);
+		scan2(TOK_VERSION, TOK_RBRACE, &tok);
+	} while (tok.kind == TOK_VERSION);
+	scan(TOK_EQUAL, &tok);
+	scan_num(&tok);
+	defp->def.pr.prog_num = tok.str;
+	*vtailp = NULL;
+}
+
+
+static void
+def_enum(definition *defp)
+{
+	token tok;
+	enumval_list *elist;
+	enumval_list **tailp;
+
+	defp->def_kind = DEF_ENUM;
+	scan(TOK_IDENT, &tok);
+	defp->def_name = tok.str;
+	scan(TOK_LBRACE, &tok);
+	tailp = &defp->def.en.vals;
+	do {
+		scan(TOK_IDENT, &tok);
+		elist = ALLOC(enumval_list);
+		elist->name = tok.str;
+		elist->assignment = NULL;
+		scan3(TOK_COMMA, TOK_RBRACE, TOK_EQUAL, &tok);
+		if (tok.kind == TOK_EQUAL) {
+			scan_num(&tok);
+			elist->assignment = tok.str;
+			scan2(TOK_COMMA, TOK_RBRACE, &tok);
+		}
+		*tailp = elist;
+		tailp = &elist->next;
+	} while (tok.kind != TOK_RBRACE);
+	*tailp = NULL;
+}
+
+static void
+def_const(definition *defp)
+{
+	token tok;
+
+	defp->def_kind = DEF_CONST;
+	scan(TOK_IDENT, &tok);
+	defp->def_name = tok.str;
+	scan(TOK_EQUAL, &tok);
+	scan2(TOK_IDENT, TOK_STRCONST, &tok);
+	defp->def.co = tok.str;
+}
+
+static void
+def_union(definition *defp)
+{
+  token tok;
+  declaration dec;
+  case_list *cases;
+/*  case_list *tcase; */
+  case_list **tailp;
+  int flag;
+
+  defp->def_kind = DEF_UNION;
+  scan(TOK_IDENT, &tok);
+  defp->def_name = tok.str;
+  scan(TOK_SWITCH, &tok);
+  scan(TOK_LPAREN, &tok);
+  get_declaration(&dec, DEF_UNION);
+  defp->def.un.enum_decl = dec;
+  tailp = &defp->def.un.cases;
+  scan(TOK_RPAREN, &tok);
+  scan(TOK_LBRACE, &tok);
+  scan(TOK_CASE, &tok);
+  while (tok.kind == TOK_CASE) {
+    scan2(TOK_IDENT, TOK_CHARCONST, &tok);
+    cases = ALLOC(case_list);
+    cases->case_name = tok.str;
+    scan(TOK_COLON, &tok);
+    /* now peek at next token */
+    flag=0;
+    if(peekscan(TOK_CASE,&tok))
+      {
+
+	do 
+	  {
+	    scan2(TOK_IDENT, TOK_CHARCONST, &tok);
+	    cases->contflag=1;	/* continued case statement */
+	    *tailp = cases;
+	    tailp = &cases->next;
+	    cases = ALLOC(case_list);
+	    cases->case_name = tok.str;
+	    scan(TOK_COLON, &tok);
+      
+	  }while(peekscan(TOK_CASE,&tok));
+      }
+    else
+      if(flag)
+	{
+
+	  *tailp = cases;
+	  tailp = &cases->next;
+	  cases = ALLOC(case_list);
+	};
+
+    get_declaration(&dec, DEF_UNION);
+    cases->case_decl = dec;
+    cases->contflag=0;		/* no continued case statement */
+    *tailp = cases;
+    tailp = &cases->next;
+    scan(TOK_SEMICOLON, &tok);
+
+    scan3(TOK_CASE, TOK_DEFAULT, TOK_RBRACE, &tok);
+  }
+  *tailp = NULL;
+  if (tok.kind == TOK_DEFAULT) {
+    scan(TOK_COLON, &tok);
+    get_declaration(&dec, DEF_UNION);
+    defp->def.un.default_decl = ALLOC(declaration);
+    *defp->def.un.default_decl = dec;
+    scan(TOK_SEMICOLON, &tok);
+    scan(TOK_RBRACE, &tok);
+  } else {
+    defp->def.un.default_decl = NULL;
+  }
+}
+
+static const char *reserved_words[] =
+{
+  "array",
+  "bytes",
+  "destroy",
+  "free",
+  "getpos",
+  "inline",
+  "pointer",
+  "reference",
+  "setpos",
+  "sizeof",
+  "union",
+  "vector",
+  NULL
+  };
+
+static const char *reserved_types[] =
+{
+  "opaque",
+  "string",
+  NULL
+  };
+
+/*
+ * check that the given name is not one that would eventually result in
+ * xdr routines that would conflict with internal XDR routines. 
+ */
+static void check_type_name(const char *name, int new_type)
+{
+  int i;
+  char tmp[100];
+
+  for( i = 0; reserved_words[i] != NULL; i++ ) {
+    if( strcmp( name, reserved_words[i] ) == 0 ) {
+      sprintf(tmp, 
+	      "illegal (reserved) name :\'%s\' in type definition", name );
+      error(tmp);
+    }
+  }
+  if( new_type ) {
+    for( i = 0; reserved_types[i] != NULL; i++ ) {
+      if( strcmp( name, reserved_types[i] ) == 0 ) {
+	sprintf(tmp, 
+		"illegal (reserved) name :\'%s\' in type definition", name );
+	error(tmp);
+      }
+    }
+  }
+}
+
+
+
+static void
+def_typedef(definition *defp)
+{
+	declaration dec;
+
+	defp->def_kind = DEF_TYPEDEF;
+	get_declaration(&dec, DEF_TYPEDEF);
+	defp->def_name = dec.name;
+	check_type_name(dec.name, 1);
+	defp->def.ty.old_prefix = dec.prefix;
+	defp->def.ty.old_type = dec.type;
+	defp->def.ty.rel = dec.rel;
+	defp->def.ty.array_max = dec.array_max;
+}
+
+static void
+get_declaration(declaration *dec, defkind dkind)
+{
+	token tok;
+
+	get_type(&dec->prefix, &dec->type, dkind);
+	dec->rel = REL_ALIAS;
+	if (streq(dec->type, "void")) {
+		return;
+	}
+
+	check_type_name(dec->type, 0);
+
+	scan2(TOK_STAR, TOK_IDENT, &tok);
+	if (tok.kind == TOK_STAR) {
+		dec->rel = REL_POINTER;
+		scan(TOK_IDENT, &tok);
+	}
+	dec->name = tok.str;
+	if (peekscan(TOK_LBRACKET, &tok)) {
+		if (dec->rel == REL_POINTER) {
+			error("no array-of-pointer declarations -- use typedef");
+		}
+		dec->rel = REL_VECTOR;
+		scan_num(&tok);
+		dec->array_max = tok.str;
+		scan(TOK_RBRACKET, &tok);
+	} else if (peekscan(TOK_LANGLE, &tok)) {
+		if (dec->rel == REL_POINTER) {
+			error("no array-of-pointer declarations -- use typedef");
+		}
+		dec->rel = REL_ARRAY;
+		if (peekscan(TOK_RANGLE, &tok)) {
+			dec->array_max = "~0";	/* unspecified size, use max */
+		} else {
+			scan_num(&tok);
+			dec->array_max = tok.str;
+			scan(TOK_RANGLE, &tok);
+		}
+	}
+	if (streq(dec->type, "opaque")) {
+		if (dec->rel != REL_ARRAY && dec->rel != REL_VECTOR) {
+			error("array declaration expected");
+		}
+	} else if (streq(dec->type, "string")) {
+		if (dec->rel != REL_ARRAY) {
+			error("variable-length array declaration expected");
+		}
+	}
+}
+
+
+static void
+get_prog_declaration(declaration *dec, defkind dkind, int num /* arg number */)
+{
+	token tok;
+	char name[10]; /* argument name */
+
+	if (dkind == DEF_PROGRAM) { 
+	  peek(&tok);
+	  if (tok.kind == TOK_RPAREN) { /* no arguments */
+	    	dec->rel = REL_ALIAS;
+		dec->type = "void";
+		dec->prefix = NULL;
+		dec->name = NULL;
+		return;
+	      }
+	}
+	get_type(&dec->prefix, &dec->type, dkind);
+	dec->rel = REL_ALIAS;
+	if (peekscan(TOK_IDENT, &tok))  /* optional name of argument */
+		strcpy(name, tok.str);
+	else 
+		sprintf(name, "%s%d", ARGNAME, num); /* default name of argument */
+
+	dec->name = (char *) strdup(name); 
+	
+	if (streq(dec->type, "void")) {
+		return;
+	}
+
+	if (streq(dec->type, "opaque")) {
+		error("opaque -- illegal argument type");
+	}
+	if (peekscan(TOK_STAR, &tok)) { 
+	  if (streq(dec->type, "string")) {
+	    error("pointer to string not allowed in program arguments\n");
+	  }
+		dec->rel = REL_POINTER;
+		if (peekscan(TOK_IDENT, &tok))  /* optional name of argument */
+		  dec->name = strdup(tok.str);
+      }
+	  if (peekscan(TOK_LANGLE, &tok)) {
+	    if (!streq(dec->type, "string")) {
+	      error("arrays cannot be declared as arguments to procedures -- use typedef");
+	    }
+		dec->rel = REL_ARRAY;
+		if (peekscan(TOK_RANGLE, &tok)) {
+			dec->array_max = "~0";/* unspecified size, use max */
+		} else {
+			scan_num(&tok);
+			dec->array_max = tok.str;
+			scan(TOK_RANGLE, &tok);
+		}
+	}
+	if (streq(dec->type, "string")) {
+		if (dec->rel != REL_ARRAY) {  /* .x specifies just string as
+					       * type of argument 
+					       * - make it string<>
+					       */
+			dec->rel = REL_ARRAY;
+			dec->array_max = "~0";/* unspecified size, use max */
+		}
+	}
+}
+
+
+
+static void
+get_type(const char **prefixp, const char **typep, defkind dkind)
+{
+	token tok;
+
+	*prefixp = NULL;
+	get_token(&tok);
+	switch (tok.kind) {
+	case TOK_IDENT:
+		*typep = tok.str;
+		break;
+	case TOK_STRUCT:
+	case TOK_ENUM:
+	case TOK_UNION:
+		*prefixp = tok.str;
+		scan(TOK_IDENT, &tok);
+		*typep = tok.str;
+		break;
+	case TOK_UNSIGNED:
+		unsigned_dec(typep);
+		break;
+	case TOK_SHORT:
+		*typep = "short";
+		(void) peekscan(TOK_INT, &tok);
+		break;
+	case TOK_LONG:
+		*typep = "long";
+		(void) peekscan(TOK_INT, &tok);
+		break;
+	case TOK_VOID:
+		if (dkind != DEF_UNION && dkind != DEF_PROGRAM) {
+			error("voids allowed only inside union and program definitions with one argument");
+		}
+		*typep = tok.str;
+		break;
+	case TOK_STRING:
+	case TOK_OPAQUE:
+	case TOK_CHAR:
+	case TOK_INT:
+	case TOK_FLOAT:
+	case TOK_DOUBLE:
+	case TOK_BOOL:
+		*typep = tok.str;
+		break;
+	default:
+		error("expected type specifier");
+	}
+}
+
+static void
+unsigned_dec(const char **typep)
+{
+	token tok;
+
+	peek(&tok);
+	switch (tok.kind) {
+	case TOK_CHAR:
+		get_token(&tok);
+		*typep = "u_char";
+		break;
+	case TOK_SHORT:
+		get_token(&tok);
+		*typep = "u_short";
+		(void) peekscan(TOK_INT, &tok);
+		break;
+	case TOK_LONG:
+		get_token(&tok);
+		*typep = "u_long";
+		(void) peekscan(TOK_INT, &tok);
+		break;
+	case TOK_INT:
+		get_token(&tok);
+		*typep = "u_int";
+		break;
+	default:
+		*typep = "u_int";
+		break;
+	}
+}
diff --git a/external/rpc_win32/RPCGEN/rpc_parse.h b/external/rpc_win32/RPCGEN/rpc_parse.h
new file mode 100644
index 0000000..07c1f67
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_parse.h
@@ -0,0 +1,168 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*      @(#)rpc_parse.h  1.3  90/08/29  (C) 1987 SMI   */
+
+/*
+ * rpc_parse.h, Definitions for the RPCL parser 
+ */
+
+enum defkind {
+	DEF_CONST,
+	DEF_STRUCT,
+	DEF_UNION,
+	DEF_ENUM,
+	DEF_TYPEDEF,
+	DEF_PROGRAM
+};
+typedef enum defkind defkind;
+
+typedef const char *const_def;
+
+enum relation {
+	REL_VECTOR,	/* fixed length array */
+	REL_ARRAY,	/* variable length array */
+	REL_POINTER,	/* pointer */
+	REL_ALIAS,	/* simple */
+};
+typedef enum relation relation;
+
+struct typedef_def {
+	const char *old_prefix;
+	const char *old_type;
+	relation rel;
+	const char *array_max;
+};
+typedef struct typedef_def typedef_def;
+
+struct enumval_list {
+	const char *name;
+	const char *assignment;
+	struct enumval_list *next;
+};
+typedef struct enumval_list enumval_list;
+
+struct enum_def {
+	enumval_list *vals;
+};
+typedef struct enum_def enum_def;
+
+struct declaration {
+	const char *prefix;
+	const char *type;
+	const char *name;
+	relation rel;
+	const char *array_max;
+};
+typedef struct declaration declaration;
+
+struct decl_list {
+	declaration decl;
+	struct decl_list *next;
+};
+typedef struct decl_list decl_list;
+
+struct struct_def {
+	decl_list *decls;
+};
+typedef struct struct_def struct_def;
+
+struct case_list {
+	const char *case_name;
+	int contflag;
+	declaration case_decl;
+	struct case_list *next;
+};
+typedef struct case_list case_list;
+
+struct union_def {
+	declaration enum_decl;
+	case_list *cases;
+	declaration *default_decl;
+};
+typedef struct union_def union_def;
+
+struct arg_list {
+	const char *argname; /* name of struct for arg*/
+	decl_list *decls;
+};
+	
+typedef struct arg_list arg_list;
+
+struct proc_list {
+	const char *proc_name;
+	const char *proc_num;
+	arg_list args;
+	int arg_num;
+	const char *res_type;
+	const char *res_prefix;
+	struct proc_list *next;
+};
+typedef struct proc_list proc_list;
+
+struct version_list {
+	const char *vers_name;
+	const char *vers_num;
+	proc_list *procs;
+	struct version_list *next;
+};
+typedef struct version_list version_list;
+
+struct program_def {
+	const char *prog_num;
+	version_list *versions;
+};
+typedef struct program_def program_def;
+
+struct definition {
+	const char *def_name;
+	defkind def_kind;
+	union {
+		const_def co;
+		struct_def st;
+		union_def un;
+		enum_def en;
+		typedef_def ty;
+		program_def pr;
+	} def;
+};
+typedef struct definition definition;
+
+definition *get_definition(void);
+
+
+struct bas_type
+{
+  const char *name;
+  int length;
+  struct bas_type *next;
+};
+
+typedef struct bas_type bas_type;
diff --git a/external/rpc_win32/RPCGEN/rpc_sample.c b/external/rpc_win32/RPCGEN/rpc_sample.c
new file mode 100644
index 0000000..dec7612
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_sample.c
@@ -0,0 +1,253 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/* 
+ * From: @(#)rpc_sample.c  1.1  90/08/30  (C) 1987 SMI
+ */
+char sample_rcsid[] = 
+  "$Id: rpc_sample.c,v 1.1.1.1 2000/10/29 20:55:05 warmerda Exp $";
+
+/*
+ * rpc_sample.c, Sample client-server code outputter for the RPC protocol compiler
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+
+static char RQSTP[] = "rqstp";
+
+static void write_sample_client(const char *program_name, version_list *vp);
+static void write_sample_server(definition *def);
+static void return_type(proc_list *plist);
+
+
+void
+write_sample_svc(definition *def)
+{
+
+	if (def->def_kind != DEF_PROGRAM) 
+	  return;
+	write_sample_server(def);
+}
+
+
+int
+write_sample_clnt(definition *def)
+{
+        version_list *vp;
+	int count = 0;
+
+	if (def->def_kind != DEF_PROGRAM) 
+	  return( 0 );
+	/* generate sample code for each version */
+	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+	  write_sample_client(def->def_name, vp );
+	  ++count;
+	}
+	return( count );
+}
+
+
+static void
+write_sample_client(const char *program_name, version_list *vp)
+{
+  proc_list *proc;
+  int i;
+  decl_list *l;
+
+  f_print(fout, "\n\nvoid\n" );
+  pvname( program_name, vp->vers_num );
+  if( Cflag )
+    f_print(fout,"( char* host )\n{\n" );
+  else
+    f_print(fout, "(host)\nchar *host;\n{\n" );
+  f_print(fout, "\tCLIENT *clnt;\n");
+
+  i = 0;
+  for (proc = vp->procs; proc != NULL; proc = proc->next) {
+      f_print(fout, "\t");
+      ptype(proc->res_prefix, proc->res_type, 1);
+      f_print(fout, " *result_%d;\n",++i);
+      /* print out declarations for arguments */
+      if( proc->arg_num < 2 && !newstyle) {
+	f_print( fout, "\t" );
+	if( !streq( proc->args.decls->decl.type, "void") )
+	  ptype(proc->args.decls->decl.prefix, proc->args.decls->decl.type, 1);
+	else
+	  f_print(fout, "char* ");  /* cannot have "void" type */
+	f_print(fout, " ");
+	pvname( proc->proc_name, vp->vers_num );
+	f_print(fout, "_arg;\n");
+      } else if (!streq( proc->args.decls->decl.type, "void")) {
+	for (l = proc->args.decls; l != NULL; l = l->next) {
+	  f_print( fout, "\t" );
+	  ptype(l->decl.prefix, l->decl.type, 1);
+	  f_print( fout, " ");
+	  pvname( proc->proc_name, vp->vers_num );
+	  f_print(fout, "_%s;\n", l->decl.name );
+/*	  pdeclaration(proc->args.argname, &l->decl, 1, ";\n" );*/
+	}
+      }
+    }
+
+  /* generate creation of client handle */
+  f_print(fout, "\tclnt = clnt_create(host, %s, %s, \"%s\");\n", 
+	  program_name, vp->vers_name, tirpcflag? "netpath" : "udp");
+  f_print(fout, "\tif (clnt == NULL) {\n");
+  f_print(fout, "\t\tclnt_pcreateerror(host);\n");
+  f_print(fout, "\t\texit(1);\n\t}\n");
+
+  /* generate calls to procedures */
+  i = 0;
+  for (proc = vp->procs; proc != NULL; proc = proc->next) {
+      f_print(fout, "\tresult_%d = ",++i);      
+      pvname(proc->proc_name, vp->vers_num);
+      if (proc->arg_num < 2 && !newstyle) {
+	f_print(fout, "(" );
+	if( streq( proc->args.decls->decl.type, "void") )  /* cast to void* */
+	  f_print(fout, "(void*)");
+	f_print(fout, "&" );
+	pvname(proc->proc_name, vp->vers_num );
+	f_print(fout, "_arg, clnt);\n");
+      } else if (streq( proc->args.decls->decl.type, "void")) {
+	    f_print(fout, "(clnt);\n");
+	  }
+      else {
+	f_print(fout, "(");
+	for (l = proc->args.decls;  l != NULL; l = l->next) {
+	  pvname( proc->proc_name, vp->vers_num );
+	  f_print(fout, "_%s, ", l->decl.name);
+	}
+	f_print(fout, "clnt);\n");
+      }
+      f_print(fout, "\tif (result_%d == NULL) {\n", i);
+      f_print(fout, "\t\tclnt_perror(clnt, \"call failed:\");\n");
+      f_print(fout, "\t}\n");
+    }
+
+  f_print(fout, "\tclnt_destroy( clnt );\n" );
+  f_print(fout, "}\n");
+}
+
+static void
+write_sample_server(definition *def)
+{
+	version_list *vp;
+	proc_list *proc;
+
+	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+		for (proc = vp->procs; proc != NULL; proc = proc->next) {
+			f_print(fout, "\n");
+/*			if( Cflag )
+			  f_print( fout, "extern \"C\"{\n");
+*/
+			return_type(proc);
+			f_print(fout, "* \n");
+			if( Cflag )
+			  pvname_svc(proc->proc_name, vp->vers_num);
+			else
+			  pvname(proc->proc_name, vp->vers_num);
+			printarglist( proc, RQSTP, "struct svc_req *" );
+
+			f_print(fout, "{\n");
+			f_print(fout, "\n\tstatic ");
+			if( !streq( proc->res_type, "void") )
+			  return_type(proc);
+			else
+			  f_print(fout, "char*" );  /* cannot have void type */
+			f_print(fout, " result;\n" /*, proc->res_type*/ /*?*/);
+			f_print(fout, 
+				"\n\t/*\n\t * insert server code here\n\t */\n\n");
+			if( !streq( proc->res_type, "void") )
+			  f_print(fout, "\treturn(&result);\n}\n");
+			else  /* cast back to void * */
+			  f_print(fout, "\treturn((void*) &result);\n}\n"); 
+/*			if( Cflag)
+			  f_print( fout, "};\n");
+*/
+
+		} 		
+	}
+}
+
+
+
+static void
+return_type(proc_list *plist)
+{
+  ptype( plist->res_prefix, plist->res_type, 1 );
+}
+
+void
+add_sample_msg(void)
+{
+	f_print(fout, "/*\n");
+	f_print(fout, " * This is sample code generated by rpcgen.\n");
+	f_print(fout, " * These are only templates and you can use them\n");
+	f_print(fout, " * as a guideline for developing your own functions.\n");
+	f_print(fout, " */\n\n");
+}
+
+void
+write_sample_clnt_main(void)
+{
+  list *l;
+  definition *def;
+  version_list *vp;
+
+  f_print(fout, "\n\n" );
+  if( Cflag )
+    f_print(fout,"main( int argc, char* argv[] )\n{\n" );
+  else
+    f_print(fout, "main(argc, argv)\nint argc;\nchar *argv[];\n{\n" );
+
+  f_print(fout, "\tchar *host;");
+  f_print(fout, "\n\n\tif(argc < 2) {");
+  f_print(fout, "\n\t\tprintf(\"usage: %%s server_host\\n\", argv[0]);\n" );
+  f_print(fout, "\t\texit(1);\n\t}");
+  f_print(fout, "\n\thost = argv[1];\n");
+
+  for (l = defined; l != NULL; l = l->next) {
+		def = l->val;
+		if (def->def_kind != DEF_PROGRAM) {
+			continue;
+		}
+		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+		        f_print( fout, "\t" );
+			pvname(def->def_name, vp->vers_num);
+			f_print( fout, "( host );\n" );
+		      }
+		}
+  f_print(fout, "}\n");
+}
diff --git a/external/rpc_win32/RPCGEN/rpc_scan.c b/external/rpc_win32/RPCGEN/rpc_scan.c
new file mode 100644
index 0000000..f357495
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_scan.c
@@ -0,0 +1,488 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * From: @(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI
+ */
+char scan_rcsid[] = 
+  "$Id: rpc_scan.c,v 1.1.1.1 2000/10/29 20:55:05 warmerda Exp $";
+
+/*
+ * rpc_scan.c, Scanner for the RPC protocol compiler 
+ * Copyright (C) 1987, Sun Microsystems, Inc. 
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdlib.h>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+#define startcomment(where) (where[0] == '/' && where[1] == '*')
+#define endcomment(where) (where[-1] == '*' && where[0] == '/')
+
+static int pushed = 0;	/* is a token pushed */
+static token lasttok;	/* last token, if pushed */
+
+static void unget_token(token *tokp);
+static void findstrconst(const char **str, const char **val);
+static void findchrconst(const char **str, const char **val);
+static void findconst(const char **str, const char **val);
+static void findkind(const char **mark, token *tokp);
+static int cppline(const char *line);
+static int directive(const char *line);
+static void printdirective(const char *line);
+static void docppline(const char *line, int *lineno, const char **fname);
+
+/*
+ * scan expecting 1 given token 
+ */
+void
+scan(tok_kind expect, token *tokp)
+{
+	get_token(tokp);
+	if (tokp->kind != expect) {
+		expected1(expect);
+	}
+}
+
+/*
+ * scan expecting any of the 2 given tokens 
+ */
+void
+scan2(tok_kind expect1, tok_kind expect2, token *tokp)
+{
+	get_token(tokp);
+	if (tokp->kind != expect1 && tokp->kind != expect2) {
+		expected2(expect1, expect2);
+	}
+}
+
+/*
+ * scan expecting any of the 3 given token 
+ */
+void
+scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp)
+{
+	get_token(tokp);
+	if (tokp->kind != expect1 && tokp->kind != expect2
+	    && tokp->kind != expect3) {
+		expected3(expect1, expect2, expect3);
+	}
+}
+
+/*
+ * scan expecting a constant, possibly symbolic 
+ */
+void
+scan_num(token *tokp)
+{
+	get_token(tokp);
+	switch (tokp->kind) {
+	case TOK_IDENT:
+		break;
+	default:
+		error("constant or identifier expected");
+	}
+}
+
+/*
+ * Peek at the next token 
+ */
+void
+peek(token *tokp)
+{
+	get_token(tokp);
+	unget_token(tokp);
+}
+
+/*
+ * Peek at the next token and scan it if it matches what you expect 
+ */
+int
+peekscan(tok_kind expect, token *tokp)
+{
+	peek(tokp);
+	if (tokp->kind == expect) {
+		get_token(tokp);
+		return (1);
+	}
+	return (0);
+}
+
+/*
+ * Get the next token, printing out any directive that are encountered. 
+ */
+void
+get_token(token *tokp)
+{
+	int commenting;
+
+	if (pushed) {
+		pushed = 0;
+		*tokp = lasttok;
+		return;
+	}
+	commenting = 0;
+	for (;;) {
+		if (*where == 0) {
+			for (;;) {
+				if (!fgets(curline, MAXLINESIZE, fin)) {
+					tokp->kind = TOK_EOF;
+					*curline = 0;
+					where = curline;
+					return;
+				}
+				linenum++;
+				if (commenting) {
+					break;
+				} else if (cppline(curline)) {
+					docppline(curline, &linenum, 
+						  &infilename);
+				} else if (directive(curline)) {
+					printdirective(curline);
+				} else {
+					break;
+				}
+			}
+			where = curline;
+		} else if (isspace(*where)) {
+			while (isspace(*where)) {
+				where++;	/* eat */
+			}
+		} else if (commenting) {
+			for (where++; *where; where++) {
+				if (endcomment(where)) {
+					where++;
+					commenting--;
+					break;
+				}
+			}
+		} else if (startcomment(where)) {
+			where += 2;
+			commenting++;
+		} else {
+			break;
+		}
+	}
+
+	/*
+	 * 'where' is not whitespace, comment or directive Must be a token! 
+	 */
+	switch (*where) {
+	case ':':
+		tokp->kind = TOK_COLON;
+		where++;
+		break;
+	case ';':
+		tokp->kind = TOK_SEMICOLON;
+		where++;
+		break;
+	case ',':
+		tokp->kind = TOK_COMMA;
+		where++;
+		break;
+	case '=':
+		tokp->kind = TOK_EQUAL;
+		where++;
+		break;
+	case '*':
+		tokp->kind = TOK_STAR;
+		where++;
+		break;
+	case '[':
+		tokp->kind = TOK_LBRACKET;
+		where++;
+		break;
+	case ']':
+		tokp->kind = TOK_RBRACKET;
+		where++;
+		break;
+	case '{':
+		tokp->kind = TOK_LBRACE;
+		where++;
+		break;
+	case '}':
+		tokp->kind = TOK_RBRACE;
+		where++;
+		break;
+	case '(':
+		tokp->kind = TOK_LPAREN;
+		where++;
+		break;
+	case ')':
+		tokp->kind = TOK_RPAREN;
+		where++;
+		break;
+	case '<':
+		tokp->kind = TOK_LANGLE;
+		where++;
+		break;
+	case '>':
+		tokp->kind = TOK_RANGLE;
+		where++;
+		break;
+
+	case '"':
+		tokp->kind = TOK_STRCONST;
+		findstrconst(&where, &tokp->str);
+		break;
+	case '\'':
+		tokp->kind = TOK_CHARCONST;
+		findchrconst(&where, &tokp->str);
+		break;
+
+	case '-':
+	case '0':
+	case '1':
+	case '2':
+	case '3':
+	case '4':
+	case '5':
+	case '6':
+	case '7':
+	case '8':
+	case '9':
+		tokp->kind = TOK_IDENT;
+		findconst(&where, &tokp->str);
+		break;
+
+	default:
+		if (!(isalpha(*where) || *where == '_')) {
+			char buf[100];
+			char *p;
+
+			s_print(buf, "illegal character in file: ");
+			p = buf + strlen(buf);
+			if (isprint(*where)) {
+				s_print(p, "%c", *where);
+			} else {
+				s_print(p, "%d", *where);
+			}
+			error(buf);
+		}
+		findkind(&where, tokp);
+		break;
+	}
+}
+
+static void
+unget_token(token *tokp)
+{
+	lasttok = *tokp;
+	pushed = 1;
+}
+
+static void
+findstrconst(const char **str, const char **val)
+{
+	const char *p;
+	char *tmp;
+	int size;
+
+	p = *str;
+	do {
+		p++;
+	} while (*p && *p != '"');
+	if (*p == 0) {
+		error("unterminated string constant");
+	}
+	p++;
+	size = p - *str;
+	tmp = alloc(size + 1);
+	strncpy(tmp, *str, size);
+	tmp[size] = 0;
+	*val = tmp;
+	*str = p;
+}
+
+static void
+findchrconst(const char **str, const char **val)
+{
+	const char *p;
+	char *tmp;
+	int size;
+
+	p = *str;
+	do {
+		p++;
+	} while (*p && *p != '\'');
+	if (*p == 0) {
+		error("unterminated string constant");
+	}
+	p++;
+	size = p - *str;
+	if (size != 3) {
+		error("empty char string");
+	}
+	tmp = alloc(size + 1);
+	strncpy(tmp, *str, size);
+	tmp[size] = 0;
+	*val = tmp;
+	*str = p;
+}
+
+static void
+findconst(const char **str, const char **val)
+{
+	const char *p;
+	char *tmp;
+	int size;
+
+	p = *str;
+	if (*p == '0' && *(p + 1) == 'x') {
+		p++;
+		do {
+			p++;
+		} while (isxdigit(*p));
+	} else {
+		do {
+			p++;
+		} while (isdigit(*p));
+	}
+	size = p - *str;
+	tmp = alloc(size + 1);
+	strncpy(tmp, *str, size);
+	tmp[size] = 0;
+	*val = tmp;
+	*str = p;
+}
+
+static token symbols[] = {
+			  {TOK_CONST, "const"},
+			  {TOK_UNION, "union"},
+			  {TOK_SWITCH, "switch"},
+			  {TOK_CASE, "case"},
+			  {TOK_DEFAULT, "default"},
+			  {TOK_STRUCT, "struct"},
+			  {TOK_TYPEDEF, "typedef"},
+			  {TOK_ENUM, "enum"},
+			  {TOK_OPAQUE, "opaque"},
+			  {TOK_BOOL, "bool"},
+			  {TOK_VOID, "void"},
+			  {TOK_CHAR, "char"},
+			  {TOK_INT, "int"},
+			  {TOK_UNSIGNED, "unsigned"},
+			  {TOK_SHORT, "short"},
+			  {TOK_LONG, "long"},
+			  {TOK_FLOAT, "float"},
+			  {TOK_DOUBLE, "double"},
+			  {TOK_STRING, "string"},
+			  {TOK_PROGRAM, "program"},
+			  {TOK_VERSION, "version"},
+			  {TOK_EOF, "??????"},
+};
+
+static void
+findkind(const char **mark, token *tokp)
+{
+	int len;
+	token *s;
+	const char *str;
+	char *tmp;
+
+	str = *mark;
+	for (s = symbols; s->kind != TOK_EOF; s++) {
+		len = strlen(s->str);
+		if (strncmp(str, s->str, len) == 0) {
+			if (!isalnum(str[len]) && str[len] != '_') {
+				tokp->kind = s->kind;
+				tokp->str = s->str;
+				*mark = str + len;
+				return;
+			}
+		}
+	}
+	tokp->kind = TOK_IDENT;
+	for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
+	tmp = alloc(len + 1);
+	strncpy(tmp, str, len);
+	tmp[len] = 0;
+	tokp->str = tmp;
+	*mark = str + len;
+}
+
+static int
+cppline(const char *line)
+{
+	return (line == curline && *line == '#');
+}
+
+static int
+directive(const char *line)
+{
+	return (line == curline && *line == '%');
+}
+
+static void
+printdirective(const char *line)
+{
+	f_print(fout, "%s", line + 1);
+}
+
+static void
+docppline(const char *line, int *lineno, const char **fname)
+{
+	char *file;
+	int num;
+	char *p;
+
+	line++;
+	while (isspace(*line)) {
+		line++;
+	}
+	num = atoi(line);
+	while (isdigit(*line)) {
+		line++;
+	}
+	while (isspace(*line)) {
+		line++;
+	}
+	if (*line != '"') {
+		error("preprocessor error");
+	}
+	line++;
+	p = file = alloc(strlen(line) + 1);
+	while (*line && *line != '"') {
+		*p++ = *line++;
+	}
+	if (*line == 0) {
+		error("preprocessor error");
+	}
+	*p = 0;
+	if (*file == 0) {
+		*fname = NULL;
+	} else {
+		*fname = file;
+	}
+	*lineno = num - 1;
+}
diff --git a/external/rpc_win32/RPCGEN/rpc_scan.h b/external/rpc_win32/RPCGEN/rpc_scan.h
new file mode 100644
index 0000000..9a4383d
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_scan.h
@@ -0,0 +1,105 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*      @(#)rpc_scan.h  1.3  90/08/29  (C) 1987 SMI   */
+
+/*
+ * rpc_scan.h, Definitions for the RPCL scanner 
+ */
+
+/*
+ * kinds of tokens 
+ */
+enum tok_kind {
+	TOK_IDENT,
+	TOK_CHARCONST,
+	TOK_STRCONST,
+	TOK_LPAREN,
+	TOK_RPAREN,
+	TOK_LBRACE,
+	TOK_RBRACE,
+	TOK_LBRACKET,
+	TOK_RBRACKET,
+	TOK_LANGLE,
+	TOK_RANGLE,
+	TOK_STAR,
+	TOK_COMMA,
+	TOK_EQUAL,
+	TOK_COLON,
+	TOK_SEMICOLON,
+	TOK_CONST,
+	TOK_STRUCT,
+	TOK_UNION,
+	TOK_SWITCH,
+	TOK_CASE,
+	TOK_DEFAULT,
+	TOK_ENUM,
+	TOK_TYPEDEF,
+	TOK_INT,
+	TOK_SHORT,
+	TOK_LONG,
+	TOK_UNSIGNED,
+	TOK_FLOAT,
+	TOK_DOUBLE,
+	TOK_OPAQUE,
+	TOK_CHAR,
+	TOK_STRING,
+	TOK_BOOL,
+	TOK_VOID,
+	TOK_PROGRAM,
+	TOK_VERSION,
+	TOK_EOF
+};
+typedef enum tok_kind tok_kind;
+
+/*
+ * a token 
+ */
+struct token {
+	tok_kind kind;
+	const char *str;
+};
+typedef struct token token;
+
+
+/*
+ * routine interface 
+ */
+void scan(tok_kind expect, token *tokp);
+void scan2(tok_kind expect1, tok_kind expect2, token *tokp);
+void scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp);
+void scan_num(token *tokp);
+void peek(token *tokp);
+int peekscan(tok_kind expect, token *tokp);
+void get_token(token *tokp);
+void expected1(tok_kind exp1);
+void expected2(tok_kind exp1, tok_kind exp2);
+void expected3(tok_kind exp1, tok_kind exp2, tok_kind exp3);
+
diff --git a/external/rpc_win32/RPCGEN/rpc_svcout.c b/external/rpc_win32/RPCGEN/rpc_svcout.c
new file mode 100644
index 0000000..e36d005
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_svcout.c
@@ -0,0 +1,965 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*
+ * From: @(#)rpc_svcout.c 1.29 89/03/30 (C) 1987 SMI
+ */
+char svcout_rcsid[] =
+  "$Id: rpc_svcout.c,v 1.1.1.1 2000/10/29 20:55:06 warmerda Exp $";
+
+/*
+ * rpc_svcout.c, Server-skeleton outputter for the RPC protocol compiler
+ */
+#include <stdio.h>
+#include <string.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+static char RQSTP[] = "rqstp";
+static char TRANSP[] = "transp";
+static char ARG[] = "argument";
+static char RESULT[] = "result";
+static char ROUTINE[] = "local";
+
+char _errbuf[256];	/* For all messages */
+
+static void internal_proctype(proc_list *plist);
+static void p_xdrfunc(const char *rname, const char *typename);
+static void write_real_program(definition *def);
+static void write_program(definition *def, const char *storage);
+static void printerr(const char *err, const char *transp);
+static void printif(const char *proc, const char *transp,
+		    const char *prefix, const char *arg);
+static void write_inetmost(const char *infile);
+static void print_return(const char *space);
+static void print_pmapunset(const char *space);
+static void print_err_message(const char *space);
+static void write_timeout_func(void);
+static void write_pm_most(const char *infile, int netflag);
+static void write_rpc_svc_fg(const char *infile, const char *sp);
+static void open_log_file(const char *infile, const char *sp);
+
+static void
+p_xdrfunc(const char *rname, const char *typename)
+{
+  if( Cflag )
+    f_print(fout, "\t\txdr_%s = (xdrproc_t) xdr_%s;\n", rname,
+	    stringfix(typename) );
+  else
+    f_print(fout, "\t\txdr_%s = xdr_%s;\n", rname, stringfix(typename) );
+}
+
+void
+internal_proctype(proc_list *plist)
+{
+	f_print(fout, "static ");
+	ptype( plist->res_prefix, plist->res_type, 1 );
+	f_print( fout, "*" );
+}
+
+
+/*
+ * write most of the service, that is, everything but the registrations.
+ */
+void
+write_most(const char *infile /* our name */, int netflag, int nomain)
+{
+	if (inetdflag || pmflag) {
+	        const char *var_type;
+#ifdef __GNU_LIBRARY__
+		/* WHY? */
+		var_type = (nomain? "extern" : "");
+#else
+		var_type = (nomain? "extern" : "static");
+#endif
+		f_print(fout, "%s int _rpcpmstart;", var_type );
+		f_print(fout, "\t\t/* Started by a port monitor ? */\n");
+		f_print(fout, "%s int _rpcfdtype;", var_type );
+		f_print(fout, "\t\t/* Whether Stream or Datagram ? */\n");
+		if (timerflag) {
+			f_print(fout, "%s int _rpcsvcdirty;", var_type );
+			f_print(fout, "\t/* Still serving ? */\n");
+		}
+		write_svc_aux( nomain );
+	}
+	/* write out dispatcher and stubs */
+	write_programs(nomain ? NULL : "static");
+
+        if( nomain )
+	  return;
+
+#ifdef __GNU_LIBRARY__
+	if (Cflag)
+		f_print(fout, "\nint\nmain(int argc, char **argv)\n");
+	else {
+		f_print(fout, "\nint\nmain(argc, argv)\n");
+		f_print(fout, "\tint argc;\n");
+		f_print(fout, "\tchar **argv;\n");
+	}
+#else
+	f_print(fout, "\nmain()\n");
+#endif
+	f_print(fout, "{\n");
+	if (inetdflag) {
+		write_inetmost(infile); /* Includes call to write_rpc_svc_fg() */
+	} else {
+	  if( tirpcflag ) {
+		if (netflag) {
+			f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
+			f_print(fout, "\tstruct netconfig *nconf = NULL;\n");
+		}
+#ifdef WIN32
+		f_print(fout, "#ifdef WIN32\n\trpc_nt_init();\n#endif\n\n");
+#endif
+		f_print(fout, "\tpid_t pid;\n");
+		f_print(fout, "\tint i;\n");
+		f_print(fout, "\tchar mname[FMNAMESZ + 1];\n\n");
+		write_pm_most(infile, netflag);
+		f_print(fout, "\telse {\n");
+		write_rpc_svc_fg(infile, "\t\t");
+		f_print(fout, "\t}\n");
+	      } else {
+		f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
+		f_print(fout, "\n");
+		print_pmapunset("\t");
+	      }
+	}
+
+	if (logflag && !inetdflag) {
+		open_log_file(infile, "\t");
+	}
+}
+
+/*
+ * write a registration for the given transport
+ */
+void
+write_netid_register(const char *transp)
+{
+	list *l;
+	definition *def;
+	version_list *vp;
+	const char *sp;
+	char tmpbuf[32];
+
+	sp = "";
+	f_print(fout, "\n");
+	f_print(fout, "%s\tnconf = getnetconfigent(\"%s\");\n", sp, transp);
+	f_print(fout, "%s\tif (nconf == NULL) {\n", sp);
+	(void) sprintf(_errbuf, "cannot find %s netid.", transp);
+	sprintf(tmpbuf, "%s\t\t", sp);
+	print_err_message(tmpbuf);
+#ifdef WIN32
+	f_print(fout, "#ifdef WIN32\n\trpc_nt_exit();\n#endif\n\n");
+#endif
+	f_print(fout, "%s\t\texit(1);\n", sp);
+	f_print(fout, "%s\t}\n", sp);
+	f_print(fout, "%s\t%s = svc_tli_create(RPC_ANYFD, nconf, 0, 0, 0);\n",
+		sp, TRANSP /*, transp*/  /* ?!?... */ );
+	f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
+	(void) sprintf(_errbuf, "cannot create %s service.", transp);
+	print_err_message(tmpbuf);
+#ifdef WIN32
+	f_print(fout, "#ifdef WIN32\n\trpc_nt_exit();\n#endif\n\n");
+#endif
+	f_print(fout, "%s\t\texit(1);\n", sp);
+	f_print(fout, "%s\t}\n", sp);
+
+	for (l = defined; l != NULL; l = l->next) {
+		def = (definition *) l->val;
+		if (def->def_kind != DEF_PROGRAM) {
+			continue;
+		}
+		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+			f_print(fout,
+				"%s\t(void) rpcb_unset(%s, %s, nconf);\n",
+				sp, def->def_name, vp->vers_name);
+			f_print(fout,
+				"%s\tif (!svc_reg(%s, %s, %s, ",
+				sp, TRANSP, def->def_name, vp->vers_name);
+			pvname(def->def_name, vp->vers_num);
+			f_print(fout, ", nconf)) {\n");
+			(void) sprintf(_errbuf, "unable to register (%s, %s, %s).",
+					def->def_name, vp->vers_name, transp);
+			print_err_message(tmpbuf);
+#ifdef WIN32
+			f_print(fout, "#ifdef WIN32\n\trpc_nt_exit();\n#endif\n\n");
+#endif
+			f_print(fout, "%s\t\texit(1);\n", sp);
+			f_print(fout, "%s\t}\n", sp);
+		}
+	}
+	f_print(fout, "%s\tfreenetconfigent(nconf);\n", sp);
+}
+
+/*
+ * write a registration for the given transport for TLI
+ */
+void
+write_nettype_register(const char *transp)
+{
+	list *l;
+	definition *def;
+	version_list *vp;
+
+	for (l = defined; l != NULL; l = l->next) {
+		def = (definition *) l->val;
+		if (def->def_kind != DEF_PROGRAM) {
+			continue;
+		}
+		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+			f_print(fout, "\tif (!svc_create(");
+			pvname(def->def_name, vp->vers_num);
+			f_print(fout, ", %s, %s, \"%s\")) {\n ",
+				def->def_name, vp->vers_name, transp);
+			(void) sprintf(_errbuf,
+				"unable to create (%s, %s) for %s.",
+					def->def_name, vp->vers_name, transp);
+			print_err_message("\t\t");
+#ifdef WIN32
+			f_print(fout, "#ifdef WIN32\n\trpc_nt_exit();\n#endif\n\n");
+#endif
+			f_print(fout, "\t\texit(1);\n");
+			f_print(fout, "\t}\n");
+		}
+	}
+}
+
+/*
+ * write the rest of the service
+ */
+void
+write_rest(void)
+{
+	f_print(fout, "\n");
+	if (inetdflag) {
+		f_print(fout, "\tif (%s == (SVCXPRT *)NULL) {\n", TRANSP);
+		(void) sprintf(_errbuf, "could not create a handle");
+		print_err_message("\t\t");
+#ifdef WIN32
+		f_print(fout, "#ifdef WIN32\n\trpc_nt_exit();\n#endif\n\n");
+#endif
+		f_print(fout, "\t\texit(1);\n");
+		f_print(fout, "\t}\n");
+		if (timerflag) {
+			f_print(fout, "\tif (_rpcpmstart) {\n");
+			f_print(fout,
+				"\t\t(void) signal(SIGALRM, %s closedown);\n",
+				Cflag? "(SIG_PF)" : "(void(*)())" );
+			f_print(fout, "\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
+			f_print(fout, "\t}\n");
+		}
+	}
+	f_print(fout, "\tsvc_run();\n");
+	(void) sprintf(_errbuf, "svc_run returned");
+	print_err_message("\t");
+#ifdef WIN32
+	f_print(fout, "#ifdef WIN32\n\trpc_nt_exit();\n#endif\n\n");
+#endif
+	f_print(fout, "\texit(1);\n");
+	f_print(fout, "\t/* NOTREACHED */\n");
+	f_print(fout, "}\n");
+}
+
+void
+write_programs(const char *storage)
+{
+	list *l;
+	definition *def;
+
+	/* write out stubs for procedure  definitions */
+	for (l = defined; l != NULL; l = l->next) {
+		def = (definition *) l->val;
+		if (def->def_kind == DEF_PROGRAM) {
+			write_real_program(def);
+		}
+	}
+
+	/* write out dispatcher for each program */
+	for (l = defined; l != NULL; l = l->next) {
+		def = (definition *) l->val;
+		if (def->def_kind == DEF_PROGRAM) {
+			write_program(def, storage);
+		}
+	}
+
+
+}
+
+/* write out definition of internal function (e.g. _printmsg_1(...))
+   which calls server's defintion of actual function (e.g. printmsg_1(...)).
+   Unpacks single user argument of printmsg_1 to call-by-value format
+   expected by printmsg_1. */
+static void
+write_real_program(definition *def)
+{
+	version_list *vp;
+	proc_list *proc;
+	decl_list *l;
+
+	if( !newstyle ) return;  /* not needed for old style */
+	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+		for (proc = vp->procs; proc != NULL; proc = proc->next) {
+			f_print(fout, "\n");
+			internal_proctype(proc);
+			f_print(fout, "\n_");
+			pvname(proc->proc_name, vp->vers_num);
+			if( Cflag ) {
+			  f_print(fout, "(" );
+			  /* arg name */
+			  if (proc->arg_num > 1)
+			    f_print(fout, proc->args.argname);
+			  else
+			    ptype(proc->args.decls->decl.prefix,
+				  proc->args.decls->decl.type, 0);
+			  f_print(fout, " *argp, struct svc_req *%s)\n",
+				  RQSTP);
+			} else {
+			  f_print(fout, "(argp, %s)\n", RQSTP );
+			  /* arg name */
+			  if (proc->arg_num > 1)
+			    f_print(fout, "\t%s *argp;\n", proc->args.argname);
+			  else {
+			    f_print(fout, "\t");
+			    ptype(proc->args.decls->decl.prefix,
+				  proc->args.decls->decl.type, 0);
+			    f_print(fout, " *argp;\n");
+			  }
+			  f_print(fout, "	struct svc_req *%s;\n", RQSTP);
+			}
+
+			f_print(fout, "{\n");
+			f_print(fout, "\treturn(");
+			if( Cflag )
+			  pvname_svc(proc->proc_name, vp->vers_num);
+			else
+			  pvname(proc->proc_name, vp->vers_num);
+			f_print(fout, "(");
+			if (proc->arg_num < 2) { /* single argument */
+			  if (!streq( proc->args.decls->decl.type, "void"))
+			    f_print(fout, "*argp, ");  /* non-void */
+			} else {
+			  for (l = proc->args.decls;  l != NULL; l = l->next)
+			    f_print(fout, "argp->%s, ", l->decl.name);
+			}
+			f_print(fout, "%s));\n}\n", RQSTP);
+		}
+	}
+}
+
+static void
+write_program(definition *def, const char *storage)
+{
+	version_list *vp;
+	proc_list *proc;
+	int filled;
+
+	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+		f_print(fout, "\n");
+		if (storage != NULL) {
+			f_print(fout, "%s ", storage);
+		}
+		f_print(fout, "void\n");
+		pvname(def->def_name, vp->vers_num);
+
+		if (Cflag) {
+		   f_print(fout, "(struct svc_req *%s, ", RQSTP);
+		   f_print(fout, "register SVCXPRT *%s)\n", TRANSP);
+		} else {
+		   f_print(fout, "(%s, %s)\n", RQSTP, TRANSP);
+		   f_print(fout, "	struct svc_req *%s;\n", RQSTP);
+		   f_print(fout, "	register SVCXPRT *%s;\n", TRANSP);
+		}
+
+		f_print(fout, "{\n");
+
+		filled = 0;
+		f_print(fout, "\tunion {\n");
+		for (proc = vp->procs; proc != NULL; proc = proc->next) {
+			if (proc->arg_num < 2) { /* single argument */
+				if (streq(proc->args.decls->decl.type,
+					  "void")) {
+					continue;
+				}
+				filled = 1;
+				f_print(fout, "\t\t");
+				ptype(proc->args.decls->decl.prefix,
+				      proc->args.decls->decl.type, 0);
+				pvname(proc->proc_name, vp->vers_num);
+				f_print(fout, "_arg;\n");
+
+			}
+			else {
+				filled = 1;
+				f_print(fout, "\t\t%s", proc->args.argname);
+				f_print(fout, " ");
+				pvname(proc->proc_name, vp->vers_num);
+				f_print(fout, "_arg;\n");
+			}
+		}
+		if (!filled) {
+			f_print(fout, "\t\tint fill;\n");
+		}
+		f_print(fout, "\t} %s;\n", ARG);
+		f_print(fout, "\tchar *%s;\n", RESULT);
+
+		if (Cflag) {
+		    f_print(fout, "\txdrproc_t xdr_%s, xdr_%s;\n", ARG, RESULT);
+		    f_print(fout,
+			    "\tchar *(*%s)(char *, struct svc_req *);\n",
+			    ROUTINE);
+		} else {
+		    f_print(fout, "\tbool_t (*xdr_%s)(), (*xdr_%s)();\n", ARG, RESULT);
+		    f_print(fout, "\tchar *(*%s)();\n", ROUTINE);
+		}
+
+		f_print(fout, "\n");
+
+		if (timerflag)
+			f_print(fout, "\t_rpcsvcdirty = 1;\n");
+		f_print(fout, "\tswitch (%s->rq_proc) {\n", RQSTP);
+		if (!nullproc(vp->procs)) {
+			f_print(fout, "\tcase NULLPROC:\n");
+			f_print(fout,
+			Cflag
+			? "\t\t(void) svc_sendreply(%s, (xdrproc_t) xdr_void, (char *)NULL);\n"
+			: "\t\t(void) svc_sendreply(%s, xdr_void, (char *)NULL);\n",
+					TRANSP);
+			print_return("\t\t");
+			f_print(fout, "\n");
+		}
+		for (proc = vp->procs; proc != NULL; proc = proc->next) {
+			f_print(fout, "\tcase %s:\n", proc->proc_name);
+			if (proc->arg_num < 2) { /* single argument */
+			  p_xdrfunc( ARG, proc->args.decls->decl.type);
+			} else {
+			  p_xdrfunc( ARG, proc->args.argname);
+			}
+			p_xdrfunc( RESULT, proc->res_type);
+			if( Cflag )
+			    f_print(fout,
+				    "\t\t%s = (char *(*)(char *, struct svc_req *)) ",
+				    ROUTINE);
+			else
+			    f_print(fout, "\t\t%s = (char *(*)()) ", ROUTINE);
+
+			if (newstyle) { /* new style: calls internal routine */
+				f_print(fout,"_");
+			}
+			if( Cflag && !newstyle )
+			  pvname_svc(proc->proc_name, vp->vers_num);
+			else
+			  pvname(proc->proc_name, vp->vers_num);
+			f_print(fout, ";\n");
+			f_print(fout, "\t\tbreak;\n\n");
+		}
+		f_print(fout, "\tdefault:\n");
+		printerr("noproc", TRANSP);
+		print_return("\t\t");
+		f_print(fout, "\t}\n");
+
+		f_print(fout, "\t(void) memset((char *)&%s, 0, sizeof (%s));\n", ARG, ARG);
+		if (Cflag)
+		    printif("getargs", TRANSP, "(caddr_t) &", ARG);
+		else
+		    printif("getargs", TRANSP, "&", ARG);
+		printerr("decode", TRANSP);
+		print_return("\t\t");
+		f_print(fout, "\t}\n");
+
+		if (Cflag)
+		    f_print(fout, "\t%s = (*%s)((char *)&%s, %s);\n",
+			    RESULT, ROUTINE, ARG, RQSTP);
+		else
+		    f_print(fout, "\t%s = (*%s)(&%s, %s);\n",
+			    RESULT, ROUTINE, ARG, RQSTP);
+		f_print(fout,
+			"\tif (%s != NULL && !svc_sendreply(%s, xdr_%s, %s)) {\n",
+			RESULT, TRANSP, RESULT, RESULT);
+		printerr("systemerr", TRANSP);
+		f_print(fout, "\t}\n");
+
+		if (Cflag)
+		    printif("freeargs", TRANSP, "(caddr_t) &", ARG);
+		else
+		    printif("freeargs", TRANSP, "&", ARG);
+		(void) sprintf(_errbuf, "unable to free arguments");
+		print_err_message("\t\t");
+#ifdef WIN32
+	f_print(fout, "#ifdef WIN32\n\t\trpc_nt_exit();\n#endif\n\n");
+#endif
+		f_print(fout, "\t\texit(1);\n");
+		f_print(fout, "\t}\n");
+		print_return("\t");
+		f_print(fout, "}\n");
+	}
+}
+
+static void
+printerr(const char *err, const char *transp)
+{
+	f_print(fout, "\t\tsvcerr_%s(%s);\n", err, transp);
+}
+
+static void
+printif(const char *proc, const char *transp, const char *prefix,
+	const char *arg)
+{
+	f_print(fout, "\tif (!svc_%s(%s, xdr_%s, %s%s)) {\n",
+		proc, transp, arg, prefix, arg);
+}
+
+int
+nullproc(proc_list *proc)
+{
+	for (; proc != NULL; proc = proc->next) {
+		if (streq(proc->proc_num, "0")) {
+			return (1);
+		}
+	}
+	return (0);
+}
+
+static void
+write_inetmost(const char *infile)
+{
+	f_print(fout, "\tregister SVCXPRT *%s;\n", TRANSP);
+	f_print(fout, "\tint sock;\n");
+	f_print(fout, "\tint proto;\n");
+	f_print(fout, "\tstruct sockaddr_in saddr;\n");
+	f_print(fout, "\tint asize = sizeof (saddr);\n");
+	f_print(fout, "\n");
+	f_print(fout,
+	"\tif (getsockname(0, (struct sockaddr *)&saddr, &asize) == 0) {\n");
+	f_print(fout, "\t\tint ssize = sizeof (int);\n\n");
+	f_print(fout, "\t\tif (saddr.sin_family != AF_INET)\n");
+#ifdef WIN32
+	f_print(fout, "#ifdef WIN32\n\t\t\trpc_nt_exit();\n#endif\n\n");
+#endif
+	f_print(fout, "\t\t\texit(1);\n");
+	f_print(fout, "\t\tif (getsockopt(0, SOL_SOCKET, SO_TYPE,\n");
+	f_print(fout, "\t\t\t\t(char *)&_rpcfdtype, &ssize) == -1)\n");
+#ifdef WIN32
+	f_print(fout, "#ifdef WIN32\n\t\t\trpc_nt_exit();\n#endif\n\n");
+#endif
+	f_print(fout, "\t\t\texit(1);\n");
+	f_print(fout, "\t\tsock = 0;\n");
+	f_print(fout, "\t\t_rpcpmstart = 1;\n");
+	f_print(fout, "\t\tproto = 0;\n");
+	open_log_file(infile, "\t\t");
+	f_print(fout, "\t} else {\n");
+	write_rpc_svc_fg(infile, "\t\t");
+	f_print(fout, "\t\tsock = RPC_ANYSOCK;\n");
+	print_pmapunset("\t\t");
+	f_print(fout, "\t}\n");
+}
+
+static void
+print_return(const char *space)
+{
+	if (exitnow)
+		f_print(fout, "%sexit(0);\n", space);
+	else {
+		if (timerflag)
+			f_print(fout, "%s_rpcsvcdirty = 0;\n", space);
+		f_print(fout, "%sreturn;\n", space);
+	}
+}
+
+static void
+print_pmapunset(const char *space)
+{
+	list *l;
+	definition *def;
+	version_list *vp;
+
+	for (l = defined; l != NULL; l = l->next) {
+		def = (definition *) l->val;
+		if (def->def_kind == DEF_PROGRAM) {
+			for (vp = def->def.pr.versions; vp != NULL;
+					vp = vp->next) {
+				f_print(fout, "%s(void) pmap_unset(%s, %s);\n",
+					space, def->def_name, vp->vers_name);
+			}
+		}
+	}
+}
+
+static void
+print_err_message(const char *space)
+{
+	if (logflag)
+		f_print(fout, "%ssyslog(LOG_ERR, \"%s\");\n", space, _errbuf);
+	else if (inetdflag || pmflag)
+		f_print(fout, "%s_msgout(\"%s\");\n", space, _errbuf);
+	else
+		f_print(fout, "%sfprintf(stderr, \"%s\");\n", space, _errbuf);
+}
+
+/*
+ * Write the server auxiliary function ( _msgout, timeout)
+ */
+void
+write_svc_aux(int nomain)
+{
+	if (!logflag)
+		write_msg_out();
+	if( !nomain )
+	  write_timeout_func();
+}
+
+/*
+ * Write the _msgout function
+ */
+
+void
+write_msg_out(void)
+{
+	f_print(fout, "\n");
+	f_print(fout, "static\n");
+	if( !Cflag ) {
+	  f_print(fout, "void _msgout(msg)\n");
+	  f_print(fout, "\tchar *msg;\n");
+	} else {
+	  f_print(fout, "void _msgout(char* msg)\n");
+	}
+	f_print(fout, "{\n");
+	f_print(fout, "#ifdef RPC_SVC_FG\n");
+	if (inetdflag || pmflag)
+		f_print(fout, "\tif (_rpcpmstart)\n");
+	f_print(fout, "\t\tsyslog(LOG_ERR, msg);\n");
+	f_print(fout, "\telse\n");
+	f_print(fout, "\t\t(void) fprintf(stderr, \"%%s\\n\", msg);\n");
+	f_print(fout, "#else\n");
+	f_print(fout, "\tsyslog(LOG_ERR, msg);\n");
+	f_print(fout, "#endif\n");
+	f_print(fout, "}\n");
+}
+
+/*
+ * Write the timeout function
+ */
+static void
+write_timeout_func(void)
+{
+	if (!timerflag)
+		return;
+	f_print(fout, "\n");
+	f_print(fout, "static void\n");
+#ifdef __GNU_LIBRARY__
+	if (Cflag)
+		f_print(fout, "closedown(int sig)\n");
+	else
+		f_print(fout, "closedown(sig)\n\tint sig;\n");
+#else
+	f_print(fout, "closedown()\n");
+#endif
+	f_print(fout, "{\n");
+#ifdef __GNU_LIBRARY__
+	f_print(fout, "\t(void) signal(sig, %s closedown);\n",
+		Cflag? "(SIG_PF)" : "(void(*)())" );
+#endif
+	f_print(fout, "\tif (_rpcsvcdirty == 0) {\n");
+	f_print(fout, "\t\textern fd_set svc_fdset;\n");
+	f_print(fout, "\t\tstatic int size;\n");
+	f_print(fout, "\t\tint i, openfd;\n");
+	if (tirpcflag && pmflag) {
+		f_print(fout, "\t\tstruct t_info tinfo;\n\n");
+		f_print(fout, "\t\tif (!t_getinfo(0, &tinfo) && (tinfo.servtype == T_CLTS))\n");
+	} else {
+		f_print(fout, "\n\t\tif (_rpcfdtype == SOCK_DGRAM)\n");
+	}
+	f_print(fout, "\t\t\texit(0);\n");
+	f_print(fout, "\t\tif (size == 0) {\n");
+	if( tirpcflag ) {
+	  f_print(fout, "\t\t\tstruct rlimit rl;\n\n");
+	  f_print(fout, "\t\t\trl.rlim_max = 0;\n");
+	  f_print(fout, "\t\t\tgetrlimit(RLIMIT_NOFILE, &rl);\n");
+	  f_print(fout, "\t\t\tif ((size = rl.rlim_max) == 0)\n");
+	  f_print(fout, "\t\t\t\treturn;\n");
+	} else {
+	  f_print(fout, "\t\t\tsize = getdtablesize();\n");
+	}
+	f_print(fout, "\t\t}\n");
+	f_print(fout, "\t\tfor (i = 0, openfd = 0; i < size && openfd < 2; i++)\n");
+	f_print(fout, "\t\t\tif (FD_ISSET(i, &svc_fdset))\n");
+	f_print(fout, "\t\t\t\topenfd++;\n");
+	f_print(fout, "\t\tif (openfd <= 1)\n");
+	f_print(fout, "\t\t\texit(0);\n");
+	f_print(fout, "\t}\n");
+	f_print(fout, "\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
+	f_print(fout, "}\n");
+}
+
+/*
+ * Write the most of port monitor support
+ */
+static void
+write_pm_most(const char *infile, int netflag)
+{
+	list *l;
+	definition *def;
+	version_list *vp;
+
+	f_print(fout, "\tif (!ioctl(0, I_LOOK, mname) &&\n");
+	f_print(fout, "\t\t(!strcmp(mname, \"sockmod\") ||");
+	f_print(fout, " !strcmp(mname, \"timod\"))) {\n");
+	f_print(fout, "\t\tchar *netid;\n");
+	if (!netflag) {	/* Not included by -n option */
+		f_print(fout, "\t\tstruct netconfig *nconf = NULL;\n");
+		f_print(fout, "\t\tSVCXPRT *%s;\n", TRANSP);
+	}
+	if( timerflag )
+	  f_print(fout, "\t\tint pmclose;\n");
+/* not necessary, defined in /usr/include/stdlib */
+/*	f_print(fout, "\t\textern char *getenv();\n");*/
+	f_print(fout, "\n");
+	f_print(fout, "\t\t_rpcpmstart = 1;\n");
+	if (logflag)
+		open_log_file(infile, "\t\t");
+	f_print(fout, "\t\tif ((netid = getenv(\"NLSPROVIDER\")) == NULL) {\n");
+	sprintf(_errbuf, "cannot get transport name");
+	print_err_message("\t\t\t");
+	f_print(fout, "\t\t} else if ((nconf = getnetconfigent(netid)) == NULL) {\n");
+	sprintf(_errbuf, "cannot get transport info");
+	print_err_message("\t\t\t");
+	f_print(fout, "\t\t}\n");
+	/*
+	 * A kludgy support for inetd services. Inetd only works with
+	 * sockmod, and RPC works only with timod, hence all this jugglery
+	 */
+	f_print(fout, "\t\tif (strcmp(mname, \"sockmod\") == 0) {\n");
+	f_print(fout, "\t\t\tif (ioctl(0, I_POP, 0) || ioctl(0, I_PUSH, \"timod\")) {\n");
+	sprintf(_errbuf, "could not get the right module");
+	print_err_message("\t\t\t\t");
+#ifdef WIN32
+	f_print(fout, "#ifdef WIN32\n\t\t\t\trpc_nt_exit();\n#endif\n\n");
+#endif
+	f_print(fout, "\t\t\t\texit(1);\n");
+	f_print(fout, "\t\t\t}\n");
+	f_print(fout, "\t\t}\n");
+	if( timerflag )
+	  f_print(fout, "\t\tpmclose = (t_getstate(0) != T_DATAXFER);\n");
+	f_print(fout, "\t\tif ((%s = svc_tli_create(0, nconf, NULL, 0, 0)) == NULL) {\n",
+			TRANSP);
+	sprintf(_errbuf, "cannot create server handle");
+	print_err_message("\t\t\t");
+#ifdef WIN32
+	f_print(fout, "#ifdef WIN32\n\t\trpc_nt_exit();\n#endif\n\n");
+#endif
+	f_print(fout, "\t\t\texit(1);\n");
+	f_print(fout, "\t\t}\n");
+	f_print(fout, "\t\tif (nconf)\n");
+	f_print(fout, "\t\t\tfreenetconfigent(nconf);\n");
+	for (l = defined; l != NULL; l = l->next) {
+		def = (definition *) l->val;
+		if (def->def_kind != DEF_PROGRAM) {
+			continue;
+		}
+		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+			f_print(fout,
+				"\t\tif (!svc_reg(%s, %s, %s, ",
+				TRANSP, def->def_name, vp->vers_name);
+			pvname(def->def_name, vp->vers_num);
+			f_print(fout, ", 0)) {\n");
+			(void) sprintf(_errbuf, "unable to register (%s, %s).",
+					def->def_name, vp->vers_name);
+			print_err_message("\t\t\t");
+#ifdef WIN32
+			f_print(fout, "#ifdef WIN32\n\t\t\trpc_nt_exit();\n#endif\n\n");
+#endif
+			f_print(fout, "\t\t\texit(1);\n");
+			f_print(fout, "\t\t}\n");
+		}
+	}
+	if (timerflag) {
+		f_print(fout, "\t\tif (pmclose) {\n");
+		f_print(fout, "\t\t\t(void) signal(SIGALRM, %s closedown);\n",
+				Cflag? "(SIG_PF)" : "(void(*)())" );
+		f_print(fout, "\t\t\t(void) alarm(_RPCSVC_CLOSEDOWN);\n");
+		f_print(fout, "\t\t}\n");
+	}
+	f_print(fout, "\t\tsvc_run();\n");
+#ifdef WIN32
+	f_print(fout, "#ifdef WIN32\n\t\trpc_nt_exit();\n#endif\n\n");
+#endif
+	f_print(fout, "\t\texit(1);\n");
+	f_print(fout, "\t\t/* NOTREACHED */\n");
+	f_print(fout, "\t}\n");
+}
+
+/*
+ * Support for backgrounding the server if self started.
+ */
+static void
+write_rpc_svc_fg(const char *infile, const char *sp)
+{
+	f_print(fout, "#ifndef RPC_SVC_FG\n");
+	f_print(fout, "%sint size;\n", sp);
+	if( tirpcflag )
+	        f_print(fout, "%sstruct rlimit rl;\n", sp);
+	if (inetdflag)
+		f_print(fout, "%sint pid, i;\n\n", sp);
+	f_print(fout, "%spid = fork();\n", sp);
+	f_print(fout, "%sif (pid < 0) {\n", sp);
+	f_print(fout, "%s\tperror(\"cannot fork\");\n", sp);
+#ifdef WIN32
+	f_print(fout, "#ifdef WIN32\n\trpc_nt_exit();\n#endif\n\n");
+#endif
+	f_print(fout, "%s\texit(1);\n", sp);
+	f_print(fout, "%s}\n", sp);
+	f_print(fout, "%sif (pid)\n", sp);
+	f_print(fout, "%s\texit(0);\n", sp);
+	/* get number of file descriptors */
+	if( tirpcflag ) {
+	  f_print(fout, "%srl.rlim_max = 0;\n", sp);
+	  f_print(fout, "%sgetrlimit(RLIMIT_NOFILE, &rl);\n", sp);
+	  f_print(fout, "%sif ((size = rl.rlim_max) == 0)\n", sp);
+#ifdef WIN32
+	  f_print(fout, "#ifdef WIN32\n\trpc_nt_exit();\n#endif\n\n");
+#endif
+	  f_print(fout, "%s\texit(1);\n", sp);
+	} else {
+	  f_print(fout, "%ssize = getdtablesize();\n", sp);
+	}
+
+	f_print(fout, "%sfor (i = 0; i < size; i++)\n", sp);
+	f_print(fout, "%s\t(void) close(i);\n", sp);
+	/* Redirect stderr and stdout to console */
+	f_print(fout, "%si = open(\"/dev/console\", 2);\n", sp);
+	f_print(fout, "%s(void) dup2(i, 1);\n", sp);
+	f_print(fout, "%s(void) dup2(i, 2);\n", sp);
+	/* This removes control of the controlling terminal */
+	if( tirpcflag )
+	  f_print(fout, "%ssetsid();\n", sp);
+	else {
+	  f_print(fout, "%si = open(\"/dev/tty\", 2);\n", sp);
+	  f_print(fout, "%sif (i >= 0) {\n", sp);
+	  f_print(fout, "%s\t(void) ioctl(i, TIOCNOTTY, (char *)NULL);\n", sp);;
+	  f_print(fout, "%s\t(void) close(i);\n", sp);
+	  f_print(fout, "%s}\n", sp);
+	}
+	if (!logflag)
+		open_log_file(infile, sp);
+	f_print(fout, "#endif\n");
+	if (logflag)
+		open_log_file(infile, sp);
+}
+
+static void
+open_log_file(const char *infile, const char *sp)
+{
+	char *s;
+
+	s = strrchr(infile, '.');
+	if (s)
+		*s = '\0';
+	f_print(fout,"%sopenlog(\"%s\", LOG_PID, LOG_DAEMON);\n", sp, infile);
+	if (s)
+		*s = '.';
+}
+
+
+
+
+/*
+ * write a registration for the given transport for Inetd
+ */
+void
+write_inetd_register(const char *transp)
+{
+	list *l;
+	definition *def;
+	version_list *vp;
+	const char *sp;
+	int isudp;
+	char tmpbuf[32];
+
+	if (inetdflag)
+		sp = "\t";
+	else
+		sp = "";
+	if (streq(transp, "udp"))
+		isudp = 1;
+	else
+		isudp = 0;
+	f_print(fout, "\n");
+	if (inetdflag) {
+		f_print(fout, "\tif ((_rpcfdtype == 0) || (_rpcfdtype == %s)) {\n",
+				isudp ? "SOCK_DGRAM" : "SOCK_STREAM");
+	}
+	f_print(fout, "%s\t%s = svc%s_create(%s",
+		sp, TRANSP, transp, inetdflag? "sock": "RPC_ANYSOCK");
+	if (!isudp)
+		f_print(fout, ", 0, 0");
+	f_print(fout, ");\n");
+	f_print(fout, "%s\tif (%s == NULL) {\n", sp, TRANSP);
+	(void) sprintf(_errbuf, "cannot create %s service.", transp);
+	(void) sprintf(tmpbuf, "%s\t\t", sp);
+	print_err_message(tmpbuf);
+#ifdef WIN32
+	f_print(fout, "#ifdef WIN32\n\t\trpc_nt_exit();\n#endif\n\n");
+#endif
+	f_print(fout, "%s\t\texit(1);\n", sp);
+	f_print(fout, "%s\t}\n", sp);
+
+	if (inetdflag) {
+		f_print(fout, "%s\tif (!_rpcpmstart)\n\t", sp);
+		f_print(fout, "%s\tproto = IPPROTO_%s;\n",
+				sp, isudp ? "UDP": "TCP");
+	}
+	for (l = defined; l != NULL; l = l->next) {
+		def = (definition *) l->val;
+		if (def->def_kind != DEF_PROGRAM) {
+			continue;
+		}
+		for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+			f_print(fout, "%s\tif (!svc_register(%s, %s, %s, ",
+				sp, TRANSP, def->def_name, vp->vers_name);
+			pvname(def->def_name, vp->vers_num);
+			if (inetdflag)
+				f_print(fout, ", proto)) {\n");
+			else
+				f_print(fout, ", IPPROTO_%s)) {\n",
+					isudp ? "UDP": "TCP");
+			(void) sprintf(_errbuf, "unable to register (%s, %s, %s).",
+					def->def_name, vp->vers_name, transp);
+			print_err_message(tmpbuf);
+#ifdef WIN32
+			f_print(fout, "#ifdef WIN32\n\t\trpc_nt_exit();\n#endif\n\n");
+#endif
+			f_print(fout, "%s\t\texit(1);\n", sp);
+			f_print(fout, "%s\t}\n", sp);
+		}
+	}
+	if (inetdflag)
+		f_print(fout, "\t}\n");
+}
diff --git a/external/rpc_win32/RPCGEN/rpc_tblout.c b/external/rpc_win32/RPCGEN/rpc_tblout.c
new file mode 100644
index 0000000..c210b50
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_tblout.c
@@ -0,0 +1,170 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/* 
+ * From: @(#)rpc_tblout.c 1.4 89/02/22 (C) 1988 SMI
+ */
+char tblout_rcsid[] = 
+  "$Id: rpc_tblout.c,v 1.1.1.1 2000/10/29 20:55:06 warmerda Exp $";
+
+/*
+ * rpc_tblout.c, Dispatch table outputter for the RPC protocol compiler
+ */
+#include <stdio.h>
+#include <string.h>
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+#define TABSIZE		8
+#define TABCOUNT	5
+#define TABSTOP		(TABSIZE*TABCOUNT)
+
+static char tabstr[TABCOUNT+1] = "\t\t\t\t\t";
+
+static char tbl_hdr[] = "struct rpcgen_table %s_table[] = {\n";
+static char tbl_end[] = "};\n";
+
+static char null_entry[] = "\n\t(char *(*)())0,\n\
+ \t(xdrproc_t) xdr_void,\t\t\t0,\n\
+ \t(xdrproc_t) xdr_void,\t\t\t0,\n";
+
+
+static char tbl_nproc[] = "int %s_nproc =\n\tsizeof(%s_table)/sizeof(%s_table[0]);\n\n";
+
+static void write_table(const definition *def);
+static void printit(const char *prefix, const char *type);
+
+void
+write_tables(void)
+{
+	list *l;
+	definition *def;
+
+	f_print(fout, "\n");
+	for (l = defined; l != NULL; l = l->next) {
+		def = (definition *) l->val;
+		if (def->def_kind == DEF_PROGRAM) {
+			write_table(def);
+		}
+	}
+}
+
+static void
+write_table(const definition *def)
+{
+	version_list *vp;
+	proc_list *proc;
+	int current;
+	int expected;
+	char progvers[100];
+	int warning;
+
+	for (vp = def->def.pr.versions; vp != NULL; vp = vp->next) {
+		warning = 0;
+		s_print(progvers, "%s_%s",
+		    locase(def->def_name), vp->vers_num);
+		/* print the table header */
+		f_print(fout, tbl_hdr, progvers);
+
+		if (nullproc(vp->procs)) {
+			expected = 0;
+		} 
+		else {
+			expected = 1;
+			f_print(fout, null_entry);
+		}
+		for (proc = vp->procs; proc != NULL; proc = proc->next) {
+			current = atoi(proc->proc_num);
+			if (current != expected++) {
+				f_print(fout,
+			"\n/*\n * WARNING: table out of order\n */\n");
+				if (warning == 0) {
+					f_print(stderr,
+				    "WARNING %s table is out of order\n",
+					    progvers);
+					warning = 1;
+					nonfatalerrors = 1;
+				}
+				expected = current + 1;
+			}
+			f_print(fout, "\n\t(char *(*)())RPCGEN_ACTION(");
+
+			/* routine to invoke */
+			if( Cflag && !newstyle )
+			  pvname_svc(proc->proc_name, vp->vers_num);
+			else {
+			  if( newstyle )
+			    f_print( fout, "_");   /* calls internal func */
+			  pvname(proc->proc_name, vp->vers_num);
+			}
+			f_print(fout, "),\n");
+
+			/* argument info */
+			if( proc->arg_num > 1 )
+			  printit((char*) NULL, proc->args.argname );
+			else  
+			  /* do we have to do something special for newstyle */
+			  printit( proc->args.decls->decl.prefix,
+				  proc->args.decls->decl.type );
+			/* result info */
+			printit(proc->res_prefix, proc->res_type);
+		}
+
+		/* print the table trailer */
+		f_print(fout, tbl_end);
+		f_print(fout, tbl_nproc, progvers, progvers, progvers);
+	}
+}
+
+static void
+printit(const char *prefix, const char *type)
+{
+	int len;
+	int tabs;
+
+
+ 	len = fprintf(fout, "\txdr_%s,", stringfix(type));
+	/* account for leading tab expansion */
+	len += TABSIZE - 1;
+	/* round up to tabs required */
+	tabs = (TABSTOP - len + TABSIZE - 1)/TABSIZE;
+	f_print(fout, "%s", &tabstr[TABCOUNT-tabs]);
+
+	if (streq(type, "void")) {
+		f_print(fout, "0");
+	} else {
+		f_print(fout, "sizeof ( ");
+		/* XXX: should "follow" be 1 ??? */
+		ptype(prefix, type, 0);
+		f_print(fout, ")");
+	}
+	f_print(fout, ",\n");
+}
diff --git a/external/rpc_win32/RPCGEN/rpc_util.c b/external/rpc_win32/RPCGEN/rpc_util.c
new file mode 100644
index 0000000..c47993d
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_util.c
@@ -0,0 +1,487 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/* 
+ * From: @(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI
+ */
+char util_rcsid[] =
+  "$Id: rpc_util.c,v 1.1.1.1 2000/10/29 20:55:06 warmerda Exp $";
+
+/*
+ * rpc_util.c, Utility routines for the RPC protocol compiler 
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include "rpc_scan.h"
+#include "rpc_parse.h"
+#include "rpc_util.h"
+#include "proto.h"
+
+#define ARGEXT "argument"
+
+char curline[MAXLINESIZE];	/* current read line */
+const char *where = curline;	/* current point in line */
+int linenum = 0;		/* current line number */
+
+const char *infilename;		/* input filename */
+
+#define NFILES 7
+const char *outfiles[NFILES];	/* output file names */
+int nfiles;
+
+FILE *fout;			/* file pointer of current output */
+FILE *fin;			/* file pointer of current input */
+
+list *defined;			/* list of defined things */
+
+static int findit(const definition *def, const char *type);
+static const char *fixit(const char *type, const char *orig);
+static int typedefed(const definition *def, const char *type);
+static const char *toktostr(tok_kind kind);
+static void printbuf(void);
+static void printwhere(void);
+
+/*
+ * Reinitialize the world 
+ */
+void
+reinitialize(void)
+{
+	memset(curline, 0, MAXLINESIZE);
+	where = curline;
+	linenum = 0;
+	defined = NULL;
+}
+
+/*
+ * string equality 
+ */
+int
+streq(const char *a, const char *b)
+{
+	return (strcmp(a, b) == 0);
+}
+
+/*
+ * find a value in a list 
+ */
+definition *
+findval(list *lst, const char *val, 
+	int (*cmp)(const definition *, const char *))
+{
+         
+	for (; lst != NULL; lst = lst->next) {
+		if (cmp(lst->val, val)) {
+			return (lst->val);
+		}
+	}
+	return NULL;
+}
+
+/*
+ * store a value in a list 
+ */
+void
+storeval(list **lstp, definition *val)
+{
+	list **l;
+	list *lst;
+
+	
+	for (l = lstp; *l != NULL; l = (list **) & (*l)->next);
+	lst = ALLOC(list);
+	lst->val = val;
+	lst->next = NULL;
+	*l = lst;
+}
+
+static int
+findit(const definition *def, const char *type)
+{
+	return (streq(def->def_name, type));
+}
+
+static const char *
+fixit(const char *type, const char *orig)
+{
+	definition *def;
+
+	def = findval(defined, type, findit);
+	if (def == NULL || def->def_kind != DEF_TYPEDEF) {
+		return (orig);
+	}
+	switch (def->def.ty.rel) {
+	case REL_VECTOR:
+		return (def->def.ty.old_type);
+	case REL_ALIAS:
+		return (fixit(def->def.ty.old_type, orig));
+	default:
+		return (orig);
+	}
+}
+
+const char *
+fixtype(const char *type)
+{
+	return (fixit(type, type));
+}
+
+const char *
+stringfix(const char *type)
+{
+	if (streq(type, "string")) {
+		return "wrapstring";
+	} 
+	else {
+		return type;
+	}
+}
+
+void
+ptype(const char *prefix, const char *type, int follow)
+{
+	if (prefix != NULL) {
+		if (streq(prefix, "enum")) {
+			f_print(fout, "enum ");
+		} else {
+			f_print(fout, "struct ");
+		}
+	}
+	if (streq(type, "bool")) {
+		f_print(fout, "bool_t ");
+	} else if (streq(type, "string")) {
+		f_print(fout, "char *");
+	} else {
+		f_print(fout, "%s ", follow ? fixtype(type) : type);
+	}
+}
+
+static int
+typedefed(const definition *def, const char *type)
+{
+	if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) {
+		return (0);
+	} else {
+		return (streq(def->def_name, type));
+	}
+}
+
+int
+isvectordef(const char *type, relation rel)
+{
+	definition *def;
+
+	for (;;) {
+		switch (rel) {
+		case REL_VECTOR:
+			return (!streq(type, "string"));
+		case REL_ARRAY:
+			return (0);
+		case REL_POINTER:
+			return (0);
+		case REL_ALIAS:
+			def = findval(defined, type, typedefed);
+			if (def == NULL) {
+				return (0);
+			}
+			type = def->def.ty.old_type;
+			rel = def->def.ty.rel;
+		}
+	}
+}
+
+char *
+locase(const char *str)
+{
+	char c;
+	static char buf[100];
+	char *p = buf;
+
+	while ((c = *str++)!=0) {
+		*p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c;
+	}
+	*p = 0;
+	return (buf);
+}
+
+void
+pvname_svc(const char *pname, const char *vnum)
+{
+	f_print(fout, "%s_%s_svc", locase(pname), vnum);
+}
+
+void
+pvname(const char *pname, const char *vnum)
+{
+	f_print(fout, "%s_%s", locase(pname), vnum);
+}
+
+/*
+ * print a useful (?) error message, and then die 
+ */
+void
+error(const char *msg)
+{
+	printwhere();
+	f_print(stderr, "%s, line %d: ", infilename, linenum);
+	f_print(stderr, "%s\n", msg);
+	crash();
+}
+
+/*
+ * Something went wrong, unlink any files that we may have created and then
+ * die. 
+ */
+void
+crash(void)
+{
+	int i;
+
+	for (i = 0; i < nfiles; i++) {
+		(void) unlink(outfiles[i]);
+	}
+	exit(1);
+}
+
+void
+record_open(const char *file)
+{
+	if (nfiles < NFILES) {
+		outfiles[nfiles++] = file;
+	} 
+	else {
+		f_print(stderr, "too many files!\n");
+		crash();
+	}
+}
+
+static char expectbuf[100];
+
+/*
+ * error, token encountered was not the expected one 
+ */
+void
+expected1(tok_kind exp1)
+{
+	s_print(expectbuf, "expected '%s'",
+		toktostr(exp1));
+	error(expectbuf);
+}
+
+/*
+ * error, token encountered was not one of two expected ones 
+ */
+void
+expected2(tok_kind exp1, tok_kind exp2)
+{
+	s_print(expectbuf, "expected '%s' or '%s'",
+		toktostr(exp1),
+		toktostr(exp2));
+	error(expectbuf);
+}
+
+/*
+ * error, token encountered was not one of 3 expected ones 
+ */
+void
+expected3(tok_kind exp1, tok_kind exp2, tok_kind exp3)
+{
+	s_print(expectbuf, "expected '%s', '%s' or '%s'",
+		toktostr(exp1),
+		toktostr(exp2),
+		toktostr(exp3));
+	error(expectbuf);
+}
+
+void
+tabify(FILE *f, int tab)
+{
+	while (tab--) {
+		(void) fputc('\t', f);
+	}
+}
+
+
+static token tokstrings[] = {
+			     {TOK_IDENT, "identifier"},
+			     {TOK_CONST, "const"},
+			     {TOK_RPAREN, ")"},
+			     {TOK_LPAREN, "("},
+			     {TOK_RBRACE, "}"},
+			     {TOK_LBRACE, "{"},
+			     {TOK_LBRACKET, "["},
+			     {TOK_RBRACKET, "]"},
+			     {TOK_STAR, "*"},
+			     {TOK_COMMA, ","},
+			     {TOK_EQUAL, "="},
+			     {TOK_COLON, ":"},
+			     {TOK_SEMICOLON, ";"},
+			     {TOK_UNION, "union"},
+			     {TOK_STRUCT, "struct"},
+			     {TOK_SWITCH, "switch"},
+			     {TOK_CASE, "case"},
+			     {TOK_DEFAULT, "default"},
+			     {TOK_ENUM, "enum"},
+			     {TOK_TYPEDEF, "typedef"},
+			     {TOK_INT, "int"},
+			     {TOK_SHORT, "short"},
+			     {TOK_LONG, "long"},
+			     {TOK_UNSIGNED, "unsigned"},
+			     {TOK_DOUBLE, "double"},
+			     {TOK_FLOAT, "float"},
+			     {TOK_CHAR, "char"},
+			     {TOK_STRING, "string"},
+			     {TOK_OPAQUE, "opaque"},
+			     {TOK_BOOL, "bool"},
+			     {TOK_VOID, "void"},
+			     {TOK_PROGRAM, "program"},
+			     {TOK_VERSION, "version"},
+			     {TOK_EOF, "??????"}
+};
+
+static const char *
+toktostr(tok_kind kind)
+{
+	token *sp;
+
+	for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++);
+	return (sp->str);
+}
+
+static void
+printbuf(void)
+{
+	char c;
+	int i;
+	int cnt;
+
+#	define TABSIZE 4
+
+	for (i = 0; (c = curline[i])!=0; i++) {
+		if (c == '\t') {
+			cnt = 8 - (i % TABSIZE);
+			c = ' ';
+		} else {
+			cnt = 1;
+		}
+		while (cnt--) {
+			(void) fputc(c, stderr);
+		}
+	}
+}
+
+static void
+printwhere(void)
+{
+	int i;
+	char c;
+	int cnt;
+
+	printbuf();
+	for (i = 0; i < where - curline; i++) {
+		c = curline[i];
+		if (c == '\t') {
+			cnt = 8 - (i % TABSIZE);
+		} else {
+			cnt = 1;
+		}
+		while (cnt--) {
+			(void) fputc('^', stderr);
+		}
+	}
+	(void) fputc('\n', stderr);
+}
+
+char * 
+make_argname(const char *pname, const char *vname) 
+{
+	char *name;
+	
+	name = malloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3);
+	if (!name) {
+		fprintf(stderr, "failed in malloc");
+		exit(1);
+	}
+	sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT);
+	return name;
+}
+
+bas_type *typ_list_h;
+bas_type *typ_list_t;
+
+void
+add_type(int len, const char *type)
+{
+  bas_type *ptr;
+
+
+  if ((ptr = malloc(sizeof(bas_type))) == NULL) {
+      fprintf(stderr, "failed in malloc");
+      exit(1);
+  }
+
+  ptr->name=type;
+  ptr->length=len;
+  ptr->next=NULL;
+  if(typ_list_t == NULL)
+    {
+
+      typ_list_t=ptr;
+      typ_list_h=ptr;
+    }
+  else
+    {
+
+    typ_list_t->next=ptr;
+    typ_list_t=ptr;
+    }
+
+}
+
+
+bas_type *find_type(const char *type)
+{
+  bas_type *ptr;
+
+  ptr=typ_list_h;
+
+
+  while(ptr != NULL)
+    {
+    if(strcmp(ptr->name,type) == 0)
+           return(ptr);
+    else
+      ptr=ptr->next;
+    };
+return(NULL);
+}
+
diff --git a/external/rpc_win32/RPCGEN/rpc_util.h b/external/rpc_win32/RPCGEN/rpc_util.h
new file mode 100644
index 0000000..bdbe183
--- /dev/null
+++ b/external/rpc_win32/RPCGEN/rpc_util.h
@@ -0,0 +1,147 @@
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+/*      @(#)rpc_util.h  1.5  90/08/29  (C) 1987 SMI   */
+
+/*
+ * rpc_util.h, Useful definitions for the RPC protocol compiler 
+ */
+
+#include <stdlib.h>
+
+#define alloc(size)		malloc((unsigned)(size))
+#define ALLOC(object)   (object *) malloc(sizeof(object))
+
+#define s_print	(void) sprintf
+#define f_print (void) fprintf
+
+struct list {
+	definition *val;
+	struct list *next;
+};
+typedef struct list list;
+
+#define PUT 1
+#define GET 2
+
+/*
+ * Global variables 
+ */
+#define MAXLINESIZE 1024
+extern char curline[MAXLINESIZE];
+extern const char *where;
+extern int linenum;
+
+extern const char *infilename;
+extern FILE *fout;
+extern FILE *fin;
+
+extern list *defined;
+
+
+extern bas_type *typ_list_h;
+extern bas_type *typ_list_t;
+
+/*
+ * All the option flags
+ */
+extern int inetdflag;
+extern int pmflag;   
+extern int tblflag;
+extern int logflag;
+extern int newstyle;
+extern int Cflag;     /* C++ flag */
+extern int tirpcflag; /* flag for generating tirpc code */
+extern int inlineflag; /* if this is 0, then do not generate inline code */
+
+/*
+ * Other flags related with inetd jumpstart.
+ */
+extern int indefinitewait;
+extern int exitnow;
+extern int timerflag;
+
+extern int nonfatalerrors;
+
+/*
+ * rpc_util routines 
+ */
+void storeval(list **lstp, definition *val);
+#define STOREVAL(list,item) storeval(list,item)
+
+definition *findval(list *lst, const char *val, 
+		    int (*cmp)(const definition *, const char *));
+#define FINDVAL(list,item,finder) findval(list, item, finder)
+
+const char *fixtype(const char *type);
+const char *stringfix(const char *type);
+char *locase(const char *str);
+void pvname_svc(const char *pname, const char *vnum);
+void pvname(const char *pname, const char *vnum);
+void ptype(const char *prefix, const char *type, int follow);
+int isvectordef(const char *type, relation rel);
+int streq(const char *a, const char *b);
+void error(const char *msg);
+void tabify(FILE *f, int tab);
+void record_open(const char *file);
+bas_type *find_type(const char *type);
+
+
+/*
+ * rpc_cout routines 
+ */
+void emit(definition *def);
+
+/*
+ * rpc_hout routines 
+ */
+void print_datadef(definition *def);
+void print_funcdef(definition *def);
+
+/*
+ * rpc_svcout routines 
+ */
+void write_most(const char *infile, int netflag, int nomain);
+void write_register(void);
+void write_rest(void);
+void write_programs(const char *storage);
+void write_svc_aux(int nomain);
+void write_inetd_register(const char *transp);
+void write_netid_register(const char *);
+void write_nettype_register(const char *);
+/*
+ * rpc_clntout routines
+ */
+void write_stubs(void);
+
+/*
+ * rpc_tblout routines
+ */
+void write_tables(void);
diff --git a/external/rpc_win32/SERVICE/INST_PM.C b/external/rpc_win32/SERVICE/INST_PM.C
new file mode 100644
index 0000000..ff3e2cd
--- /dev/null
+++ b/external/rpc_win32/SERVICE/INST_PM.C
@@ -0,0 +1,91 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+SC_HANDLE   service;
+SC_HANDLE   manager;
+
+VOID
+InstallService(LPCTSTR serviceName, LPCTSTR serviceExe)
+{
+    LPCTSTR lpszBinaryPathName = serviceExe;
+
+    service = CreateService(
+        manager,
+        serviceName,
+        serviceName,
+        SERVICE_ALL_ACCESS,
+        SERVICE_WIN32_OWN_PROCESS,
+        SERVICE_DEMAND_START,
+        SERVICE_ERROR_NORMAL,
+        lpszBinaryPathName,
+        NULL,
+        NULL,
+        NULL,
+        NULL,
+        NULL);
+
+    if (service == NULL) {
+        printf("failure: CreateService (0x%02x)\n", GetLastError());
+        return;
+    } else
+        printf("CreateService SUCCESS\n");
+
+    CloseServiceHandle(service);
+}
+
+VOID
+RemoveService(LPCTSTR serviceName)
+{
+    service = OpenService(manager, serviceName, SERVICE_ALL_ACCESS);
+
+    if (service == NULL) {
+        printf("failure: OpenService (0x%02x)\n", GetLastError());
+        return;
+    }
+
+    if (DeleteService(service))
+        printf("DeleteService SUCCESS\n");
+    else
+        printf("failure: DeleteService (0x%02x)\n", GetLastError());
+}
+
+VOID
+main(int argc, char *argv[])
+{
+    if (argc != 2) {
+        printf("usage: inst_pm <full pathname>\n");
+        printf("           to install portmap, or:\n");
+        printf("       inst_pm remove\n");
+        printf("           to remove it.\n");
+        exit(1);
+    }
+
+    manager = OpenSCManager(
+                        NULL,
+                        NULL,
+                        SC_MANAGER_ALL_ACCESS
+                        );
+
+    if (manager == NULL) {
+        printf("OpenSCManager() failed! (missing priviledges?)\n");
+        exit(1);
+    }
+    	
+    if (!stricmp(argv[1], "remove"))
+        RemoveService("Portmap");
+    else
+        InstallService("Portmap", argv[1]);
+
+    CloseServiceHandle(manager);
+}
diff --git a/external/rpc_win32/SERVICE/Makefile b/external/rpc_win32/SERVICE/Makefile
new file mode 100644
index 0000000..c6539fd
--- /dev/null
+++ b/external/rpc_win32/SERVICE/Makefile
@@ -0,0 +1,27 @@
+!include <ntwin32.mak>
+
+# If the rpc include directory is not included in the standard path
+# you have to give the path to it here.
+RPCINCLUDEPATH = ..
+
+# If the rpc library is not included in the standard lib path
+# you have to give the path to it here.
+RPCLIBPATH = ..\lib\\
+
+all: portmap.exe inst_pm.exe
+
+# Update the object file if necessary
+
+clean:
+    del *.obj *.exe
+
+portmap.exe: service.obj portmap.obj $(RPCLIBPATH)oncrpc.lib
+    $(link) $(ldebug) $(conflags) -out:portmap.exe portmap.obj service.obj $(conlibs) $(RPCLIBPATH)oncrpc.lib wsock32.lib  advapi32.lib
+    copy portmap.exe ..\bin
+
+inst_pm.exe: inst_pm.obj
+    $(link) $(ldebug) $(conflags) -out:inst_pm.exe inst_pm.obj $(conlibs) advapi32.lib
+    copy inst_pm.exe ..\bin
+
+.c.obj:
+    $(cc) /I$(RPCINCLUDEPATH) $(cdebug) $(cflags) $(cvars) $*.c
diff --git a/external/rpc_win32/SERVICE/PORTMAP.C b/external/rpc_win32/SERVICE/PORTMAP.C
new file mode 100644
index 0000000..b55a6e5
--- /dev/null
+++ b/external/rpc_win32/SERVICE/PORTMAP.C
@@ -0,0 +1,361 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ * Users may use, copy or modify Sun RPC for the Windows NT Operating 
+ * System according to the Sun copyright below.
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO 
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE 
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+/*
+ * Copyright (c) 1984 by Sun Microsystems, Inc.
+ */
+
+/*
+ * portmap.c, Implements the program,version to port number mapping for
+ * rpc.
+ */
+
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#include <rpc/rpc.h>
+#include <rpc/pmap_pro.h>
+#include <stdio.h>
+
+VOID	Report(LPTSTR lpszMsg);
+
+static void callit();
+
+struct pmaplist *pmaplist;
+
+static struct pmaplist *
+find_service(prog, vers, prot)
+	u_long prog;
+	u_long vers;
+{
+	register struct pmaplist *hit = NULL;
+	register struct pmaplist *pml;
+	static char str[150];
+
+	for (pml = pmaplist; pml != NULL; pml = pml->pml_next) {
+		if ((pml->pml_map.pm_prog != prog) ||
+			(pml->pml_map.pm_prot != prot))
+			continue;
+		hit = pml;
+		if (pml->pml_map.pm_vers == vers)
+		    break;
+	}
+
+	if (hit != NULL)
+		sprintf(str, "found program %d, version %d with protocol %d, port %d",
+			prog, vers, hit->pml_map.pm_prot, hit->pml_map.pm_port);
+	else
+		sprintf(str, "can not find program %d, version %d", prog, vers);
+	Report(str);
+
+	return (hit);
+}
+
+/* 
+ * 1 OK, 0 not
+ */
+void reg_service(rqstp, xprt)
+	struct svc_req *rqstp;
+	SVCXPRT *xprt;
+{
+	struct pmap reg;
+	struct pmaplist *pml, *prevpml, *fnd;
+	int ans, port;
+	caddr_t t;
+	
+	switch (rqstp->rq_proc) {
+
+	case PMAPPROC_NULL:
+		/*
+		 * Null proc call
+		 */
+		svc_sendreply(xprt, xdr_void, NULL);
+		break;
+
+	case PMAPPROC_SET:
+		/*
+		 * Set a program,version to port mapping
+		 */
+		if (!svc_getargs(xprt, xdr_pmap, &reg))
+			svcerr_decode(xprt);
+		else {
+			/*
+			 * check to see if already used
+			 * find_service returns a hit even if
+			 * the versions don't match, so check for it
+			 */
+			fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
+			if (fnd && fnd->pml_map.pm_vers == reg.pm_vers) {
+				if (fnd->pml_map.pm_port == reg.pm_port) {
+					ans = 1;
+					goto done;
+				}
+				else {
+					ans = 0;
+					goto done;
+				}
+			} else {
+				/* 
+				 * add to list
+				 */
+				pml = (struct pmaplist *)
+				    malloc((u_int)sizeof(struct pmaplist));
+				pml->pml_map = reg;
+				pml->pml_next = pmaplist;
+				pmaplist = pml;
+				ans = 1;
+			}
+		done:
+			svc_sendreply(xprt, xdr_long, (caddr_t)&ans);
+		}
+		break;
+
+	case PMAPPROC_UNSET:
+		/*
+		 * Remove a program,version to port mapping.
+		 */
+		if (!svc_getargs(xprt, xdr_pmap, &reg))
+			svcerr_decode(xprt);
+		else {
+			ans = 0;
+			for (prevpml = NULL, pml = pmaplist; pml != NULL; ) {
+				if ((pml->pml_map.pm_prog != reg.pm_prog) ||
+					(pml->pml_map.pm_vers != reg.pm_vers)) {
+					/* both pml & prevpml move forwards */
+					prevpml = pml;
+					pml = pml->pml_next;
+					continue;
+				}
+				/* found it; pml moves forward, prevpml stays */
+				ans = 1;
+				t = (caddr_t)pml;
+				pml = pml->pml_next;
+				if (prevpml == NULL)
+					pmaplist = pml;
+				else
+					prevpml->pml_next = pml;
+				free(t);
+			}
+			svc_sendreply(xprt, xdr_long, (caddr_t)&ans);
+		}
+		break;
+
+	case PMAPPROC_GETPORT:
+		/*
+		 * Lookup the mapping for a program,version and return its port
+		 */
+		if (!svc_getargs(xprt, xdr_pmap, &reg))
+			svcerr_decode(xprt);
+		else {
+			fnd = find_service(reg.pm_prog, reg.pm_vers, reg.pm_prot);
+			if (fnd)
+				port = fnd->pml_map.pm_port;
+			else
+				port = 0;
+			svc_sendreply(xprt, xdr_long, (caddr_t)&port);
+		}
+		break;
+
+	case PMAPPROC_DUMP:
+		/*
+		 * Return the current set of mapped program,version
+		 */
+		if (!svc_getargs(xprt, xdr_void, NULL))
+			svcerr_decode(xprt);
+		else {
+			svc_sendreply(xprt, xdr_pmaplist, (caddr_t)&pmaplist);
+		}
+		break;
+
+	case PMAPPROC_CALLIT:
+		/*
+		 * Calls a procedure on the local machine.  If the requested
+		 * procedure is not registered this procedure does not return
+		 * error information!!
+		 * This procedure is only supported on rpc/udp and calls via 
+		 * rpc/udp.  It passes null authentication parameters.
+		 */
+		callit(rqstp, xprt);
+		break;
+
+	default:
+		svcerr_noproc(xprt);
+		break;
+	}
+}
+
+
+/*
+ * Stuff for the rmtcall service
+ */
+#define ARGSIZE 9000
+
+typedef struct encap_parms {
+	u_long arglen;
+	char *args;
+} encap_parms_t;
+
+static bool_t
+xdr_encap_parms(xdrs, epp)
+	XDR *xdrs;
+	struct encap_parms *epp;
+{
+
+	return (xdr_bytes(xdrs, &(epp->args), &(epp->arglen), ARGSIZE));
+}
+
+typedef struct rmtcallargs {
+	u_long	rmt_prog;
+	u_long	rmt_vers;
+	u_long	rmt_port;
+	u_long	rmt_proc;
+	struct encap_parms rmt_args;
+} rmtcallargs_t;
+
+static bool_t
+xdr_rmtcall_args(xdrs, cap)
+	register XDR *xdrs;
+	register struct rmtcallargs *cap;
+{
+
+	/* does not get a port number */
+	if (xdr_u_long(xdrs, &(cap->rmt_prog)) &&
+	    xdr_u_long(xdrs, &(cap->rmt_vers)) &&
+	    xdr_u_long(xdrs, &(cap->rmt_proc))) {
+		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
+	}
+	return (FALSE);
+}
+
+static bool_t
+xdr_rmtcall_result(xdrs, cap)
+	register XDR *xdrs;
+	register struct rmtcallargs *cap;
+{
+	if (xdr_u_long(xdrs, &(cap->rmt_port)))
+		return (xdr_encap_parms(xdrs, &(cap->rmt_args)));
+	return (FALSE);
+}
+
+/*
+ * only worries about the struct encap_parms part of struct rmtcallargs.
+ * The arglen must already be set!!
+ */
+static bool_t
+xdr_opaque_parms(xdrs, cap)
+	XDR *xdrs;
+	struct rmtcallargs *cap;
+{
+
+	return (xdr_opaque(xdrs, cap->rmt_args.args, cap->rmt_args.arglen));
+}
+
+/*
+ * This routine finds and sets the length of incoming opaque paraters
+ * and then calls xdr_opaque_parms.
+ */
+static bool_t
+xdr_len_opaque_parms(xdrs, cap)
+	register XDR *xdrs;
+	struct rmtcallargs *cap;
+{
+	register u_int beginpos, lowpos, highpos, currpos, pos;
+
+	beginpos = lowpos = pos = xdr_getpos(xdrs);
+	highpos = lowpos + ARGSIZE;
+	while ((int)(highpos - lowpos) >= 0) {
+		currpos = (lowpos + highpos) / 2;
+		if (xdr_setpos(xdrs, currpos)) {
+			pos = currpos;
+			lowpos = currpos + 1;
+		} else {
+			highpos = currpos - 1;
+		}
+	}
+	xdr_setpos(xdrs, beginpos);
+	cap->rmt_args.arglen = pos - beginpos;
+	return (xdr_opaque_parms(xdrs, cap));
+}
+
+/*
+ * Call a remote procedure service
+ * This procedure is very quiet when things go wrong.
+ * The proc is written to support broadcast rpc.  In the broadcast case,
+ * a machine should shut-up instead of complain, less the requestor be
+ * overrun with complaints at the expense of not hearing a valid reply ...
+ */
+static void
+callit(rqstp, xprt)
+	struct svc_req *rqstp;
+	SVCXPRT *xprt;
+{
+	char buf[2000];
+	struct rmtcallargs a;
+	struct pmaplist *pml;
+	u_short port;
+	struct sockaddr_in me;
+	int socket = -1;
+	CLIENT *client;
+	struct authunix_parms *au = (struct authunix_parms *)rqstp->rq_clntcred;
+	struct timeval timeout;
+
+	timeout.tv_sec = 5;
+	timeout.tv_usec = 0;
+	a.rmt_args.args = buf;
+	if (!svc_getargs(xprt, xdr_rmtcall_args, &a))
+	    return;
+	if ((pml = find_service(a.rmt_prog, a.rmt_vers, IPPROTO_UDP)) == NULL)
+	    return;
+	port = pml->pml_map.pm_port;
+	get_myaddress(&me);
+	me.sin_port = htons(port);
+	client = clntudp_create(&me, a.rmt_prog, a.rmt_vers, timeout, &socket);
+	if (client != (CLIENT *)NULL) {
+		if (rqstp->rq_cred.oa_flavor == AUTH_UNIX) {
+			client->cl_auth = authunix_create(au->aup_machname,
+			   au->aup_uid, au->aup_gid, au->aup_len, au->aup_gids);
+		}
+		a.rmt_port = (u_long)port;
+		if (clnt_call(client, a.rmt_proc, xdr_opaque_parms, &a,
+		    xdr_len_opaque_parms, &a, timeout) == RPC_SUCCESS) {
+			svc_sendreply(xprt, xdr_rmtcall_result, &a);
+		}
+		AUTH_DESTROY(client->cl_auth);
+		clnt_destroy(client);
+	}
+	(void)closesocket(socket);
+}
diff --git a/external/rpc_win32/SERVICE/SERVICE.C b/external/rpc_win32/SERVICE/SERVICE.C
new file mode 100644
index 0000000..2938b5f
--- /dev/null
+++ b/external/rpc_win32/SERVICE/SERVICE.C
@@ -0,0 +1,283 @@
+/*********************************************************************
+ * RPC for the Windows NT Operating System
+ * 1993 by Martin F. Gergeleit
+ *
+ * RPC for the Windows NT Operating System COMES WITH ABSOLUTELY NO
+ * WARRANTY, NOR WILL I BE LIABLE FOR ANY DAMAGES INCURRED FROM THE
+ * USE OF. USE ENTIRELY AT YOUR OWN RISK!!!
+ *********************************************************************/
+
+#include <rpc/rpc.h>
+#include <windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <rpc/pmap_pro.h>
+
+void reg_service();
+
+HANDLE                  hServDoneEvent = NULL;
+SERVICE_STATUS          ssStatus;
+SERVICE_STATUS_HANDLE   sshStatusHandle;
+DWORD                   dwGlobalErr;
+DWORD                   TID = 0;
+HANDLE                  threadHandle = NULL;
+HANDLE                  pipeHandle;
+
+VOID    service_main(DWORD dwArgc, LPTSTR *lpszArgv);
+VOID    WINAPI service_ctrl(DWORD dwCtrlCode);
+BOOL    ReportStatusToSCMgr(DWORD dwCurrentState,
+                            DWORD dwWin32ExitCode,
+                            DWORD dwCheckPoint,
+                            DWORD dwWaitHint);
+VOID    portmap_main(VOID *notUsed);
+VOID    StopPortmapService(LPTSTR lpszMsg);
+VOID	Report(LPTSTR lpszMsg);
+
+
+VOID
+main()
+
+{
+    SERVICE_TABLE_ENTRY dispatchTable[] = {
+        { TEXT("PortmapService"), (LPSERVICE_MAIN_FUNCTION)service_main },
+        { NULL, NULL }
+    };
+
+    if (!StartServiceCtrlDispatcher(dispatchTable)) {
+        StopPortmapService("StartServiceCtrlDispatcher failed.");
+    }
+}
+
+
+VOID
+service_main(DWORD dwArgc, LPTSTR *lpszArgv)
+
+{
+    DWORD                   dwWait;
+    int sock;
+    struct sockaddr_in addr;
+    SVCXPRT *xprt;
+    int len = sizeof(struct sockaddr_in);
+
+    sshStatusHandle = RegisterServiceCtrlHandler(
+                                    TEXT("PortmapService"),
+                                    (LPHANDLER_FUNCTION)service_ctrl);
+
+    if (!sshStatusHandle)
+        goto exit_portmap;
+
+    ssStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+    ssStatus.dwServiceSpecificExitCode = 0;
+
+    if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 1, 3000))
+        goto exit_portmap;
+
+    hServDoneEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+    if (hServDoneEvent == (HANDLE)NULL)
+        goto exit_portmap;
+
+
+    if (!ReportStatusToSCMgr(SERVICE_START_PENDING, NO_ERROR, 2, 3000))
+        goto exit_portmap;
+
+    if (rpc_nt_init() != 0) {
+	goto exit_portmap;
+	}
+
+	if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET) {
+		StopPortmapService("cannot create socket");
+		return;
+	}
+
+	addr.sin_addr.s_addr = 0;
+	addr.sin_family = AF_INET;
+	addr.sin_port = htons(PMAPPORT);
+	if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
+		StopPortmapService("cannot bind");
+		return;
+	}
+
+	if ((xprt = svcudp_create(sock)) == (SVCXPRT *)NULL) {
+		StopPortmapService("couldn't do udp_create");
+		return;
+	}
+
+	if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+		StopPortmapService("cannot create socket");
+		return;
+	}
+	if (bind(sock, (struct sockaddr *)&addr, len) != 0) {
+		StopPortmapService("cannot bind");
+		return;
+	}
+	if ((xprt = svctcp_create(sock, 0, 0)) == (SVCXPRT *)NULL) {
+		StopPortmapService("couldn't do tcp_create");
+		return;
+	}
+
+        (void)svc_register(xprt, PMAPPROG, PMAPVERS, reg_service, FALSE);
+
+    threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)svc_run, NULL, 0, &TID);
+
+    if (!threadHandle)
+        goto exit_portmap;
+
+    if (!ReportStatusToSCMgr(SERVICE_RUNNING, NO_ERROR, 0, 0))
+        goto exit_portmap;
+
+    dwWait = WaitForSingleObject(hServDoneEvent, INFINITE);
+
+    TerminateThread(threadHandle, 0);
+
+exit_portmap:
+
+    Report("Portmap service terminates");
+
+    rpc_nt_exit();
+
+    if (hServDoneEvent != NULL)
+        CloseHandle(hServDoneEvent);
+
+    if (sshStatusHandle != 0)
+        (VOID)ReportStatusToSCMgr(SERVICE_STOPPED, dwGlobalErr, 0, 0);
+
+    return;
+}
+
+
+VOID
+WINAPI service_ctrl(DWORD dwCtrlCode)
+{
+    DWORD  dwState = SERVICE_RUNNING;
+
+    switch(dwCtrlCode) {
+
+        case SERVICE_CONTROL_PAUSE:
+
+            if (ssStatus.dwCurrentState == SERVICE_RUNNING) {
+                SuspendThread(threadHandle);
+                dwState = SERVICE_PAUSED;
+            }
+            break;
+
+        case SERVICE_CONTROL_CONTINUE:
+
+            if (ssStatus.dwCurrentState == SERVICE_PAUSED) {
+                ResumeThread(threadHandle);
+                dwState = SERVICE_RUNNING;
+            }
+            break;
+
+        case SERVICE_CONTROL_STOP:
+
+            dwState = SERVICE_STOP_PENDING;
+
+            ReportStatusToSCMgr(SERVICE_STOP_PENDING, NO_ERROR, 1, 3000);
+
+            SetEvent(hServDoneEvent);
+            return;
+
+        case SERVICE_CONTROL_INTERROGATE:
+            break;
+
+        default:
+            break;
+
+    }
+
+    ReportStatusToSCMgr(dwState, NO_ERROR, 0, 0);
+}
+
+
+BOOL
+ReportStatusToSCMgr(DWORD dwCurrentState,
+                    DWORD dwWin32ExitCode,
+                    DWORD dwCheckPoint,
+                    DWORD dwWaitHint)
+{
+    BOOL fResult;
+
+    if (dwCurrentState == SERVICE_START_PENDING)
+        ssStatus.dwControlsAccepted = 0;
+    else
+        ssStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
+            SERVICE_ACCEPT_PAUSE_CONTINUE;
+
+    ssStatus.dwCurrentState = dwCurrentState;
+    ssStatus.dwWin32ExitCode = dwWin32ExitCode;
+    ssStatus.dwCheckPoint = dwCheckPoint;
+
+    ssStatus.dwWaitHint = dwWaitHint;
+
+    if (!(fResult = SetServiceStatus(sshStatusHandle, &ssStatus)))
+            StopPortmapService("SetServiceStatus");
+
+    return fResult;
+}
+
+
+VOID
+StopPortmapService(LPTSTR lpszMsg)
+{
+    CHAR    chMsg[256];
+    HANDLE  hEventSource;
+    LPTSTR  lpszStrings[2];
+
+    dwGlobalErr = GetLastError();
+
+    hEventSource = RegisterEventSource(NULL,
+                            TEXT("Portmap"));
+
+    sprintf(chMsg, "Portmap error: %d", dwGlobalErr);
+    lpszStrings[0] = chMsg;
+    lpszStrings[1] = lpszMsg;
+
+    if (hEventSource != NULL) {
+        ReportEvent(hEventSource,
+            EVENTLOG_ERROR_TYPE,
+            0,
+            0,
+            NULL,
+            2,
+            0,
+            lpszStrings,
+            NULL);
+
+        (VOID) DeregisterEventSource(hEventSource);
+    }
+
+    SetEvent(hServDoneEvent);
+}
+
+
+VOID
+Report(LPTSTR lpszMsg)
+{
+    CHAR    chMsg[256];
+    HANDLE  hEventSource;
+    LPTSTR  lpszStrings[2];
+
+    dwGlobalErr = GetLastError();
+
+    hEventSource = RegisterEventSource(NULL,
+                            TEXT("Portmap"));
+
+    sprintf(chMsg, "Portmap report: %d", dwGlobalErr);
+    lpszStrings[0] = chMsg;
+    lpszStrings[1] = lpszMsg;
+
+    if (hEventSource != NULL) {
+        ReportEvent(hEventSource,
+            EVENTLOG_INFORMATION_TYPE,
+            0,
+            0,
+            NULL,
+            2,
+            0,
+            lpszStrings,
+            NULL);
+
+        (VOID) DeregisterEventSource(hEventSource);
+    }
+}
diff --git a/external/rpc_win32/TEST/COU.X b/external/rpc_win32/TEST/COU.X
new file mode 100644
index 0000000..5f5544a
--- /dev/null
+++ b/external/rpc_win32/TEST/COU.X
@@ -0,0 +1,8 @@
+program COUNTSERV {
+	version COUNTVERS {
+		int inc(void) = 1;
+		int dec(void) = 2;
+		int set(int) = 3;
+	} = 1;
+} = 77;
+
diff --git a/external/rpc_win32/TEST/COUNT.C b/external/rpc_win32/TEST/COUNT.C
new file mode 100644
index 0000000..b45dc67
--- /dev/null
+++ b/external/rpc_win32/TEST/COUNT.C
@@ -0,0 +1,29 @@
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include "cou.h"
+
+static int count;
+
+int *inc_1 (dummy)
+void *dummy;
+{
+	count++;
+	printf("inc called; result: %d\n", count);
+	return (&count);
+}
+
+int *dec_1 (dummy)
+void *dummy;
+{
+	count--;
+	printf("dec called; result: %d\n", count);
+	return (&count);
+}
+
+int *set_1 (val)
+int *val;
+{
+	count = *val;
+	printf("set called; value: %d\n", count);
+	return (&count);
+}
diff --git a/external/rpc_win32/TEST/DO_COU.C b/external/rpc_win32/TEST/DO_COU.C
new file mode 100644
index 0000000..0230e58
--- /dev/null
+++ b/external/rpc_win32/TEST/DO_COU.C
@@ -0,0 +1,41 @@
+#include <stdio.h>
+#include <rpc/rpc.h>
+#include "cou.h"
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+CLIENT *cl;
+void *dummy;
+int i, val, final;
+
+rpc_nt_init();
+
+if (argc != 2) {
+	fprintf(stderr, "usage: %s host\n", argv[0]);
+	exit (1);
+	}
+
+cl = clnt_create(argv[1], COUNTSERV, COUNTVERS, "tcp");
+
+if (cl == NULL) {
+	clnt_pcreateerror(argv[1]);
+	exit (1);
+	}
+
+for (i = 0; i < 10; i++) {
+	inc_1(dummy, cl);
+	inc_1(dummy, cl);
+	val = *dec_1(dummy, cl);
+	printf("New value: %d\n", val);
+}
+
+val = val + 100;
+final = *set_1(&val, cl);
+printf("Final value: %d\n", final);
+
+rpc_nt_exit();
+
+exit(0);
+}
diff --git a/external/rpc_win32/TEST/Makefile b/external/rpc_win32/TEST/Makefile
new file mode 100644
index 0000000..71ad3a5
--- /dev/null
+++ b/external/rpc_win32/TEST/Makefile
@@ -0,0 +1,57 @@
+# Nmake macros for building Windows 32-Bit apps
+
+!include <ntwin32.mak>
+
+# If the rpc include directory is not included in the standard path
+# you have to give the path to it here.
+RPCINCLUDEPATH = ..
+
+# If the rpc library is not included in the standard lib path
+# you have to give the path to it here.
+RPCLIBPATH = ..\lib\\
+
+OBJS =		COUNT.OBJ \
+		COU_SVC.OBJ \
+		COU_XDR.OBJ
+
+RPCGEN = 	..\rpcgen\rpcgen.exe
+
+all: COU_SVC.EXE DO_COU.EXE
+
+clean:
+	del *.OBJ *.EXE COU.H COU_CLNT.* COU_SVC.* COU_XDR.*
+
+COU_SVC.EXE: 	COUNT.OBJ \
+		COU_SVC.OBJ \
+		COU_XDR.OBJ \
+		$(RPCLIBPATH)oncrpc.lib
+     $(link) $(conlflags) $(ldebug) -out:COU_svc.exe COUNT.obj COU_XDR.obj COU_SVC.obj $(conlibsdll) $(RPCLIBPATH)oncrpc.lib
+     copy COU_svc.exe ..\bin
+
+DO_COU.EXE: 	COU_CLNT.OBJ \
+		COU_XDR.OBJ \
+		DO_COU.OBJ \
+		$(RPCLIBPATH)oncrpc.lib
+     $(link) $(conlflags) $(ldebug) -out:DO_COU.exe COU_XDR.obj COU_CLNT.obj DO_COU.OBJ $(conlibsdll) $(RPCLIBPATH)oncrpc.lib
+     copy DO_COU.exe ..\bin
+
+.c.obj:
+    $(cc) /I$(RPCINCLUDEPATH) $(cdebug) $(cflags) $(cvarsdll) $*.c
+
+COUNT.obj: COUNT.c COU.H
+COU_SVC.OBJ: COU_SVC.c
+COU_CLNT.OBJ: COU_CLNT.c
+DO_COU.OBJ: DO_COU.c COU.H
+COU_XDR.OBJ: COU_XDR.c
+
+COU_XDR.C:	COU.X
+    $(RPCGEN) COU.X
+
+COU.H:	COU.X
+    $(RPCGEN) COU.X
+
+COU_CLNT.C:	COU.X
+    $(RPCGEN) COU.X
+
+COU_SVC.C:	COU.X
+    $(RPCGEN) COU.X
diff --git a/external/rpc_win32/makefile b/external/rpc_win32/makefile
new file mode 100644
index 0000000..cd06734
--- /dev/null
+++ b/external/rpc_win32/makefile
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 1996 Logiciels et Applications Scientifiques (L.A.S.) Inc
+# Permission to use, copy, modify and distribute this software and
+# its documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies, that
+# both the copyright notice and this permission notice appear in
+# supporting documentation, and that the name of L.A.S. Inc not be used 
+# in advertising or publicity pertaining to distribution of the software 
+# without specific, written prior permission. L.A.S. Inc. makes no
+# representations about the suitability of this software for any purpose.
+# It is provided "as is" without express or implied warranty.
+#
+
+include $(TOPDIR)/config/common.mak
+ 
+#
+# Sub-directories that need to be built
+#
+subdirs	= librpc rpcgen
+
+#
+# Default target to build everything in all sub-directories
+#
+all: $(subdirs) 
+
+#
+# Target to allow individual sub-directories to be built 
+# (e.g.  make zlib)
+#
+.PHONY: $(subdirs)
+$(subdirs): 
+	cd $@; $(MAKE)
+
+#
+# Pass specialized targets into the sub-directories
+#
+.PHONY: $(STANDARD_TARGETS)
+$(STANDARD_TARGETS):
+	for i in $(subdirs); do \
+	  $(MAKE) --directory $$i $@; \
+	done
diff --git a/external/zlib/OGDI_ZLIB.TXT b/external/zlib/OGDI_ZLIB.TXT
new file mode 100644
index 0000000..e132b79
--- /dev/null
+++ b/external/zlib/OGDI_ZLIB.TXT
@@ -0,0 +1,19 @@
+	OGDI / ZLIB README
+	==================
+
+
+This directory contains the ZLIB 1.1.4 source release code.  Only the
+core ZLIB code has been preserved, various contributed utilities and
+so forth have been omitted.  
+
+The nt/zlib.cnt DLL def file has been renamed zlib.def, and the only change
+has been to remove the DLL name so the makefile can force it to be based
+on the OGDI version.  Otherwise the DLL should be entry point compatible with
+a generic 1.1.3 zlib build. 
+
+
+More information about zlib can be found at:
+
+  http://www.gzip.org/zlib
+
+
diff --git a/external/zlib/README b/external/zlib/README
new file mode 100644
index 0000000..29d6714
--- /dev/null
+++ b/external/zlib/README
@@ -0,0 +1,147 @@
+zlib 1.1.4 is a general purpose data compression library.  All the code
+is thread safe.  The data format used by the zlib library
+is described by RFCs (Request for Comments) 1950 to 1952 in the files 
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
+format) and rfc1952.txt (gzip format). These documents are also available in
+other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact jloup at gzip.org). A usage
+example of the library is given in the file example.c which also tests that
+the library is working correctly. Another example is given in the file
+minigzip.c. The compression library itself is composed of all source files
+except example.c and minigzip.c.
+
+To compile all files and run the test program, follow the instructions
+given at the top of Makefile. In short "make test; make install"
+should work for most machines. For Unix: "./configure; make test; make install"
+For MSDOS, use one of the special makefiles such as Makefile.msc.
+For VMS, use Make_vms.com or descrip.mms.
+
+Questions about zlib should be sent to <zlib at gzip.org>, or to
+Gilles Vollant <info at winimage.com> for the Windows DLL version.
+The zlib home page is http://www.zlib.org or http://www.gzip.org/zlib/
+Before reporting a problem, please check this site to verify that
+you have the latest version of zlib; otherwise get the latest version and
+check whether the problem still exists or not.
+
+PLEASE read the zlib FAQ http://www.gzip.org/zlib/zlib_faq.html
+before asking for help.
+
+Mark Nelson <markn at ieee.org> wrote an article about zlib for the Jan. 1997
+issue of  Dr. Dobb's Journal; a copy of the article is available in
+http://dogma.net/markn/articles/zlibtool/zlibtool.htm
+
+The changes made in version 1.1.4 are documented in the file ChangeLog.
+The only changes made since 1.1.3 are bug corrections:
+
+- ZFREE was repeated on same allocation on some error conditions.
+  This creates a security problem described in
+  http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+  less than 32K.
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+  of 256 bytes. (A complete fix will be available in 1.1.5).
+
+The beta version 1.1.5beta includes many more changes. A new official
+version 1.1.5 will be released as soon as extensive testing has been
+completed on it.
+
+
+Unsupported third party contributions are provided in directory "contrib".
+
+A Java implementation of zlib is available in the Java Development Kit
+http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
+See the zlib home page http://www.zlib.org for details.
+
+A Perl interface to zlib written by Paul Marquess <pmarquess at bfsec.bt.co.uk>
+is in the CPAN (Comprehensive Perl Archive Network) sites
+http://www.cpan.org/modules/by-module/Compress/
+
+A Python interface to zlib written by A.M. Kuchling <amk at magnet.com>
+is available in Python 1.5 and later versions, see
+http://www.python.org/doc/lib/module-zlib.html
+
+A zlib binding for TCL written by Andreas Kupries <a.kupries at westend.com>
+is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
+
+An experimental package to read and write files in .zip format,
+written on top of zlib by Gilles Vollant <info at winimage.com>, is
+available at http://www.winimage.com/zLibDll/unzip.html
+and also in the contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
+  and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
+  The zlib DLL support was initially done by Alessandro Iacopetti and is
+  now maintained by Gilles Vollant <info at winimage.com>. Check the zlib DLL
+  home page at http://www.winimage.com/zLibDll
+
+  From Visual Basic, you can call the DLL functions which do not take
+  a structure as argument: compress, uncompress and all gz* functions.
+  See contrib/visual-basic.txt for more information, or get
+  http://www.tcfb.com/dowseware/cmp-z-it.zip
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization.
+  With -O, one libpng test fails. The test works in 32 bit mode (with
+  the -n32 compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1   
+  it works when compiled with cc.
+
+- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
+  is necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
+  with other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
+
+- For Turbo C the small model is supported only with reduced performance to
+  avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
+
+- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
+  Per Harald Myrvang <perm at stud.cs.uit.no>
+
+
+Acknowledgments:
+
+  The deflate format used by zlib was defined by Phil Katz. The deflate
+  and zlib specifications were written by L. Peter Deutsch. Thanks to all the
+  people who reported problems and suggested various improvements in zlib;
+  they are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2002 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup at gzip.org          madler at alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not*
+receiving lengthy legal documents to sign. The sources are provided
+for free but without warranty of any kind.  The library has been
+entirely written by Jean-loup Gailly and Mark Adler; it does not
+include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include
+in the file ChangeLog history information documenting your changes.
diff --git a/external/zlib/adler32.c b/external/zlib/adler32.c
new file mode 100644
index 0000000..08fa305
--- /dev/null
+++ b/external/zlib/adler32.c
@@ -0,0 +1,48 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: adler32.c,v 1.3 2002/03/28 16:05:34 warmerda Exp $ */
+
+#include "zlib.h"
+
+#define BASE 65521L /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    unsigned long s1 = adler & 0xffff;
+    unsigned long s2 = (adler >> 16) & 0xffff;
+    int k;
+
+    if (buf == Z_NULL) return 1L;
+
+    while (len > 0) {
+        k = len < NMAX ? len : NMAX;
+        len -= k;
+        while (k >= 16) {
+            DO16(buf);
+	    buf += 16;
+            k -= 16;
+        }
+        if (k != 0) do {
+            s1 += *buf++;
+	    s2 += s1;
+        } while (--k);
+        s1 %= BASE;
+        s2 %= BASE;
+    }
+    return (s2 << 16) | s1;
+}
diff --git a/external/zlib/compress.c b/external/zlib/compress.c
new file mode 100644
index 0000000..39bcbb6
--- /dev/null
+++ b/external/zlib/compress.c
@@ -0,0 +1,68 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: compress.c,v 1.3 2002/03/28 16:05:34 warmerda Exp $ */
+
+#include "zlib.h"
+
+/* ===========================================================================
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+    int level;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+    stream.opaque = (voidpf)0;
+
+    err = deflateInit(&stream, level);
+    if (err != Z_OK) return err;
+
+    err = deflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        deflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = deflateEnd(&stream);
+    return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
diff --git a/external/zlib/crc32.c b/external/zlib/crc32.c
new file mode 100644
index 0000000..d3c3592
--- /dev/null
+++ b/external/zlib/crc32.c
@@ -0,0 +1,162 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: crc32.c,v 1.3 2002/03/28 16:05:34 warmerda Exp $ */
+
+#include "zlib.h"
+
+#define local static
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local int crc_table_empty = 1;
+local uLongf crc_table[256];
+local void make_crc_table OF((void));
+
+/*
+  Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The table is simply the CRC of all possible eight bit values.  This is all
+  the information needed to generate CRC's on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.
+*/
+local void make_crc_table()
+{
+  uLong c;
+  int n, k;
+  uLong poly;            /* polynomial exclusive-or pattern */
+  /* terms of polynomial defining this crc (except x^32): */
+  static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+  /* make exclusive-or pattern from polynomial (0xedb88320L) */
+  poly = 0L;
+  for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
+    poly |= 1L << (31 - p[n]);
+ 
+  for (n = 0; n < 256; n++)
+  {
+    c = (uLong)n;
+    for (k = 0; k < 8; k++)
+      c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+    crc_table[n] = c;
+  }
+  crc_table_empty = 0;
+}
+#else
+/* ========================================================================
+ * Table of CRC-32's of all single-byte values (made by make_crc_table)
+ */
+local const uLongf crc_table[256] = {
+  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+  0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+  0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+  0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+  0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+  0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+  0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+  0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+  0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+  0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+  0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+  0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+  0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+  0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+  0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+  0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+  0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+  0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+  0x2d02ef8dL
+};
+#endif
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const uLongf * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+  if (crc_table_empty) make_crc_table();
+#endif
+  return (const uLongf *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+
+/* ========================================================================= */
+uLong ZEXPORT crc32(crc, buf, len)
+    uLong crc;
+    const Bytef *buf;
+    uInt len;
+{
+    if (buf == Z_NULL) return 0L;
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+      make_crc_table();
+#endif
+    crc = crc ^ 0xffffffffL;
+    while (len >= 8)
+    {
+      DO8(buf);
+      len -= 8;
+    }
+    if (len) do {
+      DO1(buf);
+    } while (--len);
+    return crc ^ 0xffffffffL;
+}
diff --git a/external/zlib/deflate.c b/external/zlib/deflate.c
new file mode 100644
index 0000000..ca67fb4
--- /dev/null
+++ b/external/zlib/deflate.c
@@ -0,0 +1,1350 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in ftp://ds.internic.net/rfc/rfc1951.txt
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id: deflate.c,v 1.3 2002/03/28 16:05:34 warmerda Exp $ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+   " deflate 1.1.4 Copyright 1995-2002 Jean-loup Gailly ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+      void match_init OF((void)); /* asm code initialization */
+      uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+local const config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* maximum speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+			 Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+		  version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int noheader = 0;
+    static const char* my_version = ZLIB_VERSION;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+	return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+    if (strm->zalloc == Z_NULL) {
+	strm->zalloc = zcalloc;
+	strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == Z_NULL) strm->zfree = zcfree;
+
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#ifdef FASTEST
+    level = 1;
+#endif
+
+    if (windowBits < 0) { /* undocumented feature: suppress zlib header */
+        noheader = 1;
+        windowBits = -windowBits;
+    }
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 9 || windowBits > 15 || level < 0 || level > 9 ||
+	strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+        return Z_STREAM_ERROR;
+    }
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+
+    s->noheader = noheader;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt length = dictLength;
+    uInt n;
+    IPos hash_head = 0;
+
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
+        strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
+
+    s = strm->state;
+    strm->adler = adler32(strm->adler, dictionary, dictLength);
+
+    if (length < MIN_MATCH) return Z_OK;
+    if (length > MAX_DIST(s)) {
+	length = MAX_DIST(s);
+#ifndef USE_DICT_HEAD
+	dictionary += dictLength - length; /* use the tail of the dictionary */
+#endif
+    }
+    zmemcpy(s->window, dictionary, length);
+    s->strstart = length;
+    s->block_start = (long)length;
+
+    /* Insert all strings in the hash table (except for the last two bytes).
+     * s->lookahead stays null, so s->ins_h will be recomputed at the next
+     * call of fill_window.
+     */
+    s->ins_h = s->window[0];
+    UPDATE_HASH(s, s->ins_h, s->window[1]);
+    for (n = 0; n <= length - MIN_MATCH; n++) {
+	INSERT_STRING(s, n, hash_head);
+    }
+    if (hash_head) hash_head = 0;  /* to make compiler happy */
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+    
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->noheader < 0) {
+        s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
+    }
+    s->status = s->noheader ? BUSY_STATE : INIT_STATE;
+    strm->adler = 1;
+    s->last_flush = Z_NO_FLUSH;
+
+    _tr_init(s);
+    lm_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+    int err = Z_OK;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+
+    if (level == Z_DEFAULT_COMPRESSION) {
+	level = 6;
+    }
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
+	return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if (func != configuration_table[level].func && strm->total_in != 0) {
+	/* Flush the last buffer: */
+	err = deflate(strm, Z_PARTIAL_FLUSH);
+    }
+    if (s->level != level) {
+	s->level = level;
+	s->max_lazy_match   = configuration_table[level].max_lazy;
+	s->good_match       = configuration_table[level].good_length;
+	s->nice_match       = configuration_table[level].nice_length;
+	s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return err;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}   
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    unsigned len = strm->state->pending;
+
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    zmemcpy(strm->next_out, strm->state->pending_out, len);
+    strm->next_out  += len;
+    strm->state->pending_out  += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    strm->state->pending -= len;
+    if (strm->state->pending == 0) {
+        strm->state->pending_out = strm->state->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+	flush > Z_FINISH || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = strm->state;
+
+    if (strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+	(s->status == FINISH_STATE && flush != Z_FINISH)) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Write the zlib header */
+    if (s->status == INIT_STATE) {
+
+        uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+        uInt level_flags = (s->level-1) >> 1;
+
+        if (level_flags > 3) level_flags = 3;
+        header |= (level_flags << 6);
+	if (s->strstart != 0) header |= PRESET_DICT;
+        header += 31 - (header % 31);
+
+        s->status = BUSY_STATE;
+        putShortMSB(s, header);
+
+	/* Save the adler32 of the preset dictionary: */
+	if (s->strstart != 0) {
+	    putShortMSB(s, (uInt)(strm->adler >> 16));
+	    putShortMSB(s, (uInt)(strm->adler & 0xffff));
+	}
+	strm->adler = 1L;
+    }
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+	    /* Since avail_out is 0, deflate will be called again with
+	     * more output space, but possibly with both pending and
+	     * avail_in equal to zero. There won't be anything to do,
+	     * but this is not an error situation so make sure we
+	     * return OK instead of BUF_ERROR at next call of deflate:
+             */
+	    s->last_flush = -1;
+	    return Z_OK;
+	}
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUFF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && flush <= old_flush &&
+	       flush != Z_FINISH) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+	bstate = (*(configuration_table[s->level].func))(s, flush);
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+	    if (strm->avail_out == 0) {
+	        s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+	    }
+	    return Z_OK;
+	    /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+	     * of deflate should use the same flush parameter to make sure
+	     * that the flush is complete. So we don't have to output an
+	     * empty block here, this will be done at next call. This also
+	     * ensures that for a very small output buffer, we emit at most
+	     * one empty block.
+	     */
+	}
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                _tr_align(s);
+            } else { /* FULL_FLUSH or SYNC_FLUSH */
+                _tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                }
+            }
+            flush_pending(strm);
+	    if (strm->avail_out == 0) {
+	      s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+	      return Z_OK;
+	    }
+        }
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->noheader) return Z_STREAM_END;
+
+    /* Write the zlib trailer (adler32) */
+    putShortMSB(s, (uInt)(strm->adler >> 16));
+    putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    s->noheader = -1; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+    status = strm->state->status;
+    if (status != INIT_STATE && status != BUSY_STATE &&
+	status != FINISH_STATE) {
+      return Z_STREAM_ERROR;
+    }
+
+    /* Deallocate in reverse order of allocations: */
+    TRY_FREE(strm, strm->state->pending_buf);
+    TRY_FREE(strm, strm->state->head);
+    TRY_FREE(strm, strm->state->prev);
+    TRY_FREE(strm, strm->state->window);
+
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+#ifdef MAXSEG_64K
+    return Z_STREAM_ERROR;
+#else
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+
+
+    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+
+    ss = source->state;
+
+    *dest = *source;
+
+    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+    if (ds == Z_NULL) return Z_MEM_ERROR;
+    dest->state = (struct internal_state FAR *) ds;
+    *ds = *ss;
+    ds->strm = dest;
+
+    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
+    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
+    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+    ds->pending_buf = (uchf *) overlay;
+
+    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+        ds->pending_buf == Z_NULL) {
+        deflateEnd (dest);
+        return Z_MEM_ERROR;
+    }
+    /* following zmemcpy do not work for 16-bit MSDOS */
+    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
+    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
+    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+#endif
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+    z_streamp strm;
+    Bytef *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    if (!strm->state->noheader) {
+        strm->adler = adler32(strm->adler, strm->next_in, len);
+    }
+    zmemcpy(buf, strm->next_in, len);
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+}
+
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+#ifndef FASTEST
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2:
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+    return s->lookahead;
+}
+
+#else /* FASTEST */
+/* ---------------------------------------------------------------------------
+ * Optimized version for level == 1 only
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    Assert(cur_match < s->strstart, "no future");
+
+    match = s->window + cur_match;
+
+    /* Return failure if the match length is less than 2:
+     */
+    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+    /* The check at best_len-1 can be removed because it will be made
+     * again later. (This heuristic is not always a win.)
+     * It is not necessary to compare scan[2] and match[2] since they
+     * are always equal when the other bytes match, given that
+     * the hash keys are equal and that HASH_BITS >= 8.
+     */
+    scan += 2, match += 2;
+    Assert(*scan == *match, "match[2]?");
+
+    /* We check for insufficient lookahead only every 8th comparison;
+     * the 256th check will be made at strstart+258.
+     */
+    do {
+    } while (*++scan == *++match && *++scan == *++match &&
+	     *++scan == *++match && *++scan == *++match &&
+	     *++scan == *++match && *++scan == *++match &&
+	     *++scan == *++match && *++scan == *++match &&
+	     scan < strend);
+
+    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (int)(strend - scan);
+
+    if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+    s->match_start = cur_match;
+    return len <= s->lookahead ? len : s->lookahead;
+}
+#endif /* FASTEST */
+#endif /* ASMV */
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (zmemcmp(s->window + match,
+                s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+		start, match, length);
+        do {
+	    fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+	} while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Posf *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+            more = wsize;
+
+        } else if (more == (unsigned)(-1)) {
+            /* Very unlikely, but possible on 16 bit machine if strstart == 0
+             * and lookahead == 1 (input done one byte at time)
+             */
+            more--;
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        } else if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage). We slide even when level == 0
+               to keep the hash table consistent if we switch back to level > 0
+               later. (Using level 0 permanently is not an optimal usage of
+               zlib, so we don't care about this pathological case.)
+             */
+	    n = s->hash_size;
+	    p = &s->head[n];
+	    do {
+		m = *--p;
+		*p = (Pos)(m >= wsize ? m-wsize : NIL);
+	    } while (--n);
+
+	    n = wsize;
+#ifndef FASTEST
+	    p = &s->prev[n];
+	    do {
+		m = *--p;
+		*p = (Pos)(m >= wsize ? m-wsize : NIL);
+		/* If n is not on any hash chain, prev[n] is garbage but
+		 * its value will never be used.
+		 */
+	    } while (--n);
+#endif
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) return;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead >= MIN_MATCH) {
+            s->ins_h = s->window[s->strstart];
+            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, eof) { \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+		(ulg)((long)s->strstart - s->block_start), \
+		(eof)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, eof) { \
+   FLUSH_BLOCK_ONLY(s, eof); \
+   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+     * to pending_buf_size, and each stored block has a 5 byte header:
+     */
+    ulg max_block_size = 0xffff;
+    ulg max_start;
+
+    if (max_block_size > s->pending_buf_size - 5) {
+        max_block_size = s->pending_buf_size - 5;
+    }
+
+    /* Copy as much as possible from input to output: */
+    for (;;) {
+        /* Fill the window as much as possible: */
+        if (s->lookahead <= 1) {
+
+            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+		   s->block_start >= (long)s->w_size, "slide too late");
+
+            fill_window(s);
+            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+	Assert(s->block_start >= 0L, "block gone");
+
+	s->strstart += s->lookahead;
+	s->lookahead = 0;
+
+	/* Emit a stored block if pending_buf will be full: */
+ 	max_start = s->block_start + max_block_size;
+        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+	    /* strstart == 0 is possible when wraparound on 16-bit machine */
+	    s->lookahead = (uInt)(s->strstart - max_start);
+	    s->strstart = (uInt)max_start;
+            FLUSH_BLOCK(s, 0);
+	}
+	/* Flush if we may have to slide, otherwise block_start may become
+         * negative and the data will be gone:
+         */
+        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+            FLUSH_BLOCK(s, 0);
+	}
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL; /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+	        return need_more;
+	    }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            }
+            /* longest_match() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            _tr_tally_dist(s, s->strstart - s->match_start,
+                           s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+#ifndef FASTEST
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in hash table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++; 
+            } else
+#endif
+	    {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++; 
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
+
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head = NIL;    /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+	        return need_more;
+	    }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            if (s->strategy != Z_HUFFMAN_ONLY) {
+                s->match_length = longest_match (s, hash_head);
+            }
+            /* longest_match() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
+                 (s->match_length == MIN_MATCH &&
+                  s->strstart - s->match_start > TOO_FAR))) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+			   s->prev_length - MIN_MATCH, bflush);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+	    _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+	    if (bflush) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+        s->match_available = 0;
+    }
+    FLUSH_BLOCK(s, flush == Z_FINISH);
+    return flush == Z_FINISH ? finish_done : block_done;
+}
diff --git a/external/zlib/deflate.h b/external/zlib/deflate.h
new file mode 100644
index 0000000..08fb76e
--- /dev/null
+++ b/external/zlib/deflate.h
@@ -0,0 +1,318 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2002 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id: deflate.h,v 1.3 2002/03/28 16:05:34 warmerda Exp $ */
+
+#ifndef _DEFLATE_H
+#define _DEFLATE_H
+
+#include "zutil.h"
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define INIT_STATE    42
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    int   pending;       /* nb of bytes in the pending buffer */
+    int   noheader;      /* suppress zlib header and adler32 */
+    Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
+    Byte  method;        /* STORED (for zip only) or DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to supress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    uInt matches;       /* number of string matches in current block */
+    int last_eob_len;   /* bit length of EOB code for last block */
+
+#ifdef DEBUG
+    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+        /* in trees.c */
+void _tr_init         OF((deflate_state *s));
+int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
+void _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
+			  int eof));
+void _tr_align        OF((deflate_state *s));
+void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
+                          int eof));
+
+#define d_code(dist) \
+   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+  extern uch _length_code[];
+  extern uch _dist_code[];
+#else
+  extern const uch _length_code[];
+  extern const uch _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+  { uch cc = (c); \
+    s->d_buf[s->last_lit] = 0; \
+    s->l_buf[s->last_lit++] = cc; \
+    s->dyn_ltree[cc].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+   }
+# define _tr_tally_dist(s, distance, length, flush) \
+  { uch len = (length); \
+    ush dist = (distance); \
+    s->d_buf[s->last_lit] = dist; \
+    s->l_buf[s->last_lit++] = len; \
+    dist--; \
+    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+    s->dyn_dtree[d_code(dist)].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+  }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+              flush = _tr_tally(s, distance, length) 
+#endif
+
+#endif
diff --git a/external/zlib/example.c b/external/zlib/example.c
new file mode 100644
index 0000000..fc353ce
--- /dev/null
+++ b/external/zlib/example.c
@@ -0,0 +1,556 @@
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: example.c,v 1.3 2002/03/28 16:05:34 warmerda Exp $ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#else
+   extern void exit  OF((int));
+#endif
+
+#if defined(VMS) || defined(RISCOS)
+#  define TESTFILE "foo-gz"
+#else
+#  define TESTFILE "foo.gz"
+#endif
+
+#define CHECK_ERR(err, msg) { \
+    if (err != Z_OK) { \
+        fprintf(stderr, "%s error: %d\n", msg, err); \
+        exit(1); \
+    } \
+}
+
+const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+const char dictionary[] = "hello";
+uLong dictId; /* Adler32 value of the dictionary */
+
+void test_compress      OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_gzio          OF((const char *out, const char *in, 
+		            Byte *uncompr, int uncomprLen));
+void test_deflate       OF((Byte *compr, uLong comprLen));
+void test_inflate       OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_flush         OF((Byte *compr, uLong *comprLen));
+void test_sync          OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate  OF((Byte *compr, uLong comprLen));
+void test_dict_inflate  OF((Byte *compr, uLong comprLen,
+		            Byte *uncompr, uLong uncomprLen));
+int  main               OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    uLong len = strlen(hello)+1;
+
+    err = compress(compr, &comprLen, (const Bytef*)hello, len);
+    CHECK_ERR(err, "compress");
+
+    strcpy((char*)uncompr, "garbage");
+
+    err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+    CHECK_ERR(err, "uncompress");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad uncompress\n");
+	exit(1);
+    } else {
+        printf("uncompress(): %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(out, in, uncompr, uncomprLen)
+    const char *out; /* compressed output file */
+    const char *in;  /* compressed input file */
+    Byte *uncompr;
+    int  uncomprLen;
+{
+    int err;
+    int len = strlen(hello)+1;
+    gzFile file;
+    z_off_t pos;
+
+    file = gzopen(out, "wb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+        exit(1);
+    }
+    gzputc(file, 'h');
+    if (gzputs(file, "ello") != 4) {
+        fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+	exit(1);
+    }
+    if (gzprintf(file, ", %s!", "hello") != 8) {
+        fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+	exit(1);
+    }
+    gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+    gzclose(file);
+
+    file = gzopen(in, "rb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+    }
+    strcpy((char*)uncompr, "garbage");
+
+    uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen);
+    if (uncomprLen != len) {
+        fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+	exit(1);
+    }
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+	exit(1);
+    } else {
+        printf("gzread(): %s\n", (char *)uncompr);
+    }
+
+    pos = gzseek(file, -8L, SEEK_CUR);
+    if (pos != 6 || gztell(file) != pos) {
+	fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+		(long)pos, (long)gztell(file));
+	exit(1);
+    }
+
+    if (gzgetc(file) != ' ') {
+	fprintf(stderr, "gzgetc error\n");
+	exit(1);
+    }
+
+    gzgets(file, (char*)uncompr, uncomprLen);
+    uncomprLen = strlen((char*)uncompr);
+    if (uncomprLen != 6) { /* "hello!" */
+        fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+	exit(1);
+    }
+    if (strcmp((char*)uncompr, hello+7)) {
+        fprintf(stderr, "bad gzgets after gzseek\n");
+	exit(1);
+    } else {
+        printf("gzgets() after gzseek: %s\n", (char *)uncompr);
+    }
+
+    gzclose(file);
+}
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    int len = strlen(hello)+1;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (Bytef*)hello;
+    c_stream.next_out = compr;
+
+    while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) {
+        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+        err = deflate(&c_stream, Z_NO_FLUSH);
+        CHECK_ERR(err, "deflate");
+    }
+    /* Finish the stream, still forcing small buffers: */
+    for (;;) {
+        c_stream.avail_out = 1;
+        err = deflate(&c_stream, Z_FINISH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "deflate");
+    }
+
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = 0;
+    d_stream.next_out = uncompr;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate\n");
+	exit(1);
+    } else {
+        printf("inflate(): %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_SPEED);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    /* At this point, uncompr is still mostly zeroes, so it should compress
+     * very well:
+     */
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (uInt)uncomprLen;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+    if (c_stream.avail_in != 0) {
+        fprintf(stderr, "deflate not greedy\n");
+	exit(1);
+    }
+
+    /* Feed in already compressed data and switch to no compression: */
+    deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+    c_stream.next_in = compr;
+    c_stream.avail_in = (uInt)comprLen/2;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    /* Switch back to compressing mode: */
+    deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (uInt)uncomprLen;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+	exit(1);
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    for (;;) {
+        d_stream.next_out = uncompr;            /* discard the output */
+	d_stream.avail_out = (uInt)uncomprLen;
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "large inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+        fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+	exit(1);
+    } else {
+        printf("large_inflate(): OK\n");
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+    Byte *compr;
+    uLong *comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    int len = strlen(hello)+1;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (Bytef*)hello;
+    c_stream.next_out = compr;
+    c_stream.avail_in = 3;
+    c_stream.avail_out = (uInt)*comprLen;
+    err = deflate(&c_stream, Z_FULL_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    compr[3]++; /* force an error in first compressed block */
+    c_stream.avail_in = len - 3;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        CHECK_ERR(err, "deflate");
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+
+    *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = 2; /* just read the zlib header */
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    inflate(&d_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "inflate");
+
+    d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
+    err = inflateSync(&d_stream);           /* but skip the damaged part */
+    CHECK_ERR(err, "inflateSync");
+
+    err = inflate(&d_stream, Z_FINISH);
+    if (err != Z_DATA_ERROR) {
+        fprintf(stderr, "inflate should report DATA_ERROR\n");
+        /* Because of incorrect adler32 */
+	exit(1);
+    }
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = (alloc_func)0;
+    c_stream.zfree = (free_func)0;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    err = deflateSetDictionary(&c_stream,
+			       (const Bytef*)dictionary, sizeof(dictionary));
+    CHECK_ERR(err, "deflateSetDictionary");
+
+    dictId = c_stream.adler;
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    c_stream.next_in = (Bytef*)hello;
+    c_stream.avail_in = (uInt)strlen(hello)+1;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+	exit(1);
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = (alloc_func)0;
+    d_stream.zfree = (free_func)0;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    for (;;) {
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+	if (err == Z_NEED_DICT) {
+	    if (d_stream.adler != dictId) {
+		fprintf(stderr, "unexpected dictionary");
+		exit(1);
+	    }
+	    err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+				       sizeof(dictionary));
+	}
+        CHECK_ERR(err, "inflate with dict");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate with dict\n");
+	exit(1);
+    } else {
+        printf("inflate with dictionary: %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Usage:  example [output.gz  [input.gz]]
+ */
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    Byte *compr, *uncompr;
+    uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+    uLong uncomprLen = comprLen;
+    static const char* myVersion = ZLIB_VERSION;
+
+    if (zlibVersion()[0] != myVersion[0]) {
+        fprintf(stderr, "incompatible zlib version\n");
+        exit(1);
+
+    } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+        fprintf(stderr, "warning: different zlib version\n");
+    }
+
+    compr    = (Byte*)calloc((uInt)comprLen, 1);
+    uncompr  = (Byte*)calloc((uInt)uncomprLen, 1);
+    /* compr and uncompr are cleared to avoid reading uninitialized
+     * data and to ensure that uncompr compresses well.
+     */
+    if (compr == Z_NULL || uncompr == Z_NULL) {
+        printf("out of memory\n");
+	exit(1);
+    }
+    test_compress(compr, comprLen, uncompr, uncomprLen);
+
+    test_gzio((argc > 1 ? argv[1] : TESTFILE),
+              (argc > 2 ? argv[2] : TESTFILE),
+	      uncompr, (int)uncomprLen);
+
+    test_deflate(compr, comprLen);
+    test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+    test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    test_flush(compr, &comprLen);
+    test_sync(compr, comprLen, uncompr, uncomprLen);
+    comprLen = uncomprLen;
+
+    test_dict_deflate(compr, comprLen);
+    test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    exit(0);
+    return 0; /* to avoid warning */
+}
diff --git a/external/zlib/gzio.c b/external/zlib/gzio.c
new file mode 100644
index 0000000..f7c61c6
--- /dev/null
+++ b/external/zlib/gzio.c
@@ -0,0 +1,875 @@
+/* gzio.c -- IO on .gz files
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Compile this file with -DNO_DEFLATE to avoid the compression code.
+ */
+
+/* @(#) $Id: gzio.c,v 1.3 2002/03/28 16:05:34 warmerda Exp $ */
+
+#include <stdio.h>
+
+#include "zutil.h"
+
+struct internal_state {int dummy;}; /* for buggy compilers */
+
+#ifndef Z_BUFSIZE
+#  ifdef MAXSEG_64K
+#    define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
+#  else
+#    define Z_BUFSIZE 16384
+#  endif
+#endif
+#ifndef Z_PRINTF_BUFSIZE
+#  define Z_PRINTF_BUFSIZE 4096
+#endif
+
+#define ALLOC(size) malloc(size)
+#define TRYFREE(p) {if (p) free(p);}
+
+static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
+#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define COMMENT      0x10 /* bit 4 set: file comment present */
+#define RESERVED     0xE0 /* bits 5..7: reserved */
+
+typedef struct gz_stream {
+    z_stream stream;
+    int      z_err;   /* error code for last stream operation */
+    int      z_eof;   /* set if end of input file */
+    FILE     *file;   /* .gz file */
+    Byte     *inbuf;  /* input buffer */
+    Byte     *outbuf; /* output buffer */
+    uLong    crc;     /* crc32 of uncompressed data */
+    char     *msg;    /* error message */
+    char     *path;   /* path name for debugging only */
+    int      transparent; /* 1 if input file is not a .gz file */
+    char     mode;    /* 'w' or 'r' */
+    long     startpos; /* start of compressed data in file (header skipped) */
+} gz_stream;
+
+
+local gzFile gz_open      OF((const char *path, const char *mode, int  fd));
+local int do_flush        OF((gzFile file, int flush));
+local int    get_byte     OF((gz_stream *s));
+local void   check_header OF((gz_stream *s));
+local int    destroy      OF((gz_stream *s));
+local void   putLong      OF((FILE *file, uLong x));
+local uLong  getLong      OF((gz_stream *s));
+
+/* ===========================================================================
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb"). The file is given either by file descriptor
+   or path name (if fd == -1).
+     gz_open return NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).
+*/
+local gzFile gz_open (path, mode, fd)
+    const char *path;
+    const char *mode;
+    int  fd;
+{
+    int err;
+    int level = Z_DEFAULT_COMPRESSION; /* compression level */
+    int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
+    char *p = (char*)mode;
+    gz_stream *s;
+    char fmode[80]; /* copy of mode, without the compression level */
+    char *m = fmode;
+
+    if (!path || !mode) return Z_NULL;
+
+    s = (gz_stream *)ALLOC(sizeof(gz_stream));
+    if (!s) return Z_NULL;
+
+    s->stream.zalloc = (alloc_func)0;
+    s->stream.zfree = (free_func)0;
+    s->stream.opaque = (voidpf)0;
+    s->stream.next_in = s->inbuf = Z_NULL;
+    s->stream.next_out = s->outbuf = Z_NULL;
+    s->stream.avail_in = s->stream.avail_out = 0;
+    s->file = NULL;
+    s->z_err = Z_OK;
+    s->z_eof = 0;
+    s->crc = crc32(0L, Z_NULL, 0);
+    s->msg = NULL;
+    s->transparent = 0;
+
+    s->path = (char*)ALLOC(strlen(path)+1);
+    if (s->path == NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+    strcpy(s->path, path); /* do this early for debugging */
+
+    s->mode = '\0';
+    do {
+        if (*p == 'r') s->mode = 'r';
+        if (*p == 'w' || *p == 'a') s->mode = 'w';
+        if (*p >= '0' && *p <= '9') {
+	    level = *p - '0';
+	} else if (*p == 'f') {
+	  strategy = Z_FILTERED;
+	} else if (*p == 'h') {
+	  strategy = Z_HUFFMAN_ONLY;
+	} else {
+	    *m++ = *p; /* copy the mode */
+	}
+    } while (*p++ && m != fmode + sizeof(fmode));
+    if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
+    
+    if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+        err = Z_STREAM_ERROR;
+#else
+        err = deflateInit2(&(s->stream), level,
+                           Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
+        /* windowBits is passed < 0 to suppress zlib header */
+
+        s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+#endif
+        if (err != Z_OK || s->outbuf == Z_NULL) {
+            return destroy(s), (gzFile)Z_NULL;
+        }
+    } else {
+        s->stream.next_in  = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
+
+        err = inflateInit2(&(s->stream), -MAX_WBITS);
+        /* windowBits is passed < 0 to tell that there is no zlib header.
+         * Note that in this case inflate *requires* an extra "dummy" byte
+         * after the compressed stream in order to complete decompression and
+         * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
+         * present after the compressed stream.
+         */
+        if (err != Z_OK || s->inbuf == Z_NULL) {
+            return destroy(s), (gzFile)Z_NULL;
+        }
+    }
+    s->stream.avail_out = Z_BUFSIZE;
+
+    errno = 0;
+    s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
+
+    if (s->file == NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+    if (s->mode == 'w') {
+        /* Write a very simple .gz header:
+         */
+        fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
+             Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
+	s->startpos = 10L;
+	/* We use 10L instead of ftell(s->file) to because ftell causes an
+         * fflush on some systems. This version of the library doesn't use
+         * startpos anyway in write mode, so this initialization is not
+         * necessary.
+         */
+    } else {
+	check_header(s); /* skip the .gz header */
+	s->startpos = (ftell(s->file) - s->stream.avail_in);
+    }
+    
+    return (gzFile)s;
+}
+
+/* ===========================================================================
+     Opens a gzip (.gz) file for reading or writing.
+*/
+gzFile ZEXPORT gzopen (path, mode)
+    const char *path;
+    const char *mode;
+{
+    return gz_open (path, mode, -1);
+}
+
+/* ===========================================================================
+     Associate a gzFile with the file descriptor fd. fd is not dup'ed here
+   to mimic the behavio(u)r of fdopen.
+*/
+gzFile ZEXPORT gzdopen (fd, mode)
+    int fd;
+    const char *mode;
+{
+    char name[20];
+
+    if (fd < 0) return (gzFile)Z_NULL;
+    sprintf(name, "<fd:%d>", fd); /* for debugging */
+
+    return gz_open (name, mode, fd);
+}
+
+/* ===========================================================================
+ * Update the compression level and strategy
+ */
+int ZEXPORT gzsetparams (file, level, strategy)
+    gzFile file;
+    int level;
+    int strategy;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    /* Make room to allow flushing */
+    if (s->stream.avail_out == 0) {
+
+	s->stream.next_out = s->outbuf;
+	if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+	    s->z_err = Z_ERRNO;
+	}
+	s->stream.avail_out = Z_BUFSIZE;
+    }
+
+    return deflateParams (&(s->stream), level, strategy);
+}
+
+/* ===========================================================================
+     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+   for end of file.
+   IN assertion: the stream s has been sucessfully opened for reading.
+*/
+local int get_byte(s)
+    gz_stream *s;
+{
+    if (s->z_eof) return EOF;
+    if (s->stream.avail_in == 0) {
+	errno = 0;
+	s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+	if (s->stream.avail_in == 0) {
+	    s->z_eof = 1;
+	    if (ferror(s->file)) s->z_err = Z_ERRNO;
+	    return EOF;
+	}
+	s->stream.next_in = s->inbuf;
+    }
+    s->stream.avail_in--;
+    return *(s->stream.next_in)++;
+}
+
+/* ===========================================================================
+      Check the gzip header of a gz_stream opened for reading. Set the stream
+    mode to transparent if the gzip magic header is not present; set s->err
+    to Z_DATA_ERROR if the magic header is present but the rest of the header
+    is incorrect.
+    IN assertion: the stream s has already been created sucessfully;
+       s->stream.avail_in is zero for the first time, but may be non-zero
+       for concatenated .gz files.
+*/
+local void check_header(s)
+    gz_stream *s;
+{
+    int method; /* method byte */
+    int flags;  /* flags byte */
+    uInt len;
+    int c;
+
+    /* Check the gzip magic header */
+    for (len = 0; len < 2; len++) {
+	c = get_byte(s);
+	if (c != gz_magic[len]) {
+	    if (len != 0) s->stream.avail_in++, s->stream.next_in--;
+	    if (c != EOF) {
+		s->stream.avail_in++, s->stream.next_in--;
+		s->transparent = 1;
+	    }
+	    s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
+	    return;
+	}
+    }
+    method = get_byte(s);
+    flags = get_byte(s);
+    if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
+	s->z_err = Z_DATA_ERROR;
+	return;
+    }
+
+    /* Discard time, xflags and OS code: */
+    for (len = 0; len < 6; len++) (void)get_byte(s);
+
+    if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
+	len  =  (uInt)get_byte(s);
+	len += ((uInt)get_byte(s))<<8;
+	/* len is garbage if EOF but the loop below will quit anyway */
+	while (len-- != 0 && get_byte(s) != EOF) ;
+    }
+    if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
+	while ((c = get_byte(s)) != 0 && c != EOF) ;
+    }
+    if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
+	while ((c = get_byte(s)) != 0 && c != EOF) ;
+    }
+    if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
+	for (len = 0; len < 2; len++) (void)get_byte(s);
+    }
+    s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
+}
+
+ /* ===========================================================================
+ * Cleanup then free the given gz_stream. Return a zlib error code.
+   Try freeing in the reverse order of allocations.
+ */
+local int destroy (s)
+    gz_stream *s;
+{
+    int err = Z_OK;
+
+    if (!s) return Z_STREAM_ERROR;
+
+    TRYFREE(s->msg);
+
+    if (s->stream.state != NULL) {
+	if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+	    err = Z_STREAM_ERROR;
+#else
+	    err = deflateEnd(&(s->stream));
+#endif
+	} else if (s->mode == 'r') {
+	    err = inflateEnd(&(s->stream));
+	}
+    }
+    if (s->file != NULL && fclose(s->file)) {
+#ifdef ESPIPE
+	if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
+#endif
+	    err = Z_ERRNO;
+    }
+    if (s->z_err < 0) err = s->z_err;
+
+    TRYFREE(s->inbuf);
+    TRYFREE(s->outbuf);
+    TRYFREE(s->path);
+    TRYFREE(s);
+    return err;
+}
+
+/* ===========================================================================
+     Reads the given number of uncompressed bytes from the compressed file.
+   gzread returns the number of bytes actually read (0 for end of file).
+*/
+int ZEXPORT gzread (file, buf, len)
+    gzFile file;
+    voidp buf;
+    unsigned len;
+{
+    gz_stream *s = (gz_stream*)file;
+    Bytef *start = (Bytef*)buf; /* starting point for crc computation */
+    Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */
+
+    if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
+
+    if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
+    if (s->z_err == Z_STREAM_END) return 0;  /* EOF */
+
+    next_out = (Byte*)buf;
+    s->stream.next_out = (Bytef*)buf;
+    s->stream.avail_out = len;
+
+    while (s->stream.avail_out != 0) {
+
+	if (s->transparent) {
+	    /* Copy first the lookahead bytes: */
+	    uInt n = s->stream.avail_in;
+	    if (n > s->stream.avail_out) n = s->stream.avail_out;
+	    if (n > 0) {
+		zmemcpy(s->stream.next_out, s->stream.next_in, n);
+		next_out += n;
+		s->stream.next_out = next_out;
+		s->stream.next_in   += n;
+		s->stream.avail_out -= n;
+		s->stream.avail_in  -= n;
+	    }
+	    if (s->stream.avail_out > 0) {
+		s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
+					     s->file);
+	    }
+	    len -= s->stream.avail_out;
+	    s->stream.total_in  += (uLong)len;
+	    s->stream.total_out += (uLong)len;
+            if (len == 0) s->z_eof = 1;
+	    return (int)len;
+	}
+        if (s->stream.avail_in == 0 && !s->z_eof) {
+
+            errno = 0;
+            s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+            if (s->stream.avail_in == 0) {
+                s->z_eof = 1;
+		if (ferror(s->file)) {
+		    s->z_err = Z_ERRNO;
+		    break;
+		}
+            }
+            s->stream.next_in = s->inbuf;
+        }
+        s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
+
+	if (s->z_err == Z_STREAM_END) {
+	    /* Check CRC and original size */
+	    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+	    start = s->stream.next_out;
+
+	    if (getLong(s) != s->crc) {
+		s->z_err = Z_DATA_ERROR;
+	    } else {
+	        (void)getLong(s);
+                /* The uncompressed length returned by above getlong() may
+                 * be different from s->stream.total_out) in case of
+		 * concatenated .gz files. Check for such files:
+		 */
+		check_header(s);
+		if (s->z_err == Z_OK) {
+		    uLong total_in = s->stream.total_in;
+		    uLong total_out = s->stream.total_out;
+
+		    inflateReset(&(s->stream));
+		    s->stream.total_in = total_in;
+		    s->stream.total_out = total_out;
+		    s->crc = crc32(0L, Z_NULL, 0);
+		}
+	    }
+	}
+	if (s->z_err != Z_OK || s->z_eof) break;
+    }
+    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
+
+    return (int)(len - s->stream.avail_out);
+}
+
+
+/* ===========================================================================
+      Reads one byte from the compressed file. gzgetc returns this byte
+   or -1 in case of end of file or error.
+*/
+int ZEXPORT gzgetc(file)
+    gzFile file;
+{
+    unsigned char c;
+
+    return gzread(file, &c, 1) == 1 ? c : -1;
+}
+
+
+/* ===========================================================================
+      Reads bytes from the compressed file until len-1 characters are
+   read, or a newline character is read and transferred to buf, or an
+   end-of-file condition is encountered.  The string is then terminated
+   with a null character.
+      gzgets returns buf, or Z_NULL in case of error.
+
+      The current implementation is not optimized at all.
+*/
+char * ZEXPORT gzgets(file, buf, len)
+    gzFile file;
+    char *buf;
+    int len;
+{
+    char *b = buf;
+    if (buf == Z_NULL || len <= 0) return Z_NULL;
+
+    while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
+    *buf = '\0';
+    return b == buf && len > 0 ? Z_NULL : b;
+}
+
+
+#ifndef NO_DEFLATE
+/* ===========================================================================
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of bytes actually written (0 in case of error).
+*/
+int ZEXPORT gzwrite (file, buf, len)
+    gzFile file;
+    const voidp buf;
+    unsigned len;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    s->stream.next_in = (Bytef*)buf;
+    s->stream.avail_in = len;
+
+    while (s->stream.avail_in != 0) {
+
+        if (s->stream.avail_out == 0) {
+
+            s->stream.next_out = s->outbuf;
+            if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
+                s->z_err = Z_ERRNO;
+                break;
+            }
+            s->stream.avail_out = Z_BUFSIZE;
+        }
+        s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
+        if (s->z_err != Z_OK) break;
+    }
+    s->crc = crc32(s->crc, (const Bytef *)buf, len);
+
+    return (int)(len - s->stream.avail_in);
+}
+
+/* ===========================================================================
+     Converts, formats, and writes the args to the compressed file under
+   control of the format string, as in fprintf. gzprintf returns the number of
+   uncompressed bytes actually written (0 in case of error).
+*/
+#ifdef STDC
+#include <stdarg.h>
+
+int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
+{
+    char buf[Z_PRINTF_BUFSIZE];
+    va_list va;
+    int len;
+
+    va_start(va, format);
+#ifdef HAS_vsnprintf
+    (void)vsnprintf(buf, sizeof(buf), format, va);
+#else
+    (void)vsprintf(buf, format, va);
+#endif
+    va_end(va);
+    len = strlen(buf); /* some *sprintf don't return the nb of bytes written */
+    if (len <= 0) return 0;
+
+    return gzwrite(file, buf, (unsigned)len);
+}
+#else /* not ANSI C */
+
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+	               a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+    gzFile file;
+    const char *format;
+    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+	a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+    char buf[Z_PRINTF_BUFSIZE];
+    int len;
+
+#ifdef HAS_snprintf
+    snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
+	     a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#else
+    sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
+	    a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#endif
+    len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */
+    if (len <= 0) return 0;
+
+    return gzwrite(file, buf, len);
+}
+#endif
+
+/* ===========================================================================
+      Writes c, converted to an unsigned char, into the compressed file.
+   gzputc returns the value that was written, or -1 in case of error.
+*/
+int ZEXPORT gzputc(file, c)
+    gzFile file;
+    int c;
+{
+    unsigned char cc = (unsigned char) c; /* required for big endian systems */
+
+    return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
+}
+
+
+/* ===========================================================================
+      Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+      gzputs returns the number of characters written, or -1 in case of error.
+*/
+int ZEXPORT gzputs(file, s)
+    gzFile file;
+    const char *s;
+{
+    return gzwrite(file, (char*)s, (unsigned)strlen(s));
+}
+
+
+/* ===========================================================================
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function.
+*/
+local int do_flush (file, flush)
+    gzFile file;
+    int flush;
+{
+    uInt len;
+    int done = 0;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
+
+    s->stream.avail_in = 0; /* should be zero already anyway */
+
+    for (;;) {
+        len = Z_BUFSIZE - s->stream.avail_out;
+
+        if (len != 0) {
+            if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
+                s->z_err = Z_ERRNO;
+                return Z_ERRNO;
+            }
+            s->stream.next_out = s->outbuf;
+            s->stream.avail_out = Z_BUFSIZE;
+        }
+        if (done) break;
+        s->z_err = deflate(&(s->stream), flush);
+
+	/* Ignore the second of two consecutive flushes: */
+	if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
+
+        /* deflate has finished flushing only when it hasn't used up
+         * all the available space in the output buffer: 
+         */
+        done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
+ 
+        if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
+    }
+    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+
+int ZEXPORT gzflush (file, flush)
+     gzFile file;
+     int flush;
+{
+    gz_stream *s = (gz_stream*)file;
+    int err = do_flush (file, flush);
+
+    if (err) return err;
+    fflush(s->file);
+    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
+}
+#endif /* NO_DEFLATE */
+
+/* ===========================================================================
+      Sets the starting position for the next gzread or gzwrite on the given
+   compressed file. The offset represents a number of bytes in the
+      gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error.
+      SEEK_END is not implemented, returns error.
+      In this version of the library, gzseek can be extremely slow.
+*/
+z_off_t ZEXPORT gzseek (file, offset, whence)
+    gzFile file;
+    z_off_t offset;
+    int whence;
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL || whence == SEEK_END ||
+	s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
+	return -1L;
+    }
+    
+    if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+	return -1L;
+#else
+	if (whence == SEEK_SET) {
+	    offset -= s->stream.total_in;
+	}
+	if (offset < 0) return -1L;
+
+	/* At this point, offset is the number of zero bytes to write. */
+	if (s->inbuf == Z_NULL) {
+	    s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
+	    zmemzero(s->inbuf, Z_BUFSIZE);
+	}
+	while (offset > 0)  {
+	    uInt size = Z_BUFSIZE;
+	    if (offset < Z_BUFSIZE) size = (uInt)offset;
+
+	    size = gzwrite(file, s->inbuf, size);
+	    if (size == 0) return -1L;
+
+	    offset -= size;
+	}
+	return (z_off_t)s->stream.total_in;
+#endif
+    }
+    /* Rest of function is for reading only */
+
+    /* compute absolute position */
+    if (whence == SEEK_CUR) {
+	offset += s->stream.total_out;
+    }
+    if (offset < 0) return -1L;
+
+    if (s->transparent) {
+	/* map to fseek */
+	s->stream.avail_in = 0;
+	s->stream.next_in = s->inbuf;
+        if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
+
+	s->stream.total_in = s->stream.total_out = (uLong)offset;
+	return offset;
+    }
+
+    /* For a negative seek, rewind and use positive seek */
+    if ((uLong)offset >= s->stream.total_out) {
+	offset -= s->stream.total_out;
+    } else if (gzrewind(file) < 0) {
+	return -1L;
+    }
+    /* offset is now the number of bytes to skip. */
+
+    if (offset != 0 && s->outbuf == Z_NULL) {
+	s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
+    }
+    while (offset > 0)  {
+	int size = Z_BUFSIZE;
+	if (offset < Z_BUFSIZE) size = (int)offset;
+
+	size = gzread(file, s->outbuf, (uInt)size);
+	if (size <= 0) return -1L;
+	offset -= size;
+    }
+    return (z_off_t)s->stream.total_out;
+}
+
+/* ===========================================================================
+     Rewinds input file. 
+*/
+int ZEXPORT gzrewind (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+    
+    if (s == NULL || s->mode != 'r') return -1;
+
+    s->z_err = Z_OK;
+    s->z_eof = 0;
+    s->stream.avail_in = 0;
+    s->stream.next_in = s->inbuf;
+    s->crc = crc32(0L, Z_NULL, 0);
+	
+    if (s->startpos == 0) { /* not a compressed file */
+	rewind(s->file);
+	return 0;
+    }
+
+    (void) inflateReset(&s->stream);
+    return fseek(s->file, s->startpos, SEEK_SET);
+}
+
+/* ===========================================================================
+     Returns the starting position for the next gzread or gzwrite on the
+   given compressed file. This position represents a number of bytes in the
+   uncompressed data stream.
+*/
+z_off_t ZEXPORT gztell (file)
+    gzFile file;
+{
+    return gzseek(file, 0L, SEEK_CUR);
+}
+
+/* ===========================================================================
+     Returns 1 when EOF has previously been detected reading the given
+   input stream, otherwise zero.
+*/
+int ZEXPORT gzeof (file)
+    gzFile file;
+{
+    gz_stream *s = (gz_stream*)file;
+    
+    return (s == NULL || s->mode != 'r') ? 0 : s->z_eof;
+}
+
+/* ===========================================================================
+   Outputs a long in LSB order to the given file
+*/
+local void putLong (file, x)
+    FILE *file;
+    uLong x;
+{
+    int n;
+    for (n = 0; n < 4; n++) {
+        fputc((int)(x & 0xff), file);
+        x >>= 8;
+    }
+}
+
+/* ===========================================================================
+   Reads a long in LSB order from the given gz_stream. Sets z_err in case
+   of error.
+*/
+local uLong getLong (s)
+    gz_stream *s;
+{
+    uLong x = (uLong)get_byte(s);
+    int c;
+
+    x += ((uLong)get_byte(s))<<8;
+    x += ((uLong)get_byte(s))<<16;
+    c = get_byte(s);
+    if (c == EOF) s->z_err = Z_DATA_ERROR;
+    x += ((uLong)c)<<24;
+    return x;
+}
+
+/* ===========================================================================
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state.
+*/
+int ZEXPORT gzclose (file)
+    gzFile file;
+{
+    int err;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL) return Z_STREAM_ERROR;
+
+    if (s->mode == 'w') {
+#ifdef NO_DEFLATE
+	return Z_STREAM_ERROR;
+#else
+        err = do_flush (file, Z_FINISH);
+        if (err != Z_OK) return destroy((gz_stream*)file);
+
+        putLong (s->file, s->crc);
+        putLong (s->file, s->stream.total_in);
+#endif
+    }
+    return destroy((gz_stream*)file);
+}
+
+/* ===========================================================================
+     Returns the error message for the last error which occured on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occured in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+const char*  ZEXPORT gzerror (file, errnum)
+    gzFile file;
+    int *errnum;
+{
+    char *m;
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL) {
+        *errnum = Z_STREAM_ERROR;
+        return (const char*)ERR_MSG(Z_STREAM_ERROR);
+    }
+    *errnum = s->z_err;
+    if (*errnum == Z_OK) return (const char*)"";
+
+    m =  (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
+
+    if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
+
+    TRYFREE(s->msg);
+    s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
+    strcpy(s->msg, s->path);
+    strcat(s->msg, ": ");
+    strcat(s->msg, m);
+    return (const char*)s->msg;
+}
diff --git a/external/zlib/infblock.c b/external/zlib/infblock.c
new file mode 100644
index 0000000..dd7a6d4
--- /dev/null
+++ b/external/zlib/infblock.c
@@ -0,0 +1,403 @@
+/* infblock.c -- interpret and process block types to last block
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* Table for deflate from PKZIP's appnote.txt. */
+local const uInt border[] = { /* Order of the bit length code lengths */
+        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+/*
+   Notes beyond the 1.93a appnote.txt:
+
+   1. Distance pointers never point before the beginning of the output
+      stream.
+   2. Distance pointers can point back across blocks, up to 32k away.
+   3. There is an implied maximum of 7 bits for the bit length table and
+      15 bits for the actual data.
+   4. If only one code exists, then it is encoded using one bit.  (Zero
+      would be more efficient, but perhaps a little confusing.)  If two
+      codes exist, they are coded using one bit each (0 and 1).
+   5. There is no way of sending zero distance codes--a dummy must be
+      sent if there are none.  (History: a pre 2.0 version of PKZIP would
+      store blocks with no distance codes, but this was discovered to be
+      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
+      zero distance codes, which is sent as one code of zero bits in
+      length.
+   6. There are up to 286 literal/length codes.  Code 256 represents the
+      end-of-block.  Note however that the static length tree defines
+      288 codes just to fill out the Huffman codes.  Codes 286 and 287
+      cannot be used though, since there is no length base or extra bits
+      defined for them.  Similarily, there are up to 30 distance codes.
+      However, static trees define 32 codes (all 5 bits) to fill out the
+      Huffman codes, but the last two had better not show up in the data.
+   7. Unzip can check dynamic Huffman blocks for complete code sets.
+      The exception is that a single code would not be complete (see #4).
+   8. The five bits following the block type is really the number of
+      literal codes sent minus 257.
+   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
+      (1+6+6).  Therefore, to output three times the length, you output
+      three codes (1+1+1), whereas to output four times the same length,
+      you only need two codes (1+3).  Hmm.
+  10. In the tree reconstruction algorithm, Code = Code + Increment
+      only if BitLength(i) is not zero.  (Pretty obvious.)
+  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
+  12. Note: length code 284 can represent 227-258, but length code 285
+      really is 258.  The last length deserves its own, short code
+      since it gets used a lot in very redundant files.  The length
+      258 is special since 258 - 3 (the min match length) is 255.
+  13. The literal/length and distance code bit lengths are read as a
+      single stream of lengths.  It is possible (and advantageous) for
+      a repeat code (16, 17, or 18) to go across the boundary between
+      the two sets of lengths.
+ */
+
+
+void inflate_blocks_reset(s, z, c)
+inflate_blocks_statef *s;
+z_streamp z;
+uLongf *c;
+{
+  if (c != Z_NULL)
+    *c = s->check;
+  if (s->mode == BTREE || s->mode == DTREE)
+    ZFREE(z, s->sub.trees.blens);
+  if (s->mode == CODES)
+    inflate_codes_free(s->sub.decode.codes, z);
+  s->mode = TYPE;
+  s->bitk = 0;
+  s->bitb = 0;
+  s->read = s->write = s->window;
+  if (s->checkfn != Z_NULL)
+    z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
+  Tracev((stderr, "inflate:   blocks reset\n"));
+}
+
+
+inflate_blocks_statef *inflate_blocks_new(z, c, w)
+z_streamp z;
+check_func c;
+uInt w;
+{
+  inflate_blocks_statef *s;
+
+  if ((s = (inflate_blocks_statef *)ZALLOC
+       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
+    return s;
+  if ((s->hufts =
+       (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
+  {
+    ZFREE(z, s);
+    return Z_NULL;
+  }
+  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
+  {
+    ZFREE(z, s->hufts);
+    ZFREE(z, s);
+    return Z_NULL;
+  }
+  s->end = s->window + w;
+  s->checkfn = c;
+  s->mode = TYPE;
+  Tracev((stderr, "inflate:   blocks allocated\n"));
+  inflate_blocks_reset(s, z, Z_NULL);
+  return s;
+}
+
+
+int inflate_blocks(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt t;               /* temporary storage */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input based on current state */
+  while (1) switch (s->mode)
+  {
+    case TYPE:
+      NEEDBITS(3)
+      t = (uInt)b & 7;
+      s->last = t & 1;
+      switch (t >> 1)
+      {
+        case 0:                         /* stored */
+          Tracev((stderr, "inflate:     stored block%s\n",
+                 s->last ? " (last)" : ""));
+          DUMPBITS(3)
+          t = k & 7;                    /* go to byte boundary */
+          DUMPBITS(t)
+          s->mode = LENS;               /* get length of stored block */
+          break;
+        case 1:                         /* fixed */
+          Tracev((stderr, "inflate:     fixed codes block%s\n",
+                 s->last ? " (last)" : ""));
+          {
+            uInt bl, bd;
+            inflate_huft *tl, *td;
+
+            inflate_trees_fixed(&bl, &bd, &tl, &td, z);
+            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
+            if (s->sub.decode.codes == Z_NULL)
+            {
+              r = Z_MEM_ERROR;
+              LEAVE
+            }
+          }
+          DUMPBITS(3)
+          s->mode = CODES;
+          break;
+        case 2:                         /* dynamic */
+          Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                 s->last ? " (last)" : ""));
+          DUMPBITS(3)
+          s->mode = TABLE;
+          break;
+        case 3:                         /* illegal */
+          DUMPBITS(3)
+          s->mode = BAD;
+          z->msg = (char*)"invalid block type";
+          r = Z_DATA_ERROR;
+          LEAVE
+      }
+      break;
+    case LENS:
+      NEEDBITS(32)
+      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
+      {
+        s->mode = BAD;
+        z->msg = (char*)"invalid stored block lengths";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+      s->sub.left = (uInt)b & 0xffff;
+      b = k = 0;                      /* dump bits */
+      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
+      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
+      break;
+    case STORED:
+      if (n == 0)
+        LEAVE
+      NEEDOUT
+      t = s->sub.left;
+      if (t > n) t = n;
+      if (t > m) t = m;
+      zmemcpy(q, p, t);
+      p += t;  n -= t;
+      q += t;  m -= t;
+      if ((s->sub.left -= t) != 0)
+        break;
+      Tracev((stderr, "inflate:       stored end, %lu total out\n",
+              z->total_out + (q >= s->read ? q - s->read :
+              (s->end - s->read) + (q - s->window))));
+      s->mode = s->last ? DRY : TYPE;
+      break;
+    case TABLE:
+      NEEDBITS(14)
+      s->sub.trees.table = t = (uInt)b & 0x3fff;
+#ifndef PKZIP_BUG_WORKAROUND
+      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
+      {
+        s->mode = BAD;
+        z->msg = (char*)"too many length or distance symbols";
+        r = Z_DATA_ERROR;
+        LEAVE
+      }
+#endif
+      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
+      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
+      {
+        r = Z_MEM_ERROR;
+        LEAVE
+      }
+      DUMPBITS(14)
+      s->sub.trees.index = 0;
+      Tracev((stderr, "inflate:       table sizes ok\n"));
+      s->mode = BTREE;
+    case BTREE:
+      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
+      {
+        NEEDBITS(3)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
+        DUMPBITS(3)
+      }
+      while (s->sub.trees.index < 19)
+        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
+      s->sub.trees.bb = 7;
+      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
+                             &s->sub.trees.tb, s->hufts, z);
+      if (t != Z_OK)
+      {
+        r = t;
+        if (r == Z_DATA_ERROR)
+        {
+          ZFREE(z, s->sub.trees.blens);
+          s->mode = BAD;
+        }
+        LEAVE
+      }
+      s->sub.trees.index = 0;
+      Tracev((stderr, "inflate:       bits tree ok\n"));
+      s->mode = DTREE;
+    case DTREE:
+      while (t = s->sub.trees.table,
+             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
+      {
+        inflate_huft *h;
+        uInt i, j, c;
+
+        t = s->sub.trees.bb;
+        NEEDBITS(t)
+        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
+        t = h->bits;
+        c = h->base;
+        if (c < 16)
+        {
+          DUMPBITS(t)
+          s->sub.trees.blens[s->sub.trees.index++] = c;
+        }
+        else /* c == 16..18 */
+        {
+          i = c == 18 ? 7 : c - 14;
+          j = c == 18 ? 11 : 3;
+          NEEDBITS(t + i)
+          DUMPBITS(t)
+          j += (uInt)b & inflate_mask[i];
+          DUMPBITS(i)
+          i = s->sub.trees.index;
+          t = s->sub.trees.table;
+          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
+              (c == 16 && i < 1))
+          {
+            ZFREE(z, s->sub.trees.blens);
+            s->mode = BAD;
+            z->msg = (char*)"invalid bit length repeat";
+            r = Z_DATA_ERROR;
+            LEAVE
+          }
+          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
+          do {
+            s->sub.trees.blens[i++] = c;
+          } while (--j);
+          s->sub.trees.index = i;
+        }
+      }
+      s->sub.trees.tb = Z_NULL;
+      {
+        uInt bl, bd;
+        inflate_huft *tl, *td;
+        inflate_codes_statef *c;
+
+        bl = 9;         /* must be <= 9 for lookahead assumptions */
+        bd = 6;         /* must be <= 9 for lookahead assumptions */
+        t = s->sub.trees.table;
+        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
+                                  s->sub.trees.blens, &bl, &bd, &tl, &td,
+                                  s->hufts, z);
+        if (t != Z_OK)
+        {
+          if (t == (uInt)Z_DATA_ERROR)
+          {
+            ZFREE(z, s->sub.trees.blens);
+            s->mode = BAD;
+          }
+          r = t;
+          LEAVE
+        }
+        Tracev((stderr, "inflate:       trees ok\n"));
+        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
+        {
+          r = Z_MEM_ERROR;
+          LEAVE
+        }
+        s->sub.decode.codes = c;
+      }
+      ZFREE(z, s->sub.trees.blens);
+      s->mode = CODES;
+    case CODES:
+      UPDATE
+      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
+        return inflate_flush(s, z, r);
+      r = Z_OK;
+      inflate_codes_free(s->sub.decode.codes, z);
+      LOAD
+      Tracev((stderr, "inflate:       codes end, %lu total out\n",
+              z->total_out + (q >= s->read ? q - s->read :
+              (s->end - s->read) + (q - s->window))));
+      if (!s->last)
+      {
+        s->mode = TYPE;
+        break;
+      }
+      s->mode = DRY;
+    case DRY:
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      s->mode = DONE;
+    case DONE:
+      r = Z_STREAM_END;
+      LEAVE
+    case BAD:
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+}
+
+
+int inflate_blocks_free(s, z)
+inflate_blocks_statef *s;
+z_streamp z;
+{
+  inflate_blocks_reset(s, z, Z_NULL);
+  ZFREE(z, s->window);
+  ZFREE(z, s->hufts);
+  ZFREE(z, s);
+  Tracev((stderr, "inflate:   blocks freed\n"));
+  return Z_OK;
+}
+
+
+void inflate_set_dictionary(s, d, n)
+inflate_blocks_statef *s;
+const Bytef *d;
+uInt  n;
+{
+  zmemcpy(s->window, d, n);
+  s->read = s->write = s->window + n;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
+ * IN assertion: s != Z_NULL
+ */
+int inflate_blocks_sync_point(s)
+inflate_blocks_statef *s;
+{
+  return s->mode == LENS;
+}
diff --git a/external/zlib/infblock.h b/external/zlib/infblock.h
new file mode 100644
index 0000000..173b226
--- /dev/null
+++ b/external/zlib/infblock.h
@@ -0,0 +1,39 @@
+/* infblock.h -- header to use infblock.c
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_blocks_state;
+typedef struct inflate_blocks_state FAR inflate_blocks_statef;
+
+extern inflate_blocks_statef * inflate_blocks_new OF((
+    z_streamp z,
+    check_func c,               /* check function */
+    uInt w));                   /* window size */
+
+extern int inflate_blocks OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));                      /* initial return code */
+
+extern void inflate_blocks_reset OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    uLongf *));                  /* check value on output */
+
+extern int inflate_blocks_free OF((
+    inflate_blocks_statef *,
+    z_streamp));
+
+extern void inflate_set_dictionary OF((
+    inflate_blocks_statef *s,
+    const Bytef *d,  /* dictionary */
+    uInt  n));       /* dictionary length */
+
+extern int inflate_blocks_sync_point OF((
+    inflate_blocks_statef *s));
diff --git a/external/zlib/infcodes.c b/external/zlib/infcodes.c
new file mode 100644
index 0000000..9abe541
--- /dev/null
+++ b/external/zlib/infcodes.c
@@ -0,0 +1,251 @@
+/* infcodes.c -- process literals and length/distance pairs
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infblock.h"
+#include "infcodes.h"
+#include "infutil.h"
+#include "inffast.h"
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+      START,    /* x: set up for LEN */
+      LEN,      /* i: get length/literal/eob next */
+      LENEXT,   /* i: getting length extra (have base) */
+      DIST,     /* i: get distance next */
+      DISTEXT,  /* i: getting distance extra */
+      COPY,     /* o: copying bytes in window, waiting for space */
+      LIT,      /* o: got literal, waiting for output space */
+      WASH,     /* o: got eob, possibly still output waiting */
+      END,      /* x: got eob and all data flushed */
+      BADCODE}  /* x: got error */
+inflate_codes_mode;
+
+/* inflate codes private state */
+struct inflate_codes_state {
+
+  /* mode */
+  inflate_codes_mode mode;      /* current inflate_codes mode */
+
+  /* mode dependent information */
+  uInt len;
+  union {
+    struct {
+      inflate_huft *tree;       /* pointer into tree */
+      uInt need;                /* bits needed */
+    } code;             /* if LEN or DIST, where in tree */
+    uInt lit;           /* if LIT, literal */
+    struct {
+      uInt get;                 /* bits to get for extra */
+      uInt dist;                /* distance back to copy from */
+    } copy;             /* if EXT or COPY, where and how much */
+  } sub;                /* submode */
+
+  /* mode independent information */
+  Byte lbits;           /* ltree bits decoded per branch */
+  Byte dbits;           /* dtree bits decoder per branch */
+  inflate_huft *ltree;          /* literal/length/eob tree */
+  inflate_huft *dtree;          /* distance tree */
+
+};
+
+
+inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+z_streamp z;
+{
+  inflate_codes_statef *c;
+
+  if ((c = (inflate_codes_statef *)
+       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
+  {
+    c->mode = START;
+    c->lbits = (Byte)bl;
+    c->dbits = (Byte)bd;
+    c->ltree = tl;
+    c->dtree = td;
+    Tracev((stderr, "inflate:       codes new\n"));
+  }
+  return c;
+}
+
+
+int inflate_codes(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt j;               /* temporary storage */
+  inflate_huft *t;      /* temporary pointer */
+  uInt e;               /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  Bytef *f;             /* pointer to copy strings from */
+  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
+
+  /* copy input/output information to locals (UPDATE macro restores) */
+  LOAD
+
+  /* process input and output based on current state */
+  while (1) switch (c->mode)
+  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
+    case START:         /* x: set up for LEN */
+#ifndef SLOW
+      if (m >= 258 && n >= 10)
+      {
+        UPDATE
+        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
+        LOAD
+        if (r != Z_OK)
+        {
+          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
+          break;
+        }
+      }
+#endif /* !SLOW */
+      c->sub.code.need = c->lbits;
+      c->sub.code.tree = c->ltree;
+      c->mode = LEN;
+    case LEN:           /* i: get length/literal/eob next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+      DUMPBITS(t->bits)
+      e = (uInt)(t->exop);
+      if (e == 0)               /* literal */
+      {
+        c->sub.lit = t->base;
+        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                 "inflate:         literal '%c'\n" :
+                 "inflate:         literal 0x%02x\n", t->base));
+        c->mode = LIT;
+        break;
+      }
+      if (e & 16)               /* length */
+      {
+        c->sub.copy.get = e & 15;
+        c->len = t->base;
+        c->mode = LENEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t + t->base;
+        break;
+      }
+      if (e & 32)               /* end of block */
+      {
+        Tracevv((stderr, "inflate:         end of block\n"));
+        c->mode = WASH;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = (char*)"invalid literal/length code";
+      r = Z_DATA_ERROR;
+      LEAVE
+    case LENEXT:        /* i: getting length extra (have base) */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->len += (uInt)b & inflate_mask[j];
+      DUMPBITS(j)
+      c->sub.code.need = c->dbits;
+      c->sub.code.tree = c->dtree;
+      Tracevv((stderr, "inflate:         length %u\n", c->len));
+      c->mode = DIST;
+    case DIST:          /* i: get distance next */
+      j = c->sub.code.need;
+      NEEDBITS(j)
+      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
+      DUMPBITS(t->bits)
+      e = (uInt)(t->exop);
+      if (e & 16)               /* distance */
+      {
+        c->sub.copy.get = e & 15;
+        c->sub.copy.dist = t->base;
+        c->mode = DISTEXT;
+        break;
+      }
+      if ((e & 64) == 0)        /* next table */
+      {
+        c->sub.code.need = e;
+        c->sub.code.tree = t + t->base;
+        break;
+      }
+      c->mode = BADCODE;        /* invalid code */
+      z->msg = (char*)"invalid distance code";
+      r = Z_DATA_ERROR;
+      LEAVE
+    case DISTEXT:       /* i: getting distance extra */
+      j = c->sub.copy.get;
+      NEEDBITS(j)
+      c->sub.copy.dist += (uInt)b & inflate_mask[j];
+      DUMPBITS(j)
+      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
+      c->mode = COPY;
+    case COPY:          /* o: copying bytes in window, waiting for space */
+      f = q - c->sub.copy.dist;
+      while (f < s->window)             /* modulo window size-"while" instead */
+        f += s->end - s->window;        /* of "if" handles invalid distances */
+      while (c->len)
+      {
+        NEEDOUT
+        OUTBYTE(*f++)
+        if (f == s->end)
+          f = s->window;
+        c->len--;
+      }
+      c->mode = START;
+      break;
+    case LIT:           /* o: got literal, waiting for output space */
+      NEEDOUT
+      OUTBYTE(c->sub.lit)
+      c->mode = START;
+      break;
+    case WASH:          /* o: got eob, possibly more output */
+      if (k > 7)        /* return unused byte, if any */
+      {
+        Assert(k < 16, "inflate_codes grabbed too many bytes")
+        k -= 8;
+        n++;
+        p--;            /* can always return one */
+      }
+      FLUSH
+      if (s->read != s->write)
+        LEAVE
+      c->mode = END;
+    case END:
+      r = Z_STREAM_END;
+      LEAVE
+    case BADCODE:       /* x: got error */
+      r = Z_DATA_ERROR;
+      LEAVE
+    default:
+      r = Z_STREAM_ERROR;
+      LEAVE
+  }
+#ifdef NEED_DUMMY_RETURN
+  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
+#endif
+}
+
+
+void inflate_codes_free(c, z)
+inflate_codes_statef *c;
+z_streamp z;
+{
+  ZFREE(z, c);
+  Tracev((stderr, "inflate:       codes free\n"));
+}
diff --git a/external/zlib/infcodes.h b/external/zlib/infcodes.h
new file mode 100644
index 0000000..46821a0
--- /dev/null
+++ b/external/zlib/infcodes.h
@@ -0,0 +1,27 @@
+/* infcodes.h -- header to use infcodes.c
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+struct inflate_codes_state;
+typedef struct inflate_codes_state FAR inflate_codes_statef;
+
+extern inflate_codes_statef *inflate_codes_new OF((
+    uInt, uInt,
+    inflate_huft *, inflate_huft *,
+    z_streamp ));
+
+extern int inflate_codes OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));
+
+extern void inflate_codes_free OF((
+    inflate_codes_statef *,
+    z_streamp ));
+
diff --git a/external/zlib/inffast.c b/external/zlib/inffast.c
new file mode 100644
index 0000000..aa7f1d4
--- /dev/null
+++ b/external/zlib/inffast.c
@@ -0,0 +1,183 @@
+/* inffast.c -- process literals and length/distance pairs fast
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "infblock.h"
+#include "infcodes.h"
+#include "infutil.h"
+#include "inffast.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+/* macros for bit input with no checking and for returning unused bytes */
+#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
+
+/* Called with number of bytes left to write in window at least 258
+   (the maximum string length) and number of input bytes available
+   at least ten.  The ten bytes are six bytes for the longest length/
+   distance pair plus four bytes for overloading the bit buffer. */
+
+int inflate_fast(bl, bd, tl, td, s, z)
+uInt bl, bd;
+inflate_huft *tl;
+inflate_huft *td; /* need separate declaration for Borland C++ */
+inflate_blocks_statef *s;
+z_streamp z;
+{
+  inflate_huft *t;      /* temporary pointer */
+  uInt e;               /* extra bits or operation */
+  uLong b;              /* bit buffer */
+  uInt k;               /* bits in bit buffer */
+  Bytef *p;             /* input data pointer */
+  uInt n;               /* bytes available there */
+  Bytef *q;             /* output window write pointer */
+  uInt m;               /* bytes to end of window or read pointer */
+  uInt ml;              /* mask for literal/length tree */
+  uInt md;              /* mask for distance tree */
+  uInt c;               /* bytes to copy */
+  uInt d;               /* distance back to copy from */
+  Bytef *r;             /* copy source pointer */
+
+  /* load input, output, bit values */
+  LOAD
+
+  /* initialize masks */
+  ml = inflate_mask[bl];
+  md = inflate_mask[bd];
+
+  /* do until not enough input or output space for fast loop */
+  do {                          /* assume called with m >= 258 && n >= 10 */
+    /* get literal/length code */
+    GRABBITS(20)                /* max bits for literal/length code */
+    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
+    {
+      DUMPBITS(t->bits)
+      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                "inflate:         * literal '%c'\n" :
+                "inflate:         * literal 0x%02x\n", t->base));
+      *q++ = (Byte)t->base;
+      m--;
+      continue;
+    }
+    do {
+      DUMPBITS(t->bits)
+      if (e & 16)
+      {
+        /* get extra bits for length */
+        e &= 15;
+        c = t->base + ((uInt)b & inflate_mask[e]);
+        DUMPBITS(e)
+        Tracevv((stderr, "inflate:         * length %u\n", c));
+
+        /* decode distance base of block to copy */
+        GRABBITS(15);           /* max bits for distance code */
+        e = (t = td + ((uInt)b & md))->exop;
+        do {
+          DUMPBITS(t->bits)
+          if (e & 16)
+          {
+            /* get extra bits to add to distance base */
+            e &= 15;
+            GRABBITS(e)         /* get extra bits (up to 13) */
+            d = t->base + ((uInt)b & inflate_mask[e]);
+            DUMPBITS(e)
+            Tracevv((stderr, "inflate:         * distance %u\n", d));
+
+            /* do the copy */
+            m -= c;
+            r = q - d;
+            if (r < s->window)                  /* wrap if needed */
+            {
+              do {
+                r += s->end - s->window;        /* force pointer in window */
+              } while (r < s->window);          /* covers invalid distances */
+              e = s->end - r;
+              if (c > e)
+              {
+                c -= e;                         /* wrapped copy */
+                do {
+                    *q++ = *r++;
+                } while (--e);
+                r = s->window;
+                do {
+                    *q++ = *r++;
+                } while (--c);
+              }
+              else                              /* normal copy */
+              {
+                *q++ = *r++;  c--;
+                *q++ = *r++;  c--;
+                do {
+                    *q++ = *r++;
+                } while (--c);
+              }
+            }
+            else                                /* normal copy */
+            {
+              *q++ = *r++;  c--;
+              *q++ = *r++;  c--;
+              do {
+                *q++ = *r++;
+              } while (--c);
+            }
+            break;
+          }
+          else if ((e & 64) == 0)
+          {
+            t += t->base;
+            e = (t += ((uInt)b & inflate_mask[e]))->exop;
+          }
+          else
+          {
+            z->msg = (char*)"invalid distance code";
+            UNGRAB
+            UPDATE
+            return Z_DATA_ERROR;
+          }
+        } while (1);
+        break;
+      }
+      if ((e & 64) == 0)
+      {
+        t += t->base;
+        if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
+        {
+          DUMPBITS(t->bits)
+          Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
+                    "inflate:         * literal '%c'\n" :
+                    "inflate:         * literal 0x%02x\n", t->base));
+          *q++ = (Byte)t->base;
+          m--;
+          break;
+        }
+      }
+      else if (e & 32)
+      {
+        Tracevv((stderr, "inflate:         * end of block\n"));
+        UNGRAB
+        UPDATE
+        return Z_STREAM_END;
+      }
+      else
+      {
+        z->msg = (char*)"invalid literal/length code";
+        UNGRAB
+        UPDATE
+        return Z_DATA_ERROR;
+      }
+    } while (1);
+  } while (m >= 258 && n >= 10);
+
+  /* not enough input or output--restore pointers and return */
+  UNGRAB
+  UPDATE
+  return Z_OK;
+}
diff --git a/external/zlib/inffast.h b/external/zlib/inffast.h
new file mode 100644
index 0000000..a31a4bb
--- /dev/null
+++ b/external/zlib/inffast.h
@@ -0,0 +1,17 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+extern int inflate_fast OF((
+    uInt,
+    uInt,
+    inflate_huft *,
+    inflate_huft *,
+    inflate_blocks_statef *,
+    z_streamp ));
diff --git a/external/zlib/inffixed.h b/external/zlib/inffixed.h
new file mode 100644
index 0000000..77f7e76
--- /dev/null
+++ b/external/zlib/inffixed.h
@@ -0,0 +1,151 @@
+/* inffixed.h -- table for decoding fixed codes
+ * Generated automatically by the maketree.c program
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+local uInt fixed_bl = 9;
+local uInt fixed_bd = 5;
+local inflate_huft fixed_tl[] = {
+    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
+    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
+    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
+    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
+    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
+    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
+    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
+    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
+    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
+    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
+    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
+    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
+    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
+    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
+    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
+    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
+    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
+    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
+    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
+    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
+    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
+    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
+    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
+    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
+    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
+    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
+    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
+    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
+    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
+    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
+    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
+    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
+    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
+    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
+    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
+    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
+    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
+    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
+    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
+    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
+    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
+    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
+    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
+    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
+    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
+    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
+    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
+    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
+    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
+    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
+    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
+    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
+    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
+    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
+    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
+    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
+    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
+    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
+    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
+    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
+    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
+    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
+    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
+    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
+    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
+    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
+    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
+    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
+    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
+    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
+    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
+    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
+    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
+    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
+    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
+    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
+    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
+    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
+    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
+    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
+    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
+    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
+    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
+    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
+    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
+    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
+    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
+    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
+    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
+    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
+    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
+    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
+    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
+    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
+    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
+    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
+    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
+    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
+    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
+    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
+    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
+    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
+    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
+    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
+    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
+    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
+    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
+    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
+    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
+    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
+    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
+    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
+    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
+    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
+    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
+    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
+    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
+    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
+    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
+    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
+    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
+    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
+    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
+    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
+    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
+    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
+    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
+    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
+  };
+local inflate_huft fixed_td[] = {
+    {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
+    {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
+    {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
+    {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
+    {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
+    {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
+    {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
+    {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
+  };
diff --git a/external/zlib/inflate.c b/external/zlib/inflate.c
new file mode 100644
index 0000000..dfb2e86
--- /dev/null
+++ b/external/zlib/inflate.c
@@ -0,0 +1,366 @@
+/* inflate.c -- zlib interface to inflate modules
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+
+struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
+
+typedef enum {
+      METHOD,   /* waiting for method byte */
+      FLAG,     /* waiting for flag byte */
+      DICT4,    /* four dictionary check bytes to go */
+      DICT3,    /* three dictionary check bytes to go */
+      DICT2,    /* two dictionary check bytes to go */
+      DICT1,    /* one dictionary check byte to go */
+      DICT0,    /* waiting for inflateSetDictionary */
+      BLOCKS,   /* decompressing blocks */
+      CHECK4,   /* four check bytes to go */
+      CHECK3,   /* three check bytes to go */
+      CHECK2,   /* two check bytes to go */
+      CHECK1,   /* one check byte to go */
+      DONE,     /* finished check, done */
+      BAD}      /* got an error--stay here */
+inflate_mode;
+
+/* inflate private state */
+struct internal_state {
+
+  /* mode */
+  inflate_mode  mode;   /* current inflate mode */
+
+  /* mode dependent information */
+  union {
+    uInt method;        /* if FLAGS, method byte */
+    struct {
+      uLong was;                /* computed check value */
+      uLong need;               /* stream check value */
+    } check;            /* if CHECK, check values to compare */
+    uInt marker;        /* if BAD, inflateSync's marker bytes count */
+  } sub;        /* submode */
+
+  /* mode independent information */
+  int  nowrap;          /* flag for no wrapper */
+  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
+  inflate_blocks_statef 
+    *blocks;            /* current inflate_blocks state */
+
+};
+
+
+int ZEXPORT inflateReset(z)
+z_streamp z;
+{
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  z->total_in = z->total_out = 0;
+  z->msg = Z_NULL;
+  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
+  inflate_blocks_reset(z->state->blocks, z, Z_NULL);
+  Tracev((stderr, "inflate: reset\n"));
+  return Z_OK;
+}
+
+
+int ZEXPORT inflateEnd(z)
+z_streamp z;
+{
+  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->blocks != Z_NULL)
+    inflate_blocks_free(z->state->blocks, z);
+  ZFREE(z, z->state);
+  z->state = Z_NULL;
+  Tracev((stderr, "inflate: end\n"));
+  return Z_OK;
+}
+
+
+int ZEXPORT inflateInit2_(z, w, version, stream_size)
+z_streamp z;
+int w;
+const char *version;
+int stream_size;
+{
+  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+      stream_size != sizeof(z_stream))
+      return Z_VERSION_ERROR;
+
+  /* initialize state */
+  if (z == Z_NULL)
+    return Z_STREAM_ERROR;
+  z->msg = Z_NULL;
+  if (z->zalloc == Z_NULL)
+  {
+    z->zalloc = zcalloc;
+    z->opaque = (voidpf)0;
+  }
+  if (z->zfree == Z_NULL) z->zfree = zcfree;
+  if ((z->state = (struct internal_state FAR *)
+       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
+    return Z_MEM_ERROR;
+  z->state->blocks = Z_NULL;
+
+  /* handle undocumented nowrap option (no zlib header or check) */
+  z->state->nowrap = 0;
+  if (w < 0)
+  {
+    w = - w;
+    z->state->nowrap = 1;
+  }
+
+  /* set window size */
+  if (w < 8 || w > 15)
+  {
+    inflateEnd(z);
+    return Z_STREAM_ERROR;
+  }
+  z->state->wbits = (uInt)w;
+
+  /* create inflate_blocks state */
+  if ((z->state->blocks =
+      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
+      == Z_NULL)
+  {
+    inflateEnd(z);
+    return Z_MEM_ERROR;
+  }
+  Tracev((stderr, "inflate: allocated\n"));
+
+  /* reset state */
+  inflateReset(z);
+  return Z_OK;
+}
+
+
+int ZEXPORT inflateInit_(z, version, stream_size)
+z_streamp z;
+const char *version;
+int stream_size;
+{
+  return inflateInit2_(z, DEF_WBITS, version, stream_size);
+}
+
+
+#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
+#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
+
+int ZEXPORT inflate(z, f)
+z_streamp z;
+int f;
+{
+  int r;
+  uInt b;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
+    return Z_STREAM_ERROR;
+  f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
+  r = Z_BUF_ERROR;
+  while (1) switch (z->state->mode)
+  {
+    case METHOD:
+      NEEDBYTE
+      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"unknown compression method";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"invalid window size";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      z->state->mode = FLAG;
+    case FLAG:
+      NEEDBYTE
+      b = NEXTBYTE;
+      if (((z->state->sub.method << 8) + b) % 31)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"incorrect header check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      Tracev((stderr, "inflate: zlib header ok\n"));
+      if (!(b & PRESET_DICT))
+      {
+        z->state->mode = BLOCKS;
+        break;
+      }
+      z->state->mode = DICT4;
+    case DICT4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = DICT3;
+    case DICT3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = DICT2;
+    case DICT2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = DICT1;
+    case DICT1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+      z->adler = z->state->sub.check.need;
+      z->state->mode = DICT0;
+      return Z_NEED_DICT;
+    case DICT0:
+      z->state->mode = BAD;
+      z->msg = (char*)"need dictionary";
+      z->state->sub.marker = 0;       /* can try inflateSync */
+      return Z_STREAM_ERROR;
+    case BLOCKS:
+      r = inflate_blocks(z->state->blocks, z, r);
+      if (r == Z_DATA_ERROR)
+      {
+        z->state->mode = BAD;
+        z->state->sub.marker = 0;       /* can try inflateSync */
+        break;
+      }
+      if (r == Z_OK)
+        r = f;
+      if (r != Z_STREAM_END)
+        return r;
+      r = f;
+      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
+      if (z->state->nowrap)
+      {
+        z->state->mode = DONE;
+        break;
+      }
+      z->state->mode = CHECK4;
+    case CHECK4:
+      NEEDBYTE
+      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
+      z->state->mode = CHECK3;
+    case CHECK3:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
+      z->state->mode = CHECK2;
+    case CHECK2:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
+      z->state->mode = CHECK1;
+    case CHECK1:
+      NEEDBYTE
+      z->state->sub.check.need += (uLong)NEXTBYTE;
+
+      if (z->state->sub.check.was != z->state->sub.check.need)
+      {
+        z->state->mode = BAD;
+        z->msg = (char*)"incorrect data check";
+        z->state->sub.marker = 5;       /* can't try inflateSync */
+        break;
+      }
+      Tracev((stderr, "inflate: zlib check ok\n"));
+      z->state->mode = DONE;
+    case DONE:
+      return Z_STREAM_END;
+    case BAD:
+      return Z_DATA_ERROR;
+    default:
+      return Z_STREAM_ERROR;
+  }
+#ifdef NEED_DUMMY_RETURN
+  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
+#endif
+}
+
+
+int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
+z_streamp z;
+const Bytef *dictionary;
+uInt  dictLength;
+{
+  uInt length = dictLength;
+
+  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
+    return Z_STREAM_ERROR;
+
+  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
+  z->adler = 1L;
+
+  if (length >= ((uInt)1<<z->state->wbits))
+  {
+    length = (1<<z->state->wbits)-1;
+    dictionary += dictLength - length;
+  }
+  inflate_set_dictionary(z->state->blocks, dictionary, length);
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
+
+
+int ZEXPORT inflateSync(z)
+z_streamp z;
+{
+  uInt n;       /* number of bytes to look at */
+  Bytef *p;     /* pointer to bytes */
+  uInt m;       /* number of marker bytes found in a row */
+  uLong r, w;   /* temporaries to save total_in and total_out */
+
+  /* set up */
+  if (z == Z_NULL || z->state == Z_NULL)
+    return Z_STREAM_ERROR;
+  if (z->state->mode != BAD)
+  {
+    z->state->mode = BAD;
+    z->state->sub.marker = 0;
+  }
+  if ((n = z->avail_in) == 0)
+    return Z_BUF_ERROR;
+  p = z->next_in;
+  m = z->state->sub.marker;
+
+  /* search */
+  while (n && m < 4)
+  {
+    static const Byte mark[4] = {0, 0, 0xff, 0xff};
+    if (*p == mark[m])
+      m++;
+    else if (*p)
+      m = 0;
+    else
+      m = 4 - m;
+    p++, n--;
+  }
+
+  /* restore */
+  z->total_in += p - z->next_in;
+  z->next_in = p;
+  z->avail_in = n;
+  z->state->sub.marker = m;
+
+  /* return no joy or set up to restart on a new block */
+  if (m != 4)
+    return Z_DATA_ERROR;
+  r = z->total_in;  w = z->total_out;
+  inflateReset(z);
+  z->total_in = r;  z->total_out = w;
+  z->state->mode = BLOCKS;
+  return Z_OK;
+}
+
+
+/* Returns true if inflate is currently at the end of a block generated
+ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
+ * but removes the length bytes of the resulting empty stored block. When
+ * decompressing, PPP checks that at the end of input packet, inflate is
+ * waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(z)
+z_streamp z;
+{
+  if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
+    return Z_STREAM_ERROR;
+  return inflate_blocks_sync_point(z->state->blocks);
+}
diff --git a/external/zlib/inftrees.c b/external/zlib/inftrees.c
new file mode 100644
index 0000000..4c32ca3
--- /dev/null
+++ b/external/zlib/inftrees.c
@@ -0,0 +1,454 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#if !defined(BUILDFIXED) && !defined(STDC)
+#  define BUILDFIXED   /* non ANSI compilers may not accept inffixed.h */
+#endif
+
+const char inflate_copyright[] =
+   " inflate 1.1.4 Copyright 1995-2002 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+struct internal_state  {int dummy;}; /* for buggy compilers */
+
+/* simplify the use of the inflate_huft type with some defines */
+#define exop word.what.Exop
+#define bits word.what.Bits
+
+
+local int huft_build OF((
+    uIntf *,            /* code lengths in bits */
+    uInt,               /* number of codes */
+    uInt,               /* number of "simple" codes */
+    const uIntf *,      /* list of base values for non-simple codes */
+    const uIntf *,      /* list of extra bits for non-simple codes */
+    inflate_huft * FAR*,/* result: starting table */
+    uIntf *,            /* maximum lookup bits (returns actual) */
+    inflate_huft *,     /* space for trees */
+    uInt *,             /* hufts used in space */
+    uIntf * ));         /* space for values */
+
+/* Tables for deflate from PKZIP's appnote.txt. */
+local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+        /* see note #13 above about 258 */
+local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
+        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
+local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577};
+local const uInt cpdext[30] = { /* Extra bits for distance codes */
+        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+        12, 12, 13, 13};
+
+/*
+   Huffman code decoding is performed using a multi-level table lookup.
+   The fastest way to decode is to simply build a lookup table whose
+   size is determined by the longest code.  However, the time it takes
+   to build this table can also be a factor if the data being decoded
+   is not very long.  The most common codes are necessarily the
+   shortest codes, so those codes dominate the decoding time, and hence
+   the speed.  The idea is you can have a shorter table that decodes the
+   shorter, more probable codes, and then point to subsidiary tables for
+   the longer codes.  The time it costs to decode the longer codes is
+   then traded against the time it takes to make longer tables.
+
+   This results of this trade are in the variables lbits and dbits
+   below.  lbits is the number of bits the first level table for literal/
+   length codes can decode in one step, and dbits is the same thing for
+   the distance codes.  Subsequent tables are also less than or equal to
+   those sizes.  These values may be adjusted either when all of the
+   codes are shorter than that, in which case the longest code length in
+   bits is used, or when the shortest code is *longer* than the requested
+   table size, in which case the length of the shortest code in bits is
+   used.
+
+   There are two different values for the two tables, since they code a
+   different number of possibilities each.  The literal/length table
+   codes 286 possible values, or in a flat code, a little over eight
+   bits.  The distance table codes 30 possible values, or a little less
+   than five bits, flat.  The optimum values for speed end up being
+   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
+   The optimum values may differ though from machine to machine, and
+   possibly even between compilers.  Your mileage may vary.
+ */
+
+
+/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
+#define BMAX 15         /* maximum bit length of any code */
+
+local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
+uIntf *b;               /* code lengths in bits (all assumed <= BMAX) */
+uInt n;                 /* number of codes (assumed <= 288) */
+uInt s;                 /* number of simple-valued codes (0..s-1) */
+const uIntf *d;         /* list of base values for non-simple codes */
+const uIntf *e;         /* list of extra bits for non-simple codes */
+inflate_huft * FAR *t;  /* result: starting table */
+uIntf *m;               /* maximum lookup bits, returns actual */
+inflate_huft *hp;       /* space for trees */
+uInt *hn;               /* hufts used in space */
+uIntf *v;               /* working area: values in order of bit length */
+/* Given a list of code lengths and a maximum table size, make a set of
+   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
+   if the given code set is incomplete (the tables are still built in this
+   case), or Z_DATA_ERROR if the input is invalid. */
+{
+
+  uInt a;                       /* counter for codes of length k */
+  uInt c[BMAX+1];               /* bit length count table */
+  uInt f;                       /* i repeats in table every f entries */
+  int g;                        /* maximum code length */
+  int h;                        /* table level */
+  register uInt i;              /* counter, current code */
+  register uInt j;              /* counter */
+  register int k;               /* number of bits in current code */
+  int l;                        /* bits per table (returned in m) */
+  uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */
+  register uIntf *p;            /* pointer into c[], b[], or v[] */
+  inflate_huft *q;              /* points to current table */
+  struct inflate_huft_s r;      /* table entry for structure assignment */
+  inflate_huft *u[BMAX];        /* table stack */
+  register int w;               /* bits before this table == (l * h) */
+  uInt x[BMAX+1];               /* bit offsets, then code stack */
+  uIntf *xp;                    /* pointer into x */
+  int y;                        /* number of dummy codes added */
+  uInt z;                       /* number of entries in current table */
+
+
+  /* Generate counts for each bit length */
+  p = c;
+#define C0 *p++ = 0;
+#define C2 C0 C0 C0 C0
+#define C4 C2 C2 C2 C2
+  C4                            /* clear c[]--assume BMAX+1 is 16 */
+  p = b;  i = n;
+  do {
+    c[*p++]++;                  /* assume all entries <= BMAX */
+  } while (--i);
+  if (c[0] == n)                /* null input--all zero length codes */
+  {
+    *t = (inflate_huft *)Z_NULL;
+    *m = 0;
+    return Z_OK;
+  }
+
+
+  /* Find minimum and maximum length, bound *m by those */
+  l = *m;
+  for (j = 1; j <= BMAX; j++)
+    if (c[j])
+      break;
+  k = j;                        /* minimum code length */
+  if ((uInt)l < j)
+    l = j;
+  for (i = BMAX; i; i--)
+    if (c[i])
+      break;
+  g = i;                        /* maximum code length */
+  if ((uInt)l > i)
+    l = i;
+  *m = l;
+
+
+  /* Adjust last length count to fill out codes, if needed */
+  for (y = 1 << j; j < i; j++, y <<= 1)
+    if ((y -= c[j]) < 0)
+      return Z_DATA_ERROR;
+  if ((y -= c[i]) < 0)
+    return Z_DATA_ERROR;
+  c[i] += y;
+
+
+  /* Generate starting offsets into the value table for each length */
+  x[1] = j = 0;
+  p = c + 1;  xp = x + 2;
+  while (--i) {                 /* note that i == g from above */
+    *xp++ = (j += *p++);
+  }
+
+
+  /* Make a table of values in order of bit lengths */
+  p = b;  i = 0;
+  do {
+    if ((j = *p++) != 0)
+      v[x[j]++] = i;
+  } while (++i < n);
+  n = x[g];                     /* set n to length of v */
+
+
+  /* Generate the Huffman codes and for each, make the table entries */
+  x[0] = i = 0;                 /* first Huffman code is zero */
+  p = v;                        /* grab values in bit order */
+  h = -1;                       /* no tables yet--level -1 */
+  w = -l;                       /* bits decoded == (l * h) */
+  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
+  q = (inflate_huft *)Z_NULL;   /* ditto */
+  z = 0;                        /* ditto */
+
+  /* go through the bit lengths (k already is bits in shortest code) */
+  for (; k <= g; k++)
+  {
+    a = c[k];
+    while (a--)
+    {
+      /* here i is the Huffman code of length k bits for value *p */
+      /* make tables up to required level */
+      while (k > w + l)
+      {
+        h++;
+        w += l;                 /* previous table always l bits */
+
+        /* compute minimum size table less than or equal to l bits */
+        z = g - w;
+        z = z > (uInt)l ? l : z;        /* table size upper limit */
+        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
+        {                       /* too few codes for k-w bit table */
+          f -= a + 1;           /* deduct codes from patterns left */
+          xp = c + k;
+          if (j < z)
+            while (++j < z)     /* try smaller tables up to z bits */
+            {
+              if ((f <<= 1) <= *++xp)
+                break;          /* enough codes to use up j bits */
+              f -= *xp;         /* else deduct codes from patterns */
+            }
+        }
+        z = 1 << j;             /* table entries for j-bit table */
+
+        /* allocate new table */
+        if (*hn + z > MANY)     /* (note: doesn't matter for fixed) */
+          return Z_DATA_ERROR;  /* overflow of MANY */
+        u[h] = q = hp + *hn;
+        *hn += z;
+
+        /* connect to last table, if there is one */
+        if (h)
+        {
+          x[h] = i;             /* save pattern for backing up */
+          r.bits = (Byte)l;     /* bits to dump before this table */
+          r.exop = (Byte)j;     /* bits in this table */
+          j = i >> (w - l);
+          r.base = (uInt)(q - u[h-1] - j);   /* offset to this table */
+          u[h-1][j] = r;        /* connect to last table */
+        }
+        else
+          *t = q;               /* first table is returned result */
+      }
+
+      /* set up table entry in r */
+      r.bits = (Byte)(k - w);
+      if (p >= v + n)
+        r.exop = 128 + 64;      /* out of values--invalid code */
+      else if (*p < s)
+      {
+        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
+        r.base = *p++;          /* simple code is just the value */
+      }
+      else
+      {
+        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
+        r.base = d[*p++ - s];
+      }
+
+      /* fill code-like entries with r */
+      f = 1 << (k - w);
+      for (j = i >> w; j < z; j += f)
+        q[j] = r;
+
+      /* backwards increment the k-bit code i */
+      for (j = 1 << (k - 1); i & j; j >>= 1)
+        i ^= j;
+      i ^= j;
+
+      /* backup over finished tables */
+      mask = (1 << w) - 1;      /* needed on HP, cc -O bug */
+      while ((i & mask) != x[h])
+      {
+        h--;                    /* don't need to update q */
+        w -= l;
+        mask = (1 << w) - 1;
+      }
+    }
+  }
+
+
+  /* Return Z_BUF_ERROR if we were given an incomplete table */
+  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
+}
+
+
+int inflate_trees_bits(c, bb, tb, hp, z)
+uIntf *c;               /* 19 code lengths */
+uIntf *bb;              /* bits tree desired/actual depth */
+inflate_huft * FAR *tb; /* bits tree result */
+inflate_huft *hp;       /* space for trees */
+z_streamp z;            /* for messages */
+{
+  int r;
+  uInt hn = 0;          /* hufts used in space */
+  uIntf *v;             /* work area for huft_build */
+
+  if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
+    return Z_MEM_ERROR;
+  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
+                 tb, bb, hp, &hn, v);
+  if (r == Z_DATA_ERROR)
+    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
+  else if (r == Z_BUF_ERROR || *bb == 0)
+  {
+    z->msg = (char*)"incomplete dynamic bit lengths tree";
+    r = Z_DATA_ERROR;
+  }
+  ZFREE(z, v);
+  return r;
+}
+
+
+int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
+uInt nl;                /* number of literal/length codes */
+uInt nd;                /* number of distance codes */
+uIntf *c;               /* that many (total) code lengths */
+uIntf *bl;              /* literal desired/actual bit depth */
+uIntf *bd;              /* distance desired/actual bit depth */
+inflate_huft * FAR *tl; /* literal/length tree result */
+inflate_huft * FAR *td; /* distance tree result */
+inflate_huft *hp;       /* space for trees */
+z_streamp z;            /* for messages */
+{
+  int r;
+  uInt hn = 0;          /* hufts used in space */
+  uIntf *v;             /* work area for huft_build */
+
+  /* allocate work area */
+  if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+    return Z_MEM_ERROR;
+
+  /* build literal/length tree */
+  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
+  if (r != Z_OK || *bl == 0)
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = (char*)"oversubscribed literal/length tree";
+    else if (r != Z_MEM_ERROR)
+    {
+      z->msg = (char*)"incomplete literal/length tree";
+      r = Z_DATA_ERROR;
+    }
+    ZFREE(z, v);
+    return r;
+  }
+
+  /* build distance tree */
+  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
+  if (r != Z_OK || (*bd == 0 && nl > 257))
+  {
+    if (r == Z_DATA_ERROR)
+      z->msg = (char*)"oversubscribed distance tree";
+    else if (r == Z_BUF_ERROR) {
+#ifdef PKZIP_BUG_WORKAROUND
+      r = Z_OK;
+    }
+#else
+      z->msg = (char*)"incomplete distance tree";
+      r = Z_DATA_ERROR;
+    }
+    else if (r != Z_MEM_ERROR)
+    {
+      z->msg = (char*)"empty distance tree with lengths";
+      r = Z_DATA_ERROR;
+    }
+    ZFREE(z, v);
+    return r;
+#endif
+  }
+
+  /* done */
+  ZFREE(z, v);
+  return Z_OK;
+}
+
+
+/* build fixed tables only once--keep them here */
+#ifdef BUILDFIXED
+local int fixed_built = 0;
+#define FIXEDH 544      /* number of hufts used by fixed tables */
+local inflate_huft fixed_mem[FIXEDH];
+local uInt fixed_bl;
+local uInt fixed_bd;
+local inflate_huft *fixed_tl;
+local inflate_huft *fixed_td;
+#else
+#include "inffixed.h"
+#endif
+
+
+int inflate_trees_fixed(bl, bd, tl, td, z)
+uIntf *bl;               /* literal desired/actual bit depth */
+uIntf *bd;               /* distance desired/actual bit depth */
+inflate_huft * FAR *tl;  /* literal/length tree result */
+inflate_huft * FAR *td;  /* distance tree result */
+z_streamp z;             /* for memory allocation */
+{
+#ifdef BUILDFIXED
+  /* build fixed tables if not already */
+  if (!fixed_built)
+  {
+    int k;              /* temporary variable */
+    uInt f = 0;         /* number of hufts used in fixed_mem */
+    uIntf *c;           /* length list for huft_build */
+    uIntf *v;           /* work area for huft_build */
+
+    /* allocate memory */
+    if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+      return Z_MEM_ERROR;
+    if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
+    {
+      ZFREE(z, c);
+      return Z_MEM_ERROR;
+    }
+
+    /* literal table */
+    for (k = 0; k < 144; k++)
+      c[k] = 8;
+    for (; k < 256; k++)
+      c[k] = 9;
+    for (; k < 280; k++)
+      c[k] = 7;
+    for (; k < 288; k++)
+      c[k] = 8;
+    fixed_bl = 9;
+    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
+               fixed_mem, &f, v);
+
+    /* distance table */
+    for (k = 0; k < 30; k++)
+      c[k] = 5;
+    fixed_bd = 5;
+    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
+               fixed_mem, &f, v);
+
+    /* done */
+    ZFREE(z, v);
+    ZFREE(z, c);
+    fixed_built = 1;
+  }
+#endif
+  *bl = fixed_bl;
+  *bd = fixed_bd;
+  *tl = fixed_tl;
+  *td = fixed_td;
+  return Z_OK;
+}
diff --git a/external/zlib/inftrees.h b/external/zlib/inftrees.h
new file mode 100644
index 0000000..04b73b7
--- /dev/null
+++ b/external/zlib/inftrees.h
@@ -0,0 +1,58 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Huffman code lookup table entry--this entry is four bytes for machines
+   that have 16-bit pointers (e.g. PC's in the small or medium model). */
+
+typedef struct inflate_huft_s FAR inflate_huft;
+
+struct inflate_huft_s {
+  union {
+    struct {
+      Byte Exop;        /* number of extra bits or operation */
+      Byte Bits;        /* number of bits in this code or subcode */
+    } what;
+    uInt pad;           /* pad structure to a power of 2 (4 bytes for */
+  } word;               /*  16-bit, 8 bytes for 32-bit int's) */
+  uInt base;            /* literal, length base, distance base,
+                           or table offset */
+};
+
+/* Maximum size of dynamic tree.  The maximum found in a long but non-
+   exhaustive search was 1004 huft structures (850 for length/literals
+   and 154 for distances, the latter actually the result of an
+   exhaustive search).  The actual maximum is not known, but the
+   value below is more than safe. */
+#define MANY 1440
+
+extern int inflate_trees_bits OF((
+    uIntf *,                    /* 19 code lengths */
+    uIntf *,                    /* bits tree desired/actual depth */
+    inflate_huft * FAR *,       /* bits tree result */
+    inflate_huft *,             /* space for trees */
+    z_streamp));                /* for messages */
+
+extern int inflate_trees_dynamic OF((
+    uInt,                       /* number of literal/length codes */
+    uInt,                       /* number of distance codes */
+    uIntf *,                    /* that many (total) code lengths */
+    uIntf *,                    /* literal desired/actual bit depth */
+    uIntf *,                    /* distance desired/actual bit depth */
+    inflate_huft * FAR *,       /* literal/length tree result */
+    inflate_huft * FAR *,       /* distance tree result */
+    inflate_huft *,             /* space for trees */
+    z_streamp));                /* for messages */
+
+extern int inflate_trees_fixed OF((
+    uIntf *,                    /* literal desired/actual bit depth */
+    uIntf *,                    /* distance desired/actual bit depth */
+    inflate_huft * FAR *,       /* literal/length tree result */
+    inflate_huft * FAR *,       /* distance tree result */
+    z_streamp));                /* for memory allocation */
diff --git a/external/zlib/infutil.c b/external/zlib/infutil.c
new file mode 100644
index 0000000..9a07622
--- /dev/null
+++ b/external/zlib/infutil.c
@@ -0,0 +1,87 @@
+/* inflate_util.c -- data and routines common to blocks and codes
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+#include "zutil.h"
+#include "infblock.h"
+#include "inftrees.h"
+#include "infcodes.h"
+#include "infutil.h"
+
+struct inflate_codes_state {int dummy;}; /* for buggy compilers */
+
+/* And'ing with mask[n] masks the lower n bits */
+uInt inflate_mask[17] = {
+    0x0000,
+    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
+    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
+};
+
+
+/* copy as much as possible from the sliding window to the output area */
+int inflate_flush(s, z, r)
+inflate_blocks_statef *s;
+z_streamp z;
+int r;
+{
+  uInt n;
+  Bytef *p;
+  Bytef *q;
+
+  /* local copies of source and destination pointers */
+  p = z->next_out;
+  q = s->read;
+
+  /* compute number of bytes to copy as far as end of window */
+  n = (uInt)((q <= s->write ? s->write : s->end) - q);
+  if (n > z->avail_out) n = z->avail_out;
+  if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+  /* update counters */
+  z->avail_out -= n;
+  z->total_out += n;
+
+  /* update check information */
+  if (s->checkfn != Z_NULL)
+    z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+  /* copy as far as end of window */
+  zmemcpy(p, q, n);
+  p += n;
+  q += n;
+
+  /* see if more to copy at beginning of window */
+  if (q == s->end)
+  {
+    /* wrap pointers */
+    q = s->window;
+    if (s->write == s->end)
+      s->write = s->window;
+
+    /* compute bytes to copy */
+    n = (uInt)(s->write - q);
+    if (n > z->avail_out) n = z->avail_out;
+    if (n && r == Z_BUF_ERROR) r = Z_OK;
+
+    /* update counters */
+    z->avail_out -= n;
+    z->total_out += n;
+
+    /* update check information */
+    if (s->checkfn != Z_NULL)
+      z->adler = s->check = (*s->checkfn)(s->check, q, n);
+
+    /* copy */
+    zmemcpy(p, q, n);
+    p += n;
+    q += n;
+  }
+
+  /* update pointers */
+  z->next_out = p;
+  s->read = q;
+
+  /* done */
+  return r;
+}
diff --git a/external/zlib/infutil.h b/external/zlib/infutil.h
new file mode 100644
index 0000000..4401df8
--- /dev/null
+++ b/external/zlib/infutil.h
@@ -0,0 +1,98 @@
+/* infutil.h -- types and macros common to blocks and codes
+ * Copyright (C) 1995-2002 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+#ifndef _INFUTIL_H
+#define _INFUTIL_H
+
+typedef enum {
+      TYPE,     /* get type bits (3, including end bit) */
+      LENS,     /* get lengths for stored */
+      STORED,   /* processing stored block */
+      TABLE,    /* get table lengths */
+      BTREE,    /* get bit lengths tree for a dynamic block */
+      DTREE,    /* get length, distance trees for a dynamic block */
+      CODES,    /* processing fixed or dynamic block */
+      DRY,      /* output remaining window bytes */
+      DONE,     /* finished last block, done */
+      BAD}      /* got a data error--stuck here */
+inflate_block_mode;
+
+/* inflate blocks semi-private state */
+struct inflate_blocks_state {
+
+  /* mode */
+  inflate_block_mode  mode;     /* current inflate_block mode */
+
+  /* mode dependent information */
+  union {
+    uInt left;          /* if STORED, bytes left to copy */
+    struct {
+      uInt table;               /* table lengths (14 bits) */
+      uInt index;               /* index into blens (or border) */
+      uIntf *blens;             /* bit lengths of codes */
+      uInt bb;                  /* bit length tree depth */
+      inflate_huft *tb;         /* bit length decoding tree */
+    } trees;            /* if DTREE, decoding info for trees */
+    struct {
+      inflate_codes_statef 
+         *codes;
+    } decode;           /* if CODES, current state */
+  } sub;                /* submode */
+  uInt last;            /* true if this block is the last block */
+
+  /* mode independent information */
+  uInt bitk;            /* bits in bit buffer */
+  uLong bitb;           /* bit buffer */
+  inflate_huft *hufts;  /* single malloc for tree space */
+  Bytef *window;        /* sliding window */
+  Bytef *end;           /* one byte after sliding window */
+  Bytef *read;          /* window read pointer */
+  Bytef *write;         /* window write pointer */
+  check_func checkfn;   /* check function */
+  uLong check;          /* check on output */
+
+};
+
+
+/* defines for inflate input/output */
+/*   update pointers and return */
+#define UPDBITS {s->bitb=b;s->bitk=k;}
+#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
+#define UPDOUT {s->write=q;}
+#define UPDATE {UPDBITS UPDIN UPDOUT}
+#define LEAVE {UPDATE return inflate_flush(s,z,r);}
+/*   get bytes and bits */
+#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
+#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
+#define NEXTBYTE (n--,*p++)
+#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
+#define DUMPBITS(j) {b>>=(j);k-=(j);}
+/*   output bytes */
+#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
+#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
+#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
+#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
+#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
+#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
+/*   load local pointers */
+#define LOAD {LOADIN LOADOUT}
+
+/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
+extern uInt inflate_mask[17];
+
+/* copy as much as possible from the sliding window to the output area */
+extern int inflate_flush OF((
+    inflate_blocks_statef *,
+    z_streamp ,
+    int));
+
+struct internal_state      {int dummy;}; /* for buggy compilers */
+
+#endif
diff --git a/external/zlib/makefile b/external/zlib/makefile
new file mode 100644
index 0000000..116e526
--- /dev/null
+++ b/external/zlib/makefile
@@ -0,0 +1,58 @@
+#
+#  Zlib compression library makefile
+#
+# Copyright (C) 1997 Logiciels et Applications Scientifiques (L.A.S.) Inc
+# Permission to use, copy, modify and distribute this software and
+# its documentation for any purpose and without fee is hereby granted,
+# provided that the above copyright notice appear in all copies, that
+# both the copyright notice and this permission notice appear in
+# supporting documentation, and that the name of L.A.S. Inc not be used 
+# in advertising or publicity pertaining to distribution of the software 
+# without specific, written prior permission. L.A.S. Inc. makes no
+# representations about the suitability of this software for any purpose.
+# It is provided "as is" without express or implied warranty.
+#
+
+#
+# The names of the targets to build
+#
+TOBEGEN		= zlib_ogdi$(OGDI_VERSION)
+TARGETGEN	= $(DYNAGEN)
+
+#
+# Source files
+#
+SOURCES =   adler32.c \
+            compress.c \
+            crc32.c \
+            deflate.c \
+            gzio.c \
+            infblock.c \
+            infcodes.c \
+            inffast.c \
+            inflate.c \
+            inftrees.c \
+            infutil.c \
+            trees.c \
+            uncompr.c \
+            zutil.c
+
+#
+# Include the common configuration
+#
+include $(TOPDIR)/config/common.mak
+
+#
+# Compilation flags
+#
+INCLUDES = $(CURRENT_INCLUDE)
+CFLAGS 	= $(INCLUDES) $(COMMON_CFLAGS)
+
+#
+# Primary target
+#
+all: MKOBJECTDIR
+	@echo "making $(TARGETGEN)"
+	$(MAKE) --directory $(OBJDIR) -f ../makefile PASS='depend' $(TARGETGEN)
+
+clean: default-clean
diff --git a/external/zlib/minigzip.c b/external/zlib/minigzip.c
new file mode 100644
index 0000000..57baac4
--- /dev/null
+++ b/external/zlib/minigzip.c
@@ -0,0 +1,320 @@
+/* minigzip.c -- simulate gzip using the zlib compression library
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ * minigzip is a minimal implementation of the gzip utility. This is
+ * only an example of using zlib and isn't meant to replace the
+ * full-featured gzip. No attempt is made to deal with file systems
+ * limiting names to 14 or 8+3 characters, etc... Error checking is
+ * very limited. So use minigzip only for testing; use gzip for the
+ * real thing. On MSDOS, use only on file names without extension
+ * or in pipe mode.
+ */
+
+/* @(#) $Id: minigzip.c,v 1.3 2002/03/28 16:05:34 warmerda Exp $ */
+
+#include <stdio.h>
+#include "zlib.h"
+
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#else
+   extern void exit  OF((int));
+#endif
+
+#ifdef USE_MMAP
+#  include <sys/types.h>
+#  include <sys/mman.h>
+#  include <sys/stat.h>
+#endif
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32)
+#  include <fcntl.h>
+#  include <io.h>
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+
+#ifdef VMS
+#  define unlink delete
+#  define GZ_SUFFIX "-gz"
+#endif
+#ifdef RISCOS
+#  define unlink remove
+#  define GZ_SUFFIX "-gz"
+#  define fileno(file) file->__file
+#endif
+#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#  include <unix.h> /* for fileno */
+#endif
+
+#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
+  extern int unlink OF((const char *));
+#endif
+
+#ifndef GZ_SUFFIX
+#  define GZ_SUFFIX ".gz"
+#endif
+#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
+
+#define BUFLEN      16384
+#define MAX_NAME_LEN 1024
+
+#ifdef MAXSEG_64K
+#  define local static
+   /* Needed for systems with limitation on stack size. */
+#else
+#  define local
+#endif
+
+char *prog;
+
+void error            OF((const char *msg));
+void gz_compress      OF((FILE   *in, gzFile out));
+#ifdef USE_MMAP
+int  gz_compress_mmap OF((FILE   *in, gzFile out));
+#endif
+void gz_uncompress    OF((gzFile in, FILE   *out));
+void file_compress    OF((char  *file, char *mode));
+void file_uncompress  OF((char  *file));
+int  main             OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Display error message and exit
+ */
+void error(msg)
+    const char *msg;
+{
+    fprintf(stderr, "%s: %s\n", prog, msg);
+    exit(1);
+}
+
+/* ===========================================================================
+ * Compress input to output then close both files.
+ */
+
+void gz_compress(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+#ifdef USE_MMAP
+    /* Try first compressing with mmap. If mmap fails (minigzip used in a
+     * pipe), use the normal fread loop.
+     */
+    if (gz_compress_mmap(in, out) == Z_OK) return;
+#endif
+    for (;;) {
+        len = fread(buf, 1, sizeof(buf), in);
+        if (ferror(in)) {
+            perror("fread");
+            exit(1);
+        }
+        if (len == 0) break;
+
+        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
+    }
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+}
+
+#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech at eso.org> */
+
+/* Try compressing the input file at once using mmap. Return Z_OK if
+ * if success, Z_ERRNO otherwise.
+ */
+int gz_compress_mmap(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    int len;
+    int err;
+    int ifd = fileno(in);
+    caddr_t buf;    /* mmap'ed buffer for the entire input file */
+    off_t buf_len;  /* length of the input file */
+    struct stat sb;
+
+    /* Determine the size of the file, needed for mmap: */
+    if (fstat(ifd, &sb) < 0) return Z_ERRNO;
+    buf_len = sb.st_size;
+    if (buf_len <= 0) return Z_ERRNO;
+
+    /* Now do the actual mmap: */
+    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); 
+    if (buf == (caddr_t)(-1)) return Z_ERRNO;
+
+    /* Compress the whole file at once: */
+    len = gzwrite(out, (char *)buf, (unsigned)buf_len);
+
+    if (len != (int)buf_len) error(gzerror(out, &err));
+
+    munmap(buf, buf_len);
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+    return Z_OK;
+}
+#endif /* USE_MMAP */
+
+/* ===========================================================================
+ * Uncompress input to output then close both files.
+ */
+void gz_uncompress(in, out)
+    gzFile in;
+    FILE   *out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+    for (;;) {
+        len = gzread(in, buf, sizeof(buf));
+        if (len < 0) error (gzerror(in, &err));
+        if (len == 0) break;
+
+        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
+	    error("failed fwrite");
+	}
+    }
+    if (fclose(out)) error("failed fclose");
+
+    if (gzclose(in) != Z_OK) error("failed gzclose");
+}
+
+
+/* ===========================================================================
+ * Compress the given file: create a corresponding .gz file and remove the
+ * original.
+ */
+void file_compress(file, mode)
+    char  *file;
+    char  *mode;
+{
+    local char outfile[MAX_NAME_LEN];
+    FILE  *in;
+    gzFile out;
+
+    strcpy(outfile, file);
+    strcat(outfile, GZ_SUFFIX);
+
+    in = fopen(file, "rb");
+    if (in == NULL) {
+        perror(file);
+        exit(1);
+    }
+    out = gzopen(outfile, mode);
+    if (out == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
+        exit(1);
+    }
+    gz_compress(in, out);
+
+    unlink(file);
+}
+
+
+/* ===========================================================================
+ * Uncompress the given file and remove the original.
+ */
+void file_uncompress(file)
+    char  *file;
+{
+    local char buf[MAX_NAME_LEN];
+    char *infile, *outfile;
+    FILE  *out;
+    gzFile in;
+    int len = strlen(file);
+
+    strcpy(buf, file);
+
+    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
+        infile = file;
+        outfile = buf;
+        outfile[len-3] = '\0';
+    } else {
+        outfile = file;
+        infile = buf;
+        strcat(infile, GZ_SUFFIX);
+    }
+    in = gzopen(infile, "rb");
+    if (in == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
+        exit(1);
+    }
+    out = fopen(outfile, "wb");
+    if (out == NULL) {
+        perror(file);
+        exit(1);
+    }
+
+    gz_uncompress(in, out);
+
+    unlink(infile);
+}
+
+
+/* ===========================================================================
+ * Usage:  minigzip [-d] [-f] [-h] [-1 to -9] [files...]
+ *   -d : decompress
+ *   -f : compress with Z_FILTERED
+ *   -h : compress with Z_HUFFMAN_ONLY
+ *   -1 to -9 : compression level
+ */
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    int uncompr = 0;
+    gzFile file;
+    char outmode[20];
+
+    strcpy(outmode, "wb6 ");
+
+    prog = argv[0];
+    argc--, argv++;
+
+    while (argc > 0) {
+      if (strcmp(*argv, "-d") == 0)
+	uncompr = 1;
+      else if (strcmp(*argv, "-f") == 0)
+	outmode[3] = 'f';
+      else if (strcmp(*argv, "-h") == 0)
+	outmode[3] = 'h';
+      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
+	       (*argv)[2] == 0)
+	outmode[2] = (*argv)[1];
+      else
+	break;
+      argc--, argv++;
+    }
+    if (argc == 0) {
+        SET_BINARY_MODE(stdin);
+        SET_BINARY_MODE(stdout);
+        if (uncompr) {
+            file = gzdopen(fileno(stdin), "rb");
+            if (file == NULL) error("can't gzdopen stdin");
+            gz_uncompress(file, stdout);
+        } else {
+            file = gzdopen(fileno(stdout), outmode);
+            if (file == NULL) error("can't gzdopen stdout");
+            gz_compress(stdin, file);
+        }
+    } else {
+        do {
+            if (uncompr) {
+                file_uncompress(*argv);
+            } else {
+                file_compress(*argv, outmode);
+            }
+        } while (argv++, --argc);
+    }
+    exit(0);
+    return 0; /* to avoid warning */
+}
diff --git a/external/zlib/trees.c b/external/zlib/trees.c
new file mode 100644
index 0000000..196ad6c
--- /dev/null
+++ b/external/zlib/trees.c
@@ -0,0 +1,1214 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2002 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id: trees.c,v 1.3 2002/03/28 16:05:34 warmerda Exp $ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+#define Buf_size (8 * 2*sizeof(char))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+#  include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+    const ct_data *static_tree;  /* static tree or NULL */
+    const intf *extra_bits;      /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, ct_data *ltree,
+                              ct_data *dtree));
+local void set_data_type  OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
+                              int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+#  define send_code(s, c, tree) \
+     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (value << s->bi_valid);
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = value;\
+    s->bi_buf |= (val << s->bi_valid);\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* DEBUG */
+
+
+#define MAX(a,b) (a >= b ? a : b)
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* For some embedded targets, global variables are not initialized: */
+    static_l_desc.static_tree = static_ltree;
+    static_l_desc.extra_bits = extra_lbits;
+    static_d_desc.static_tree = static_dtree;
+    static_d_desc.extra_bits = extra_dbits;
+    static_bl_desc.extra_bits = extra_blbits;
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            _length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    _length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            _dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            _dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+
+#  ifdef GEN_TREES_H
+    gen_trees_header();
+#  endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+#  ifndef DEBUG
+#    include <stdio.h>
+#  endif
+
+#  define SEPARATOR(i, last, width) \
+      ((i) == (last)? "\n};\n\n" :    \
+       ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+    FILE *header = fopen("trees.h", "w");
+    int i;
+
+    Assert (header != NULL, "Can't open trees.h");
+    fprintf(header,
+	    "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+    for (i = 0; i < L_CODES+2; i++) {
+	fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+		static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+    }
+
+    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+	fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+		static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+    }
+
+    fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
+    for (i = 0; i < DIST_CODE_LEN; i++) {
+	fprintf(header, "%2u%s", _dist_code[i],
+		SEPARATOR(i, DIST_CODE_LEN-1, 20));
+    }
+
+    fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+	fprintf(header, "%2u%s", _length_code[i],
+		SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+    }
+
+    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+    for (i = 0; i < LENGTH_CODES; i++) {
+	fprintf(header, "%1u%s", base_length[i],
+		SEPARATOR(i, LENGTH_CODES-1, 20));
+    }
+
+    fprintf(header, "local const int base_dist[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+	fprintf(header, "%5u%s", base_dist[i],
+		SEPARATOR(i, D_CODES-1, 10));
+    }
+
+    fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void _tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+#ifdef DEBUG
+    s->compressed_len = 0L;
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree        = desc->dyn_tree;
+    int max_code         = desc->max_code;
+    const ct_data *stree = desc->stat_desc->static_tree;
+    const intf *extra    = desc->stat_desc->extra_bits;
+    int base             = desc->stat_desc->extra_base;
+    int max_length       = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if (tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree         = desc->dyn_tree;
+    const ct_data *stree  = desc->stat_desc->static_tree;
+    int elems             = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void _tr_stored_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
+#ifdef DEBUG
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+#endif
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ * The current inflate code requires 9 bits of lookahead. If the
+ * last two codes for the previous block (real code plus EOB) were coded
+ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ * the last real code. In this case we send two empty static blocks instead
+ * of one. (There are no problems if the previous block is stored or fixed.)
+ * To simplify the code, we assume the worst case of last real code encoded
+ * on one bit only.
+ */
+void _tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+    bi_flush(s);
+    /* Of the 10 bits for the empty block, we have already sent
+     * (10 - bi_valid) bits. The lookahead for the last real code (before
+     * the EOB of the previous block) was thus at least one plus the length
+     * of the EOB plus what we have just sent of the empty static block.
+     */
+    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
+        send_bits(s, STATIC_TREES<<1, 3);
+        send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+        s->compressed_len += 10L;
+#endif
+        bi_flush(s);
+    }
+    s->last_eob_len = 7;
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void _tr_flush_block(s, buf, stored_len, eof)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int eof;          /* true if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+	 /* Check if the file is ascii or binary */
+	if (s->data_type == Z_UNKNOWN) set_data_type(s);
+
+	/* Construct the literal and distance trees */
+	build_tree(s, (tree_desc *)(&(s->l_desc)));
+	Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+		s->static_len));
+
+	build_tree(s, (tree_desc *)(&(s->d_desc)));
+	Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+		s->static_len));
+	/* At this point, opt_len and static_len are the total bit lengths of
+	 * the compressed block data, excluding the tree representations.
+	 */
+
+	/* Build the bit length tree for the above two trees, and get the index
+	 * in bl_order of the last bit length code to send.
+	 */
+	max_blindex = build_bl_tree(s);
+
+	/* Determine the best encoding. Compute first the block length in bytes*/
+	opt_lenb = (s->opt_len+3+7)>>3;
+	static_lenb = (s->static_len+3+7)>>3;
+
+	Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+		opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+		s->last_lit));
+
+	if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+	opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        _tr_stored_block(s, buf, stored_len, eof);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+eof, 3);
+        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->static_len;
+#endif
+    } else {
+        send_bits(s, (DYN_TREES<<1)+eof, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->opt_len;
+#endif
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    /* The above check is made mod 2^32, for files larger than 512 MB
+     * and uLong implemented on 32 bits.
+     */
+    init_block(s);
+
+    if (eof) {
+        bi_windup(s);
+#ifdef DEBUG
+        s->compressed_len += 7;  /* align on byte boundary */
+#endif
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*eof));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int _tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+#ifdef TRUNCATE_BLOCK
+    /* Try to guess if it is profitable to stop the current block here */
+    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+#endif
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    ct_data *ltree; /* literal tree */
+    ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = _length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+    s->last_eob_len = ltree[END_BLOCK].Len;
+}
+
+/* ===========================================================================
+ * Set the data type to ASCII or BINARY, using a crude approximation:
+ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
+ * IN assertion: the fields freq of dyn_ltree are set and the total of all
+ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
+ */
+local void set_data_type(s)
+    deflate_state *s;
+{
+    int n = 0;
+    unsigned ascii_freq = 0;
+    unsigned bin_freq = 0;
+    while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
+    while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
+    while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
+    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+    deflate_state *s;
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    charf    *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);        /* align on byte boundary */
+    s->last_eob_len = 8; /* enough lookahead for inflate */
+
+    if (header) {
+        put_short(s, (ush)len);   
+        put_short(s, (ush)~len);
+#ifdef DEBUG
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG
+    s->bits_sent += (ulg)len<<3;
+#endif
+    while (len--) {
+        put_byte(s, *buf++);
+    }
+}
diff --git a/external/zlib/trees.h b/external/zlib/trees.h
new file mode 100644
index 0000000..72facf9
--- /dev/null
+++ b/external/zlib/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
+{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
+{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
+{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
+{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
+{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
+{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
+{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
+{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
+{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
+{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
+{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
+{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
+{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
+{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
+{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
+{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
+{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
+{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
+{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
+{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
+{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
+{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
+{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
+{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
+{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
+{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
+{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
+{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
+{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
+{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
+{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
+{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
+{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
+{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
+{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
+{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
+{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
+{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
+{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
+{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
+{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
+{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
+{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
+{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
+{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
+{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
+{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
+{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
+{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
+{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
+{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
+{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
+{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
+{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
+{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
+{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
+{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch _dist_code[DIST_CODE_LEN] = {
+ 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
+ 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
+   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
+ 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
+};
+
diff --git a/external/zlib/uncompr.c b/external/zlib/uncompr.c
new file mode 100644
index 0000000..2e2070d
--- /dev/null
+++ b/external/zlib/uncompr.c
@@ -0,0 +1,58 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: uncompr.c,v 1.3 2002/03/28 16:05:34 warmerda Exp $ */
+
+#include "zlib.h"
+
+/* ===========================================================================
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (Bytef*)source;
+    stream.avail_in = (uInt)sourceLen;
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+
+    err = inflateInit(&stream);
+    if (err != Z_OK) return err;
+
+    err = inflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        inflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = inflateEnd(&stream);
+    return err;
+}
diff --git a/external/zlib/zconf.h b/external/zlib/zconf.h
new file mode 100644
index 0000000..eede4a2
--- /dev/null
+++ b/external/zlib/zconf.h
@@ -0,0 +1,279 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: zconf.h,v 1.3 2002/03/28 16:05:34 warmerda Exp $ */
+
+#ifndef _ZCONF_H
+#define _ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ */
+#ifdef Z_PREFIX
+#  define deflateInit_	z_deflateInit_
+#  define deflate	z_deflate
+#  define deflateEnd	z_deflateEnd
+#  define inflateInit_ 	z_inflateInit_
+#  define inflate	z_inflate
+#  define inflateEnd	z_inflateEnd
+#  define deflateInit2_	z_deflateInit2_
+#  define deflateSetDictionary z_deflateSetDictionary
+#  define deflateCopy	z_deflateCopy
+#  define deflateReset	z_deflateReset
+#  define deflateParams	z_deflateParams
+#  define inflateInit2_	z_inflateInit2_
+#  define inflateSetDictionary z_inflateSetDictionary
+#  define inflateSync	z_inflateSync
+#  define inflateSyncPoint z_inflateSyncPoint
+#  define inflateReset	z_inflateReset
+#  define compress	z_compress
+#  define compress2	z_compress2
+#  define uncompress	z_uncompress
+#  define adler32	z_adler32
+#  define crc32		z_crc32
+#  define get_crc_table z_get_crc_table
+
+#  define Byte		z_Byte
+#  define uInt		z_uInt
+#  define uLong		z_uLong
+#  define Bytef	        z_Bytef
+#  define charf		z_charf
+#  define intf		z_intf
+#  define uIntf		z_uIntf
+#  define uLongf	z_uLongf
+#  define voidpf	z_voidpf
+#  define voidp		z_voidp
+#endif
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#  define WIN32
+#endif
+#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
+#  ifndef __32BIT__
+#    define __32BIT__
+#  endif
+#endif
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#if defined(MSDOS) && !defined(__32BIT__)
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)
+#  define STDC
+#endif
+#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
+#  ifndef STDC
+#    define STDC
+#  endif
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const
+#  endif
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Old Borland C incorrectly complains about missing returns: */
+#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
+#  define NEED_DUMMY_RETURN
+#endif
+
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
+   /* MSC small or medium model */
+#  define SMALL_MEDIUM
+#  ifdef _MSC_VER
+#    define FAR _far
+#  else
+#    define FAR far
+#  endif
+#endif
+#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
+#  ifndef __32BIT__
+#    define SMALL_MEDIUM
+#    define FAR _far
+#  endif
+#endif
+
+/* Compile with -DZLIB_DLL for Windows DLL support */
+#if defined(ZLIB_DLL)
+#  if defined(_WINDOWS) || defined(WINDOWS)
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+#    define ZEXPORT  WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA  WINAPIV
+#    else
+#      define ZEXPORTVA  FAR _cdecl _export
+#    endif
+#  endif
+#  if defined (__BORLANDC__)
+#    if (__BORLANDC__ >= 0x0500) && defined (WIN32)
+#      include <windows.h>
+#      define ZEXPORT __declspec(dllexport) WINAPI
+#      define ZEXPORTRVA __declspec(dllexport) WINAPIV
+#    else
+#      if defined (_Windows) && defined (__DLL__)
+#        define ZEXPORT _export
+#        define ZEXPORTVA _export
+#      endif
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  if defined (ZLIB_DLL)
+#    define ZEXTERN extern __declspec(dllexport)
+#  else
+#    define ZEXTERN extern __declspec(dllimport)
+#  endif
+#endif
+
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+
+#ifndef FAR
+#   define FAR
+#endif
+
+#if !defined(MACOS) && !defined(TARGET_OS_MAC)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void FAR *voidpf;
+   typedef void     *voidp;
+#else
+   typedef Byte FAR *voidpf;
+   typedef Byte     *voidp;
+#endif
+
+#ifdef HAVE_UNISTD_H
+#  include <sys/types.h> /* for off_t */
+#  include <unistd.h>    /* for SEEK_* and off_t */
+#  define z_off_t  off_t
+#endif
+#ifndef SEEK_SET
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+#ifndef z_off_t
+#  define  z_off_t long
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+#   pragma map(deflateInit_,"DEIN")
+#   pragma map(deflateInit2_,"DEIN2")
+#   pragma map(deflateEnd,"DEEND")
+#   pragma map(inflateInit_,"ININ")
+#   pragma map(inflateInit2_,"ININ2")
+#   pragma map(inflateEnd,"INEND")
+#   pragma map(inflateSync,"INSY")
+#   pragma map(inflateSetDictionary,"INSEDI")
+#   pragma map(inflate_blocks,"INBL")
+#   pragma map(inflate_blocks_new,"INBLNE")
+#   pragma map(inflate_blocks_free,"INBLFR")
+#   pragma map(inflate_blocks_reset,"INBLRE")
+#   pragma map(inflate_codes_free,"INCOFR")
+#   pragma map(inflate_codes,"INCO")
+#   pragma map(inflate_fast,"INFA")
+#   pragma map(inflate_flush,"INFLU")
+#   pragma map(inflate_mask,"INMA")
+#   pragma map(inflate_set_dictionary,"INSEDI2")
+#   pragma map(inflate_copyright,"INCOPY")
+#   pragma map(inflate_trees_bits,"INTRBI")
+#   pragma map(inflate_trees_dynamic,"INTRDY")
+#   pragma map(inflate_trees_fixed,"INTRFI")
+#   pragma map(inflate_trees_free,"INTRFR")
+#endif
+
+#endif /* _ZCONF_H */
diff --git a/external/zlib/zlib.h b/external/zlib/zlib.h
new file mode 100644
index 0000000..52cb529
--- /dev/null
+++ b/external/zlib/zlib.h
@@ -0,0 +1,893 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.1.4, March 11th, 2002
+
+  Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup at gzip.org          madler at alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
+  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
+*/
+
+#ifndef _ZLIB_H
+#define _ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.1.4"
+
+/* 
+     The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed
+  data.  This version of the library supports only one compression method
+  (deflation) but other algorithms will be added later and will have the same
+  stream interface.
+
+     Compression can be done in a single step if the buffers are large
+  enough (for example if an input file is mmap'ed), or can be done by
+  repeated calls of the compression function.  In the latter case, the
+  application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+     The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio.
+
+     The library does not install any signal handler. The decoder checks
+  the consistency of the compressed data, so the library should never
+  crash even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    Bytef    *next_in;  /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total nb of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total nb of bytes output so far */
+
+    char     *msg;      /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: ascii or binary */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+   The application must update next_in and avail_in when avail_in has
+   dropped to zero. It must update next_out and avail_out when avail_out
+   has dropped to zero. The application must initialize zalloc, zfree and
+   opaque before calling the init function. All other fields are set by the
+   compression library and must not be updated by the application.
+
+   The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree. This can be useful for custom
+   memory management. The compression library attaches no meaning to the
+   opaque value.
+
+   zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.
+
+   On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this
+   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
+   pointers returned by zalloc for objects of exactly 65536 bytes *must*
+   have their offset normalized to zero. The default allocation function
+   provided by this library ensures this (see zutil.c). To reduce memory
+   requirements and avoid any allocation of 64K objects, at the expense of
+   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
+
+   The fields total_in and total_out can be used for statistics or
+   progress reports. After compression, total_in holds the total size of
+   the uncompressed data and may be saved for use in the decompressor
+   (particularly if the decompressor wants to decompress everything in
+   a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+/* Allowed flush values; see deflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative
+ * values are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_ASCII    1
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is
+   not compatible with the zlib.h header file used by the application.
+   This check is automatically made by deflateInit and inflateInit.
+ */
+
+/* 
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression. The fields
+   zalloc, zfree and opaque must be initialized before by the caller.
+   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
+   use default allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at
+   all (the input data is simply copied a block at a time).
+   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
+   compression (currently equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).
+   msg is set to null if there is no error message.  deflateInit does not
+   perform any compression: this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may introduce some
+  output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows. deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly. This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).
+    Some output may be provided even if flush is not set.
+
+  Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating avail_in or avail_out accordingly; avail_out
+  should never be zero before the call. The application can consume the
+  compressed output when it wants, for example when the output buffer is full
+  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
+  and with zero avail_out, it must be called again after making room in the
+  output buffer because there might be more output pending.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far. (In particular
+  avail_in is zero after the call if enough output space has been provided
+  before the call.)  Flushing may degrade compression for some compression
+  algorithms and so it should be used only when necessary.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
+  the compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out).
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there
+  was enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error. After
+  deflate has returned Z_STREAM_END, the only possible operations on the
+  stream are deflateReset or deflateEnd.
+  
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step. In this case, avail_out must be at least
+  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
+  Z_STREAM_END, then it must be called again as described above.
+
+    deflate() sets strm->adler to the adler32 checksum of all input read
+  so far (that is, total_in bytes).
+
+    deflate() may update data_type if it can make a good guess about
+  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
+  binary. This field is only for information purposes and does not affect
+  the compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
+  (for example avail_in or avail_out was zero).
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded). In the error case,
+   msg may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/* 
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression. The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
+   value depends on the compression method), inflateInit determines the
+   compression method from the zlib header and allocates all data structures
+   accordingly; otherwise the allocation will be deferred to the first call of
+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+   use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller.  msg is set to null if there is no error
+   message. inflateInit does not perform any decompression apart from reading
+   the zlib header if present: this will be done by inflate().  (So next_in and
+   avail_in may be modified, but next_out and avail_out are unchanged.)
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full. It may some
+  introduce some output latency (reading input without producing any output)
+  except when forced to flush.
+
+  The detailed semantics are as follows. inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly. If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing
+    will resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there
+    is no more input data or no more space in the output buffer (see below
+    about the flush parameter).
+
+  Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming
+  more output, and updating the next_* and avail_* values accordingly.
+  The application can consume the uncompressed output when it wants, for
+  example when the output buffer is full (avail_out == 0), or after each
+  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
+  must be called again after making room in the output buffer because there
+  might be more output pending.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
+  output as possible to the output buffer. The flushing behavior of inflate is
+  not specified for values of the flush parameter other than Z_SYNC_FLUSH
+  and Z_FINISH, but the current implementation actually flushes as much output
+  as possible anyway.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error. However if all decompression is to be performed in a single step
+  (a single call of inflate), the parameter flush should be set to
+  Z_FINISH. In this case all pending input is processed and all pending
+  output is flushed; avail_out must be large enough to hold all the
+  uncompressed data. (The size of the uncompressed data may have been saved
+  by the compressor for this purpose.) The next operation on this stream must
+  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
+  is never required, but can be used to inform inflate that a faster routine
+  may be used for the single inflate() call.
+
+     If a preset dictionary is needed at this point (see inflateSetDictionary
+  below), inflate sets strm-adler to the adler32 checksum of the
+  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise 
+  it sets strm->adler to the adler32 checksum of all output produced
+  so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
+  an error code as described below. At the end of the stream, inflate()
+  checks that its computed adler32 checksum is equal to that saved by the
+  compressor and returns Z_STREAM_END only if the checksum is correct.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect
+  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
+  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
+  enough memory, Z_BUF_ERROR if no progress is possible or if there was not
+  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
+  case, the application may then call inflateSync to look for a good
+  compression block.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any
+   pending output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent. In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*   
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options. The
+   fields next_in, zalloc, zfree and opaque must be initialized before by
+   the caller.
+
+     The method parameter is the compression method. It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer).  It should be in the range 8..15 for this
+   version of the library. Larger values of this parameter result in better
+   compression at the expense of memory usage. The default value is 15 if
+   deflateInit is used instead.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state. memLevel=1 uses minimum memory but
+   is slow and reduces compression ratio; memLevel=9 uses maximum memory
+   for optimal speed. The default value is 8. See zconf.h for total memory
+   usage as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm. Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match).  Filtered data consists mostly of small values with a
+   somewhat random distribution. In this case, the compression algorithm is
+   tuned to compress them better. The effect of Z_FILTERED is to force more
+   Huffman coding and less string matching; it is somewhat intermediate
+   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
+   the compression ratio but not the correctness of the compressed output even
+   if it is not set appropriately.
+
+      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
+   method). msg is set to null if there is no error message.  deflateInit2 does
+   not perform any compression: this will be done by deflate().
+*/
+                            
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output. This function must be called
+   immediately after deflateInit, deflateInit2 or deflateReset, before any
+   call of deflate. The compressor and decompressor must use exactly the same
+   dictionary (see inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary. Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size in
+   deflate or deflate2. Thus the strings most likely to be useful should be
+   put at the end of the dictionary, not at the front.
+
+     Upon return of this function, strm->adler is set to the Adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor. (The Adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.)
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if the compression method is bsort). deflateSetDictionary does not
+   perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter. The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and
+   can consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being NULL). msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.
+   The stream will keep the same compression level and any other attributes
+   that may have been set by deflateInit2.
+
+      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+				      int level,
+				      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2.  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different
+   strategy. If the compression level is changed, the input available so far
+   is compressed with the old level (and may be flushed); the new level will
+   take effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to
+   be compressed and flushed. In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
+   if strm->avail_out was zero.
+*/
+
+/*   
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter. The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library. The default value is 15 if inflateInit is used
+   instead. If a compressed stream with a larger window size is given as
+   input, inflate() will return with the error code Z_DATA_ERROR instead of
+   trying to allocate a larger window.
+
+      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
+   memLevel). msg is set to null if there is no error message.  inflateInit2
+   does not perform any decompression apart from reading the zlib header if
+   present: this will be done by inflate(). (So next_in and avail_in may be
+   modified, but next_out and avail_out are unchanged.)
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence. This function must be called immediately after a call of inflate
+   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
+   can be determined from the Adler32 value returned by this call of
+   inflate. The compressor and decompressor must use exactly the same
+   dictionary (see deflateSetDictionary).
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (such as NULL dictionary) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect Adler32 value). inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/* 
+    Skips invalid compressed data until a full flush point (see above the
+  description of deflate with Z_FULL_FLUSH) can be found, or until all
+  available input is skipped. No output is provided.
+
+    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
+  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
+  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
+  case, the application may save the current current value of total_in which
+  indicates where valid compressed data was found. In the error case, the
+  application may repeatedly call inflateSync, providing more input each time,
+  until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.
+   The stream will keep attributes that may have been set by inflateInit2.
+
+      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being NULL).
+*/
+
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the
+   basic stream-oriented functions. To simplify the interface, some
+   default options are assumed (compression level and memory usage,
+   standard memory allocation functions). The source code of these
+   utility functions can easily be modified if you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be at least 0.1% larger than
+   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
+   compressed buffer.
+     This function can be used to compress a whole file at once if the
+   input file is mmap'ed.
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
+/*
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+     This function can be used to decompress a whole file at once if the
+   input file is mmap'ed.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+
+
+typedef voidp gzFile;
+
+ZEXTERN gzFile ZEXPORT gzopen  OF((const char *path, const char *mode));
+/*
+     Opens a gzip (.gz) file for reading or writing. The mode parameter
+   is as in fopen ("rb" or "wb") but can also include a compression level
+   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
+   Huffman only compression as in "wb1h". (See the description
+   of deflateInit2 for more information about the strategy parameter.)
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.
+
+     gzopen returns NULL if the file could not be opened or if there was
+   insufficient memory to allocate the (de)compression state; errno
+   can be checked to distinguish the two cases (if errno is zero, the
+   zlib error is Z_MEM_ERROR).  */
+
+ZEXTERN gzFile ZEXPORT gzdopen  OF((int fd, const char *mode));
+/*
+     gzdopen() associates a gzFile with the file descriptor fd.  File
+   descriptors are obtained from calls like open, dup, creat, pipe or
+   fileno (in the file has been previously opened with fopen).
+   The mode parameter is as in gzopen.
+     The next call of gzclose on the returned gzFile will also close the
+   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
+   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
+     gzdopen returns NULL if there was insufficient memory to allocate
+   the (de)compression state.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy. See the description
+   of deflateInit2 for the meaning of these parameters.
+     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+   opened for writing.
+*/
+
+ZEXTERN int ZEXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.
+   If the input file was not in gzip format, gzread copies the given number
+   of bytes into the buffer.
+     gzread returns the number of uncompressed bytes actually read (0 for
+   end of file, -1 for error). */
+
+ZEXTERN int ZEXPORT    gzwrite OF((gzFile file, 
+				   const voidp buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes actually written
+   (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORTVA   gzprintf OF((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the args to the compressed file under
+   control of the format string, as in fprintf. gzprintf returns the number of
+   uncompressed bytes actually written (0 in case of error).
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+      Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+      gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+      Reads bytes from the compressed file until len-1 characters are read, or
+   a newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  The string is then terminated with a null
+   character.
+      gzgets returns buf, or Z_NULL in case of error.
+*/
+
+ZEXTERN int ZEXPORT    gzputc OF((gzFile file, int c));
+/*
+      Writes c, converted to an unsigned char, into the compressed file.
+   gzputc returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT    gzgetc OF((gzFile file));
+/*
+      Reads one byte from the compressed file. gzgetc returns this byte
+   or -1 in case of end of file or error.
+*/
+
+ZEXTERN int ZEXPORT    gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file. The parameter
+   flush is as in the deflate() function. The return value is the zlib
+   error number (see function gzerror below). gzflush returns Z_OK if
+   the flush parameter is Z_FINISH and all output could be flushed.
+     gzflush should be called only when strictly necessary because it can
+   degrade compression.
+*/
+
+ZEXTERN z_off_t ZEXPORT    gzseek OF((gzFile file,
+				      z_off_t offset, int whence));
+/* 
+      Sets the starting position for the next gzread or gzwrite on the
+   given compressed file. The offset represents a number of bytes in the
+   uncompressed data stream. The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow. If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+      gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+/*
+     Returns the starting position for the next gzread or gzwrite on the
+   given compressed file. This position represents a number of bytes in the
+   uncompressed data stream.
+
+   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns 1 when EOF has previously been detected reading the given
+   input stream, otherwise zero.
+*/
+
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file
+   and deallocates all the (de)compression state. The return value is the zlib
+   error number (see function gzerror below).
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the
+   given compressed file. errnum is set to zlib error number. If an
+   error occurred in the file system and not in the compression library,
+   errnum is set to Z_ERRNO and the application may consult errno
+   to get the exact error code.
+*/
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the
+   compression library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum. If buf is NULL, this function returns
+   the required initial value for the checksum.
+   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster. Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running crc with the bytes buf[0..len-1] and return the updated
+   crc. If buf is NULL, this function returns the required initial value
+   for the crc. Pre- and post-conditioning (one's complement) is performed
+   within this function so it shouldn't be done by the application.
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
+
+
+#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;}; /* hack for buggy compilers */
+#endif
+
+ZEXTERN const char   * ZEXPORT zError           OF((int err));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp z));
+ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ZLIB_H */
diff --git a/external/zlib/zlib_ogdi.def b/external/zlib/zlib_ogdi.def
new file mode 100644
index 0000000..184a0d4
--- /dev/null
+++ b/external/zlib/zlib_ogdi.def
@@ -0,0 +1,46 @@
+EXETYPE WINDOWS
+CODE		 PRELOAD MOVEABLE DISCARDABLE
+DATA		 PRELOAD MOVEABLE MULTIPLE
+
+EXPORTS
+    adler32                        @1
+    compress                       @2
+    crc32                          @3
+    deflate                        @4
+    deflateCopy                    @5
+    deflateEnd                     @6
+    deflateInit2_                  @7
+    deflateInit_                   @8
+    deflateParams                  @9
+    deflateReset                   @10
+    deflateSetDictionary           @11
+    gzclose                        @12
+    gzdopen                        @13
+    gzerror                        @14
+    gzflush                        @15
+    gzopen                         @16
+    gzread                         @17
+    gzwrite                        @18
+    inflate                        @19
+    inflateEnd                     @20
+    inflateInit2_                  @21
+    inflateInit_                   @22
+    inflateReset                   @23
+    inflateSetDictionary           @24
+    inflateSync                    @25
+    uncompress                     @26
+    zlibVersion                    @27
+    gzprintf                       @28
+    gzputc                         @29
+    gzgetc                         @30
+    gzseek                         @31
+    gzrewind                       @32
+    gztell                         @33
+    gzeof                          @34
+    gzsetparams                    @35
+    zError                         @36
+    inflateSyncPoint               @37
+    get_crc_table                  @38
+    compress2                      @39
+    gzputs                         @40
+    gzgets                         @41
diff --git a/external/zlib/zutil.c b/external/zlib/zutil.c
new file mode 100644
index 0000000..707bfe2
--- /dev/null
+++ b/external/zlib/zutil.c
@@ -0,0 +1,225 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h 
+ */
+
+/* @(#) $Id: zutil.c,v 1.3 2002/03/28 16:05:35 warmerda Exp $ */
+
+#include "zutil.h"
+
+struct internal_state      {int dummy;}; /* for buggy compilers */
+
+#ifndef STDC
+extern void exit OF((int));
+#endif
+
+const char *z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+#ifdef DEBUG
+
+#  ifndef verbose
+#    define verbose 0
+#  endif
+int z_verbose = verbose;
+
+void z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+    int err;
+{
+    return ERR_MSG(err);
+}
+
+
+#ifndef HAVE_MEMCPY
+
+void zmemcpy(dest, source, len)
+    Bytef* dest;
+    const Bytef* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+int zmemcmp(s1, s2, len)
+    const Bytef* s1;
+    const Bytef* s2;
+    uInt  len;
+{
+    uInt j;
+
+    for (j = 0; j < len; j++) {
+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+    }
+    return 0;
+}
+
+void zmemzero(dest, len)
+    Bytef* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+#ifdef __TURBOC__
+#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
+/* Small and medium model in Turbo C are for now limited to near allocation
+ * with reduced MAX_WBITS and MAX_MEM_LEVEL
+ */
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidpf org_ptr;
+    voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    voidpf buf = opaque; /* just to make some compilers happy */
+    ulg bsize = (ulg)items*size;
+
+    /* If we allocate less than 65520 bytes, we assume that farmalloc
+     * will return a usable pointer which doesn't have to be normalized.
+     */
+    if (bsize < 65520L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void  zcfree (voidpf opaque, voidpf ptr)
+{
+    int n;
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    ptr = opaque; /* just to make some compilers happy */
+    Assert(0, "zcfree: ptr not found");
+}
+#endif
+#endif /* __TURBOC__ */
+
+
+#if defined(M_I86) && !defined(__32BIT__)
+/* Microsoft C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    return _halloc((long)items, size);
+}
+
+void  zcfree (voidpf opaque, voidpf ptr)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    _hfree(ptr);
+}
+
+#endif /* MSC */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+voidpf zcalloc (opaque, items, size)
+    voidpf opaque;
+    unsigned items;
+    unsigned size;
+{
+    if (opaque) items += size - size; /* make compiler happy */
+    return (voidpf)calloc(items, size);
+}
+
+void  zcfree (opaque, ptr)
+    voidpf opaque;
+    voidpf ptr;
+{
+    free(ptr);
+    if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
diff --git a/external/zlib/zutil.h b/external/zlib/zutil.h
new file mode 100644
index 0000000..a0aee7a
--- /dev/null
+++ b/external/zlib/zutil.h
@@ -0,0 +1,220 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2002 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id: zutil.h,v 1.3 2002/03/28 16:05:35 warmerda Exp $ */
+
+#ifndef _Z_UTIL_H
+#define _Z_UTIL_H
+
+#include "zlib.h"
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = (char*)ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+#ifdef MSDOS
+#  define OS_CODE  0x00
+#  if defined(__TURBOC__) || defined(__BORLANDC__)
+#    if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+       /* Allow compilation with ANSI keywords only enabled */
+       void _Cdecl farfree( void *block );
+       void *_Cdecl farmalloc( unsigned long nbytes );
+#    else
+#     include <alloc.h>
+#    endif
+#  else /* MSC or DJGPP */
+#    include <malloc.h>
+#  endif
+#endif
+
+#ifdef OS2
+#  define OS_CODE  0x06
+#endif
+
+#ifdef WIN32 /* Window 95 & Windows NT */
+#  define OS_CODE  0x0b
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  0x02
+#  define F_OPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  0x01
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  0x05
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+#  define OS_CODE  0x07
+#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#    include <unix.h> /* for fdopen */
+#  else
+#    ifndef fdopen
+#      define fdopen(fd,mode) NULL /* No fdopen() */
+#    endif
+#  endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+#  define OS_CODE  0x0F
+#endif
+
+#ifdef TOPS20
+#  define OS_CODE  0x0a
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600))
+#  define fdopen(fd,type)  _fdopen(fd,type)
+#endif
+
+
+        /* Common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+#  define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#ifdef HAVE_STRERROR
+   extern char *strerror OF((int));
+#  define zstrerror(errnum) strerror(errnum)
+#else
+#  define zstrerror(errnum) ""
+#endif
+
+#if defined(pyr)
+#  define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+  * You may have to use the same strategy for Borland C (untested).
+  * The __SC__ check is for Symantec.
+  */
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+#    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
+#    define zmemzero(dest, len) _fmemset(dest, 0, len)
+#  else
+#    define zmemcpy memcpy
+#    define zmemcmp memcmp
+#    define zmemzero(dest, len) memset(dest, 0, len)
+#  endif
+#else
+   extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len));
+   extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len));
+   extern void zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  include <stdio.h>
+   extern int z_verbose;
+   extern void z_error    OF((char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+
+typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
+				       uInt len));
+voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
+void   zcfree  OF((voidpf opaque, voidpf ptr));
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+#endif /* _Z_UTIL_H */
diff --git a/lib/win32/lxlib.lib b/lib/win32/lxlib.lib
new file mode 100644
index 0000000..93d0ae0
Binary files /dev/null and b/lib/win32/lxlib.lib differ
diff --git a/makefile b/makefile
index 8c62a03..b23becf 100644
--- a/makefile
+++ b/makefile
@@ -12,6 +12,9 @@
 
 EXTRA_INSTALL_TARGETS	=	mk_nonlocal_install_dirs
 
+ifeq ($(TARGET),win32)
+IGNORE := $(shell sed "s/@OGDI_MAJOR@/3/" < $(TOPDIR)/config/common.mak.in | sed "s/@OGDI_MINOR@/2/" > $(TOPDIR)/config/common.mak)
+endif
 include $(TOPDIR)/config/common.mak
  
 #
diff --git a/ogdi/c-api/client.c b/ogdi/c-api/client.c
index b2f3d81..a1e9eee 100644
--- a/ogdi/c-api/client.c
+++ b/ogdi/c-api/client.c
@@ -18,6 +18,9 @@
  ******************************************************************************
  *
  * $Log: client.c,v $
+ * Revision 1.17  2016/06/28 14:32:45  erouault
+ * Fix all warnings about unused variables raised by GCC 4.8
+ *
  * Revision 1.16  2008/05/28 01:34:30  cbalint
  *    * Convert this file to UTF-8
  *
@@ -65,7 +68,7 @@
 #include "matrix.h"
 #include <assert.h>
 
-ECS_CVSID("$Id: client.c,v 1.16 2008/05/28 01:34:30 cbalint Exp $");
+ECS_CVSID("$Id: client.c,v 1.17 2016/06/28 14:32:45 erouault Exp $");
 
 /* 
    Definitions specific to c_interface 
@@ -2338,7 +2341,6 @@ PJ *cln_ProjInit(d)
      char *d;
 {
   int i,n;
-  int pos;
   char **tableau;
   char *l;
   int longueur;
@@ -2351,7 +2353,6 @@ PJ *cln_ProjInit(d)
   strcpy(c,d);
 
   n=0;
-  pos = 0;
   l = c;
 
   longueur = strlen(c);
@@ -2363,7 +2364,6 @@ PJ *cln_ProjInit(d)
     if (c[i] == ' ') {
       c[i]= '\0';
       tableau[n] = l;
-      pos = i;
       l = &c[i+1];
       if (strncmp(tableau[n],"+",1) == 0) 
 	tableau[n]++;
diff --git a/ogdi/c-api/ecs_dyna.c b/ogdi/c-api/ecs_dyna.c
index b6c30c8..f4245fa 100644
--- a/ogdi/c-api/ecs_dyna.c
+++ b/ogdi/c-api/ecs_dyna.c
@@ -17,6 +17,9 @@
  ******************************************************************************
  *
  * $Log: ecs_dyna.c,v $
+ * Revision 1.6  2016/07/11 09:15:53  erouault
+ * fix ecs_OpenDynamicLib on 64 bit Windows (OGDI #72)
+ *
  * Revision 1.5  2007/02/12 18:06:31  cbalint
  *         Hide plugins from system libs path.
  *         Release versioning using sonames.
@@ -31,7 +34,7 @@
 
 #include "ecs.h"
 
-ECS_CVSID("$Id: ecs_dyna.c,v 1.5 2007/02/12 18:06:31 cbalint Exp $");
+ECS_CVSID("$Id: ecs_dyna.c,v 1.6 2016/07/11 09:15:53 erouault Exp $");
 
 #if !defined(MISSING_DLFCN_H)
 #include <dlfcn.h>
@@ -61,7 +64,7 @@ void *ecs_OpenDynamicLib(libname)
   static HINSTANCE handle;
 
   handle = LoadLibrary(libname);
-  if ((int) handle <= (int) HINSTANCE_ERROR) {
+  if (handle == NULL) {
     /* Try with the .dll extension */
 
     if ((temp = (char *) malloc(strlen(libname)+5)) == NULL)
@@ -71,7 +74,7 @@ void *ecs_OpenDynamicLib(libname)
         
     handle = LoadLibrary(temp);
     free(temp);
-    if ((int) handle <= (int) HINSTANCE_ERROR) {
+    if (handle == NULL) {
       return NULL;
     } else {
       return (void *) handle;
diff --git a/ogdi/c-api/ecsassoc.c b/ogdi/c-api/ecsassoc.c
index 129e93c..9dc08da 100644
--- a/ogdi/c-api/ecsassoc.c
+++ b/ogdi/c-api/ecsassoc.c
@@ -18,6 +18,24 @@
  ******************************************************************************
  *
  * $Log: ecsassoc.c,v $
+ * Revision 1.6  2016/07/06 08:59:46  erouault
+ * ecs_SetError(): display error message on stderr if memory allocation fails
+ *
+ * Revision 1.5  2016/07/04 17:33:49  erouault
+ * Also export ecs_ShouldStopOnError and ecs_SetErrorShouldStop on Windows
+ *
+ * Revision 1.4  2016/07/04 17:03:12  erouault
+ * Error handling: Add a ecs_SetErrorShouldStop() function that can be
+ *     used internally when the code is able to recover from an error. The user
+ *     may decide if he wants to be resilient on errors by defining OGDI_STOP_ON_ERROR=NO
+ *     as environment variable (the default being YES: stop on error).
+ *     Add a ecs_SetReportErrorFunction() method to install a custom callback that
+ *     will be called when OGDI_STOP_ON_ERROR=YES so that the user code is still
+ *     aware of errors that occured. If not defined, the error will be logged in stderr.
+ *
+ * Revision 1.3  2016/06/28 14:32:45  erouault
+ * Fix all warnings about unused variables raised by GCC 4.8
+ *
  * Revision 1.2  2001/04/09 15:04:34  warmerda
  * applied new source headers
  *
@@ -25,7 +43,7 @@
 
 #include "ecs.h"
 
-ECS_CVSID("$Id: ecsassoc.c,v 1.2 2001/04/09 15:04:34 warmerda Exp $");
+ECS_CVSID("$Id: ecsassoc.c,v 1.6 2016/07/06 08:59:46 erouault Exp $");
 
 char memory_error[] = "not enough memory";
 
@@ -99,7 +117,10 @@ int ecs_SetError (r,errorcode,error_message)
   } else {
     r->message = (char *) malloc(strlen(error_message)+1);
     if (r->message == NULL)
+    {
+      fprintf(stderr, "Not enough memory in ecs_SetError(): %s\n", error_message); 
       return FALSE;
+    }
     strcpy(r->message,error_message);
   }
 
@@ -108,6 +129,83 @@ int ecs_SetError (r,errorcode,error_message)
   return TRUE;
 }
 
+/************************************************************************/
+/*                     ecs_ShouldStopOnError()                          */
+/************************************************************************/
+
+int ecs_ShouldStopOnError()
+{
+    const char* pszStopOnError = getenv("OGDI_STOP_ON_ERROR");
+    if( pszStopOnError == NULL )
+        return TRUE;
+    if( strcmp(pszStopOnError, "yes") == 0 ||
+        strcmp(pszStopOnError, "YES") == 0 )
+    {
+         return TRUE;
+    }
+    else if( strcmp(pszStopOnError, "no") == 0 ||
+             strcmp(pszStopOnError, "NO") == 0 )
+    {
+         return FALSE;
+    }
+    else
+    {
+         fprintf(stderr, "Unhandled value for OGDI_STOP_ON_ERROR = %s. "
+                         "Considering it is YES\n",
+                         pszStopOnError);
+         return TRUE;
+    }
+}
+
+/************************************************************************/
+/*                     ecs_ShouldStopOnError()                            */
+/************************************************************************/
+
+static int ecs_DefaultReportError(int errorcode, const char *error_message)
+{
+    fprintf(stderr, "Error %d: %s\n", errorcode, error_message);
+    return FALSE; /* go on */
+}
+
+/************************************************************************/
+/*                   ecs_SetReportErrorFunction()                       */
+/************************************************************************/
+
+static ReportErrorType pfnReportError = ecs_DefaultReportError;
+
+/* Installs a custom error handler and returns the previous one */
+ReportErrorType ecs_SetReportErrorFunction(ReportErrorType pfn)
+{
+    ReportErrorType oldErrorFunc = pfnReportError;
+    pfnReportError = pfn;
+    return oldErrorFunc;
+}
+
+/************************************************************************/
+/*                       ecs_SetErrorShouldStop()                       */
+/************************************************************************/
+
+/* ecs_SetErrorShouldStop() is a variant of ecs_SetError() that can be used */
+/* when the error can be recovered. By default it will be considered as non */
+/* recoverable, and thus return TRUE, and regular ecs_SetError() will be used. */
+/* But the user may have  installed its own error handler with */
+/* ecs_SetReportErrorFunction() and decide of the appropriate behaviour */
+int ecs_SetErrorShouldStop (r,errorcode,error_message)
+     ecs_Result *r;
+     int errorcode;
+     char *error_message;
+{
+  if( ecs_ShouldStopOnError() )
+  {
+      ecs_SetError(r,errorcode,error_message);
+      return TRUE;
+  }
+  else
+  {
+      return pfnReportError(errorcode,error_message);
+  }
+}
+
 /*
    ----------------------------------------------------------------------
 
@@ -1460,12 +1558,10 @@ ecs_CopyResultFromUnion(source,copy)
      ecs_Result **copy;
 {
   int returncode;
-  ecs_Object *obj;
   ecs_Result *result;
 
   returncode = TRUE;
   if (source->type == Object) {
-    obj = &(source->ecs_ResultUnion_u.dob);
 
     /* Allocate the new object */
 
diff --git a/ogdi/c-api/matrix.c b/ogdi/c-api/matrix.c
index 59f459d..c2d734b 100644
--- a/ogdi/c-api/matrix.c
+++ b/ogdi/c-api/matrix.c
@@ -7,6 +7,7 @@
  ******************************************************************************
  */
 #include <math.h>
+#include <stdlib.h>
 
 #include "ecs.h"
 #include "matrix.h"
@@ -91,9 +92,23 @@ void mat_mul_transposed (matrix_a, height_a, width_a, matrix_b, height_b, width_
 int mat_inverse (double **matrix,int n)
 {
     int i, j, k, l, ir=0, ic=0 ;
-    int ipivot[n], itemp[n][2];
-    double pivot[n], t;
-    double fabs();
+    int* ipivot;
+    int* itemp_0;
+    int* itemp_1;
+    double* pivot;
+    double t;
+    int ret = 1;
+
+    ipivot = (int*) malloc( n * sizeof(int) );
+    itemp_0 = (int*) malloc( n * sizeof(int) );
+    itemp_1 = (int*) malloc( n * sizeof(int) );
+    pivot = (double*) malloc( n * sizeof(double) );
+    if( ipivot == NULL || itemp_0 == NULL || itemp_1 == NULL || pivot == NULL )
+    {
+        fprintf(stderr, "Memory allocation failure in mat_inverse(). \n");
+        ret = -1;
+        goto end;
+    }
 
     /* initialization */
     for (i = 0; i < n; i++)
@@ -122,19 +137,22 @@ int mat_inverse (double **matrix,int n)
                         }
                         break;
                     case  1:
-                        return (-1);
+                        ret = -1;
+                        goto end;
                         break;
                     default: /* shouldn't get here */
-                        return (-1);
+                        ret = -1;
+                        goto end;
                         break;
                 }
         }
 
         ipivot[ic] += 1;
         if (ipivot[ic] > 1) /* check for dependency */
-                {
-            return (-1);
-                }
+        {
+            ret = -1;
+            goto end;
+        }
 
         /* interchange rows to put pivot element on diagonal */
         if (ir != ic)
@@ -145,15 +163,16 @@ int mat_inverse (double **matrix,int n)
                 matrix[ic][l] = t;
             }
 
-        itemp[i][0] = ir;
-        itemp[i][1] = ic;
+        itemp_0[i] = ir;
+        itemp_1[i] = ic;
         pivot[i] = matrix[ic][ic];
 
         /* check for zero pivot */
         if (fabs (pivot[i]) < EPSILON)
-                {
-            return (-1);
-                }
+        {
+            ret = -1;
+            goto end;
+        }
 
         /* divide pivot row by pivot element */
         matrix[ic][ic] = 1.0;
@@ -177,11 +196,11 @@ int mat_inverse (double **matrix,int n)
     for (i = 0; i < n; i++)
     {
         l = n - i - 1;
-        if (itemp[l][0] == itemp[l][1])
+        if (itemp_0[l] == itemp_1[l])
             continue;
 
-        ir = itemp[l][0];
-        ic = itemp[l][1];
+        ir = itemp_0[l];
+        ic = itemp_1[l];
 
         for (k = 0; k < n; k++)
         {
@@ -191,7 +210,12 @@ int mat_inverse (double **matrix,int n)
         }
     }
 
-    return 1;
+end:
+    free(ipivot);
+    free(itemp_0);
+    free(itemp_1);
+    free(pivot);
+    return ret;
 }
 
 /*
diff --git a/ogdi/c-api/ogdi.def b/ogdi/c-api/ogdi.def
index 0a59ede..8caaf91 100644
--- a/ogdi/c-api/ogdi.def
+++ b/ogdi/c-api/ogdi.def
@@ -153,3 +153,6 @@ EXPORTS
 	cln_LoadCapabilities
 	ecs_GetRGBFromPixel
 	ecs_GetPixelFromRGB
+	ecs_SetReportErrorFunction
+	ecs_ShouldStopOnError
+	ecs_SetErrorShouldStop
diff --git a/ogdi/c-api/server.c b/ogdi/c-api/server.c
index 790778f..bf1a4c0 100644
--- a/ogdi/c-api/server.c
+++ b/ogdi/c-api/server.c
@@ -17,6 +17,15 @@
  ******************************************************************************
  *
  * $Log: server.c,v $
+ * Revision 1.12  2016/07/06 08:59:20  erouault
+ * fix memory leaks in error code paths of svr_CreateServer()
+ *
+ * Revision 1.11  2016/06/28 14:32:45  erouault
+ * Fix all warnings about unused variables raised by GCC 4.8
+ *
+ * Revision 1.10  2016/06/27 20:05:12  erouault
+ * Grow some buffers in VRF driver (patch by Craig Bruce)
+ *
  * Revision 1.9  2007/02/12 21:01:48  cbalint
  *      Fix win32 target. It build and works now. (tested with VC6)
  *
@@ -54,7 +63,7 @@
 
 #include <ogdi_macro.h>
 
-ECS_CVSID("$Id: server.c,v 1.9 2007/02/12 21:01:48 cbalint Exp $");
+ECS_CVSID("$Id: server.c,v 1.12 2016/07/06 08:59:20 erouault Exp $");
 
 ecs_Result svr_dummy_result;
 
@@ -240,14 +249,19 @@ ecs_Result *svr_CreateServer(s,url,isLocal)
 
   /* if the script driver is not found, then return error message */
   if (s->handle == NULL) {
-    res = &svr_dummy_result;
     sprintf(buffer,"Could not find the dynamic library \"%s\"",s->server_type);
+    svr_DestroyServer(s);
+
+    res = &svr_dummy_result;
     ecs_SetError(res,1,buffer);
+
     return res;
   }
 
   s->createserver = (dynfunc *) ecs_GetDynamicLibFunction(s->handle,"dyn_CreateServer");
   if (s->createserver == NULL) {
+    svr_DestroyServer(s);
+
     res = &svr_dummy_result;
     ecs_SetError(res,1,svr_messages[4]);
     return res;
@@ -285,14 +299,18 @@ ecs_Result *svr_CreateServer(s,url,isLocal)
     return res;
     }
   if (res->error) {
+    char* saved_message = res->message;
+    res->message = NULL;
+    svr_DestroyServer(s);
     msg = &svr_dummy_result;
-    ecs_SetError(msg,1,res->message);
+    ecs_SetError(msg,1,saved_message);
+    free(saved_message);
 
 /*    if (s->isRemote || (s->hostname == NULL))
       ecs_CloseDynamicLib(s->handle);
 */
 
-    ecs_freeSplitURL(&(s->hostname),&(s->server_type),&(s->pathname));
+    /*ecs_freeSplitURL(&(s->hostname),&(s->server_type),&(s->pathname));*/
     return msg;
   }
 
@@ -357,6 +375,7 @@ ecs_Result *svr_DestroyServer(s)
   ecs_SetSuccess(msg);
 
   s->priv = NULL;
+  s->url = NULL;
   s->projection = NULL;
   s->hostname = NULL;
   s->server_type = NULL;
@@ -398,6 +417,7 @@ ecs_Result *svr_DestroyServer(s)
 
   if (s->rasterconversion.coef.coef_val != NULL)
     free(s->rasterconversion.coef.coef_val);
+  s->rasterconversion.coef.coef_val = NULL;
   
   if (s->layer != NULL) {
     free(s->layer);
@@ -882,10 +902,8 @@ GetOneNextObjectAttributes(s, msg, isSelected)
   char *error;
   short objSelected;
   char *temp,*attributes;
-  ecs_Family family;
 
   *isSelected = FALSE;
-  family = s->layer[s->currentLayer].sel.F;
   attribute_qty = s->layer[s->currentLayer].SelectionAttributeListQty;
 
   /* 
@@ -1973,7 +1991,11 @@ void ecs_FreeLayer(s,layer)
       free(s->layer);
       s->layer = NULL;
     } else {
-      s->layer = realloc(s->layer,sizeof(ecs_Layer)*s->layer_tablesize);
+      ecs_Layer* newlayer = realloc(s->layer,sizeof(ecs_Layer)*s->layer_tablesize);
+      if( newlayer != NULL )
+      {
+        s->layer = newlayer;
+      }
     }
   }
 
@@ -2611,7 +2633,7 @@ int ecs_ExtractRequestInformation(request,ExtractRequest,DriverType,InformationS
      char **AutorizationDescription;
      char **SelectionRequest;
 {
-  int count,i,j;
+  int count,i;
   char *temp,*ptr;
   char character[2];
   int candlist[13];
@@ -2625,11 +2647,10 @@ int ecs_ExtractRequestInformation(request,ExtractRequest,DriverType,InformationS
 
   /* Convert /SPACE/ to ' ' */
 
-  temp = malloc(strlen(request)+1);
+  temp = malloc(strlen(request)+4);
   if (temp == NULL) 
     return 5;
 
-  j=0;
   strcpy(temp,"");
   for(i=0,ptr = request;i<(int) strlen(request);i++,ptr++) {
     if(strncmp(ptr,"/SPACE/",7) == 0) {
@@ -3041,10 +3062,8 @@ int ecs_ReleaseAttributeQuery(s,l,error)
      ecs_Layer *l;
      char **error;
 {
-  int code = 0;
-
   if (l->AttributeDriverHandle != NULL) {
-    code = (l->DeinitializeDBLinkFuncPtr)(s,l,error);
+    (l->DeinitializeDBLinkFuncPtr)(s,l,error);
     ecs_CloseDynamicLib(l->AttributeDriverHandle);
     l->AttributeDriverHandle = NULL;
   }
@@ -3391,5 +3410,5 @@ SetBindListForMatrixError:
       free(attribute_list[i]);
   free(attribute_list);
   *error = svr_messages[5];
-  return 1;
+  return code;
 }
diff --git a/ogdi/datum_driver/usa/dtusa.c b/ogdi/datum_driver/usa/dtusa.c
index ed84906..5bea726 100644
--- a/ogdi/datum_driver/usa/dtusa.c
+++ b/ogdi/datum_driver/usa/dtusa.c
@@ -124,7 +124,11 @@ int dyn_nad_init(privdata, table)
     strcat(pathfile,"/");  
     strcat(pathfile,table);  
 
+#if PJ_VERSION >= 480
+    ptr->dtptr = nad_init(pj_get_default_ctx(), pathfile);
+#else
     ptr->dtptr = nad_init(pathfile);
+#endif
     if (ptr->dtptr == NULL) {
       ptr->count--;
       return FALSE;
diff --git a/ogdi/driver/adrg/adrg.c b/ogdi/driver/adrg/adrg.c
index 1555441..a217b2a 100644
--- a/ogdi/driver/adrg/adrg.c
+++ b/ogdi/driver/adrg/adrg.c
@@ -17,6 +17,9 @@
  ******************************************************************************
  *
  * $Log: adrg.c,v $
+ * Revision 1.10  2016/06/27 22:01:46  erouault
+ * Fix memory leak in ADRG driver
+ *
  * Revision 1.9  2007/02/12 16:09:06  cbalint
  *   *  Add hook macros for all GNU systems, hook fread,fwrite,read,fgets.
  *   *  Handle errors in those macro, if there are any.
@@ -55,7 +58,7 @@
 #include "datadict.h"
 #include <assert.h>
 
-ECS_CVSID("$Id: adrg.c,v 1.9 2007/02/12 16:09:06 cbalint Exp $");
+ECS_CVSID("$Id: adrg.c,v 1.10 2016/06/27 22:01:46 erouault Exp $");
 
 static void	_releaseAllLayers _ANSI_ARGS_((ecs_Server *s));
 int colorintensity[6] = {0,63,105,147,189,255};
@@ -314,6 +317,8 @@ void _freelayerpriv(lpriv)
   if (lpriv != NULL) {
     if (lpriv->tilelist != NULL)
       free(lpriv->tilelist);
+    if (lpriv->buffertile != NULL)
+      free(lpriv->buffertile);
     if (lpriv->imgfile != NULL)
       fclose(lpriv->imgfile);
     
diff --git a/ogdi/driver/adrg/object.c b/ogdi/driver/adrg/object.c
index 43ce89b..288e8cd 100644
--- a/ogdi/driver/adrg/object.c
+++ b/ogdi/driver/adrg/object.c
@@ -17,6 +17,9 @@
  ******************************************************************************
  *
  * $Log: object.c,v $
+ * Revision 1.7  2016/06/28 14:32:45  erouault
+ * Fix all warnings about unused variables raised by GCC 4.8
+ *
  * Revision 1.6  2007/02/12 16:09:06  cbalint
  *   *  Add hook macros for all GNU systems, hook fread,fwrite,read,fgets.
  *   *  Handle errors in those macro, if there are any.
@@ -42,7 +45,7 @@
 #include "ecs.h"
 #include "adrg.h"
 
-ECS_CVSID("$Id: object.c,v 1.6 2007/02/12 16:09:06 cbalint Exp $");
+ECS_CVSID("$Id: object.c,v 1.7 2016/06/28 14:32:45 erouault Exp $");
 
 /*
  *  --------------------------------------------------------------------------
@@ -199,7 +202,8 @@ void _getNextObjectRaster(s,l)
   char buffer[128];
   static int UseOverview;
 
-  int totalcol,totalrow;
+  int totalcol;
+  /*int totalrow;*/
   int value;
   double pos;
 
@@ -211,7 +215,7 @@ void _getNextObjectRaster(s,l)
   _LoadADRGTiles(s,l,&UseOverview);
 
   totalcol = (int) ((s->currentRegion.east - s->currentRegion.west)/s->currentRegion.ew_res);
-  totalrow = (int) ((s->currentRegion.north - s->currentRegion.south)/s->currentRegion.ns_res);
+  /*totalrow = (int) ((s->currentRegion.north - s->currentRegion.south)/s->currentRegion.ns_res);*/
   ecs_SetGeomMatrix(&(s->result),totalcol);
 
   if (s->rasterconversion.isProjEqual) {
@@ -253,7 +257,8 @@ _getObjectRaster(s,l,id)
 {
   int i,i2,j2;
   char buffer[128];
-  int totalcol,totalrow;
+  int totalcol;
+  /*int totalrow;*/
   int value;
   int index;
   double pos;
@@ -266,7 +271,7 @@ _getObjectRaster(s,l,id)
   }
 
   totalcol = (int) ((s->currentRegion.east - s->currentRegion.west)/s->currentRegion.ew_res);
-  totalrow = (int) ((s->currentRegion.north - s->currentRegion.south)/s->currentRegion.ns_res);
+  /*totalrow = (int) ((s->currentRegion.north - s->currentRegion.south)/s->currentRegion.ns_res);*/
   ecs_SetGeomMatrix(&(s->result),totalcol);
 
   if (s->rasterconversion.isProjEqual) {
@@ -485,7 +490,8 @@ void _getNextObjectImage(s,l)
   char buffer[128];
   static int UseOverview;
 
-  int totalcol,totalrow;
+  int totalcol;
+  /*int totalrow;*/
   int value;
   double pos;
 
@@ -497,7 +503,7 @@ void _getNextObjectImage(s,l)
   _LoadADRGTiles(s,l,&UseOverview);
 
   totalcol = (int) ((s->currentRegion.east - s->currentRegion.west)/s->currentRegion.ew_res);
-  totalrow = (int) ((s->currentRegion.north - s->currentRegion.south)/s->currentRegion.ns_res);
+  /*totalrow = (int) ((s->currentRegion.north - s->currentRegion.south)/s->currentRegion.ns_res);*/
   ecs_SetGeomImage(&(s->result),totalcol);
 
   if (s->rasterconversion.isProjEqual) {
@@ -539,7 +545,8 @@ _getObjectImage(s,l,id)
 {
   int i,i2,j2;
   char buffer[128];
-  int totalcol,totalrow;
+  int totalcol;
+  /*int totalrow;*/
   int value;
   int index;
   double pos;
@@ -552,7 +559,7 @@ _getObjectImage(s,l,id)
   }
 
   totalcol = (int) ((s->currentRegion.east - s->currentRegion.west)/s->currentRegion.ew_res);
-  totalrow = (int) ((s->currentRegion.north - s->currentRegion.south)/s->currentRegion.ns_res);
+  /*totalrow = (int) ((s->currentRegion.north - s->currentRegion.south)/s->currentRegion.ns_res);*/
   ecs_SetGeomImage(&(s->result),totalcol);
 
   if (s->rasterconversion.isProjEqual) {
diff --git a/ogdi/driver/adrg/utils.c b/ogdi/driver/adrg/utils.c
index e2e4a22..024e52e 100644
--- a/ogdi/driver/adrg/utils.c
+++ b/ogdi/driver/adrg/utils.c
@@ -17,6 +17,9 @@
  ******************************************************************************
  *
  * $Log: utils.c,v $
+ * Revision 1.8  2016/06/28 14:32:45  erouault
+ * Fix all warnings about unused variables raised by GCC 4.8
+ *
  * Revision 1.7  2007/02/12 16:09:06  cbalint
  *   *  Add hook macros for all GNU systems, hook fread,fwrite,read,fgets.
  *   *  Handle errors in those macro, if there are any.
@@ -45,7 +48,7 @@
 
 #include "adrg.h"
 
-ECS_CVSID("$Id: utils.c,v 1.7 2007/02/12 16:09:06 cbalint Exp $");
+ECS_CVSID("$Id: utils.c,v 1.8 2016/06/28 14:32:45 erouault Exp $");
 
 /* 
    ----------------------------------------------------------
@@ -270,7 +273,7 @@ int _read_overview(s)
   register ServerPrivateData *spriv = s->priv;
   register LayerPrivateData *lpriv = (LayerPrivateData *) &(spriv->overview);
   FILE *fichier;
-  int first;
+  /*int first;*/
   char c,sc[4];
   char buffer[20];
   int i,j,count;
@@ -291,7 +294,7 @@ int _read_overview(s)
     if (c==(char) 30) {
       ogdi_fread(sc,3,1,fichier);
       if(strncmp("OVV",sc,3) == 0) {
-	first = TRUE;
+	/*first = TRUE;*/
 
 	/* Jump ^^ et PRT */
 
diff --git a/ogdi/driver/dted/object.c b/ogdi/driver/dted/object.c
index f318bba..497b84c 100644
--- a/ogdi/driver/dted/object.c
+++ b/ogdi/driver/dted/object.c
@@ -17,6 +17,9 @@
  ******************************************************************************
  *
  * $Log: object.c,v $
+ * Revision 1.8  2016/06/28 14:32:45  erouault
+ * Fix all warnings about unused variables raised by GCC 4.8
+ *
  * Revision 1.7  2007/02/12 15:52:57  cbalint
  *
  *    Preliminary cleanup.
@@ -36,7 +39,7 @@
 #include "ecs.h"
 #include "dted.h"
 
-ECS_CVSID("$Id: object.c,v 1.7 2007/02/12 15:52:57 cbalint Exp $");
+ECS_CVSID("$Id: object.c,v 1.8 2016/06/28 14:32:45 erouault Exp $");
 
 /*
  *  --------------------------------------------------------------------------
@@ -54,7 +57,7 @@ void _getNextObjectRaster(s,l)
   ServerPrivateData *spriv = s->priv;
   ecs_Coordinate start, end;
   double pos_y;
-  double record_y;
+  /*double record_y;*/
 
   if (l->index >= l->nbfeature) {
     ecs_SetError(&(s->result),2,"End of selection");
@@ -65,7 +68,7 @@ void _getNextObjectRaster(s,l)
   pos_y = s->currentRegion.north - (l->index+0.5) * s->currentRegion.ns_res;  
 
   /* get the corresponding point from the global region's matrix */
-  record_y = (int) ((s->globalRegion.north-pos_y) / s->globalRegion.ns_res);
+  /*record_y = (int) ((s->globalRegion.north-pos_y) / s->globalRegion.ns_res);*/
   
   start.x=s->currentRegion.west;
   end.x=s->currentRegion.east;
diff --git a/ogdi/driver/dted/utils.c b/ogdi/driver/dted/utils.c
index 621b33c..3cdedc8 100644
--- a/ogdi/driver/dted/utils.c
+++ b/ogdi/driver/dted/utils.c
@@ -17,6 +17,9 @@
  ******************************************************************************
  *
  * $Log: utils.c,v $
+ * Revision 1.8  2016/06/28 14:32:45  erouault
+ * Fix all warnings about unused variables raised by GCC 4.8
+ *
  * Revision 1.7  2007/02/12 15:52:57  cbalint
  *
  *    Preliminary cleanup.
@@ -32,7 +35,7 @@
 
 #include "dted.h"
 
-ECS_CVSID("$Id: utils.c,v 1.7 2007/02/12 15:52:57 cbalint Exp $");
+ECS_CVSID("$Id: utils.c,v 1.8 2016/06/28 14:32:45 erouault Exp $");
 
 /* 
    ----------------------------------------------------------
@@ -429,14 +432,12 @@ _verifyLocation(s)
      ecs_Server *s;
 {
   int returnvalue;
-  int lenght;
   DIR *dirlist;
   FILE *test;
   ServerPrivateData *spriv = s->priv;
   char *ptr,*ptr1,*ptr2;
 
   returnvalue = FALSE;
-  lenght = strlen(spriv->pathname);
   /* Check if the path is valid */
   dirlist = opendir(spriv->pathname);
   if (dirlist != NULL) {
diff --git a/ogdi/driver/rpf/rpf.c b/ogdi/driver/rpf/rpf.c
index 9f0ebb0..58a3f5a 100644
--- a/ogdi/driver/rpf/rpf.c
+++ b/ogdi/driver/rpf/rpf.c
@@ -17,6 +17,9 @@
  ******************************************************************************
  *
  * $Log: rpf.c,v $
+ * Revision 1.14  2016/07/08 10:22:55  erouault
+ * Fix various compilation problems on Windows (contributed by Jerome Siot)
+ *
  * Revision 1.13  2007/02/24 16:58:17  cbalint
  *     Clear olso tilestruct while freeing memory in dyn_freelayerpriv()
  *     glibc mtrace() reports zero malloc problems now.
@@ -51,7 +54,7 @@
 #include "rpf.h"
 #include "datadict.h"
 
-ECS_CVSID("$Id: rpf.c,v 1.13 2007/02/24 16:58:17 cbalint Exp $");
+ECS_CVSID("$Id: rpf.c,v 1.14 2016/07/08 10:22:55 erouault Exp $");
 
 int colorintensity[6] = {0,63,105,147,189,255};
 
@@ -179,8 +182,11 @@ void dyn_freelayerpriv(lpriv)
       lpriv->buffertile = NULL;
     }
     
+#ifdef notdef
+   /* FIXME? ecs_TileDeleteAllLines does not exist */
    /* empty tilestruct */
    ecs_TileDeleteAllLines (&(lpriv->tilestruct));
+#endif
     
     if (lpriv->ff != NULL) 
       free(lpriv->ff);
diff --git a/ogdi/driver/rpf/utils.c b/ogdi/driver/rpf/utils.c
index 468dfb0..966c7b7 100644
--- a/ogdi/driver/rpf/utils.c
+++ b/ogdi/driver/rpf/utils.c
@@ -17,6 +17,9 @@
  ******************************************************************************
  *
  * $Log: utils.c,v $
+ * Revision 1.10  2016/06/28 14:32:45  erouault
+ * Fix all warnings about unused variables raised by GCC 4.8
+ *
  * Revision 1.9  2007/02/12 16:09:06  cbalint
  *   *  Add hook macros for all GNU systems, hook fread,fwrite,read,fgets.
  *   *  Handle errors in those macro, if there are any.
@@ -48,7 +51,7 @@
 
 #include "rpf.h"
 
-ECS_CVSID("$Id: utils.c,v 1.9 2007/02/12 16:09:06 cbalint Exp $");
+ECS_CVSID("$Id: utils.c,v 1.10 2016/06/28 14:32:45 erouault Exp $");
 
 void dyn_string_tolower(char *);
 
@@ -435,8 +438,8 @@ int dyn_read_rpftile(s, l, tile_row, tile_col)
     int tile_row;
     int tile_col;
 {
-  double origin_lon, origin_lat;
-  double lat_spacing, lon_spacing;
+  /*double origin_lon, origin_lat;*/
+  /*double lat_spacing, lon_spacing;*/
   register LayerPrivateData *lpriv = (LayerPrivateData *) l->priv;
   int i,j,k;
   char *framefile;
@@ -522,10 +525,10 @@ int dyn_read_rpftile(s, l, tile_row, tile_col)
     return FALSE; 
   }
 
-  origin_lat = lpriv->ff->cover.nw_lat  - 1536.E0*lpriv->ff->cover.vert_interval;
-  origin_lon = lpriv->ff->cover.nw_long + 1536.E0*lpriv->ff->cover.horiz_interval;
-  lon_spacing = lpriv->ff->cover.horiz_interval;
-  lat_spacing = lpriv->ff->cover.vert_interval;
+  /*origin_lat = lpriv->ff->cover.nw_lat  - 1536.E0*lpriv->ff->cover.vert_interval;
+  origin_lon = lpriv->ff->cover.nw_long + 1536.E0*lpriv->ff->cover.horiz_interval;*/
+  /*lon_spacing = lpriv->ff->cover.horiz_interval;
+  lat_spacing = lpriv->ff->cover.vert_interval;*/
   
   lpriv->columns = 1536L;
   lpriv->rows = 1536L;
@@ -600,7 +603,6 @@ dyn_verifyLocation(s)
      ecs_Server *s;
 {
   int returnvalue;
-  int lenght;
   DIR *dirlist;
   FILE *test;
   register ServerPrivateData *spriv = s->priv;
@@ -608,7 +610,6 @@ dyn_verifyLocation(s)
 
   returnvalue = FALSE;
 
-  lenght = strlen(spriv->pathname);
   /* Check if the path is valid */
   dirlist = opendir(spriv->pathname);
   if (dirlist != NULL) {
@@ -2074,7 +2075,6 @@ uchar      blackpixel;
   uint  val;
   int  index;
   int  offset;
-  int  cc;
   char  string[256];
   register ServerPrivateData *spriv = (ServerPrivateData *) s->priv;
   
@@ -2110,17 +2110,19 @@ uchar      blackpixel;
  /* Seek to start of subframe */
 
   offset = file->loc_data + tno;
-  cc = fseek(fin, offset, SEEK_SET);
+  fseek(fin, offset, SEEK_SET);
 
  /* Read the subframe */
 
-  cc = fread(subframe, 1, 6144, fin);
+  if( fread(subframe, 1, 6144, fin) != 6144 )
+  {
+    fclose(fin);
+    free(subframe);
+    return FALSE;
+  }
   fclose(fin);
 
- /* This should never occur since all subframes should be present */
-
-  if ((ptr = subframe) == NULL)
-    return FALSE;
+  ptr = subframe;
 
  /* Decompress the tile */
 
diff --git a/ogdi/driver/skeleton/object.c b/ogdi/driver/skeleton/object.c
index 65e6ae9..c76d936 100644
--- a/ogdi/driver/skeleton/object.c
+++ b/ogdi/driver/skeleton/object.c
@@ -920,6 +920,7 @@ _getObjectIdPoint(s,l,coord)
 
   firstobj = TRUE;
   index = 0;
+  distance = 0.0;
   
   position = -1;
       
@@ -1169,6 +1170,7 @@ _getObjectIdText(s,l,coord)
 
   firstobj = TRUE;
   index = 0;
+  distance = 0.0;
   
   position = -1;
       
diff --git a/ogdi/driver/skeleton/skeleton.c b/ogdi/driver/skeleton/skeleton.c
index 618a420..267b0b5 100644
--- a/ogdi/driver/skeleton/skeleton.c
+++ b/ogdi/driver/skeleton/skeleton.c
@@ -383,7 +383,6 @@ ecs_Result *dyn_SelectLayer(s,sel)
      ecs_LayerSelection *sel;
 {
   int layer;
-  register LayerPrivateData *lpriv;
   char buffer[100];
 
   /* 
@@ -430,7 +429,6 @@ ecs_Result *dyn_SelectLayer(s,sel)
     ecs_SetError(&(s->result),1,"Not enough memory to allocate layer private data");
     return &(s->result);	
   }
-  lpriv = (LayerPrivateData *) s->layer[layer].priv;
 
   /* 
      At this point, you could prepare the information related to the
diff --git a/ogdi/driver/vrf/feature.c b/ogdi/driver/vrf/feature.c
index 36020cb..56452cd 100644
--- a/ogdi/driver/vrf/feature.c
+++ b/ogdi/driver/vrf/feature.c
@@ -17,6 +17,18 @@
  ******************************************************************************
  *
  * $Log: feature.c,v $
+ * Revision 1.20  2016/07/06 09:00:14  erouault
+ * add heuristics in vrf_get_ring_coords() to detect cycling topology of edges that lead to endless looping and eventually crashes. Be robust to memory allocation failures in various places, and properly cleanup allocated structures when returning
+ *
+ * Revision 1.19  2016/06/28 14:32:45  erouault
+ * Fix all warnings about unused variables raised by GCC 4.8
+ *
+ * Revision 1.18  2016/06/27 20:05:12  erouault
+ * Grow some buffers in VRF driver (patch by Craig Bruce)
+ *
+ * Revision 1.17  2009/05/08 04:15:50  warmerda
+ * fixed count type in VRF driver for 64bit systems (#2787502)
+ *
  * Revision 1.16  2007/05/09 20:46:28  cbalint
  * From: Even Rouault <even.rouault at mines-paris.org>
  * Date: Friday 21:14:18
@@ -106,7 +118,7 @@
 #include "vrf.h"
 #include <assert.h>
 
-ECS_CVSID("$Id: feature.c,v 1.16 2007/05/09 20:46:28 cbalint Exp $");
+ECS_CVSID("$Id: feature.c,v 1.20 2016/07/06 09:00:14 erouault Exp $");
 
 vpf_projection_type NOPROJ = {DDS, 0.0, 0.0, 0.0, 0.0, 0, 0.0, 0.0,
                               NULL, NULL, "Decimal Degrees     "};
@@ -260,7 +272,14 @@ int vrf_get_merged_line_feature (s, layer, primCount, primList)
     {
         if( !vrf_get_line_feature( s, layer, primList[iPrim],
                                    primResults+iPrim ) )
-            return FALSE; /* is it worth cleaning up? */
+        {
+            for( ; iPrim >=0; iPrim-- )
+                ecs_CleanUp( primResults + iPrim );
+
+            free( primResults );
+            ecs_SetError(&(s->result), 1,"Error in vrf_get_merged_line_feature");
+            return FALSE;
+        }
 
         maxVertCount += ECSGEOM((primResults+iPrim)).line.c.c_len;
     }
@@ -425,6 +444,8 @@ int vrf_get_line_feature (s, layer, prim_id, result)
     break;
   default:
     ecs_SetError(result, 2, "Undefined VRF table type");
+    free_row(row,lpriv->l.line.edgeTable);
+    return FALSE;
   }
 
   free_row(row,lpriv->l.line.edgeTable);
@@ -453,6 +474,11 @@ int vrf_get_line_feature (s, layer, prim_id, result)
     {
       if ((count == 1) && (ptr1 == (coordinate_type*)NULL)) {
 	ecs_SetError(result, 2, "Only one coordinate found for a line");
+        xvt_free ((char*)ptr1);
+        return FALSE;
+      } else if( ptr1 == NULL ) {
+        ecs_SetError(result, 1, "ptr1 == NULL");
+        return FALSE;
       } else {
 	for (i=0; i<count; i++) {
          ECS_SETGEOMLINECOORD((result),i,
@@ -468,6 +494,11 @@ int vrf_get_line_feature (s, layer, prim_id, result)
     {
       if ((count == 1) && (ptr2 == (tri_coordinate_type*)NULL)) {
 	ecs_SetError(result, 2, "Only one coordinate found for a line");
+        xvt_free ((char*)ptr2);
+        return FALSE;
+      } else if( ptr2 == NULL ) {
+        ecs_SetError(result, 1, "ptr2 == NULL");
+        return FALSE;
       } else {
 	for (i=0; i<count; i++) {
 	  ECS_SETGEOMLINECOORD((result),i,((double) ptr2[i].x),((double) ptr2[i].y))
@@ -481,6 +512,11 @@ int vrf_get_line_feature (s, layer, prim_id, result)
     {
       if ((count == 1) && (ptr3 == (double_coordinate_type*)NULL)) {
 	ecs_SetError(result, 2, "Only one coordinate found for a line");
+        xvt_free ((char*)ptr3);
+        return FALSE;
+      } else if( ptr3 == NULL ) {
+        ecs_SetError(result, 1, "ptr3 == NULL");
+        return FALSE;
       } else {
 	for (i=0; i<count; i++) {
 	  ECS_SETGEOMLINECOORD((result),i,((double) ptr3[i].x),((double) ptr3[i].y))
@@ -494,6 +530,11 @@ int vrf_get_line_feature (s, layer, prim_id, result)
     {
       if ((count == 1) && (ptr4 == (double_tri_coordinate_type*)NULL)) {
 	ecs_SetError(result, 2, "Only one coordinate found for a line");
+        xvt_free ((char*)ptr4);
+        return FALSE;
+      } else if( ptr4 == NULL ) {
+        ecs_SetError(result, 1, "ptr4 == NULL");
+        return FALSE;
       } else {
 	for (i=0; i<count; i++) {
 	  ECS_SETGEOMLINECOORD((result),i,((double) ptr4[i].x),((double) ptr4[i].y))
@@ -519,14 +560,21 @@ static int vrf_get_mbr (table, prim_id, xmin, ymin, xmax, ymax)
      double *ymax;
 {
   int32 count;
-  float temp;
+  float temp = 0.0f;
   row_type row;
 
+  *xmin = 0;
+  *ymin = 0;
+  *xmax = 0;
+  *ymax = 0;
+
   if (table.fp == NULL) {
     return FALSE;
   }
 
   row = read_row (prim_id, table);
+  if( !row )
+    return FALSE;
 
   /* The 'DBVMAP2I' VMAP2i product has FBR tables with columns of type double instead of float */
   /* so we must check for the type */
@@ -668,6 +716,11 @@ int vrf_get_text_feature (s, layer, prim_id)
   PrivData = (LayerPrivateData *) layer->priv; /* casting the private data for a VPF Point layer from */
   table = PrivData->l.text.textTable;	       /* our interest here is the primitive table 	      */
   row = read_row (prim_id, table);	       /* Read the prim_id row from the text primitive table */
+  if( row == NULL )
+  {
+    ecs_SetError(&(s->result), 1, "Unable to get row");
+    return FALSE;
+  }
 
   pos = table_pos ("STRING", table);	       /* find the position in the primitive table */
   desc = (char *) get_table_element (pos, row, table, NULL, &count); /* get the text string   */
@@ -749,7 +802,10 @@ int vrf_get_area_feature (s, layer, prim_id)
   vpf_table_type facetable, ringtable, edgetable;
   AREA_FEATURE area;
   double x,y;
-  int firstlength, max_rings;
+#ifdef notdef
+  int firstlength;
+#endif
+  int max_rings;
     
   /* 
      -----------------------------------------------------------
@@ -796,7 +852,9 @@ int vrf_get_area_feature (s, layer, prim_id)
     xvt_free ((char*)area.rings);
     return FALSE;
   }
+#ifdef notdef
   firstlength = area.rings[n]->nr_segs;
+#endif
   n++;
   
   /* 
@@ -831,14 +889,30 @@ int vrf_get_area_feature (s, layer, prim_id)
     if (ring_rec.face == prim_id) {
       if( n == max_rings )
       {
+          RING** newrings;
           max_rings *= 2;
-          area.rings = (RING **) xvt_realloc(area.rings, 
+          newrings = (RING **) xvt_realloc(area.rings, 
                                              sizeof(RING *) * max_rings);
+          if( newrings == NULL )
+          {
+            for(i=0;i<n;i++) {
+              for(j=0;j<area.rings[i]->nr_segs;j++) {
+                xvt_free((char*) area.rings[i]->segs[j]->coords);
+                xvt_free((char*) area.rings[i]->segs[j]);
+              }
+              xvt_free((char*)area.rings[i]->segs);
+              xvt_free((char*)area.rings[i]);
+            }
+            xvt_free ((char*)area.rings);
+            ecs_SetError(&(s->result), 2, "No enough memory");
+            return FALSE;
+          }
+          area.rings = newrings;
       }
 
       area.rings[n] = (RING*)xvt_zmalloc (sizeof (RING));
       if (area.rings[n] == NULL) {
-	for(i=0;i<n-1;i++) {
+	for(i=0;i<n;i++) {
 	  for(j=0;j<area.rings[i]->nr_segs;j++) {
 	    xvt_free((char*) area.rings[i]->segs[j]->coords);
 	    xvt_free((char*) area.rings[i]->segs[j]);
@@ -854,7 +928,7 @@ int vrf_get_area_feature (s, layer, prim_id)
       area.rings[n]->id = n+1;
       
       if (!vrf_get_ring_coords (s,area.rings[n], prim_id, ring_rec.edge, edgetable)) {
-	for(i=0;i<n-1;i++) {
+	for(i=0;i<n;i++) {
 	  for(j=0;j<area.rings[i]->nr_segs;j++) {
 	    xvt_free((char*) area.rings[i]->segs[j]->coords);
 	    xvt_free((char*) area.rings[i]->segs[j]);
@@ -862,6 +936,7 @@ int vrf_get_area_feature (s, layer, prim_id)
 	  xvt_free((char*)area.rings[i]->segs);
 	  xvt_free((char*)area.rings[i]);
 	}
+	xvt_free((char*)area.rings[n]);
 	xvt_free ((char*)area.rings);
 	ecs_SetError(&(s->result), 2, "No enough memory");
 	return FALSE;
@@ -940,8 +1015,11 @@ int vrf_get_ring_coords (s,ring, face_id, start_edge, edgetable)
   vpf_projection_type proj;
   double_coordinate_type  dcoord;
   SEGMENT **temp;
-  long eqlface1=0L, eqlface2=0L;
-  long eqlnpts;
+  long eqlface1=0L;
+#ifdef notdef
+  long eqlface2=0L;
+#endif
+  /*long eqlnpts;*/
   long eqlleft_edge=0L, eqlright_edge=0L;
   long maxsegs;
   char buffer[120];
@@ -966,7 +1044,7 @@ int vrf_get_ring_coords (s,ring, face_id, start_edge, edgetable)
   if ((edge_rec.right_face == face_id) && (edge_rec.left_face == face_id))
     {
       eqlface1 = 1L;
-      eqlnpts = edge_rec.npts;
+      /*eqlnpts = edge_rec.npts;*/
       eqlleft_edge = edge_rec.left_edge;
       eqlright_edge = edge_rec.right_edge;
       start_dir = edge_rec.dir;
@@ -976,14 +1054,46 @@ int vrf_get_ring_coords (s,ring, face_id, start_edge, edgetable)
    
   /* Allocate plenty of space for array of segment addresses */
   ring->segs = (SEGMENT**)xvt_zmalloc (maxsegs * sizeof (SEGMENT*));
+  if( ring->segs == NULL )
+  {
+    if (edge_rec.coords)
+      xvt_free ((char*)edge_rec.coords);
+    sprintf(buffer,"Unable to allocate memory in vrf_get_ring_coords() for face %d",
+            (int) face_id);
+    ecs_SetError(&(s->result), 1,buffer);
+    return FALSE;
+  }
 
   /* Load the first segment of the ring */
   ring->segs[n] = (SEGMENT*)xvt_zmalloc (sizeof (SEGMENT));
+  if( ring->segs[n] == NULL )
+  {
+    xvt_free((char*)ring->segs);
+    ring->segs = NULL;
+    if (edge_rec.coords)
+      xvt_free ((char*)edge_rec.coords);
+    sprintf(buffer,"Unable to allocate memory in vrf_get_ring_coords() for face %d",
+            (int) face_id);
+    ecs_SetError(&(s->result), 1,buffer);
+    return FALSE;
+  }
   ring->segs[n]->nr_coords = edge_rec.npts;
   ring->segs[n]->id = n+1;
 
   /* Allocate space for the coordinates of the first segment */
   ring->segs[n]->coords = (COORDINATE*)xvt_zmalloc ((size_t)ring->segs[n]->nr_coords * sizeof (COORDINATE));
+  if( ring->segs[n]->coords == NULL )
+  {
+    xvt_free((char*)ring->segs[n]);
+    xvt_free((char*)ring->segs);
+    ring->segs = NULL;
+    if (edge_rec.coords)
+      xvt_free ((char*)edge_rec.coords);
+    sprintf(buffer,"Unable to allocate memory in vrf_get_ring_coords() for face %d",
+            (int) face_id);
+    ecs_SetError(&(s->result), 1,buffer);
+    return FALSE;
+  }
                                                 
   /* If the direction is - load in reverse order */
   if (edge_rec.dir == '-')
@@ -1008,6 +1118,24 @@ int vrf_get_ring_coords (s,ring, face_id, start_edge, edgetable)
 
   while (!done)
     {
+      /* This is a temptative way to detect cycles in the chaining of edges: */
+      /* There is no reason that a sane ring might follow each edges more than */
+      /* twice */
+      if( n > edgetable.nrows * 2 )
+      {
+        sprintf(buffer,"Cycle detected in the edges of face %d",
+               (int) face_id);
+        for( --n;  n >= 0; --n )
+        {
+            xvt_free((char*) ring->segs[n]->coords);
+            xvt_free((char*) ring->segs[n]);
+        }
+        xvt_free(ring->segs);
+        ring->segs = NULL;
+        ecs_SetError(&(s->result), 1,buffer);
+        return FALSE;
+      }
+
       if (next_edge < 0)
 	{
 	  done = TRUE;
@@ -1034,18 +1162,26 @@ int vrf_get_ring_coords (s,ring, face_id, start_edge, edgetable)
 	{
 	  edge_rec = read_edge( next_edge, edgetable, (long)proj.inverse_proj);
 	  if (edge_rec.npts == 0) {
-	    sprintf(buffer,"Unable to read the edge %d in the face %d",
-		    (int) next_edge, (int) face_id);
-	    ecs_SetError(&(s->result), 1,buffer);
-	    return FALSE;
+            sprintf(buffer,"Unable to read the edge %d in the face %d, segment %d",
+                    (int) next_edge, (int) face_id, n);
+            for( --n;  n >= 0; --n )
+            {
+                xvt_free((char*) ring->segs[n]->coords);
+                xvt_free((char*) ring->segs[n]);
+            }
+            xvt_free(ring->segs);
+            ring->segs = NULL;
+            ecs_SetError(&(s->result), 1,buffer);
+            return FALSE;
 	  }
 
 	  next_edge = vrf_next_face_edge( &edge_rec, &prevnode, face_id );
+#ifdef notdef
 	  if ((edge_rec.right_face == face_id) && (edge_rec.left_face ==face_id))
             eqlface2 = 1L;
 	  else
             eqlface2 = 0L;
-
+#endif
           /* 
            * This is to catch cases where there would appear to be a dangle
            * (so we set eqlface1), but when we go to repeat the start edge
@@ -1058,6 +1194,7 @@ int vrf_get_ring_coords (s,ring, face_id, start_edge, edgetable)
           {
               if (edge_rec.coords)
                   xvt_free ((char*)edge_rec.coords);
+              edge_rec.coords = NULL;
               done = TRUE;
               continue;
           }
@@ -1070,17 +1207,67 @@ int vrf_get_ring_coords (s,ring, face_id, start_edge, edgetable)
 
           if( n == maxsegs )
           {
+              SEGMENT** newsegs;
               maxsegs *= 2;
-              ring->segs = (SEGMENT**)
+              newsegs = (SEGMENT**)
                   xvt_realloc(ring->segs, maxsegs * sizeof (SEGMENT*));
+              if( newsegs == NULL )
+              {
+                  sprintf(buffer,"Line %d: Memory allocation failure for segment %d in the face %d",
+                          __LINE__, n, (int) face_id);
+                  for( --n;  n >= 0; --n )
+                  {
+                      xvt_free((char*) ring->segs[n]->coords);
+                      xvt_free((char*) ring->segs[n]);
+                  }
+                  xvt_free(ring->segs);
+                  ring->segs = NULL;
+                  if (edge_rec.coords)
+                    xvt_free ((char*)edge_rec.coords);
+                  ecs_SetError(&(s->result), 1,buffer);
+                  return FALSE;
+              }
+              ring->segs = newsegs;
           }
 
 	  ring->segs[n] = (SEGMENT*)xvt_zmalloc (sizeof (SEGMENT));
+	  if( ring->segs[n] == NULL )
+	  {
+              sprintf(buffer,"Line %d: Memory allocation failure for segment %d in the face %d",
+                          __LINE__, n, (int) face_id);
+	      for( ;  n >= 0; --n )
+	      {
+		  xvt_free((char*) ring->segs[n]->coords);
+		  xvt_free((char*) ring->segs[n]);
+	      }
+	      xvt_free(ring->segs);
+              ring->segs = NULL;
+              if (edge_rec.coords)
+                xvt_free ((char*)edge_rec.coords);
+              ecs_SetError(&(s->result), 1,buffer);
+	      return FALSE;
+	  }
 	  ring->segs[n]->nr_coords = edge_rec.npts;
 	  ring->segs[n]->id = n+1;
          
 	  /* Allocate space for the segment coordinates */
 	  ring->segs[n]->coords = (COORDINATE*)xvt_zmalloc ((size_t)ring->segs[n]->nr_coords * sizeof (COORDINATE));
+          if( ring->segs[n]->coords == NULL )
+          {
+              sprintf(buffer,"Line %d: Memory allocation failure for segment %d in the face %d",
+                          __LINE__, n, (int) face_id);
+              for( ;  n >= 0; --n )
+              {
+                  xvt_free((char*) ring->segs[n]->coords);
+                  xvt_free((char*) ring->segs[n]);
+              }
+              xvt_free(ring->segs);
+              ring->segs = NULL;
+              if (edge_rec.coords)
+                xvt_free ((char*)edge_rec.coords);
+              ecs_SetError(&(s->result), 1,buffer);
+              return FALSE;
+          }
 
 	  /* If the direction is - load in reverse order */
 	  if (edge_rec.dir == '-')
@@ -1104,6 +1291,7 @@ int vrf_get_ring_coords (s,ring, face_id, start_edge, edgetable)
 	  n++;
 	  if (edge_rec.coords)
             xvt_free ((char*)edge_rec.coords);
+          edge_rec.coords = NULL;
 
 	} /* if (!done) */
     } /* while */              
@@ -1111,10 +1299,9 @@ int vrf_get_ring_coords (s,ring, face_id, start_edge, edgetable)
   assert( ring->nr_segs <= maxsegs );
 
   /* Realloc the segs array to free unused memory */
-  temp = (SEGMENT**)xvt_zmalloc (ring->nr_segs * sizeof (SEGMENT*));
-  memcpy ((char*)temp, (char*)ring->segs, (ring->nr_segs * sizeof (SEGMENT*)));
-  xvt_free ((char*)ring->segs);
-  ring->segs = temp;
+  temp = (SEGMENT**)xvt_realloc(ring->segs, ring->nr_segs * sizeof (SEGMENT*));
+  if( temp )
+      ring->segs = temp;
 
   return TRUE;
 } 
@@ -1242,7 +1429,7 @@ int vrf_get_xy (table, row, pos, x, y)
      double         *x;
      double         *y;
 {
-  int32 count;
+  int32 count = 0;
   coordinate_type temp1, *ptr1;
   tri_coordinate_type temp2, *ptr2;
   double_coordinate_type temp3, *ptr3;
@@ -1256,6 +1443,8 @@ int vrf_get_xy (table, row, pos, x, y)
       if ((count == 1) && (ptr1 == (coordinate_type*)NULL)) {
 	*x = (double) temp1.x;
 	*y = (double) temp1.y;
+      } else if( ptr1 == NULL ) {
+        return FALSE;
       } else {
 	*x = (double) ptr1->x;
 	*y = (double) ptr1->y;
@@ -1270,6 +1459,8 @@ int vrf_get_xy (table, row, pos, x, y)
       if ((count == 1) && (ptr2 == (tri_coordinate_type*)NULL)) {
 	*x = temp2.x;
 	*y = temp2.y;
+      } else if( ptr2 == NULL ) {
+        return FALSE;
       } else {
 	*x = (double) ptr2[0].x;
 	*y = (double) ptr2[0].y;
@@ -1284,6 +1475,8 @@ int vrf_get_xy (table, row, pos, x, y)
       if ((count == 1) && (ptr3 == (double_coordinate_type*)NULL)) {
 	*x = (double) temp3.x;
 	*y = (double) temp3.y;
+      } else if( ptr3 == NULL ) {
+        return FALSE;
       } else {
 	*x = (double) ptr3[0].x;
 	*y = (double) ptr3[0].y;
@@ -1298,6 +1491,8 @@ int vrf_get_xy (table, row, pos, x, y)
       if ((count == 1) && (ptr4 == (double_tri_coordinate_type*)NULL)) {
 	*x = (double) temp4.x;
 	*y = (double) temp4.y;
+      } else if( ptr4 == NULL ) {
+        return FALSE;
       } else {
 	*x = (double) ptr4[0].x;
 	*y = (double) ptr4[0].y;
@@ -1347,7 +1542,7 @@ char *vrf_get_ObjAttributes(table, row_pos)
   short int temp4;
   int temp5;
   date_type temp6;
-  long count;
+  int32 count;
 
   if (returnString != NULL) {
     free(returnString);
@@ -1356,7 +1551,7 @@ char *vrf_get_ObjAttributes(table, row_pos)
 
   row = read_row(row_pos,table);
 
-  lenght = 1;
+  lenght = 4;
   returnString = (char *) malloc(lenght);
   strcpy(returnString,"");
 
diff --git a/ogdi/driver/vrf/object.c b/ogdi/driver/vrf/object.c
index c663eda..1ea988c 100644
--- a/ogdi/driver/vrf/object.c
+++ b/ogdi/driver/vrf/object.c
@@ -17,6 +17,21 @@
  ******************************************************************************
  *
  * $Log: object.c,v $
+ * Revision 1.12  2016/07/06 09:00:39  erouault
+ * VRF: implement ecs_SetErrorShouldStop() logic in the various _getNext.... methods
+ *
+ * Revision 1.11  2016/07/04 17:03:12  erouault
+ * Error handling: Add a ecs_SetErrorShouldStop() function that can be
+ *     used internally when the code is able to recover from an error. The user
+ *     may decide if he wants to be resilient on errors by defining OGDI_STOP_ON_ERROR=NO
+ *     as environment variable (the default being YES: stop on error).
+ *     Add a ecs_SetReportErrorFunction() method to install a custom callback that
+ *     will be called when OGDI_STOP_ON_ERROR=YES so that the user code is still
+ *     aware of errors that occured. If not defined, the error will be logged in stderr.
+ *
+ * Revision 1.10  2016/07/04 14:34:40  erouault
+ * VPF: _getNextObject / _getObject functions: validate the value of the tile_id to avoid a potential out-of-bounds read. Fix crash on dqyarea at dqy layer of DNC17/H1708311
+ *
  * Revision 1.9  2007/05/09 20:46:28  cbalint
  * From: Even Rouault <even.rouault at mines-paris.org>
  * Date: Friday 21:14:18
@@ -76,7 +91,7 @@
 #include "ecs.h"
 #include "vrf.h"
 
-ECS_CVSID("$Id: object.c,v 1.9 2007/05/09 20:46:28 cbalint Exp $");
+ECS_CVSID("$Id: object.c,v 1.12 2016/07/06 09:00:39 erouault Exp $");
 
 /* 
 ********************************************************************
@@ -363,8 +378,19 @@ void _getPrimList( ecs_Server *s,
 
         if( *primCount == maxCount )
         {
+            int32* newPrimList;
             maxCount += 100;
-            *primList = (int32*) realloc(*primList, sizeof(int32) * maxCount);
+            newPrimList = (int32*) realloc(*primList, sizeof(int32) * maxCount);
+            if( newPrimList == NULL )
+            {
+                /* Should probably error out loudly */
+                free( *primList );
+                *primList = NULL;
+                *primCount = 0;
+                object_id++;
+                break;
+            }
+            *primList = newPrimList;
         }
 
         (*primList)[*primCount] = edg_id;
@@ -445,7 +471,7 @@ _getNextObjectArea(s,l)
   char *temp;
   double xmin, xmax, ymin, ymax;
 
-
+retry:
   while(!found && l->index < l->nbfeature) {    
     _getTileAndPrimId(s,l,l->index,&area_id,&tile_id, &fac_id);
 
@@ -461,20 +487,38 @@ _getNextObjectArea(s,l)
 
     if (set_member(area_id,lpriv->feature_rows)) {
       if (tile_id == -1) {
-	ecs_SetError(&(s->result), 1, "The VRF tiles are badly defined");
-	return;
+	if( ecs_SetErrorShouldStop(&(s->result), 1, "The VRF tiles are badly defined") )
+          return;
+        l->index++;
+        continue;
       }
 
       if (tile_id == -2) {
-	ecs_SetError(&(s->result), 1, "The join table is empty");
-	return;
+	if( ecs_SetErrorShouldStop(&(s->result), 1, "The join table is empty") )
+          return;
+        l->index++;
+        continue;
       }
-
+      
+      if( lpriv->isTiled && (tile_id < 1 || tile_id > spriv->nbTile) )
+      {
+	/* Happens with dqyarea at dqy(*) coverage of DNC17/H1708311 */
+	char szErrorMsg[128];
+	sprintf(szErrorMsg, "Object index=%d references incorrect tile_id=%d (nbTile=%d)",
+	    l->index, tile_id, spriv->nbTile);
+	if( ecs_SetErrorShouldStop(&(s->result), 1, szErrorMsg) )
+	    return;
+        l->index++;
+        continue;
+      }
+      else
       if (lpriv->isTiled == 0 || spriv->tile[tile_id-1].isSelected) {
 	_selectTileArea(s,l,tile_id);
 	if (!vrf_get_area_mbr(l,fac_id,&xmin,&ymin,&xmax,&ymax)) {
-	  ecs_SetError(&(s->result), 1, "VRF table mbr not open");
-	  return;
+	  if( ecs_SetErrorShouldStop(&(s->result), 1, "VRF table mbr not open") )
+            return;
+          l->index++;
+          continue;
 	}
 	if (!vrf_IsOutsideRegion(ymax,ymin,xmax,xmin,
 			      &(s->currentRegion))) {
@@ -490,7 +534,23 @@ _getNextObjectArea(s,l)
 
   if (found) {
     if (!vrf_get_area_feature(s,l,fac_id)) 
-      return;
+    {
+        if( !ecs_ShouldStopOnError() )
+        {
+            char* message= strdup(s->result.message);
+            int should_stop;
+            ecs_CleanUp(&(s->result));
+            should_stop = ecs_SetErrorShouldStop(&(s->result),1,message);
+            free(message);
+            if( !should_stop )
+            {
+                found = 0;
+                l->index++;
+                goto retry;
+            }
+        }
+        return;
+    }
     l->index++;
   } else {
     ecs_SetError(&(s->result),2,"End of selection");
@@ -525,6 +585,7 @@ _getObjectArea(s,l,id)
      ecs_Layer *l;
      char *id;
 {
+  ServerPrivateData *spriv = (ServerPrivateData *) s->priv;
   register LayerPrivateData *lpriv = (LayerPrivateData *) l->priv;
   int object_id;
   int32 area_id;
@@ -549,7 +610,16 @@ _getObjectArea(s,l,id)
     ecs_SetError(&(s->result), 1, "The join table is empty");
     return;
   }
-	
+
+  if( lpriv->isTiled && (tile_id < 1 || tile_id > spriv->nbTile) )
+  {
+    char szErrorMsg[128];
+    sprintf(szErrorMsg, "Object index=%d references incorrect tile_id=%d (nbTile=%d)",
+            l->index, tile_id, spriv->nbTile);
+    if( ecs_SetErrorShouldStop(&(s->result), 1, szErrorMsg) )
+      return;
+  }
+
   _selectTileArea(s,l,tile_id);
 
   if (!vrf_get_area_feature(s,l,fac_id))
@@ -611,6 +681,15 @@ _getObjectIdArea(s,l,coord)
 	return;
       }
 
+      if( lpriv->isTiled && (tile_id < 1 || tile_id > spriv->nbTile) )
+      {
+        char szErrorMsg[128];
+        sprintf(szErrorMsg, "Object index=%d references incorrect tile_id=%d (nbTile=%d)",
+                l->index, tile_id, spriv->nbTile);
+        if( ecs_SetErrorShouldStop(&(s->result), 1, szErrorMsg) )
+          return;
+      }
+      else
       if (!(lpriv->isTiled) || 
 	  ((coord->x > spriv->tile[tile_id-1].xmin) && 
 	   (coord->x < spriv->tile[tile_id-1].xmax) && 
@@ -802,6 +881,7 @@ _getNextObjectLine(s,l)
   else
       edgeCount = l->nbfeature;
 
+retry:
   while(!found && l->index < edgeCount) {
 
     if( primList != NULL )
@@ -815,20 +895,39 @@ _getNextObjectLine(s,l)
     
     if (set_member(line_id,lpriv->feature_rows)) {      
       if (tile_id == -1) {
-	ecs_SetError(&(s->result), 1, "The VRF tiles are badly defined");
-	return;
+        free( primList );
+        primList = NULL;
+	if( ecs_SetErrorShouldStop(&(s->result), 1, "The VRF tiles are badly defined") )
+          return;
+        continue;
       }
       if (tile_id == -2) {
-	ecs_SetError(&(s->result), 1, "The join table is empty");
-	return;
+        free( primList );
+        primList = NULL;
+	if( ecs_SetErrorShouldStop(&(s->result), 1, "The join table is empty") )
+          return;
+        continue;
       }
 
-      if (lpriv->isTiled == 0 || spriv->tile[tile_id-1].isSelected) {
+      if( lpriv->isTiled && (tile_id < 1 || tile_id > spriv->nbTile) )
+      {
+        char szErrorMsg[128];
+        free( primList );
+        primList = NULL;
+        sprintf(szErrorMsg, "Object index=%d references incorrect tile_id=%d (nbTile=%d)",
+                l->index, tile_id, spriv->nbTile);
+        if( ecs_SetErrorShouldStop(&(s->result), 1, szErrorMsg) )
+          return;
+      }
+      else if (lpriv->isTiled == 0 || spriv->tile[tile_id-1].isSelected) {
 
 	_selectTileLine(s,l,tile_id);
 	if (!vrf_get_lines_mbr(l,primCount,primList,&xmin,&ymin,&xmax,&ymax)) {
-	  ecs_SetError(&(s->result),1,"Unable to open mbr");
-	  return;
+          free( primList );
+          primList = NULL;
+	  if( ecs_SetErrorShouldStop(&(s->result),1,"Unable to open mbr") )
+            return;
+          continue;
 	}
 	if (!vrf_IsOutsideRegion(ymax,ymin,xmax,xmin,
 			      &(s->currentRegion))) { 
@@ -845,6 +944,20 @@ _getNextObjectLine(s,l)
     if( !vrf_get_merged_line_feature(s,l,primCount,primList) )
     {
         free( primList );
+        primList = NULL;
+        if( !ecs_ShouldStopOnError() )
+        {
+            char* message= strdup(s->result.message);
+            int should_stop;
+            ecs_CleanUp(&(s->result));
+            should_stop = ecs_SetErrorShouldStop(&(s->result),1,message);
+            free(message);
+            if( !should_stop )
+            {
+                found = 0;
+                goto retry;
+            }
+        }
         return;
     }
 
@@ -1126,19 +1239,54 @@ _getNextObjectPoint(s,l)
     _getTileAndPrimId(s,l,l->index,&fpoint_id,&tile_id, &point_id);
     if (set_member(fpoint_id,lpriv->feature_rows)) {
       if (tile_id == -1) {
-	ecs_SetError(&(s->result), 1, "The VRF tiles are badly defined");
-	return;
+	if( ecs_SetErrorShouldStop(&(s->result), 1, "The VRF tiles are badly defined"))
+	    return;
+        l->index++;
+        continue;
       }
       if (tile_id == -2) {
-	ecs_SetError(&(s->result), 1, "The join table is empty");
-	return;
+	if( !ecs_SetErrorShouldStop(&(s->result), 1, "The join table is empty") )
+	    return;
+        l->index++;
+        continue;
       }
 
+      if( lpriv->isTiled && (tile_id < 1 || tile_id > spriv->nbTile) )
+      {
+	char szErrorMsg[128];
+	sprintf(szErrorMsg, "Object index=%d references incorrect tile_id=%d (nbTile=%d)",
+	    l->index, tile_id, spriv->nbTile);
+	if( ecs_SetErrorShouldStop(&(s->result), 1, szErrorMsg) )
+	    return;
+        l->index++;
+        continue;
+      }
+      else
       if (lpriv->isTiled == 0 || spriv->tile[tile_id-1].isSelected) {
 
 	_selectTilePoint(s,l,tile_id);
 	if (!vrf_get_point_feature(s,l,point_id)) 
-	  return;
+        {
+          if( !ecs_ShouldStopOnError() )
+          {
+              char* message= strdup(s->result.message);
+              int should_stop;
+              ecs_CleanUp(&(s->result));
+              should_stop = ecs_SetErrorShouldStop(&(s->result),1,message);
+              free(message);
+              if( should_stop )
+                  return;
+              else
+              {
+                  l->index++;
+                  continue;
+              }
+          }
+          else
+          {
+              return;
+          }
+        }
 	if ((ECSGEOM((&(s->result))).point.c.x>s->currentRegion.west) && 
 	    (ECSGEOM((&(s->result))).point.c.x<s->currentRegion.east) &&
 	    (ECSGEOM((&(s->result))).point.c.y>s->currentRegion.south) && 
@@ -1192,6 +1340,7 @@ _getObjectPoint(s,l,id)
      ecs_Layer *l;
      char *id;
 {
+  ServerPrivateData *spriv = (ServerPrivateData *) s->priv;
   register LayerPrivateData *lpriv = (LayerPrivateData *) l->priv;
   int object_id;
   int32 point_id;
@@ -1216,6 +1365,14 @@ _getObjectPoint(s,l,id)
     return;
   }
 
+  if( lpriv->isTiled && (tile_id < 1 || tile_id > spriv->nbTile) )
+  {
+    char szErrorMsg[128];
+    sprintf(szErrorMsg, "Object index=%d references incorrect tile_id=%d (nbTile=%d)",
+            l->index, tile_id, spriv->nbTile);
+    if( ecs_SetErrorShouldStop(&(s->result), 1, szErrorMsg) )
+      return;
+  }
 
   _selectTilePoint(s,l,tile_id);
 
@@ -1270,6 +1427,15 @@ _getObjectIdPoint(s,l,coord)
 	return;
       }      
 
+      if( lpriv->isTiled && (tile_id < 1 || tile_id > spriv->nbTile) )
+      {
+        char szErrorMsg[128];
+        sprintf(szErrorMsg, "Object index=%d references incorrect tile_id=%d (nbTile=%d)",
+                l->index, tile_id, spriv->nbTile);
+        if( ecs_SetErrorShouldStop(&(s->result), 1, szErrorMsg) )
+          return;
+      }
+      else
       if (!(lpriv->isTiled) || 
 	  ((coord->x > spriv->tile[tile_id-1].xmin) && 
 	   (coord->x < spriv->tile[tile_id-1].xmax) && 
@@ -1384,19 +1550,54 @@ _getNextObjectText(s,l)
     _getTileAndPrimId(s,l,l->index,&text_id,&tile_id, &prim_id);
     if (set_member(text_id,lpriv->feature_rows)) {
       if (tile_id == -1) {
-	ecs_SetError(&(s->result), 1, "The VRF tiles are badly defined");
-	return;
+	if( ecs_SetErrorShouldStop(&(s->result), 1, "The VRF tiles are badly defined") )
+          return;
+        l->index ++;
+        continue;
       }
       if (tile_id == -2) {
-	ecs_SetError(&(s->result), 1, "The join table is empty");
-	return;
+	if( ecs_SetErrorShouldStop(&(s->result), 1, "The join table is empty") )
+          return;
+        l->index ++;
+        continue;
       }
 
+      if( lpriv->isTiled && (tile_id < 1 || tile_id > spriv->nbTile) )
+      {
+        char szErrorMsg[128];
+        sprintf(szErrorMsg, "Object index=%d references incorrect tile_id=%d (nbTile=%d)",
+                l->index, tile_id, spriv->nbTile);
+        if( ecs_SetErrorShouldStop(&(s->result), 1, szErrorMsg) )
+          return;
+        l->index ++;
+        continue;
+      }
+      else
       if (lpriv->isTiled == 0 || spriv->tile[tile_id-1].isSelected) {
 
 	_selectTileText(s,l,tile_id);
 	if (!vrf_get_text_feature(s,l,prim_id)) 
-	  return;
+        {
+          if( !ecs_ShouldStopOnError() )
+          {
+              char* message= strdup(s->result.message);
+              int should_stop;
+              ecs_CleanUp(&(s->result));
+              should_stop = ecs_SetErrorShouldStop(&(s->result),1,message);
+              free(message);
+              if( should_stop )
+                  return;
+              else
+              {
+                  l->index ++;
+                  continue;
+              }
+          }
+          else
+          {
+              return;
+          }
+        }
 	if ((ECSGEOM((&(s->result))).text.c.x>s->currentRegion.west) && 
 	    (ECSGEOM((&(s->result))).text.c.x<s->currentRegion.east) &&
 	    (ECSGEOM((&(s->result))).text.c.y>s->currentRegion.south) && 
@@ -1414,6 +1615,7 @@ _getNextObjectText(s,l)
   if (found) {
     l->index++;
   } else {
+    ecs_CleanUp(&(s->result));
     ecs_SetError(&(s->result),2,"End of selection");
     return;
   }
@@ -1451,6 +1653,7 @@ _getObjectText(s,l,id)
      ecs_Layer *l;
      char *id;
 {
+  ServerPrivateData *spriv = (ServerPrivateData *) s->priv;
   register LayerPrivateData *lpriv = (LayerPrivateData *) l->priv;
   int object_id;
   short tile_id;
@@ -1475,6 +1678,15 @@ _getObjectText(s,l,id)
     return;
   }
 
+  if( lpriv->isTiled && (tile_id < 1 || tile_id > spriv->nbTile) )
+  {
+    char szErrorMsg[128];
+    sprintf(szErrorMsg, "Object index=%d references incorrect tile_id=%d (nbTile=%d)",
+            l->index, tile_id, spriv->nbTile);
+    if( ecs_SetErrorShouldStop(&(s->result), 1, szErrorMsg) )
+      return;
+  }
+
   _selectTileText(s,l,tile_id);
 
   if (!vrf_get_text_feature(s,l,prim_id)) 
@@ -1528,6 +1740,15 @@ _getObjectIdText(s,l,coord)
 	return;
       }      
 
+      if( lpriv->isTiled && (tile_id < 1 || tile_id > spriv->nbTile) )
+      {
+        char szErrorMsg[128];
+        sprintf(szErrorMsg, "Object index=%d references incorrect tile_id=%d (nbTile=%d)",
+                l->index, tile_id, spriv->nbTile);
+        if( ecs_SetErrorShouldStop(&(s->result), 1, szErrorMsg) )
+          return;
+      }
+      else
       if (!(lpriv->isTiled) || 
 	  ((coord->x > spriv->tile[tile_id-1].xmin) && 
 	   (coord->x < spriv->tile[tile_id-1].xmax) && 
diff --git a/ogdi/driver/vrf/utils.c b/ogdi/driver/vrf/utils.c
index 2e236b8..4a0380d 100644
--- a/ogdi/driver/vrf/utils.c
+++ b/ogdi/driver/vrf/utils.c
@@ -17,6 +17,21 @@
  ******************************************************************************
  *
  * $Log: utils.c,v $
+ * Revision 1.21  2016/07/07 15:50:15  erouault
+ * fix stack buffer overflow in vrf_GetMetadata() when reading the level in CAT files. Found by GCC 5.2 -faddress=sanitize
+ *
+ * Revision 1.20  2016/07/04 17:03:12  erouault
+ * Error handling: Add a ecs_SetErrorShouldStop() function that can be
+ *     used internally when the code is able to recover from an error. The user
+ *     may decide if he wants to be resilient on errors by defining OGDI_STOP_ON_ERROR=NO
+ *     as environment variable (the default being YES: stop on error).
+ *     Add a ecs_SetReportErrorFunction() method to install a custom callback that
+ *     will be called when OGDI_STOP_ON_ERROR=YES so that the user code is still
+ *     aware of errors that occured. If not defined, the error will be logged in stderr.
+ *
+ * Revision 1.19  2016/07/04 12:49:56  erouault
+ * VPF: Avoid a missing fcs file in a coverage to prevent opening any coverage of the library (fix opening of DNC17/COA17A dataset)
+ *
  * Revision 1.18  2008/05/28 00:18:21  cbalint
  *    * fix minor printf format gcc warnings.
  *
@@ -98,7 +113,7 @@
 #include "vrf.h"
 #include "vpfprop.h"
 
-ECS_CVSID("$Id: utils.c,v 1.18 2008/05/28 00:18:21 cbalint Exp $");
+ECS_CVSID("$Id: utils.c,v 1.21 2016/07/07 15:50:15 erouault Exp $");
 
 #ifdef _WINDOWS
 #define SEPARATOR '\\'
@@ -602,7 +617,6 @@ vrf_GetMetadata(s)
   row_type rowcomp;
   row_type rowfca;
   float buffloat;
-  short buffint;
   register ServerPrivateData *spriv = s->priv;
   char buffer[256];
   char tab[3][7]={"char","float","int"};
@@ -858,6 +872,9 @@ vrf_GetMetadata(s)
   rec_sprintf (spriv->metadatastring,"%s\n\n\nCOVERAGE ATTRIBUTE TABLE(CAT):\n\n",spriv->metadatastring);	
 
   for (i = 1; i <= spriv->catTable.nrows; ++i) {
+    int buffint = 0;
+    short buffshort = 0;
+
     row = get_row(i, spriv->catTable);
     buf1 = justify( (char *) get_table_element(1, row, spriv->catTable, NULL, &count));
     rec_sprintf(spriv->metadatastring,"%sCoverage_name: %s\n",spriv->metadatastring,buf1);
@@ -865,7 +882,15 @@ vrf_GetMetadata(s)
     buf1 = justify( (char *) get_table_element(2, row, spriv->catTable, NULL, &count));
     rec_sprintf(spriv->metadatastring,"%sDescription: %s\n",spriv->metadatastring,buf1);
     free(buf1);
-    get_table_element(3, row, spriv->catTable, &buffint, &count);
+    if( spriv->catTable.header[3].type == 'I' )
+    {
+      get_table_element(3, row, spriv->catTable, &buffint, &count);
+    }
+    else if( spriv->catTable.header[3].type == 'S' )
+    {
+      get_table_element(3, row, spriv->catTable, &buffshort, &count);
+      buffint = buffshort;
+    }
     rec_sprintf(spriv->metadatastring,"%sLevel: %d\n",spriv->metadatastring,buffint);
     free_row(row, spriv->catTable); 		
   }
@@ -1191,7 +1216,7 @@ vrf_GetMetadata(s)
     /*ajoute description et debut du covinfo*/
     buf1 = justify( (char *) get_table_element(2, rowcat, spriv->catTable, NULL, &count));
 
-    rec_sprintf(spriv->metadatastring,"%s {%s} {<Grassland>displaymetadata {",spriv->metadatastring, buf1);
+    rec_sprintf(spriv->metadatastring,"%s {%s} {",spriv->metadatastring, buf1);
     free(buf1);
 
     /********/
@@ -1212,10 +1237,27 @@ vrf_GetMetadata(s)
 #endif
 	spriv->fcaTable = vpf_open_table(buffer, disk, "rb", NULL);
 		
+	/* We do not want to abort on a whole library because a FCS file is */
+	/* missing. That happens for example with DNC17/COA17A/ENV */
 	if (spriv->fcsTable.path == NULL) 
 	  {
-	    ecs_SetError(&(s->result),1,"Can't open the FCS table, invalid VRF coverage");
-	    return 0;
+            char szErrorMessage[128];
+            sprintf(szErrorMessage, "Can't open the FCS table of '%s', invalid VRF coverage",
+                    covname);
+	    rec_sprintf(spriv->metadatastring,"%s <ERROR>Cannot open %s/%s/fcs</ERROR>",
+			spriv->metadatastring,spriv->library,covname );
+	    if( ecs_SetErrorShouldStop(&(s->result),1,szErrorMessage) )
+	    {
+                free(covname);
+                vpf_close_table(&(spriv->lhtTable));
+                vpf_close_table(&(spriv->fcaTable));
+                free_row(rowcat, spriv->catTable);
+		return 0;
+	    }
+	  }
+	  else
+	  {
+	      rec_sprintf(spriv->metadatastring,"%s<Grassland>displaymetadata {",spriv->metadatastring);
 	  }
   
 	for (i = 1; i <= spriv->fcsTable.nrows; ++i) 
@@ -1260,10 +1302,19 @@ vrf_GetMetadata(s)
             free_row(row, spriv->fcsTable);
 	    free_row(rowcomp, spriv->fcsTable);
 	  }
+	
+	  if (spriv->fcsTable.path != NULL)  {
+		rec_sprintf(spriv->metadatastring,"%s }",spriv->metadatastring);
+	  }
+	
 	vpf_close_table(&(spriv->fcaTable));		
     }
-    
-    rec_sprintf(spriv->metadatastring,"%s } {",spriv->metadatastring);
+    else
+    {
+	rec_sprintf(spriv->metadatastring,"%s<Grassland>displaymetadata { }",spriv->metadatastring);
+    }
+
+    rec_sprintf(spriv->metadatastring,"%s {",spriv->metadatastring);
     vpf_close_table(&(spriv->fcsTable));
  
 
diff --git a/ogdi/driver/vrf/vrf.c b/ogdi/driver/vrf/vrf.c
index ba94aee..0b46044 100644
--- a/ogdi/driver/vrf/vrf.c
+++ b/ogdi/driver/vrf/vrf.c
@@ -17,6 +17,9 @@
  ******************************************************************************
  *
  * $Log: vrf.c,v $
+ * Revision 1.21  2016/07/06 09:01:30  erouault
+ * VRF: fix memory leaks in error code paths of dyn_SelectLayer()
+ *
  * Revision 1.20  2007/05/09 21:29:50  cbalint
  * fix is to increase of 1 the size of smallint (5 -> 6)
  *
@@ -106,7 +109,7 @@
 #include "vrf.h"
 #include "datadict.h"
 
-ECS_CVSID("$Id: vrf.c,v 1.20 2007/05/09 21:29:50 cbalint Exp $");
+ECS_CVSID("$Id: vrf.c,v 1.21 2016/07/06 09:01:30 erouault Exp $");
 
 /* layer oriented functions are keeped in data structure to simplify code */
 
@@ -471,6 +474,12 @@ ecs_Result *dyn_SelectLayer(s,sel)
     free( lpriv->coverage );
     free( lpriv->fclass );
     free( lpriv->expression );
+    free( lpriv->featureTableName );
+    free( lpriv->featureTablePrimIdName );
+    free( lpriv->joinTableName );
+    free( lpriv->joinTableForeignKeyName );
+    free( lpriv->joinTableFeatureIdName );
+    free( lpriv->primitiveTableName );
     free(s->layer[layer].priv);
     ecs_FreeLayer(s,layer);   
     return &(s->result);
@@ -532,9 +541,12 @@ ecs_Result *dyn_SelectLayer(s,sel)
     free( lpriv->coverage );
     free( lpriv->fclass );
     free( lpriv->expression );
-    free(lpriv->featureTableName);
-    free(lpriv->primitiveTableName);
-    free(lpriv->featureTablePrimIdName);
+    free( lpriv->featureTableName );
+    free( lpriv->featureTablePrimIdName );
+    free( lpriv->joinTableName );
+    free( lpriv->joinTableForeignKeyName );
+    free( lpriv->joinTableFeatureIdName );
+    free( lpriv->primitiveTableName );
     free(s->layer[layer].priv);
     ecs_FreeLayer(s,layer);
     ecs_SetError(&(s->result),1,"Can't open this feature class");
diff --git a/ogdi/gltpd/asyncsvr.c b/ogdi/gltpd/asyncsvr.c
index 302924c..dfdf21b 100644
--- a/ogdi/gltpd/asyncsvr.c
+++ b/ogdi/gltpd/asyncsvr.c
@@ -17,6 +17,9 @@
  ******************************************************************************
  *
  * $Log: asyncsvr.c,v $
+ * Revision 1.7  2016/06/28 14:32:45  erouault
+ * Fix all warnings about unused variables raised by GCC 4.8
+ *
  * Revision 1.6  2007/02/12 21:01:48  cbalint
  *      Fix win32 target. It build and works now. (tested with VC6)
  *
@@ -49,7 +52,7 @@
 
 #include <ogdi_macro.h>
 
-ECS_CVSID("$Id: asyncsvr.c,v 1.6 2007/02/12 21:01:48 cbalint Exp $");
+ECS_CVSID("$Id: asyncsvr.c,v 1.7 2016/06/28 14:32:45 erouault Exp $");
 
 #ifdef _WINDOWS
 #  include "rpc/pmap_cln.h"
@@ -485,7 +488,7 @@ dispatchno_1(rqstp, transp)
 
 void gltpd_svc_run()
 {
-  xdrproc_t xdr_argument, xdr_result;
+  xdrproc_t xdr_argument;
   struct timeval timeout;
 #ifdef FD_SETSIZE
   fd_set readfds;
@@ -525,7 +528,8 @@ void gltpd_svc_run()
   extern int errno;
   static int tsize = 0;
   struct timeval timeout;
-  xdrproc_t xdr_argument, xdr_result;
+  xdrproc_t xdr_argument;
+  /*xdrproc_t xdr_result;*/
   long currenttime;
   
   timeout.tv_sec = COMTIMEOUT;
@@ -546,7 +550,7 @@ void gltpd_svc_run()
 	time(&currenttime);
 	if (currenttime - timecount > COMTIMEOUT) {
 	  xdr_argument = (xdrproc_t) xdr_void;
-	  xdr_result = (xdrproc_t) xdr_ecs_Result;
+	  /*xdr_result = (xdrproc_t) xdr_ecs_Result;*/
 	  destroyserver_1_svc(xdr_argument,NULL);
 	  perror("gltpd_svc_run: - timeout");
 	  return;
@@ -558,7 +562,7 @@ void gltpd_svc_run()
       return;
     case 0:
       xdr_argument = (xdrproc_t) xdr_void;
-      xdr_result = (xdrproc_t) xdr_ecs_Result;
+      /*xdr_result = (xdrproc_t) xdr_ecs_Result;*/
       destroyserver_1_svc(xdr_argument,NULL);
       perror("gltpd_svc_run: - timeout");
       return;
diff --git a/ogdi/include/ecs_util.h b/ogdi/include/ecs_util.h
index 5639213..f07f5c6 100644
--- a/ogdi/include/ecs_util.h
+++ b/ogdi/include/ecs_util.h
@@ -19,6 +19,30 @@
  ******************************************************************************
  *
  * $Log: ecs_util.h,v $
+ * Revision 1.30  2016/07/11 09:13:29  erouault
+ * Really fix Windows compilation issue due to int32/uint32
+ *
+ * Revision 1.29  2016/07/08 10:22:55  erouault
+ * Fix various compilation problems on Windows (contributed by Jerome Siot)
+ *
+ * Revision 1.28  2016/07/05 13:28:46  erouault
+ * ecs_util.h: update to 20160705 so that we have a way to know if ecs_SetReportErrorFunction() is available
+ *
+ * Revision 1.27  2016/07/04 17:33:49  erouault
+ * Also export ecs_ShouldStopOnError and ecs_SetErrorShouldStop on Windows
+ *
+ * Revision 1.26  2016/07/04 17:03:12  erouault
+ * Error handling: Add a ecs_SetErrorShouldStop() function that can be
+ *     used internally when the code is able to recover from an error. The user
+ *     may decide if he wants to be resilient on errors by defining OGDI_STOP_ON_ERROR=NO
+ *     as environment variable (the default being YES: stop on error).
+ *     Add a ecs_SetReportErrorFunction() method to install a custom callback that
+ *     will be called when OGDI_STOP_ON_ERROR=YES so that the user code is still
+ *     aware of errors that occured. If not defined, the error will be logged in stderr.
+ *
+ * Revision 1.25  2016/06/27 20:23:20  erouault
+ * Fix compiler warnings raised by GCC 4.4
+ *
  * Revision 1.24  2008/05/28 01:47:03  cbalint
  *    * prepare 3.2.0.beta2
  *
@@ -85,7 +109,7 @@
 #define ECS_UTIL 1
 
 #define OGDI_VERSION     320
-#define OGDI_RELEASEDATE 20080528
+#define OGDI_RELEASEDATE 20160705
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -126,7 +150,10 @@
 
 #ifndef __INT32DEF__
 #define __INT32DEF__
-#ifdef _ALPHA
+#ifdef _MSC_VER
+typedef signed int int32;
+typedef unsigned int uint32;
+#elif defined(_ALPHA)
 typedef int32_t int32;
 typedef uint32_t uint32;
 #else
@@ -209,8 +236,12 @@ typedef uint32_t uint32;
  */
 
 #ifndef DISABLE_CVSID
+#if defined(__GNUC__) && __GNUC__ >= 4
+#  define ECS_CVSID(string)     static const char ecs_cvsid[] __attribute__((used)) = string;
+#else
 #  define ECS_CVSID(string)	static char ecs_cvsid[] = string; \
 static char *cvsid_aw() { return( cvsid_aw() ? ((char *) NULL) : ecs_cvsid ); }
+#endif
 #else
 #  define ECS_CVSID(string)
 #endif
@@ -801,6 +832,14 @@ int ecs_GetDefaultInfo _ANSI_ARGS_((char* url, char* key, char** result));
 
 int ecs_SetError _ANSI_ARGS_((ecs_Result *r,
 			      int errorcode, char *error_message));
+
+/* Shoud return TRUE if processing must go on */
+typedef int (*ReportErrorType)(int errorcode, const char *error_message);
+ReportErrorType ecs_SetReportErrorFunction(ReportErrorType pfn);
+int ecs_ShouldStopOnError(void);
+int ecs_SetErrorShouldStop _ANSI_ARGS_((ecs_Result *r,
+                              int errorcode, char *error_message));
+
 int ecs_SetSuccess _ANSI_ARGS_((ecs_Result *r));
 int ecs_AdjustResult _ANSI_ARGS_((ecs_Result *r));
 int ecs_SetGeoRegion _ANSI_ARGS_((ecs_Result *r,
diff --git a/patch b/patch
deleted file mode 100644
index f17e010..0000000
--- a/patch
+++ /dev/null
@@ -1,52 +0,0 @@
---- ogdi-dfsg-3.2.0~beta1.orig/configure.in
-+++ ogdi-dfsg-3.2.0~beta1/configure.in
-@@ -349,5 +349,9 @@
- 		[chmod +x ogdi-config])
- 
- AC_OUTPUT(config/generic.mak)
--mv config/generic.mak config/`uname`.mak
- 
-+target=`uname`
-+if test "$target" = "GNU/kFreeBSD" ; then
-+  target=Linux
-+fi
-+mv config/generic.mak config/$target.mak
---- ogdi-dfsg-3.2.0~beta1.orig/configure
-+++ ogdi-dfsg-3.2.0~beta1/configure
-@@ -5278,5 +5875,9 @@
-   $ac_cs_success || { (exit 1); exit 1; }
- fi
- 
--mv config/generic.mak config/`uname`.mak
- 
-+target=`uname`
-+if test "$target" = "GNU/kFreeBSD" ; then
-+  target=Linux
-+fi
-+mv config/generic.mak config/$target.mak
---- ogdi-dfsg-3.2.0~beta1.orig/config/common.mak.in
-+++ ogdi-dfsg-3.2.0~beta1/config/common.mak.in
-@@ -52,6 +52,9 @@
- 
- ifndef TARGET
- TARGET = $(shell uname)
-+ifeq ($(TARGET), GNU/kFreeBSD)
-+TARGET = Linux
-+endif
- endif
- 
- #
---- ogdi-dfsg-3.2.0~beta1.orig/config/common.mak
-+++ ogdi-dfsg-3.2.0~beta1/config/common.mak
-@@ -52,6 +52,9 @@
- 
- ifndef TARGET
- TARGET = $(shell uname)
-+ifeq ($(TARGET), GNU/kFreeBSD)
-+TARGET = Linux
-+endif
- endif
- 
- #
-
-
diff --git a/proj/aasincos.c b/proj/aasincos.c
new file mode 100644
index 0000000..70be86b
--- /dev/null
+++ b/proj/aasincos.c
@@ -0,0 +1,31 @@
+/* arc sin and cosine that will not fail */
+#ifndef lint
+static const char SCCSID[]="@(#)aasincos.c	4.5	93/06/16	GIE	REL";
+#endif
+#include <projects.h>
+#define ONE_TOL	 1.00000000000001
+#define TOL	0.000000001
+	double
+aasin(double v) {
+	double av;
+
+	if ((av = fabs(v)) >= 1.) {
+		if (av > ONE_TOL)
+			pj_errno = -19;
+		return (v < 0. ? -HALFPI : HALFPI);
+	}
+	return asin(v);
+}
+	double
+aacos(double v) {
+	double av;
+
+	if ((av = fabs(v)) >= 1.) {
+		if (av > ONE_TOL)
+			pj_errno = -19;
+		return (v < 0. ? PI : 0.);
+	}
+	return acos(v);
+}
+	double
+asqrt(double v) { return ((v <= 0) ? 0. : sqrt(v)); }
diff --git a/proj/adjlon.c b/proj/adjlon.c
new file mode 100644
index 0000000..2898a03
--- /dev/null
+++ b/proj/adjlon.c
@@ -0,0 +1,25 @@
+/* reduce argument to range +/- PI */
+#ifndef lint
+static const char SCCSID[]="@(#)adjlon.c	4.3	93/06/12	GIE	REL";
+#endif
+#include <math.h>
+/* note: PI adjusted high
+** approx. true val:	3.14159265358979323844
+*/
+#define SPI		3.14159265359
+#define TWOPI	6.2831853071795864769
+double
+adjlon (double lon) {
+  double mod,temp;
+  temp = lon / TWOPI;
+  modf(temp,&mod);
+  if (mod > 0.0) {
+    lon = lon - ((mod-1.0) * TWOPI);
+  } else {
+    lon = lon - ((mod+1.0) * TWOPI);
+  }
+  while ( fabs(lon) > SPI ) {
+    lon += lon < 0. ? TWOPI : -TWOPI;
+  }
+  return( lon );
+}
diff --git a/proj/bch2bps.c b/proj/bch2bps.c
new file mode 100644
index 0000000..f1f8cd8
--- /dev/null
+++ b/proj/bch2bps.c
@@ -0,0 +1,143 @@
+/* convert bivariate w Chebyshev series to w Power series */
+#ifndef lint
+static const char SCCSID[]="@(#)bch2bps.c	4.4	93/09/17	GIE	REL";
+#endif
+#include <projects.h>
+/* basic support procedures */
+	static void /* clear vector to zero */
+clear(UV *p, int n) { static const UV c = {0., 0.}; while (n--) *p++ = c; }
+	static void /* clear matrix rows to zero */
+bclear(UV **p, int n, int m) { while (n--) clear(*p++, m); }
+	static void /* move vector */
+bmove(UV *a, UV *b, int n) { while (n--) *a++ = *b++; }
+	static void /* a <- m * b - c */
+submop(UV *a, double m, UV *b, UV *c, int n) {
+	while (n--) {
+		a->u = m * b->u - c->u;
+		a++->v = m * b++->v - c++->v;
+	}
+}
+	static void /* a <- b - c */
+subop(UV *a, UV *b, UV *c, int n) {
+	while (n--) {
+		a->u = b->u - c->u;
+		a++->v = b++->v - c++->v;
+	}
+}
+	static void /* multiply vector a by scalar m */
+dmult(UV *a, double m, int n) { while(n--) { a->u *= m; a->v *= m; ++a; } }
+	static void /* row adjust a[] <- a[] - m * b[] */
+dadd(UV *a, UV *b, double m, int n) {
+	while(n--) {
+		a->u -= m * b->u;
+		a++->v -= m * b++->v;
+	}
+}
+	static void /* convert row to pover series */
+rows(UV *c, UV *d, int n) {
+	UV sv, *dd;
+	int j, k;
+
+	dd = (UV *)vector1(n-1, sizeof(UV));
+	sv.u = sv.v = 0.;
+	for (j = 0; j < n; ++j) d[j] = dd[j] = sv;
+	d[0] = c[n-1];
+	for (j = n-2; j >= 1; --j) {
+		for (k = n-j; k >= 1; --k) {
+			sv = d[k];
+			d[k].u = 2. * d[k-1].u - dd[k].u;
+			d[k].v = 2. * d[k-1].v - dd[k].v;
+			dd[k] = sv;
+		}
+		sv = d[0];
+		d[0].u = -dd[0].u + c[j].u;
+		d[0].v = -dd[0].v + c[j].v;
+		dd[0] = sv;
+	}
+	for (j = n-1; j >= 1; --j) {
+		d[j].u = d[j-1].u - dd[j].u;
+		d[j].v = d[j-1].v - dd[j].v;
+	}
+	d[0].u = -dd[0].u + .5 * c[0].u;
+	d[0].v = -dd[0].v + .5 * c[0].v;
+	pj_dalloc(dd);
+}
+	static void /* convert columns to power series */
+cols(UV **c, UV **d, int nu, int nv) {
+	UV *sv, **dd;
+	int j, k;
+
+	dd = (UV **)vector2(nu-1, nv-1, sizeof(UV));
+	sv = (UV *)vector1(nv-1, sizeof(UV));
+	bclear(d, nu, nv);
+	bclear(dd, nu, nv);
+	bmove(d[0], c[nu-1], nv);
+	for (j = nu-2; j >= 1; --j) {
+		for (k = nu-j; k >= 1; --k) {
+			bmove(sv, d[k], nv);
+			submop(d[k], 2., d[k-1], dd[k], nv);
+			bmove(dd[k], sv, nv);
+		}
+		bmove(sv, d[0], nv);
+		subop(d[0], c[j], dd[0], nv);
+		bmove(dd[0], sv, nv);
+	}
+	for (j = nu-1; j >= 1; --j)
+		subop(d[j], d[j-1], dd[j], nv);
+	submop(d[0], .5, c[0], dd[0], nv);
+	pj_dalloc(dd);
+	pj_dalloc(sv);
+}
+	static void /* row adjust for range -1 to 1 to a to b */
+rowshft(double a, double b, UV *d, int n) {
+	int k, j;
+	double fac, cnst;
+
+	cnst = 2. / (b - a);
+	fac = cnst;
+	for (j = 1; j < n; ++j) {
+		d[j].u *= fac;
+		d[j].v *= fac;
+		fac *= cnst;
+	}
+	cnst = .5 * (a + b);
+	for (j = 0; j <= n-2; ++j)
+		for (k = n - 2; k >= j; --k) {
+			d[k].u -= cnst * d[k+1].u;
+			d[k].v -= cnst * d[k+1].v;
+		}
+}
+	static void /* column adjust for range -1 to 1 to a to b */
+colshft(double a, double b, UV **d, int n, int m) {
+	int k, j;
+	double fac, cnst;
+
+	cnst = 2. / (b - a);
+	fac = cnst;
+	for (j = 1; j < n; ++j) {
+		dmult(d[j], fac, m);
+		fac *= cnst;
+	}
+	cnst = .5 * (a + b);
+	for (j = 0; j <= n-2; ++j)
+		for (k = n - 2; k >= j; --k)
+			dadd(d[k], d[k+1], cnst, m);
+}
+	int /* entry point */
+bch2bps(UV a, UV b, UV **c, int nu, int nv) {
+	UV **d;
+	int i;
+
+	if (nu < 1 || nv < 1 || !(d = (UV **)vector2(nu, nv, sizeof(UV))))
+		return 0;
+	/* do rows to power series */
+	for (i = 0; i < nu; ++i) {
+		rows(c[i], d[i], nv);
+		rowshft(a.v, b.v, d[i], nv);
+	}
+	/* do columns to power series */
+	cols(d, c, nu, nv);
+	colshft(a.u, b.u, c, nu, nv);
+	pj_dalloc(d);
+	return 1;
+}
diff --git a/proj/bchgen.c b/proj/bchgen.c
new file mode 100644
index 0000000..d36977f
--- /dev/null
+++ b/proj/bchgen.c
@@ -0,0 +1,61 @@
+/* generate double bivariate Chebychev polynomial */
+#ifndef lint
+static const char SCCSID[]="@(#)bchgen.c	4.4	93/06/12	GIE	REL";
+#endif
+#include <projects.h>
+	int
+bchgen(UV a, UV b, int nu, int nv, UV **f, UV(*func)(UV)) {
+	int i, j, k;
+	UV arg, *t, bma, bpa, *c;
+	double d, fac;
+
+	bma.u = 0.5 * (b.u - a.u); bma.v = 0.5 * (b.v - a.v);
+	bpa.u = 0.5 * (b.u + a.u); bpa.v = 0.5 * (b.v + a.v);
+	for ( i = 0; i < nu; ++i) {
+		arg.u = cos(PI * (i + 0.5) / nu) * bma.u + bpa.u;
+		for ( j = 0; j < nv; ++j) {
+			arg.v = cos(PI * (j + 0.5) / nv) * bma.v + bpa.v;
+			f[i][j] = (*func)(arg);
+			if ((f[i][j]).u == HUGE_VAL)
+				return(1);
+		}
+	}
+	if (!(c = vector1(nu, sizeof(UV)))) return 1;
+	fac = 2. / nu;
+	for ( j = 0; j < nv ; ++j) {
+		for ( i = 0; i < nu; ++i) {
+			arg.u = arg.v = 0.;
+			for (k = 0; k < nu; ++k) {
+				d = cos(PI * i * (k + .5) / nu);
+				arg.u += f[k][j].u * d;
+				arg.v += f[k][j].v * d;
+			}
+			arg.u *= fac;
+			arg.v *= fac;
+			c[i] = arg;
+		}
+		for (i = 0; i < nu; ++i)
+			f[i][j] = c[i];
+	}
+	pj_dalloc(c);
+	if (!(c = vector1(nv, sizeof(UV)))) return 1;
+	fac = 2. / nv;
+	for ( i = 0; i < nu; ++i) {
+		t = f[i];
+		for (j = 0; j < nv; ++j) {
+			arg.u = arg.v = 0.;
+			for (k = 0; k < nv; ++k) {
+				d = cos(PI * j * (k + .5) / nv);
+				arg.u += t[k].u * d;
+				arg.v += t[k].v * d;
+			}
+			arg.u *= fac;
+			arg.v *= fac;
+			c[j] = arg;
+		}
+		f[i] = c;
+		c = t;
+	}
+	pj_dalloc(c);
+	return(0);
+}
diff --git a/proj/biveval.c b/proj/biveval.c
new file mode 100644
index 0000000..05f4d48
--- /dev/null
+++ b/proj/biveval.c
@@ -0,0 +1,90 @@
+/* procedures for evaluating Tseries */
+#ifndef lint
+static const char SCCSID[]="@(#)biveval.c	4.4	93/06/12	GIE	REL";
+#endif
+# include <projects.h>
+# define NEAR_ONE	1.00001
+	static UV
+w2, w;
+	static double /* basic bivariate Chebyshev evaluation */
+ceval(C, n) struct PW_COEF *C; {
+	double d=0, dd=0, vd, vdd, tmp, *c;
+	int j;
+
+	for (C += n ; n-- ; --C ) {
+		if (j = C->m) {
+			vd = vdd = 0.;
+			for (c = C->c + --j; j ; --j ) {
+				vd = w2.v * (tmp = vd) - vdd + *c--;
+				vdd = tmp;
+			}
+			d = w2.u * (tmp = d) - dd + w.v * vd - vdd + 0.5 * *c;
+		} else
+			d = w2.u * (tmp = d) - dd;
+		dd = tmp;
+	}
+	if (j = C->m) {
+		vd = vdd = 0.;
+		for (c = C->c + --j; j ; --j ) {
+			vd = w2.v * (tmp = vd) - vdd + *c--;
+			vdd = tmp;
+		}
+		return (w.u * d - dd + 0.5 * ( w.v * vd - vdd + 0.5 * *c ));
+	} else
+		return (w.u * d - dd);
+}
+	UV /* bivariate Chebyshev polynomial entry point */
+bcheval(UV in, Tseries *T) {
+	UV out;
+		/* scale to +-1 */
+ 	w.u = ( in.u + in.u - T->a.u ) * T->b.u;
+ 	w.v = ( in.v + in.v - T->a.v ) * T->b.v;
+	if (fabs(w.u) > NEAR_ONE || fabs(w.v) > NEAR_ONE) {
+		out.u = out.v = HUGE_VAL;
+		pj_errno = -36;
+	} else { /* double evaluation */
+		w2.u = w.u + w.u;
+		w2.v = w.v + w.v;
+		out.u = ceval(T->cu, T->mu);
+		out.v = ceval(T->cv, T->mv);
+	}
+	return out;
+}
+	UV /* bivariate power polynomial entry point */
+bpseval(UV in, Tseries *T) {
+	UV out;
+	double *c, row;
+	int i, m;
+
+	out.u = out.v = 0.;
+	for (i = T->mu; i >= 0; --i) {
+		row = 0.;
+		if (m = T->cu[i].m) {
+			c = T->cu[i].c + m;
+			while (m--)
+				row = *--c + in.v * row;
+		}
+		out.u = row + in.u * out.u;
+	}
+	for (i = T->mv; i >= 0; --i) {
+		row = 0.;
+		if (m = T->cv[i].m) {
+			c = T->cv[i].c + m;
+			while (m--)
+				row = *--c + in.v * row;
+		}
+		out.v = row + in.u * out.v;
+	}
+	return out;
+}
+
+UV /* general entry point selecting evaluation mode */
+biveval(UV in, Tseries *T) {
+
+    if (T->power) {
+        return bpseval(in, T);
+    } else {
+        return bcheval(in, T);
+    }
+}
+
diff --git a/proj/dmstor.c b/proj/dmstor.c
new file mode 100644
index 0000000..5b4bccf
--- /dev/null
+++ b/proj/dmstor.c
@@ -0,0 +1,78 @@
+/* Convert DMS string to radians */
+#ifndef lint
+static const char SCCSID[]="@(#)dmstor.c	4.4	93/06/16	GIE	REL";
+#endif
+#include <projects.h>
+#include <string.h>
+#include <ctype.h>
+
+/* following should be sufficient for all but the rediculous */
+#define MAX_WORK 64
+	static const char
+*sym = "NnEeSsWw";
+	static const double
+vm[] = {
+	.0174532925199433,
+	.0002908882086657216,
+	.0000048481368110953599
+};
+	double
+dmstor(const char *is, char **rs) {
+	int sign, n, nl;
+	char *p, *s, work[MAX_WORK];
+	double v, tv;
+
+	if (rs)
+		*rs = (char *)is;
+	/* copy sting into work space */
+	while (isspace(sign = *is)) ++is;
+	for (n = MAX_WORK, s = work, p = (char *)is; isgraph(*p) && --n ; )
+		*s++ = *p++;
+	*s = '\0';
+	/* it is possible that a really odd input (like lots of leading
+		zeros) could be truncated in copying into work.  But ... */
+	sign = *(s = work);
+	if (sign == '+' || sign == '-') s++;
+	else sign = '+';
+	for (v = 0., nl = 0 ; nl < 3 ; nl = n + 1 ) {
+		if (!(isdigit(*s) || *s == '.')) break;
+		if ((tv = strtod(s, &s)) == HUGE_VAL)
+			return tv;
+		switch (*s) {
+		case 'D': case 'd':
+			n = 0; break;
+		case '\'':
+			n = 1; break;
+		case '"':
+			n = 2; break;
+		case 'r': case 'R':
+			if (nl) {
+				pj_errno = -16;
+				return HUGE_VAL;
+			}
+			++s;
+			v = tv;
+			goto skip;
+		default:
+			v += tv * vm[nl];
+		skip:	n = 4;
+			continue;
+		}
+		if (n < nl) {
+			pj_errno = -16;
+			return HUGE_VAL;
+		}
+		v += tv * vm[n];
+		++s;
+	}
+		/* postfix sign */
+	if (*s && (p = strchr(sym, *s))) {
+		sign = (p - sym) >= 4 ? '-' : '+';
+		++s;
+	}
+	if (sign == '-')
+		v = -v;
+	if (rs) /* return point of next char after valid string */
+		*rs = (char *)is + (s - work);
+	return v;
+}
diff --git a/proj/emess.c b/proj/emess.c
new file mode 100644
index 0000000..a7cf24f
--- /dev/null
+++ b/proj/emess.c
@@ -0,0 +1,44 @@
+/* Error message processing */
+#ifndef lint
+static const char SCCSID[]="@(#)emess.c	4.4	93/10/08	GIE	REL";
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <string.h>
+#define EMESS_ROUTINE
+#include "emess.h"
+	void
+emess(int code, char *fmt, ...) {
+	va_list args;
+
+	va_start(args, fmt);
+	/* prefix program name, if given */
+	if (fmt != NULL)
+		(void)fprintf(stderr,"<%s>: ",emess_dat.Prog_name);
+	/* print file name and line, if given */
+	if (emess_dat.File_name != NULL && *emess_dat.File_name) {
+		(void)fprintf(stderr,"while processing file: %s", emess_dat.File_name);
+		if (emess_dat.File_line > 0)
+			(void)fprintf(stderr,", line %d\n", emess_dat.File_line);
+		else
+			(void)fputc('\n', stderr);
+	} else
+		putc('\n', stderr);
+	/* if |code|==2, print errno code data */
+	if (code == 2 || code == -2)
+		(void)fprintf(stderr, "Sys errno: %d: %s\n",
+			errno, strerror(errno));
+	/* post remainder of call data */
+	(void)vfprintf(stderr,fmt,args);
+	va_end(args);
+	/* die if code positive */
+	if (code > 0) {
+		(void)fputs("\nprogram abnormally terminated\n", stderr);
+		exit(code);
+	}
+	else
+		putc('\n', stderr);
+}
diff --git a/proj/emess.h b/proj/emess.h
new file mode 100644
index 0000000..6724a06
--- /dev/null
+++ b/proj/emess.h
@@ -0,0 +1,32 @@
+/* Error message processing header file */
+#ifndef EMESS_H
+#define EMESS_H
+
+#ifndef lint
+static char EMESS_H_ID[] = "@(#)emess.h	4.1	93/03/08	GIE	REL";
+#endif
+
+struct EMESS {
+	char	*File_name,	/* input file name */
+			*Prog_name;	/* name of program */
+	int		File_line;	/* approximate line read
+							where error occured */
+};
+
+#ifdef EMESS_ROUTINE	/* use type */
+/* for emess procedure */
+struct EMESS emess_dat = { (char *)0, (char *)0, 0 };
+
+#ifdef sun /* Archaic SunOs 4.1.1, etc. */
+extern char *sys_errlist[];
+#define strerror(n) (sys_errlist[n])
+#endif
+
+#else	/* for for calling procedures */
+
+extern struct EMESS emess_dat;
+void emess(int, char *, ...);
+
+#endif /* use type */
+
+#endif /* end EMESS_H */
diff --git a/proj/gen_cheby.c b/proj/gen_cheby.c
new file mode 100644
index 0000000..bb193a2
--- /dev/null
+++ b/proj/gen_cheby.c
@@ -0,0 +1,73 @@
+/* generates 'T' option output */
+#ifndef lint
+static const char SCCSID[]="@(#)gen_cheby.c	4.6	93/06/12	GIE	REL";
+#endif
+#define PJ_LIB__
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <projects.h>
+#include "emess.h"
+#ifndef COEF_LINE_MAX
+#define COEF_LINE_MAX 60
+#endif
+	void
+gen_cheby(int inverse, UV (*proj)(), char *s, PJ *P, int iargc, char **iargv) {
+	int NU = 15, NV = 15, i, res = -1, errin = 0, pwr;
+	char *arg, fmt[15];
+	UV low, upp, resid;
+	Tseries *F;
+	double (*input)();
+
+	input = inverse ? strtod : dmstor;
+	if (*s) low.u = input(s, &s); else ++errin;
+	if (*s == ',') upp.u = input(s+1, &s); else ++errin;
+	if (*s == ',') low.v = input(s+1, &s); else ++errin;
+	if (*s == ',') upp.v = input(s+1, &s); else ++errin;
+	if (errin)
+		emess(16,"null or absent -T parameters");
+	if (*s == ',') if (*++s != ',') res = strtol(s, &s, 10);
+	if (*s == ',') if (*++s != ',') NU = strtol(s, &s, 10);
+	if (*s == ',') if (*++s != ',') NV = strtol(s, &s, 10);
+	pwr = s && *s && !strcmp(s, ",P");
+	(void)printf("#proj_%s\n#    run-line:\n",
+		pwr ? "Power" : "Chebyshev");
+	if (iargc > 0) { /* proj execution audit trail */
+		int n = 0, L;
+
+		for( i = 0 ; iargc ; --iargc) {
+			arg = *iargv++;
+			if (*arg != '+') {
+				if (!n) { putchar('#'); ++n; }
+				(void)printf(" %s%n",arg, &L);
+				if ((n += L) > 50) { putchar('\n'); n = 0; }
+			}
+		}
+		if (n) putchar('\n');
+	}
+	(void)printf("# projection parameters\n");
+	pj_pr_list(P);
+	if (low.u == upp.u || low.v >= upp.v)
+		emess(16,"approx. argument range error");
+	if (low.u > upp.u)
+		low.u -= TWOPI;
+	if (NU < 2 || NV < 2)
+		emess(16,"approx. work dimensions (%d %d) too small",NU,NV);
+	if (!(F = mk_cheby(low, upp, pow(10., (double)res)*.5, &resid, proj,
+		NU, NV, pwr)))
+		emess(16,"generation of approx failed\nreason: %s\n",
+			pj_strerrno(errno));
+	(void)printf("%c,%.12g,%.12g,%.12g,%.12g,%.12g\n",inverse?'I':'F',
+		P->lam0*RAD_TO_DEG,
+		low.u*(inverse?1.:RAD_TO_DEG),upp.u*(inverse?1.:RAD_TO_DEG),
+		low.v*(inverse?1.:RAD_TO_DEG),upp.v*(inverse?1.:RAD_TO_DEG));
+	if (pwr)
+		strcpy(fmt, "%.15g");
+	else if (res <= 0)
+		(void)sprintf(fmt,"%%.%df",-res+1);
+	else
+		(void)strcpy(fmt,"%.0f");
+	pr_series(F, stdout, fmt);
+	(void)printf("# |u,v| sums %g %g\n#end_proj_%s\n",
+		resid.u, resid.v, pwr ? "Power" : "Chebyshev");
+}
diff --git a/proj/geod.c b/proj/geod.c
new file mode 100644
index 0000000..e9f2e1e
--- /dev/null
+++ b/proj/geod.c
@@ -0,0 +1,238 @@
+#ifndef lint
+static const char SCCSID[]="@(#)geod.c	4.4	93/06/12	GIE	REL";
+#endif
+/* <<<< Geodesic filter program >>>> */
+# include "projects.h"
+# include <stdio.h>
+# include "geodesic.h"
+# include "emess.h"
+# include <ctype.h>
+# include <string.h>
+
+# define MAXLINE 200
+# define MAX_PARGS 50
+# define TAB putchar('\t')
+	static int
+fullout = 0,	/* output full set of geodesic values */
+tag = '#',	/* beginning of line tag character */
+pos_azi = 0,	/* output azimuths as positive values */
+inverse = 0;	/* != 0 then inverse geodesic */
+	static char
+*oform = (char *)0,	/* output format for decimal degrees */
+*osform = "%.3f",	/* output format for S */
+pline[50],		/* work string */
+*usage =
+"usage(v. 4.REL): %s [ -afFptTwW [args] ] [ +opts[=arg] ] [ files ]\n";
+	static void
+printLL(double p, double l) {
+	if (oform) {
+		(void)printf(oform, p * RAD_TO_DEG); TAB;
+		(void)printf(oform, l * RAD_TO_DEG);
+	} else {
+		(void)fputs(rtodms(pline, p, 'N', 'S'),stdout); TAB;
+		(void)fputs(rtodms(pline, l, 'E', 'W'),stdout);
+	}
+}
+	static void
+do_arc(void) {
+	double az;
+
+	printLL(phi2, lam2); putchar('\n');
+	for (az = al12; n_alpha--; ) {
+		al12 = az = adjlon(az + del_alpha);
+		geod_prefor();
+		geod_forwd();
+		printLL(phi2, lam2); putchar('\n');
+	}
+}
+	static void	/* generate intermediate geodesic coordinates */
+do_geod(void) {
+	double phil, laml, del_S;
+
+	phil = phi2;
+	laml = lam2;
+	printLL(phi1, lam1); putchar('\n');
+	for ( S = del_S = S / n_S; --n_S; S += del_S) {
+		geod_forwd();
+		printLL(phi2, lam2); putchar('\n');
+	}
+	printLL(phil, laml); putchar('\n');
+}
+	void static	/* file processing function */
+process(FILE *fid) {
+	char line[MAXLINE+3], *s;
+
+	for (;;) {
+		++emess_dat.File_line;
+		if (!(s = fgets(line, MAXLINE, fid)))
+			break;
+		if (!strchr(s, '\n')) { /* overlong line */
+			int c;
+			strcat(s, "\n");
+			/* gobble up to newline */
+			while ((c = fgetc(fid)) != EOF && c != '\n') ;
+		}
+		if (*s == tag) {
+			fputs(line, stdout);
+			continue;
+		}
+		phi1 = dmstor(s, &s);
+		lam1 = dmstor(s, &s);
+		if (inverse) {
+			phi2 = dmstor(s, &s);
+			lam2 = dmstor(s, &s);
+			geod_invrs();
+		} else {
+			al12 = dmstor(s, &s);
+			S = strtod(s, &s) * to_meter;
+			geod_prefor();
+			geod_forwd();
+		}
+		if (!*s && (s > line)) --s; /* assumed we gobbled \n */
+		if (pos_azi) {
+			if (al12 < 0.) al12 += TWOPI;
+			if (al21 < 0.) al21 += TWOPI;
+		}
+		if (fullout) {
+			printLL(phi1, lam1); TAB;
+			printLL(phi2, lam2); TAB;
+			if (oform) {
+				(void)printf(oform, al12 * RAD_TO_DEG); TAB;
+				(void)printf(oform, al21 * RAD_TO_DEG); TAB;
+				(void)printf(osform, S * fr_meter);
+			}  else {
+				(void)fputs(rtodms(pline, al12, 0, 0), stdout); TAB;
+				(void)fputs(rtodms(pline, al21, 0, 0), stdout); TAB;
+				(void)printf(osform, S * fr_meter);
+			}
+		} else if (inverse)
+			if (oform) {
+				(void)printf(oform, al12 * RAD_TO_DEG); TAB;
+				(void)printf(oform, al21 * RAD_TO_DEG); TAB;
+				(void)printf(osform, S * fr_meter);
+			} else {
+				(void)fputs(rtodms(pline, al12, 0, 0), stdout); TAB;
+				(void)fputs(rtodms(pline, al21, 0, 0), stdout); TAB;
+				(void)printf(osform, S * fr_meter);
+			}
+		else {
+			printLL(phi2, lam2); TAB;
+			if (oform)
+				(void)printf(oform, al21 * RAD_TO_DEG);
+			else
+				(void)fputs(rtodms(pline, al21, 0, 0), stdout);
+		}
+		(void)fputs(s, stdout);
+	}
+}
+    static char
+*pargv[MAX_PARGS];
+	static int
+pargc = 0;
+	void
+main(int argc, char **argv) {
+	char *arg, **eargv = argv, *strnchr();
+	FILE *fid;
+	static int eargc = 0, c;
+
+	if (emess_dat.Prog_name = strrchr(*argv,'/')) ++emess_dat.Prog_name;
+	else emess_dat.Prog_name = *argv;
+	inverse = ! strncmp(emess_dat.Prog_name, "inv", 3);
+		/* process run line arguments */
+	while (--argc > 0) { /* collect run line arguments */
+		if(**++argv == '-') for(arg = *argv;;) {
+			switch(*++arg) {
+			case '\0': /* position of "stdin" */
+				if (arg[-1] == '-') eargv[eargc++] = "-";
+				break;
+			case 'a': /* output full set of values */
+				fullout = 1;
+				continue;
+			case 'I': /* alt. inverse spec. */
+				inverse = 1;
+				continue;
+			case 't': /* set col. one char */
+				if (arg[1]) tag = *++arg;
+				else emess(1,"missing -t col. 1 tag");
+				continue;
+			case 'W': /* specify seconds precision */
+			case 'w': /* -W for constant field width */
+				if ((c = arg[1]) && isdigit(c)) {
+					set_rtodms(c - '0', *arg == 'W');
+					++arg;
+				} else
+				    emess(1,"-W argument missing or non-digit");
+				continue;
+			case 'f': /* alternate output format degrees or xy */
+				if (--argc <= 0)
+noargument:		   emess(1,"missing argument for -%c",*arg);
+				oform = *++argv;
+				continue;
+			case 'F': /* alternate output format degrees or xy */
+				if (--argc <= 0) goto noargument;
+				osform = *++argv;
+				continue;
+			case 'l':
+				if (!arg[1] || arg[1] == 'e') { /* list of ellipsoids */
+					struct PJ_ELLPS *le;
+	
+					for (le = pj_ellps; le->id ; ++le)
+						(void)printf("%9s %-16s %-16s %s\n",
+						le->id, le->major, le->ell, le->name);
+				 		emess(1,"invalid list option: l%c",arg[1]);
+							emess(1,"-l[p|e] terminates program");
+				} else if (arg[1] == 'u') { /* list of units */
+					struct PJ_UNITS *lu;
+
+					for (lu = pj_units; lu->id ; ++lu)
+						(void)printf("%12s %-20s %s\n",
+				 			lu->id, lu->to_meter, lu->name);
+				} else
+					emess(1,"invalid list option: l%c",arg[1]);
+				emess(1,"will not proceed after display list option");
+			case 'p': /* output azimuths as positive */
+				pos_azi = 1;
+				continue;
+			default:
+				emess(1, "invalid option: -%c",*arg);
+				break;
+			}
+			break;
+		} else if (**argv == '+') /* + argument */
+			if (pargc < MAX_PARGS)
+				pargv[pargc++] = *argv + 1;
+			else
+				emess(1,"overflowed + argument table");
+		else /* assumed to be input file name(s) */
+			eargv[eargc++] = *argv;
+	}
+	/* done with parameter and control input */
+	geod_setup(pargc, pargv); /* setup projection */
+	if ((n_alpha || n_S) && eargc)
+		emess(1,"files specified for arc/geodesic mode");
+	if (n_alpha)
+		do_arc();
+	else if (n_S)
+		do_geod();
+	else { /* process input file list */
+		if (eargc == 0) /* if no specific files force sysin */
+			eargv[eargc++] = "-";
+		for ( ; eargc-- ; ++eargv) {
+			if (**eargv == '-') {
+				fid = stdin;
+				emess_dat.File_name = "<stdin>";
+			} else {
+				if ((fid = fopen(*eargv, "r")) == NULL) {
+					emess(-2, *eargv, "input file");
+					continue;
+				}
+				emess_dat.File_name = *eargv;
+			}
+			emess_dat.File_line = 0;
+			process(fid);
+			(void)fclose(fid);
+			emess_dat.File_name = (char *)0;
+		}
+	}
+	exit(0); /* normal completion */
+}
diff --git a/proj/geod_forwd.c b/proj/geod_forwd.c
new file mode 100644
index 0000000..3749daa
--- /dev/null
+++ b/proj/geod_forwd.c
@@ -0,0 +1,106 @@
+#ifndef lint
+static const char SCCSID[]="@(#)geod_forwd.c	4.4	93/10/03	GIE	REL";
+#endif
+# include "projects.h"
+# include "geodesic.h"
+# define MERI_TOL 1e-9
+	static double
+th1,costh1,sinth1,sina12,cosa12,M,N,c1,c2,D,P,s1;
+	static int
+merid, signS;
+	void
+geod_prefor(void) {
+	al12 = adjlon(al12); /* reduce to  +- 0-PI */
+	signS = fabs(al12) > HALFPI ? 1 : 0;
+	th1 = ellipse ? atan(onef * tan(phi1)) : phi1;
+	costh1 = cos(th1);
+	sinth1 = sin(th1);
+	if ((merid = fabs(sina12 = sin(al12)) < MERI_TOL)) {
+		sina12 = 0.;
+		cosa12 = fabs(al12) < HALFPI ? 1. : -1.;
+		M = 0.;
+	} else {
+		cosa12 = cos(al12);
+		M = costh1 * sina12;
+	}
+	N = costh1 * cosa12;
+	if (ellipse) {
+		if (merid) {
+			c1 = 0.;
+			c2 = f4;
+			D = 1. - c2;
+			D *= D;
+			P = c2 / D;
+		} else {
+			c1 = f * M;
+			c2 = f4 * (1. - M * M);
+			D = (1. - c2)*(1. - c2 - c1 * M);
+			P = (1. + .5 * c1 * M) * c2 / D;
+		}
+	}
+	if (merid) s1 = HALFPI - th1;
+	else {
+		s1 = (fabs(M) >= 1.) ? 0. : acos(M);
+		s1 =  sinth1 / sin(s1);
+		s1 = (fabs(s1) >= 1.) ? 0. : acos(s1);
+	}
+}
+	void
+geod_forwd(void) {
+	double d,sind,u,V,X,ds,cosds,sinds,ss,de;
+
+	if (ellipse) {
+		d = S / (D * a);
+		if (signS) d = -d;
+		u = 2. * (s1 - d);
+		V = cos(u + d);
+		X = c2 * c2 * (sind = sin(d)) * cos(d) * (2. * V * V - 1.);
+		ds = d + X - 2. * P * V * (1. - 2. * P * cos(u)) * sind;
+		ss = s1 + s1 - ds;
+	} else {
+		ds = S / a;
+		if (signS) ds = - ds;
+	}
+	cosds = cos(ds);
+	sinds = sin(ds);
+	if (signS) sinds = - sinds;
+	al21 = N * cosds - sinth1 * sinds;
+	if (merid) {
+		phi2 = atan( tan(HALFPI + s1 - ds) / onef);
+		if (al21 > 0.) {
+			al21 = PI;
+			if (signS)
+				de = PI;
+			else {
+				phi2 = - phi2;
+				de = 0.;
+			}
+		} else {
+			al21 = 0.;
+			if (signS) {
+				phi2 = - phi2;
+				de = 0;
+			} else
+				de = PI;
+		}
+	} else {
+		al21 = atan(M / al21);
+		if (al21 > 0)
+			al21 += PI;
+		if (al12 < 0.)
+			al21 -= PI;
+		al21 = adjlon(al21);
+		phi2 = atan(-(sinth1 * cosds + N * sinds) * sin(al21) /
+			(ellipse ? onef * M : M));
+		de = atan2(sinds * sina12 ,
+			(costh1 * cosds - sinth1 * sinds * cosa12));
+		if (ellipse)
+			if (signS)
+				de += c1 * ((1. - c2) * ds +
+					c2 * sinds * cos(ss));
+			else
+				de -= c1 * ((1. - c2) * ds -
+					c2 * sinds * cos(ss));
+	}
+	lam2 = adjlon( lam1 + de );
+}
diff --git a/proj/geod_invrs.c b/proj/geod_invrs.c
new file mode 100644
index 0000000..82e6fd9
--- /dev/null
+++ b/proj/geod_invrs.c
@@ -0,0 +1,59 @@
+#ifndef lint
+static const char SCCSID[]="@(#)geod_invrs.c	4.3	93/06/12	GIE	REL";
+#endif
+# include "projects.h"
+# include "geodesic.h"
+# define DTOL	1e-12
+	void
+geod_invrs(void) {
+	double	th1,th2,thm,dthm,dlamm,dlam,sindlamm,costhm,sinthm,cosdthm,
+		sindthm,L,E,cosd,d,X,Y,T,sind,tandlammp,u,v,D,A,B;
+
+	if (ellipse) {
+		th1 = atan(onef * tan(phi1));
+		th2 = atan(onef * tan(phi2));
+	} else {
+		th1 = phi1;
+		th2 = phi2;
+	}
+	thm = .5 * (th1 + th2);
+	dthm = .5 * (th2 - th1);
+	dlamm = .5 * ( dlam = adjlon(lam2 - lam1) );
+	if (fabs(dlam) < DTOL && fabs(dthm) < DTOL) {
+		al12 =  al21 = S = 0.;
+		return;
+	}
+	sindlamm = sin(dlamm);
+	costhm = cos(thm);	sinthm = sin(thm);
+	cosdthm = cos(dthm);	sindthm = sin(dthm);
+	L = sindthm * sindthm + (cosdthm * cosdthm - sinthm * sinthm)
+		* sindlamm * sindlamm;
+	d = acos(cosd = 1 - L - L);
+	if (ellipse) {
+		E = cosd + cosd;
+		sind = sin( d );
+		Y = sinthm * cosdthm;
+		Y *= (Y + Y) / (1. - L);
+		T = sindthm * costhm;
+		T *= (T + T) / L;
+		X = Y + T;
+		Y -= T;
+		T = d / sind;
+		D = 4. * T * T;
+		A = D * E;
+		B = D + D;
+		S = a * sind * (T - f4 * (T * X - Y) +
+			f64 * (X * (A + (T - .5 * (A - E)) * X) -
+			Y * (B + E * Y) + D * X * Y));
+		tandlammp = tan(.5 * (dlam - .25 * (Y + Y - E * (4. - X)) *
+			(f2 * T + f64 * (32. * T - (20. * T - A)
+			* X - (B + 4.) * Y)) * tan(dlam)));
+	} else {
+		S = a * d;
+		tandlammp = tan(dlamm);
+	}
+	u = atan2(sindthm , (tandlammp * costhm));
+	v = atan2(cosdthm , (tandlammp * sinthm));
+	al12 = adjlon(TWOPI + v - u);
+	al21 = adjlon(TWOPI - v - u);
+}
diff --git a/proj/geod_setup.c b/proj/geod_setup.c
new file mode 100644
index 0000000..58dfee0
--- /dev/null
+++ b/proj/geod_setup.c
@@ -0,0 +1,72 @@
+#ifndef lint
+static const char SCCSID[]="@(#)geod_setup.c	4.6	93/06/12	GIE	REL";
+#endif
+#include "projects.h"
+#include "geodesic.h"
+	void
+geod_setup(int argc, char **argv) {
+	paralist *start = 0, *curr;
+	double es;
+	char *name;
+	int i;
+
+    /* put arguments into internal linked list */
+	if (argc <= 0)
+		emess(1, "no arguments in initialization list");
+	for (i = 0; i < argc; ++i)
+		if (i)
+			curr = curr->next = pj_mkparam(argv[i]);
+		else
+			start = curr = pj_mkparam(argv[i]);
+	/* set elliptical parameters */
+	if (pj_ell_set(start, &a, &es)) emess(1,"ellipse setup failure");
+	/* set units */
+	if (name = pj_param(start, "sunits").s) {
+		char *s;
+
+		for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i) ;
+		if (!s)
+			emess(1,"%s unknown unit conversion id", name);
+		fr_meter = 1. / (to_meter = atof(pj_units[i].to_meter));
+	} else
+		to_meter = fr_meter = 1.;
+	if (ellipse = es != 0.) {
+		onef = sqrt(1. - es);
+		f = 1 - onef;
+		f2 = f/2;
+		f4 = f/4;
+		f64 = f*f/64;
+	} else {
+		onef = 1.;
+		f = f2 = f4 = f64 = 0.;
+	}
+	/* check if line or arc mode */
+	if (pj_param(start, "tlat_1").i) {
+		double del_S;
+#undef f
+		phi1 = pj_param(start, "rlat_1").f;
+		lam1 = pj_param(start, "rlon_1").f;
+		if (pj_param(start, "tlat_2").i) {
+			phi2 = pj_param(start, "rlat_2").f;
+			lam2 = pj_param(start, "rlon_2").f;
+			geod_invrs();
+			geod_prefor();
+		} else if (S = pj_param(start, "dS").f) {
+			al12 = pj_param(start, "rA").f;
+			geod_prefor();
+			geod_forwd();
+		} else emess(1,"incomplete geodesic/arc info");
+		if ((n_alpha = pj_param(start, "in_A").i) > 0) {
+			if (!(del_alpha = pj_param(start, "rdel_A").f))
+				emess(1,"del azimuth == 0");
+		} else if (del_S = fabs(pj_param(start, "ddel_S").f)) {
+			n_S = S / del_S + .5;
+		} else if ((n_S = pj_param(start, "in_S").i) <= 0)
+			emess(1,"no interval divisor selected");
+	}
+	/* free up linked list */
+	for ( ; start; start = curr) {
+		curr = start->next;
+		pj_dalloc(start);
+	}
+}
diff --git a/proj/geodesic.h b/proj/geodesic.h
new file mode 100644
index 0000000..a1daea4
--- /dev/null
+++ b/proj/geodesic.h
@@ -0,0 +1,35 @@
+#ifndef lint
+static char GEODESIC_H_ID[] = "@(#)geodesic.h	4.1	93/03/08	GIE	REL";
+#endif
+extern double dmstor();
+struct geodesic {
+	double	A;
+	double	LAM1, PHI1, ALPHA12;
+	double	LAM2, PHI2, ALPHA21;
+	double	DIST;
+	double	ONEF, FLAT, FLAT2, FLAT4, FLAT64;
+	int	ELLIPSE;
+} GEODESIC;
+# define a	GEODESIC.A
+# define lam1	GEODESIC.LAM1
+# define phi1	GEODESIC.PHI1
+# define al12	GEODESIC.ALPHA12
+# define lam2	GEODESIC.LAM2
+# define phi2	GEODESIC.PHI2
+# define al21	GEODESIC.ALPHA21
+# define S	GEODESIC.DIST
+# define f	GEODESIC.FLAT
+# define onef	GEODESIC.ONEF
+# define f2	GEODESIC.FLAT2
+# define f4	GEODESIC.FLAT4
+# define ff2	GEODESIC.FLAT4
+# define f64	GEODESIC.FLAT64
+# define ellipse GEODESIC.ELLIPSE
+	int
+n_alpha, n_S;
+	double
+to_meter, fr_meter, del_alpha;
+void geod_setup(int, char **);
+void geod_forwd(void);
+void geod_prefor(void);
+void geod_invrs(void);
diff --git a/proj/hypot.c b/proj/hypot.c
new file mode 100644
index 0000000..269c146
--- /dev/null
+++ b/proj/hypot.c
@@ -0,0 +1,39 @@
+#ifndef lint
+static const char SCCSID[]="@(#)hypot.c	4.4	93/06/12	GIE	REL";
+#endif
+/* hypot - sqrt(x * x + y * y)
+**
+**	Because this was omitted from the ANSI standards, this version
+** 	is included for those systems that do not include hypot as an
+**	extension to libm.a.  Note: GNU version was not used because it
+**	was not properly coded to minimize potential overflow.
+**
+**	The proper technique for determining hypot is to factor out the
+**	larger of the two terms,  thus leaving a possible case of float
+**	overflow when max(x,y)*sqrt(2) > max machine value.  This allows
+**	a wider range of numbers than the alternative of the sum of the
+**	squares < max machine value.  For an Intel x87 IEEE double of
+**	approximately 1.8e308, only argument values > 1.27e308 are at
+**	risk of causing overflow.  Whereas, not using this method limits
+**	the range to values less that 9.5e153 --- a considerable reduction
+**	in range!
+*/
+extern double sqrt(double);
+	double
+hypot(double x, double y) {
+	if ( x < 0.)
+		x = -x;
+	else if (x == 0.)
+		return (y < 0. ? -y : y);
+	if (y < 0.)
+		y = -y;
+	else if (y == 0.)
+		return (x);
+	if ( x < y ) {
+		x /= y;
+		return ( y * sqrt( 1. + x * x ) );
+	} else {
+		y /= x;
+		return ( x * sqrt( 1. + y * y ) );
+	}
+}
diff --git a/proj/makefile b/proj/makefile
new file mode 100644
index 0000000..a5d80cd
--- /dev/null
+++ b/proj/makefile
@@ -0,0 +1,55 @@
+#
+#  PROJ4.1 Projection transformation library.
+#
+#  Copyright (c) 1997 Logiciels et Applications Scientifiques (L.A.S.) Inc.
+#  Il est strictement interdit de publier ou de devoiler le contenu de ce
+#  programme sans avoir prealablement obtenu la permission de L.A.S. Inc.
+#  It is strictly forbidden to publish or divulge the content of
+#  these programs without the prior permission of L.A.S. Inc.
+#
+
+TOBEGEN = proj
+TARGETGEN = $(ARCHGEN)
+
+SOURCES	= pj_aea.c pj_aeqd.c pj_airy.c pj_aitoff.c \
+	  pj_august.c pj_bacon.c pj_bipc.c pj_boggs.c \
+	  pj_bonne.c pj_cass.c pj_cc.c pj_cea.c \
+	  pj_collg.c pj_dense.c pj_eck1.c pj_eck2.c \
+	  pj_eck3.c pj_eck4.c pj_eck5.c pj_eck6.c \
+	  pj_eisen.c pj_eqc.c pj_eqdc.c pj_fourn.c \
+	  pj_gall.c pj_gnom.c pj_hammer.c pj_hataea.c \
+	  pj_laea.c pj_lagrng.c pj_lcc.c pj_loxim.c \
+	  pj_mbtfpp.c pj_mbtfpq.c pj_mbtfps.c pj_merc.c \
+	  pj_mill.c pj_moll.c pj_nocol.c pj_nsper.c \
+	  pj_ocea.c pj_omerc.c pj_ortho.c pj_parab.c \
+	  pj_pconic.c pj_poly.c pj_putp2.c pj_putp5.c \
+	  pj_quau.c pj_robin.c pj_rpoly.c pj_sinu.c \
+	  pj_stere.c pj_tcc.c pj_tcea.c pj_tmerc.c \
+	  pj_vandg.c pj_vandg2.c pj_vandg4.c pj_wag7.c \
+	  pj_wink1.c pj_goode.c pj_chamb.c pj_lsat.c \
+	  pj_mod_ster.c pj_tpeqd.c pj_nzmg.c pj_labrd.c \
+	  pj_ob_tran.c \
+	  pj_auth.c pj_fwd.c pj_init.c pj_inv.c \
+	  pj_msfn.c pj_mlfn.c pj_phi2.c pj_qsfn.c \
+	  pj_tsfn.c mk_cheby.c pj_list.c vector1.c \
+	  bchgen.c bch2bps.c biveval.c pj_open_lib.c \
+	  pj_ellps.c pj_factors.c pj_deriv.c aasincos.c \
+	  pj_param.c pj_ell_set.c pj_units.c pj_pr_list.c \
+	  pj_zpoly1.c pj_malloc.c pj_strerrno.c nad_cvt.c \
+	  nad_init.c nad_interp.c \
+	  adjlon.c dmstor.c rtodms.c \
+	  pj_errno.c $(HYPOT) $(STRTOD)
+
+INCLUDES     	= $(CURRENT_INCLUDE)
+
+CFLAGS 		= $(INCLUDES) $(COMMON_CFLAGS) 
+
+include $(TOPDIR)/config/common.mak
+
+all: MKOBJECTDIR 
+	$(MAKE) --directory $(OBJDIR) -f ../makefile PASS='depend' $(TARGETGEN)
+
+uninstall:
+	-$(RM) $(PROJ_LIB)
+
+clean: default-clean
diff --git a/proj/mk_cheby.c b/proj/mk_cheby.c
new file mode 100644
index 0000000..453c8ec
--- /dev/null
+++ b/proj/mk_cheby.c
@@ -0,0 +1,164 @@
+#ifndef lint
+static const char SCCSID[]="@(#)mk_cheby.c	4.4	93/06/12	GIE	REL";
+#endif
+#include <projects.h>
+	static void /* sum coefficients less than res */
+eval(UV **w, int nu, int nv, double res, UV *resid) {
+	int i, j;
+	double ab;
+	UV *s;
+
+	resid->u = resid->v = 0.;
+	for (i = 0; i < nu; ++i)
+		for (s = w[i], j = 0; j < nv; ++j, ++s) {
+			if ((ab = fabs(s->u)) < res)
+				resid->u += ab;
+			if ((ab = fabs(s->v)) < res)
+				resid->v += ab;
+		}
+}
+	static Tseries * /* create power series structure */
+makeT(int nru, int nrv) {
+	Tseries *T;
+	int i;
+
+	if ((T = (Tseries *)pj_malloc(sizeof(Tseries))) &&
+		(T->cu = (struct PW_COEF *)pj_malloc(
+			sizeof(struct PW_COEF) * nru)) &&
+		(T->cv = (struct PW_COEF *)pj_malloc(
+			sizeof(struct PW_COEF) * nrv))) {
+		for (i = 0; i < nru; ++i)
+			T->cu[i].c = 0;
+		for (i = 0; i < nrv; ++i)
+			T->cv[i].c = 0;
+		return T;
+	} else
+		return 0;
+}
+	Tseries *
+mk_cheby(UV a, UV b, double res, UV *resid, UV (*func)(UV), 
+	int nu, int nv, int power) {
+	int j, i, nru, nrv, *ncu, *ncv;
+	Tseries *T;
+	UV **w;
+	double cutres;
+
+	if (!(w = (UV **)vector2(nu-1, nv-1, sizeof(UV))) ||
+		!(ncu = (int *)vector1(nu + nv - 2, sizeof(int))))
+		return 0;
+	ncv = ncu + nu;
+	if (!bchgen(a, b, nu, nv, w, func)) {
+		UV *s;
+		double ab, *p;
+
+		/* analyse coefficients and adjust until residual OK */
+		cutres = res;
+		for (i = 4; i ; --i) {
+			eval(w, nu, nv, cutres, resid);
+			if (resid->u < res && resid->v < res)
+				break;
+			cutres *= 0.5;
+		}
+		if (i <= 0) /* warn of too many tries */
+			resid->u = - resid->u;
+		/* apply cut resolution and set pointers */
+		nru = nrv = 0;
+		for (j = 0; j < nu; ++j) {
+			ncu[j] = ncv[j] = 0; /* clear column maxes */
+			for (s = w[j], i = 0; i < nv; ++i, ++s) {
+				if ((ab = fabs(s->u)) < cutres) /* < resolution ? */
+					s->u = 0.;		/* clear coefficient */
+				else
+					ncu[j] = i + 1;	/* update column max */
+				if ((ab = fabs(s->v)) < cutres) /* same for v coef's */
+					s->v = 0.;
+				else
+					ncv[j] = i + 1;
+			}
+			if (ncu[j]) nru = j + 1;	/* update row max */
+			if (ncv[j]) nrv = j + 1;
+		}
+		if (power) { /* convert to bivariate power series */
+			if (!bch2bps(a, b, w, nu, nv))
+				goto error;
+			/* possible change in some row counts, so readjust */
+			nru = nrv = 0;
+			for (j = 0; j < nu; ++j) {
+				ncu[j] = ncv[j] = 0; /* clear column maxes */
+				for (s = w[j], i = 0; i < nv; ++i, ++s) {
+					if (s->u)
+						ncu[j] = i + 1;	/* update column max */
+					if (s->v)
+						ncv[j] = i + 1;
+				}
+				if (ncu[j]) nru = j + 1;	/* update row max */
+				if (ncv[j]) nrv = j + 1;
+			}
+			if (T = makeT(nru, nrv)) {
+				T->a = a;
+				T->b = b;
+				T->mu = nru - 1;
+				T->mv = nrv - 1;
+				T->power = 1;
+				for (i = 0; i < nru; ++i) /* store coefficient rows for u */
+					if (T->cu[i].m = ncu[i])
+						if ((p = T->cu[i].c =
+								(double *)pj_malloc(sizeof(double) * ncu[i])))
+							for (j = 0; j < ncu[i]; ++j)
+								*p++ = (w[i] + j)->u;
+						else
+							goto error;
+				for (i = 0; i < nrv; ++i) /* same for v */
+					if (T->cv[i].m = ncv[i])
+						if ((p = T->cv[i].c =
+								(double *)pj_malloc(sizeof(double) * ncv[i])))
+							for (j = 0; j < ncv[i]; ++j)
+								*p++ = (w[i] + j)->v;
+						else
+							goto error;
+			}
+		} else if (T = makeT(nru, nrv)) {
+			/* else make returned Chebyshev coefficient structure */
+			T->mu = nru - 1; /* save row degree */
+			T->mv = nrv - 1;
+			T->a.u = a.u + b.u; /* set argument scaling */
+			T->a.v = a.v + b.v;
+			T->b.u = 1. / (b.u - a.u);
+			T->b.v = 1. / (b.v - a.v);
+			T->power = 0;
+			for (i = 0; i < nru; ++i) /* store coefficient rows for u */
+				if (T->cu[i].m = ncu[i]) 
+					if ((p = T->cu[i].c =
+							(double *)pj_malloc(sizeof(double) * ncu[i])))
+						for (j = 0; j < ncu[i]; ++j)
+							*p++ = (w[i] + j)->u;
+					else
+						goto error;
+			for (i = 0; i < nrv; ++i) /* same for v */
+				if (T->cv[i].m = ncv[i])
+					if ((p = T->cv[i].c =
+							(double *)pj_malloc(sizeof(double) * ncv[i])))
+						for (j = 0; j < ncv[i]; ++j)
+							*p++ = (w[i] + j)->v;
+					else
+						goto error;
+		} else
+			goto error;
+	}
+	goto gohome;
+error:
+	if (T) { /* pj_dalloc.g up possible allocations */
+		for (i = 0; i <= T->mu; ++i)
+			if (T->cu[i].c)
+				pj_dalloc(T->cu[i].c);
+		for (i = 0; i <= T->mv; ++i)
+			if (T->cv[i].c)
+				pj_dalloc(T->cv[i].c);
+		pj_dalloc(T);
+	}
+	T = 0;
+gohome:
+	pj_dalloc(w);
+	pj_dalloc(ncu);
+	return T;
+}
diff --git a/proj/nad2bin.c b/proj/nad2bin.c
new file mode 100644
index 0000000..3cf5c34
--- /dev/null
+++ b/proj/nad2bin.c
@@ -0,0 +1,68 @@
+/* Convert bivariate ASCII NAD27 to NAD83 tables to binary structure */
+#ifndef lint
+static const char SCCSID[]="@(#)nad2bin.c	4.2 93/08/25 GIE REL";
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#define PJ_LIB__
+#include <projects.h>
+#define U_SEC_TO_RAD 4.848136811095359935899141023e-12
+	static char
+*usage = "<ASCII_dist_table local_bin_table";
+	void
+main(int argc, char **argv) {
+	struct CTABLE ct;
+	FLP *p, t;
+	size_t tsize;
+	int i, j, ichk;
+	long lam, laml, phi, phil;
+	FILE *bin;
+
+	if (argc != 2) {
+		fprintf(stderr,"usage: %s %s\n", argv[0], usage);
+		exit(1);
+	}
+	fgets(ct.id, MAX_TAB_ID, stdin);
+	scanf("%d %d %*d %lf %lf %lf %lf", &ct.lim.lam, &ct.lim.phi,
+		&ct.ll.lam, &ct.del.lam, &ct.ll.phi, &ct.del.phi);
+	if (!(ct.cvs = (FLP *)malloc(tsize = ct.lim.lam * ct.lim.phi *
+		sizeof(FLP)))) {
+		perror("mem. alloc");
+		exit(1);
+	}
+	ct.ll.lam *= DEG_TO_RAD;
+	ct.ll.phi *= DEG_TO_RAD;
+	ct.del.lam *= DEG_TO_RAD;
+	ct.del.phi *= DEG_TO_RAD;
+	/* load table */
+	for (p = ct.cvs, i = 0; i < ct.lim.phi; ++i) {
+		scanf("%d:%ld %ld", &ichk, &laml, &phil);
+		if (ichk != i) {
+			fprintf(stderr,"format check on row\n");
+			exit(1);
+		}
+		t.lam = laml * U_SEC_TO_RAD;
+		t.phi = phil * U_SEC_TO_RAD;
+		*p++ = t;
+		for (j = 1; j < ct.lim.lam; ++j) {
+			scanf("%ld %ld", &lam, &phi);
+			t.lam = (laml += lam) * U_SEC_TO_RAD;
+			t.phi = (phil += phi) * U_SEC_TO_RAD;
+			*p++ = t;
+		}
+	}
+	if (feof(stdin)) {
+		fprintf(stderr, "premature EOF\n");
+		exit(1);
+	}
+	if (!(bin = freopen(argv[1], "wb", stdout))) {
+		perror(argv[1]);
+		exit(2);
+	}
+	if (fwrite(&ct, sizeof(ct), 1, stdout) != 1 ||
+		fwrite(ct.cvs, tsize, 1, stdout) != 1) {
+		fprintf(stderr, "output failure\n");
+		exit(2);
+	}
+	exit(0); /* normal completion */
+}
diff --git a/proj/nad2nad.c b/proj/nad2nad.c
new file mode 100644
index 0000000..a685401
--- /dev/null
+++ b/proj/nad2nad.c
@@ -0,0 +1,321 @@
+/* <<<< North American Datum Transfer Program >>>> */
+#ifndef lint
+static const char SCCSID[]="@(#)nad2nad.c	4.4	93/08/25	GIE	REL";
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <projects.h>
+#include "emess.h"
+
+#define MAX_LINE 200
+#define MAX_PARGS 100
+#define PJ_INVERS(P) (P->inv ? 1 : 0)
+	static int
+echoin = 0,	/* echo input data to output line */
+tag = '#';	/* beginning of line tag character */
+	static char
+*oform = (char *)0,	/* output format for x-y or decimal degrees */
+*oterr = "*\t*",	/* output line for unprojectable input */
+*inargs = 0,
+*outargs = 0,
+*czone = 0,
+*usage =
+"REL 4.4 usage: %s [ -eEfihortwW [args] ] [ files ]\n";
+	struct CTABLE
+*ctab = 0,
+*htab = 0;
+static struct TAG_LIST {
+	char *tag;
+	short sw;
+} ops_list[] = {
+	"utm=",	0,
+	"spcs=", 1,
+	"feet", 2,
+	"27", 3,
+	"83", 4,
+	"hp", 5,
+	"bin", 6,
+	"rev", 7,
+	0, 0,
+};
+static struct IO_CON {
+	short rev;	/* reverse lon/lat or x/y */
+	short bin;	/* io binary */
+	short ll;	/* io lat-lon */
+	short t83;	/* data in 83 datum */
+	short zone;	/* <100 utm zone, ==0 geog,  else state plane zone */
+	short nprojc; /* number of entries in projc */
+	char *hp;	/* high precision name */
+	char *projc[10];	/* params for pj_init */
+	PJ *cnv;
+} input = {
+	0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+	0,
+}, output = {
+	0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+	0,
+};
+extern void *pj_omerc(), *pj_lcc(), *pj_tmerc(), *pj_utm(), *pj_poly();
+struct PJ_LIST pj_list[] = { /* local needs */
+	"lcc",		pj_lcc,		"Lambert Conformal Conic - Inv",
+	"omerc",	pj_omerc,	"Oblique Mercator - Inv",
+	"poly",		pj_poly,	"Polyconic (American) - Inv",
+	"tmerc",	pj_tmerc,	"Transverse Mercator - Inv",
+	"utm",		pj_utm,		"Universal Transverse Mercator - Inv",
+	0,		0,	"list terminator"
+};
+	static void
+set_zone(int in, struct IO_CON *io) {
+	char tmp[20];
+
+	if (io->hp) {
+		io->t83 = 1;
+		if (!(htab = nad_init(io->hp)))
+			emess(1,"hp datum file: %s, failed: %s", io->hp,
+				pj_strerrno(pj_errno));
+	}
+	if (io->zone > 0) {
+		if (io->zone <= 60) { /* UTM zone */
+			io->nprojc = 2; /* no other options allowed */
+			io->projc[0] = "proj=utm";
+			sprintf(tmp, "zone=%d", io->zone);
+			io->projc[1] = io->t83 ? "ellps=GRS80" : "ellps=clrk66";
+		} else /* SPCS zone */
+			sprintf(tmp, "init=nad%s:%d", io->t83 ? "83" : "27", io->zone);
+		io->projc[io->nprojc++] = tmp;
+		io->projc[io->nprojc++] = "no_defs";
+		if (!(io->cnv = pj_init(io->nprojc, io->projc)))
+			emess(1,pj_strerrno(pj_errno));
+		io->ll = 0;
+	}
+}
+	static void
+setup() {
+	/* check and set zone operations */
+	if (input.hp && output.hp)
+		emess(1,"both input and output cannot be high precision");
+	set_zone(1, &input);
+	set_zone(0, &output);
+	if (input.cnv && !output.cnv)
+		output.ll = 1;
+	if (output.cnv && !input.cnv)
+		input.ll = 1;
+	if (!input.cnv && !output.cnv)
+		output.ll = input.ll = 1;
+	if (czone) {
+		if (!input.hp && !output.hp && input.t83 == output.t83)
+			emess(1,"identical datums");
+		if (!(ctab = nad_init(czone)))
+			emess(1,"datum file: %s, failed: %s", czone, pj_strerrno(pj_errno));
+	} else if (input.t83 != output.t83)
+		emess(1,"conversion region (-r) not specified");
+}
+	static void
+set_ops(char *s, struct IO_CON *io) {
+	char *intag;
+	struct TAG_LIST *p;
+
+	for ( ; intag = strtok(s, " ,\t"); s = 0) {
+		for (p = ops_list; p->tag; ++p) {
+			if (!strncmp(intag, p->tag, strlen(p->tag)))
+				break;
+		}
+		if (!p->tag)
+			emess(1,"invalid selection");
+		switch (p->sw) {
+		case 0:
+		case 1:
+			s = strchr(intag, '=') + 1;
+			io->zone = atoi(s);
+			break;
+		case 2:
+			if (io->zone <= 60)
+				emess(1,"spcs zone must be selected");
+			io->projc[io->nprojc++] = "units=us-ft";
+			break;
+		case 3: io->t83 = 0; break;
+		case 4: io->t83 = 1; break;
+		case 5:
+			if (!(intag = strchr(intag, '=')) || *++intag == '\0')
+				emess(1,"hp missing name");
+			strcpy(io->hp = malloc(strlen(intag)+1), intag);
+			break;
+		case 6: io->bin = 1; break;
+		case 7: io->rev = 1; break;
+		}
+	}
+}
+	static void
+process(FILE *fid) {
+	char line[MAX_LINE], *s, t, pline[100];
+	UV val;
+	double tmp;
+
+	for (;;) {
+		if (input.bin)
+			fread(&val, sizeof(UV), 1, fid);
+		else if (s = fgets(line, MAX_LINE, fid)) {
+			if (*s == tag) {
+				fputs(line, stdout);
+				continue;
+			} else if (input.ll) {
+				val.u = dmstor(s, &s);
+				val.v = dmstor(s, &s);
+			} else {
+				val.u = strtod(s, &s);
+				val.v = strtod(s, &s);
+			}
+		}
+		if (feof(fid))
+			break;
+		if (input.rev) {
+			tmp = val.u;
+			val.u = val.v;
+			val.v = tmp;
+		}
+		/* data in, manupulate */
+		if (input.cnv)
+			val = pj_inv(val, input.cnv);
+		if (input.hp)
+			val = nad_cvt(val, 1, htab);
+		/* nad conversion */
+		if (ctab)
+			val = nad_cvt(val, input.t83 ? 1 : 0, ctab);
+		if (output.hp)
+			val = nad_cvt(val, 0, htab);
+		if (output.cnv)
+			val = pj_fwd(val, output.cnv);
+		/* output data */
+		if (output.rev) {
+			tmp = val.u;
+			val.u = val.v;
+			val.v = tmp;
+		}
+		if (output.bin)
+			(void)fwrite(&val, sizeof(UV), 1, stdout);
+		else {
+			if (echoin) {
+				t = *s;
+				*s = '\0';
+				(void)fputs(line, stdout);
+				(void)putchar('\t');
+				*s = t;
+			}
+			if (val.u == HUGE_VAL)
+				(void)fputs(oterr, stdout);
+			else if (output.ll)
+				if (oform) {
+					(void)printf(oform, val.u * RAD_TO_DEG);
+					(void)putchar('\t');
+					(void)printf(oform, val.v * RAD_TO_DEG);
+				} else if (output.rev) {
+					(void)fputs(rtodms(pline, val.u, 'N', 'S'), stdout);
+					(void)putchar('\t');
+					(void)fputs(rtodms(pline, val.v, 'E', 'W'), stdout);
+				} else {
+					(void)fputs(rtodms(pline, val.u, 'E', 'W'), stdout);
+					(void)putchar('\t');
+					(void)fputs(rtodms(pline, val.v, 'N', 'S'), stdout);
+				}
+			else {
+				(void)printf(oform ? oform : "%.2f", val.u);
+				(void)putchar('\t');
+				(void)printf(oform ? oform : "%.2f", val.v);
+			}
+			if (input.bin)
+				putchar('\n');
+			else
+				(void)fputs(s, stdout);
+		}
+	}
+}
+	void
+main(int argc, char **argv) {
+	char *arg, **eargv = argv, work[MAX_PARGS];
+	FILE *fid;
+	int eargc = 0, c;
+
+	if (emess_dat.Prog_name = strrchr(*argv,DIR_CHAR))
+		++emess_dat.Prog_name;
+	else emess_dat.Prog_name = *argv;
+	if (argc <= 1 ) {
+		(void)fprintf(stderr, usage, emess_dat.Prog_name);
+		exit (0);
+	}
+		/* process run line arguments */
+	while (--argc > 0) { /* collect run line arguments */
+		if(**++argv == '-') for(arg = *argv;;) {
+			switch(*++arg) {
+			case '\0': /* position of "stdin" */
+				if (arg[-1] == '-') eargv[eargc++] = "-";
+				break;
+			case 'i': /* input control */
+			case 'o': /* output control */
+				if (--argc <= 0) goto noargument;
+				strncpy(work, *++argv, MAX_PARGS);
+				set_ops(work, *arg == 'i' ? &input : &output);
+				continue;
+			case 'r': /* nad27/83 conversion zone */
+				if (--argc <= 0) goto noargument;
+				czone = *++argv;
+				continue;
+			case 'E': /* echo ascii input to ascii output */
+				echoin = 1;
+				continue;
+			case 't': /* set col. one char */
+				if (arg[1]) tag = *++arg;
+				else emess(1,"missing -t col. 1 tag");
+				continue;
+			case 'W': /* specify seconds precision */
+			case 'w': /* -W for constant field width */
+				if ((c = arg[1]) != 0 && isdigit(c)) {
+					set_rtodms(c - '0', *arg == 'W');
+					++arg;
+				} else
+				    emess(1,"-W argument missing or non-digit");
+				continue;
+			case 'f': /* alternate output format degrees or xy */
+				if (--argc <= 0) goto noargument;
+				oform = *++argv;
+				continue;
+			case 'e': /* error line alternative */
+				if (--argc <= 0)
+noargument:			   emess(1,"missing argument for -%c",*arg);
+				oterr = *++argv;
+				continue;
+			default:
+				emess(1, "invalid option: -%c",*arg);
+				break;
+			}
+			break;
+		} else /* assumed to be input file name(s) */
+			eargv[eargc++] = *argv;
+	}
+	if (eargc == 0) /* if no specific files force sysin */
+		eargv[eargc++] = "-";
+	/* done with parameter and control input */
+	setup();
+	/* process input file list */
+	for ( ; eargc-- ; ++eargv) {
+		if (**eargv == '-') {
+			fid = stdin;
+			emess_dat.File_name = "<stdin>";
+		} else {
+			if ((fid = fopen(*eargv, "r")) == NULL) {
+				emess(-2, *eargv, "input file");
+				continue;
+			}
+			emess_dat.File_name = *eargv;
+		}
+		emess_dat.File_line = 0;
+		/* process file */
+		process(fid);
+		(void)fclose(fid);
+		emess_dat.File_name = 0;
+	}
+	exit(0); /* normal completion */
+}
diff --git a/proj/nad_cvt.c b/proj/nad_cvt.c
new file mode 100644
index 0000000..2c7a0c2
--- /dev/null
+++ b/proj/nad_cvt.c
@@ -0,0 +1,49 @@
+#ifndef lint
+static const char SCCSID[]="@(#)nad_cvt.c	4.1   93/08/19 GIE REL";
+#endif
+#define PJ_LIB__
+#include <projects.h>
+#define MAX_TRY 9
+#define TOL 1e-12
+	LP
+nad_cvt(LP in, int inverse, struct CTABLE *ct) {
+	LP t, tb;
+
+	if (in.lam == HUGE_VAL)
+		return in;
+	/* normalize input to ll origin */
+	tb = in;
+	tb.lam -= ct->ll.lam;
+	tb.phi -= ct->ll.phi;
+	tb.lam = adjlon(tb.lam);
+	t = nad_interp(tb, ct);
+	if (inverse) {
+		LP del, dif;
+		int i = MAX_TRY;
+
+		if (t.lam == HUGE_VAL) return t;
+		t.lam = tb.lam + t.lam;
+		t.phi = tb.phi - t.phi;
+
+		do {
+			del = nad_interp(t, ct);
+			if (del.lam == HUGE_VAL) return del;
+			t.lam -= dif.lam = t.lam - del.lam - tb.lam;
+			t.phi -= dif.phi = t.phi + del.phi - tb.phi;
+		} while (i-- && fabs(dif.lam) > TOL && fabs(dif.phi) > TOL);
+		if (i < 0) {
+			t.lam = t.phi = HUGE_VAL;
+			return t;
+		}
+		in.lam = adjlon(t.lam + ct->ll.lam);
+		in.phi = t.phi + ct->ll.phi;
+	} else {
+		if (t.lam == HUGE_VAL)
+			in = t;
+		else {
+			in.lam -= t.lam;
+			in.phi += t.phi;
+		}
+	}
+	return in;
+}
diff --git a/proj/nad_init.c b/proj/nad_init.c
new file mode 100644
index 0000000..ec38e3f
--- /dev/null
+++ b/proj/nad_init.c
@@ -0,0 +1,46 @@
+/* open structure for NAD27<->NAD83 conversion */
+#ifndef lint
+static const char SCCSID[]="@(#)nad_init.c	4.3   93/08/25 GIE REL";
+#endif
+#define PJ_LIB__
+#include <projects.h>
+#include <stdio.h>
+#include <errno.h>
+extern FILE *pj_open_lib(char *, char *);
+	struct CTABLE *
+nad_init(char *name) {
+	char fname[FILENAME_MAX+1];
+	struct CTABLE *ct;
+	FILE *fid;
+	size_t i;
+
+	errno = pj_errno = 0;
+	if (!(fid = pj_open_lib(name, "rb"))) {
+	  strcpy(fname, "nad2783/");
+	  strcat(fname, name);
+	  if (!(fid = pj_open_lib(fname, "rb"))) {
+	    pj_errno = errno;
+	    return 0;
+	  }
+	}
+	
+	if (!(ct = pj_malloc(124)) ||
+	    fread(ct, 124, 1, fid) != 1 ||
+	    !(ct->cvs = (FLP *)pj_malloc(i=sizeof(FLP)*ct->lim.lam*ct->lim.phi)) ||
+	    fread(ct->cvs, i, 1, fid) != 1) {
+	  nad_free(ct);
+	  pj_errno = -38;
+	  ct = 0;
+	  return 0;
+	}
+	fclose(fid);
+	pj_errno = 0;
+	return ct;
+}
+	void
+nad_free(struct CTABLE *ct) {
+	if (ct) {
+		pj_dalloc(ct->cvs);
+		pj_dalloc(ct);
+	}
+}
diff --git a/proj/nad_interp.c b/proj/nad_interp.c
new file mode 100644
index 0000000..b49af02
--- /dev/null
+++ b/proj/nad_interp.c
@@ -0,0 +1,65 @@
+/* Determine nad table correction value */
+#ifndef lint
+static const char SCCSID[]="@(#)nad_interp.c	4.1   93/08/19 GIE REL";
+#endif
+#define PJ_LIB__
+#include <projects.h>
+	LP
+nad_interp(LP t, struct CTABLE *ct) {
+	LP val, frct;
+	ILP indx;
+	double m00, m10, m01, m11;
+	FLP *f00, *f10, *f01, *f11;
+	long index;
+	int in;
+
+	indx.lam = floor(t.lam /= ct->del.lam);
+	indx.phi = floor(t.phi /= ct->del.phi);
+	frct.lam = t.lam - indx.lam;
+	frct.phi = t.phi - indx.phi;
+	val.lam = val.phi = HUGE_VAL;
+	if (indx.lam < 0) {
+		if (indx.lam == -1 && frct.lam > 0.99999999999) {
+			++indx.lam;
+			frct.lam = 0.;
+		} else
+			return val;
+	} else if ((in = indx.lam + 1) >= ct->lim.lam) {
+		if (in == ct->lim.lam && frct.lam < 1e-11) {
+			--indx.lam;
+			frct.lam = 1.;
+		} else
+			return val;
+	}
+	if (indx.phi < 0) {
+		if (indx.phi == -1 && frct.phi > 0.99999999999) {
+			++indx.phi;
+			frct.phi = 0.;
+		} else
+			return val;
+	} else if ((in = indx.phi + 1) >= ct->lim.phi) {
+		if (in == ct->lim.phi && frct.phi < 1e-11) {
+			--indx.phi;
+			frct.phi = 1.;
+		} else
+			return val;
+	}
+	index = indx.phi * ct->lim.lam + indx.lam;
+	f00 = ct->cvs + index++;
+	f10 = ct->cvs + index;
+	index += ct->lim.lam;
+	f11 = ct->cvs + index--;
+	f01 = ct->cvs + index;
+	m11 = m10 = frct.lam;
+	m00 = m01 = 1. - frct.lam;
+	m11 *= frct.phi;
+	m01 *= frct.phi;
+	frct.phi = 1. - frct.phi;
+	m00 *= frct.phi;
+	m10 *= frct.phi;
+	val.lam = m00 * f00->lam + m10 * f10->lam +
+			  m01 * f01->lam + m11 * f11->lam;
+	val.phi = m00 * f00->phi + m10 * f10->phi +
+			  m01 * f01->phi + m11 * f11->phi;
+	return val;
+}
diff --git a/proj/pj_aea.c b/proj/pj_aea.c
new file mode 100644
index 0000000..7a5d72c
--- /dev/null
+++ b/proj/pj_aea.c
@@ -0,0 +1,128 @@
+/* Albers Equal Area Conic */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_aea.c	4.4	93/06/12	GIE	REL";
+#endif
+# define EPS10	1.e-10
+# define TOL7	1.e-7
+#define PROJ_PARMS__ \
+	double	ec; \
+	double	n; \
+	double	c; \
+	double	dd; \
+	double	n2; \
+	double	rho0; \
+	double	rho; \
+	double	phi1; \
+	double	phi2; \
+	double	*en; \
+	int		ellips;
+#define PJ_LIB__
+# include	<projects.h>
+/* determine latitude angle phi-1 */
+# define N_ITER 15
+# define EPSILON 1.0e-7
+# define TOL 1.0e-10
+	static double
+phi1_(double qs, double Te, double Tone_es) {
+	int i;
+	double Phi, sinpi, cospi, con, com, dphi;
+
+	Phi = asin (.5 * qs);
+	if (Te < EPSILON)
+		return( Phi );
+	i = N_ITER;
+	do {
+		sinpi = sin (Phi);
+		cospi = cos (Phi);
+		con = Te * sinpi;
+		com = 1. - con * con;
+		dphi = .5 * com * com / cospi * (qs / Tone_es -
+		   sinpi / com + .5 / Te * log ((1. - con) /
+		   (1. + con)));
+		Phi += dphi;
+	} while (fabs(dphi) > TOL && --i);
+	return( i ? Phi : HUGE_VAL );
+}
+FORWARD(e_forward); /* ellipsoid & spheroid */
+	if ((P->rho = P->c - (P->ellips ? P->n * pj_qsfn(sin(lp.phi),
+		P->e, P->one_es) : P->n2 * sin(lp.phi))) < 0.) F_ERROR
+	P->rho = P->dd * sqrt(P->rho);
+	xy.x = P->rho * sin( lp.lam *= P->n );
+	xy.y = P->rho0 - P->rho * cos(lp.lam);
+	return (xy);
+}
+INVERSE(e_inverse) /* ellipsoid & spheroid */;
+	if (P->rho = hypot(xy.x, xy.y = P->rho0 - xy.y)) {
+		if (P->n < 0.) {
+			P->rho = -P->rho;
+			xy.x = -xy.x;
+			xy.y = -xy.y;
+		}
+		lp.phi =  P->rho / P->dd;
+		if (P->ellips) {
+			lp.phi = (P->c - lp.phi * lp.phi) / P->n;
+			if (fabs(P->ec - fabs(lp.phi)) > TOL7) {
+				if ((lp.phi = phi1_(lp.phi, P->e, P->one_es)) == HUGE_VAL)
+					I_ERROR
+			} else
+				lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
+		} else if (fabs(lp.phi = (P->c - lp.phi * lp.phi) / P->n2) <= 1.)
+			lp.phi = asin(lp.phi);
+		else
+			lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
+		lp.lam = atan2(xy.x, xy.y) / P->n;
+	} else {
+		lp.lam = 0.;
+		lp.phi = P->n > 0. ? HALFPI : - HALFPI;
+	}
+	return (lp);
+}
+FREEUP; if (P) { if (P->en) pj_dalloc(P->en); pj_dalloc(P); } }
+	static PJ *
+setup(PJ *P) {
+	double cosphi, sinphi;
+	int secant;
+
+	if (fabs(P->phi1 + P->phi2) < EPS10) E_ERROR(-21);
+	P->n = sinphi = sin(P->phi1);
+	cosphi = cos(P->phi1);
+	secant = fabs(P->phi1 - P->phi2) >= EPS10;
+	if (P->ellips = P->es > 0.) {
+		double ml1, m1;
+
+		if (!(P->en = pj_enfn(P->es))) E_ERROR_0;
+		m1 = pj_msfn(sinphi, cosphi, P->es);
+		ml1 = pj_qsfn(sinphi, P->e, P->one_es);
+		if (secant) { /* secant cone */
+			double ml2, m2;
+
+			sinphi = sin(P->phi2);
+			cosphi = cos(P->phi2);
+			m2 = pj_msfn(sinphi, cosphi, P->es);
+			ml2 = pj_qsfn(sinphi, P->e, P->one_es);
+			P->n = (m1 * m1 - m2 * m2) / (ml2 - ml1);
+		}
+		P->ec = 1. - .5 * P->one_es * log((1. - P->e) /
+			(1. + P->e)) / P->e;
+		P->c = m1 * m1 + P->n * ml1;
+		P->dd = 1. / P->n;
+		P->rho0 = P->dd * sqrt(P->c - P->n * pj_qsfn(sin(P->phi0),
+			P->e, P->one_es));
+	} else {
+		if (secant) P->n = .5 * (P->n + sin(P->phi2));
+		P->n2 = P->n + P->n;
+		P->c = cosphi * cosphi + P->n2 * sinphi;
+		P->dd = 1. / P->n;
+		P->rho0 = P->dd * sqrt(P->c - P->n2 * sin(P->phi0));
+	}
+	P->inv = e_inverse; P->fwd = e_forward;
+	return P;
+}
+ENTRY1(pj_aea, en)
+	P->phi1 = pj_param(P->params, "rlat_1").f;
+	P->phi2 = pj_param(P->params, "rlat_2").f;
+ENDENTRY(setup(P))
+ENTRY1(pj_leac, en)
+	P->phi2 = pj_param(P->params, "rlat_1").f;
+	P->phi1 = pj_param(P->params, "bsouth").i ? - HALFPI: HALFPI;
+ENDENTRY(setup(P))
diff --git a/proj/pj_aeqd.c b/proj/pj_aeqd.c
new file mode 100644
index 0000000..7df17db
--- /dev/null
+++ b/proj/pj_aeqd.c
@@ -0,0 +1,256 @@
+/* Azimuthal Equidistant projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_aeqd.c	4.5	93/06/12	GIE	REL";
+#endif
+#define EPS10 1.e-10
+#define TOL 1.e-14
+#define PROJ_PARMS__ \
+	double	sinph0; \
+	double	cosph0; \
+	double	*en; \
+	double	M1; \
+	double	N1; \
+	double	Mp; \
+	double	He; \
+	double	G; \
+	int		mode;
+#define PJ_LIB__
+#include	<projects.h>
+#define N_POLE	0
+#define S_POLE 1
+#define EQUIT	2
+#define OBLIQ	3
+FORWARD(e_guam_fwd); /* Guam elliptical */
+	double  cosphi, sinphi, t;
+
+	cosphi = cos(lp.phi);
+	sinphi = sin(lp.phi);
+	t = 1. / sqrt(1. - P->es * sinphi * sinphi);
+	xy.x = lp.lam * cosphi * t;
+	xy.y = pj_mlfn(lp.phi, sinphi, cosphi, P->en) - P->M1 +
+		.5 * lp.lam * lp.lam * cosphi * sinphi * t;
+	return (xy);
+}
+FORWARD(e_forward); /* elliptical */
+	double  coslam, cosphi, sinphi, rho, s, H, H2, c, Az, t;
+
+	coslam = cos(lp.lam);
+	cosphi = cos(lp.phi);
+	sinphi = sin(lp.phi);
+	switch (P->mode) {
+	case N_POLE:
+		coslam = - coslam;
+		lp.phi = -lp.phi;
+	case S_POLE:
+		xy.x = (rho = P->Mp + pj_mlfn(lp.phi, sinphi, cosphi, P->en)) *
+			sin(lp.lam);
+		xy.y = rho * coslam;
+		break;
+	case EQUIT:
+	case OBLIQ:
+		if (fabs((t = fabs(lp.phi)) - HALFPI) < TOL) {
+			s = fabs(aasin(P->cosph0));
+			if (lp.phi < 0.)
+				Az = PI;
+			else {
+				Az = 0;
+				s = -s;
+			}
+		} else if ( t < TOL && fabs(lp.lam) < EPS10) {
+			xy.x = xy.y = 0.;
+			break;
+		} else {
+			t = P->one_es * tan(lp.phi) + P->es * P->N1 * P->sinph0 *
+				sqrt(1. - P->es * sinphi * sinphi) / cosphi;
+			Az = atan2(sin(lp.lam),P->cosph0 * t - P->sinph0 * coslam);
+			t = atan(t);
+			if ((s = sin(Az)) < TOL)
+				s = aasin(P->cosph0 * sin(t) - P->sinph0 * cos(t));
+			else {
+				s = fabs(aasin(sin(lp.lam) * cos(t) / s));
+				if (Az < 0.)
+					s = -s;
+			}
+		}
+		H = P->He * cos(Az);
+		H2 = H * H;
+		c = P->N1 * s * (1. + s * s * (- H2 * (1. - H2)/6. +
+			s * ( P->G * H * (1. - H2 - H2) / 8. +
+			s * ((H2 * (4. - 7. * H2) - 3. * P->G * P->G * (1. - 7. * H2)) /
+			120. - s * P->G * H / 48.))));
+		xy.x = c * sin(Az);
+		xy.y = c * cos(Az);
+		break;
+	}
+	return (xy);
+}
+FORWARD(s_forward); /* spherical */
+	double  coslam, cosphi, sinphi;
+
+	sinphi = sin(lp.phi);
+	cosphi = cos(lp.phi);
+	coslam = cos(lp.lam);
+	switch (P->mode) {
+	case EQUIT:
+		xy.y = cosphi * coslam;
+		goto oblcon;
+	case OBLIQ:
+		xy.y = P->sinph0 * sinphi + P->cosph0 * cosphi * coslam;
+oblcon:
+		if (fabs(fabs(xy.y) - 1.) < TOL)
+			if (xy.y < 0.)
+				F_ERROR 
+			else
+				xy.x = xy.y = 0.;
+		else {
+			xy.y = acos(xy.y);
+			xy.y /= sin(xy.y);
+			xy.x = xy.y * cosphi * sin(lp.lam);
+			xy.y *= (P->mode == EQUIT) ? sinphi :
+		   		P->cosph0 * sinphi - P->sinph0 * cosphi * coslam;
+		}
+		break;
+	case N_POLE:
+		lp.phi = -lp.phi;
+		coslam = -coslam;
+	case S_POLE:
+		if (fabs(lp.phi - HALFPI) < EPS10) F_ERROR;
+		xy.x = (xy.y = (HALFPI + lp.phi)) * sin(lp.lam);
+		xy.y *= coslam;
+		break;
+	}
+	return (xy);
+}
+INVERSE(e_guam_inv); /* Guam elliptical */
+	double x2, t;
+	int i;
+
+	x2 = 0.5 * xy.x * xy.x;
+	lp.phi = P->phi0;
+	for (i = 0; i < 3; ++i) {
+		t = P->e * sin(lp.phi);
+		lp.phi = pj_inv_mlfn(P->M1 + xy.y -
+			x2 * tan(lp.phi) * (t = sqrt(1. - t * t)), P->es, P->en);
+	}
+	lp.lam = xy.x * t / cos(lp.phi);
+	return (lp);
+}
+INVERSE(e_inverse); /* elliptical */
+	double c, Az, cosAz, A, B, D, E, F, psi, t;
+
+	if ((c = hypot(xy.x, xy.y)) > PI) {
+		if (c - EPS10 > PI) I_ERROR;
+		c = PI;
+	} else if (c < EPS10) {
+		lp.phi = P->phi0;
+		lp.lam = 0.;
+		return (lp);
+	}
+	if (P->mode == OBLIQ || P->mode == EQUIT) {
+		cosAz = cos(Az = atan2(xy.x, xy.y));
+		t = P->cosph0 * cosAz;
+		B = P->es * t / P->one_es;
+		A = - B * t;
+		B *= 3. * (1. - A) * P->sinph0;
+		D = c / P->N1;
+		E = D * (1. - D * D * (A * (1. + A) / 6. + B * (1. + 3.*A) * D / 24.));
+		F = 1. - E * E * (A / 2. + B * E / 6.);
+		psi = aasin(P->sinph0 * cos(E) + t * sin(E));
+		lp.lam = aasin(sin(Az) * sin(E) / cos(psi));
+		if ((t = fabs(psi)) < EPS10)
+			lp.phi = 0.;
+		else if (fabs(t - HALFPI) < 0.)
+			lp.phi = HALFPI;
+		else
+			lp.phi = atan((1. - P->es * F * P->sinph0 / sin(psi)) * tan(psi) /
+				P->one_es);
+	} else if (P->mode == N_POLE) {
+		lp.phi = pj_inv_mlfn(P->Mp - c, P->es, P->en);
+		lp.lam = atan2(xy.x, -xy.y);
+	} else {
+		lp.phi = pj_inv_mlfn(c - P->Mp, P->es, P->en);
+		lp.lam = atan2(xy.x, xy.y);
+	}
+	return (lp);
+}
+INVERSE(s_inverse); /* spherical */
+	double cosc, c_rh, sinc;
+
+	if ((c_rh = hypot(xy.x, xy.y)) > PI) {
+		if (c_rh - EPS10 > PI) I_ERROR;
+		c_rh = PI;
+	} else if (c_rh < EPS10) {
+		lp.phi = P->phi0;
+		lp.lam = 0.;
+		return (lp);
+	}
+	if (P->mode == OBLIQ || P->mode == EQUIT) {
+		sinc = sin(c_rh);
+		cosc = cos(c_rh);
+		if (P->mode == EQUIT) {
+			lp.phi = aasin(xy.y * sinc / c_rh);
+			xy.x *= sinc;
+			xy.y = cosc * c_rh;
+		} else {
+			lp.phi = aasin(cosc * P->sinph0 + xy.y * sinc * P->cosph0 /
+				c_rh);
+			xy.y = (cosc - P->sinph0 * sin(lp.phi)) * c_rh;
+			xy.x *= sinc * P->cosph0;
+		}
+		lp.lam = xy.y == 0. ? 0. : atan2(xy.x, xy.y);
+	} else if (P->mode == N_POLE) {
+		lp.phi = HALFPI - c_rh;
+		lp.lam = atan2(xy.x, -xy.y);
+	} else {
+		lp.phi = c_rh - HALFPI;
+		lp.lam = atan2(xy.x, xy.y);
+	}
+	return (lp);
+}
+FREEUP;
+    if (P) {
+		if (P->en)
+			pj_dalloc(P->en);
+		pj_dalloc(P);
+	}
+}
+ENTRY1(pj_aeqd, en)
+	P->phi0 = pj_param(P->params, "rlat_0").f;
+	if (fabs(fabs(P->phi0) - HALFPI) < EPS10) {
+		P->mode = P->phi0 < 0. ? S_POLE : N_POLE;
+		P->sinph0 = P->phi0 < 0. ? -1. : 1.;
+		P->cosph0 = 0.;
+	} else if (fabs(P->phi0) < EPS10) {
+		P->mode = EQUIT;
+		P->sinph0 = 0.;
+		P->cosph0 = 1.;
+	} else {
+		P->mode = OBLIQ;
+		P->sinph0 = sin(P->phi0);
+		P->cosph0 = cos(P->phi0);
+	}
+	if (! P->es) {
+		P->inv = s_inverse; P->fwd = s_forward;
+	} else {
+		if (!(P->en = pj_enfn(P->es))) E_ERROR_0;
+		if (pj_param(P->params, "bguam").i) {
+			P->M1 = pj_mlfn(P->phi0, P->sinph0, P->cosph0, P->en);
+			P->inv = e_guam_inv; P->fwd = e_guam_fwd;
+		} else {
+			switch (P->mode) {
+			case N_POLE:
+			case S_POLE:
+				P->Mp = pj_mlfn(HALFPI, 0., 1., P->en);
+				break;
+			case EQUIT:
+			case OBLIQ:
+				P->inv = e_inverse; P->fwd = e_forward;
+				P->N1 = 1. / sqrt(1. - P->es * P->sinph0 * P->sinph0);
+				P->G = P->sinph0 * (P->He = P->e / sqrt(P->one_es));
+				P->He *= P->cosph0;
+				break;
+			}
+			P->inv = e_inverse; P->fwd = e_forward;
+		}
+	}
+ENDENTRY(P)
diff --git a/proj/pj_airy.c b/proj/pj_airy.c
new file mode 100644
index 0000000..74a06b2
--- /dev/null
+++ b/proj/pj_airy.c
@@ -0,0 +1,94 @@
+/* Airy projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_airy.c	4.5	93/06/13	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	p_halfpi; \
+	double	sinph0; \
+	double	cosph0; \
+	double	Cb; \
+	int		mode; \
+	int		no_cut;	/* do not cut at hemisphere limit */
+#define PJ_LIB__
+#include	<projects.h>
+# define EPS 1.e-10
+# define N_POLE	0
+# define S_POLE 1
+# define EQUIT	2
+# define OBLIQ	3
+FORWARD(s_forward); /* spheroid */
+	double  sinlam, coslam, cosphi, sinphi, t, s, Krho, cosz;
+
+	sinlam = sin(lp.lam);
+	coslam = cos(lp.lam);
+	switch (P->mode) {
+	case EQUIT:
+	case OBLIQ:
+		sinphi = sin(lp.phi);
+		cosphi = cos(lp.phi);
+		cosz = cosphi * coslam;
+		if (P->mode == OBLIQ)
+			cosz = P->sinph0 * sinphi + P->cosph0 * cosz;
+		if (!P->no_cut && cosz < -EPS)
+			F_ERROR;
+		if (fabs(s = 1. - cosz) > EPS) {
+			t = 0.5 * (1. + cosz);
+			Krho = -log(t)/s - P->Cb / t;
+		} else
+			Krho = 0.5 - P->Cb;
+		xy.x = Krho * cosphi * sinlam;
+		if (P->mode == OBLIQ)
+			xy.y = Krho * (P->cosph0 * sinphi -
+				P->sinph0 * cosphi * coslam);
+		else
+			xy.y = Krho * sinphi;
+		break;
+	case S_POLE:
+	case N_POLE:
+		lp.phi = fabs(P->p_halfpi - lp.phi);
+		if (!P->no_cut && (lp.phi - EPS) > HALFPI)
+			F_ERROR;
+		if ((lp.phi *= 0.5) > EPS) {
+			t = tan(lp.phi);
+			Krho = -2.*(log(cos(lp.phi)) / t + t * P->Cb);
+			xy.x = Krho * sinlam;
+			xy.y = Krho * coslam;
+			if (P->mode == N_POLE)
+				xy.y = -xy.y;
+		} else
+			xy.x = xy.y = 0.;
+	}
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_airy)
+	double beta;
+
+	P->no_cut = pj_param(P->params, "bno_cut").i;
+	beta = 0.5 * (HALFPI - pj_param(P->params, "rlat_b").f);
+	if (fabs(beta) < EPS)
+		P->Cb = -0.5;
+	else {
+		P->Cb = 1./tan(beta);
+		P->Cb *= P->Cb * log(cos(beta));
+	}
+	if (fabs(fabs(P->phi0) - HALFPI) < EPS)
+		if (P->phi0 < 0.) {
+			P->p_halfpi = -HALFPI;
+			P->mode = S_POLE;
+		} else {
+			P->p_halfpi =  HALFPI;
+			P->mode = N_POLE;
+		}
+	else {
+		if (fabs(P->phi0) < EPS)
+			P->mode = EQUIT;
+		else {
+			P->mode = OBLIQ;
+			P->sinph0 = sin(P->phi0);
+			P->cosph0 = cos(P->phi0);
+		}
+	}
+	P->fwd = s_forward;
+	P->es = 0.;
+ENDENTRY(P)
diff --git a/proj/pj_aitoff.c b/proj/pj_aitoff.c
new file mode 100644
index 0000000..7cc638c
--- /dev/null
+++ b/proj/pj_aitoff.c
@@ -0,0 +1,46 @@
+/*  Aitoff and Winkel Tripel Projections */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_aitoff.c	4.5	93/06/13	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	cosphi1; \
+	int		mode;
+#define EPS	1e-8
+#define PJ_LIB__
+#include	<projects.h>
+FORWARD(s_forward); /* spheroid */
+	double c, d;
+
+	if (d = acos(cos(lp.phi) * cos(0.5 * lp.lam))) { /* basic Aitoff */
+		c = sin(lp.phi) / sin(d);
+		if ((xy.x = 1. - c * c) < EPS)
+			if (xy.x < -EPS) F_ERROR
+			else xy.x = 0.;
+		else
+			xy.x = 2. * d * sqrt(xy.x);
+		if (lp.lam < 0.) xy.x = - xy.x;
+		xy.y = d * c;
+	} else
+		xy.x = xy.y = 0.;
+	if (P->mode) { /* Winkel Tripel */
+		xy.x = (xy.x + lp.lam * P->cosphi1) * 0.5;
+		xy.y = (xy.y + lp.phi) * 0.5;
+	}
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+	static PJ *
+setup(PJ *P) {
+	P->inv = 0;
+	P->fwd = s_forward;
+	P->es = 0.;
+	return P;
+}
+ENTRY0(pj_aitoff)
+	P->mode = 0;
+ENDENTRY(setup(P))
+ENTRY0(pj_wintri)
+	P->mode = 1;
+	if ((P->cosphi1 = cos(pj_param(P->params, "rlat_1").f)) == 0.)
+		E_ERROR(-22);
+ENDENTRY(setup(P))
diff --git a/proj/pj_august.c b/proj/pj_august.c
new file mode 100644
index 0000000..bedbddb
--- /dev/null
+++ b/proj/pj_august.c
@@ -0,0 +1,21 @@
+/*  August Epicycloidal */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_august.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define M 1.333333333333333
+FORWARD(s_forward); /* spheroid */
+	double t, c1, c, x1, x12, y1, y12;
+
+	t = tan(.5 * lp.phi);
+	c1 = sqrt(1. - t * t);
+	c = 1. + c1 * cos(lp.lam *= .5);
+	x1 = sin(lp.lam) *  c1 / c;
+	y1 =  t / c;
+	xy.x = M * x1 * (3. + (x12 = x1 * x1) - 3. * (y12 = y1 *  y1));
+	xy.y = M * y1 * (3. + 3. * x12 - y12);
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_august) P->inv = 0; P->fwd = s_forward; P->es = 0.; ENDENTRY(P)
diff --git a/proj/pj_auth.c b/proj/pj_auth.c
new file mode 100644
index 0000000..92ec339
--- /dev/null
+++ b/proj/pj_auth.c
@@ -0,0 +1,33 @@
+/* determine latitude from authalic latitude */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_auth.c	4.3	93/06/12	GIE	REL";
+#endif
+#include <projects.h>
+# define P00 .33333333333333333333
+# define P01 .17222222222222222222
+# define P02 .10257936507936507936
+# define P10 .06388888888888888888
+# define P11 .06640211640211640211
+# define P20 .01641501294219154443
+#define APA_SIZE 3
+	double *
+pj_authset(double es) {
+	double t, *APA;
+
+	if (APA = (double *)pj_malloc(APA_SIZE * sizeof(double))) {
+		APA[0] = es * P00;
+		t = es * es;
+		APA[0] += t * P01;
+		APA[1] = t * P10;
+		t *= es;
+		APA[0] += t * P02;
+		APA[1] += t * P11;
+		APA[2] = t * P20;
+	}
+	return APA;
+}
+	double
+pj_authlat(double beta, double *APA) {
+	double t = beta+beta;
+	return(beta + APA[0] * sin(t) + APA[1] * sin(t+t) + APA[2] * sin(t+t+t));
+}
diff --git a/proj/pj_bacon.c b/proj/pj_bacon.c
new file mode 100644
index 0000000..9975f59
--- /dev/null
+++ b/proj/pj_bacon.c
@@ -0,0 +1,42 @@
+/*  Bacon Globular, Apian Globular I and Ortelius Oval */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_bacon.c	4.4	93/06/13	GIE	REL";
+#endif
+# define HLFPI2	2.46740110027233965467
+# define EPS	1e-10
+#define PROJ_PARMS__ \
+	int bacn; \
+	int ortl;
+#define PJ_LIB__
+#include	<projects.h>
+FORWARD(s_forward); /* spheroid */
+	double ax, f;
+
+	xy.y = P->bacn ? HALFPI * sin(lp.phi) : lp.phi;
+	if ((ax = fabs(lp.lam)) >= EPS) {
+		if (P->ortl && ax >= HALFPI)
+			xy.x = sqrt(HLFPI2 - lp.phi * lp.phi + EPS) + ax - HALFPI;
+		else {
+			f = 0.5 * (HLFPI2 / ax + ax);
+			xy.x = ax - f + sqrt(f * f - xy.y * xy.y);
+		}
+		if (lp.lam < 0.) xy.x = - xy.x;
+	} else
+		xy.x = 0.;
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_bacon)
+	P->bacn = 1;
+	P->ortl = 0;
+	P->es = 0.; P->fwd = s_forward;
+ENDENTRY(P)
+ENTRY0(pj_apian)
+	P->bacn = P->ortl = 0;
+	P->es = 0.; P->fwd = s_forward;
+ENDENTRY(P)
+ENTRY0(pj_ortel)
+	P->bacn = 0;
+	P->ortl = 1;
+	P->es = 0.; P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_bipc.c b/proj/pj_bipc.c
new file mode 100644
index 0000000..cedd012
--- /dev/null
+++ b/proj/pj_bipc.c
@@ -0,0 +1,134 @@
+/* Bipolar conic of western hemisphere */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_bipc.c	4.5	93/06/13	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	int	noskew;
+#define PJ_LIB__
+# include	<projects.h>
+# define EPS	1e-10
+# define EPS10	1e-10
+# define ONEEPS 1.000000001
+# define NITER	10
+# define lamB	-.34894976726250681539
+# define n	.63055844881274687180
+# define F	1.89724742567461030582
+# define Azab	.81650043674686363166
+# define Azba	1.82261843856185925133
+# define T	1.27246578267089012270
+# define rhoc	1.20709121521568721927
+# define cAzc	.69691523038678375519
+# define sAzc	.71715351331143607555
+# define C45	.70710678118654752469
+# define S45	.70710678118654752410
+# define C20	.93969262078590838411
+# define S20	-.34202014332566873287
+# define R110	1.91986217719376253360
+# define R104	1.81514242207410275904
+FORWARD(s_forward); /* spheroid */
+	double cphi, sphi, tphi, t, al, Az, z, Av, cdlam, sdlam, r;
+	int tag;
+
+	cphi = cos(lp.phi);
+	sphi = sin(lp.phi);
+	cdlam = cos(sdlam = lamB - lp.lam);
+	sdlam = sin(sdlam);
+	if (fabs(fabs(lp.phi) - HALFPI) < EPS10) {
+		Az = lp.phi < 0. ? PI : 0.;
+		tphi = HUGE_VAL;
+	} else {
+		tphi = sphi / cphi;
+		Az = atan2(sdlam , C45 * (tphi - cdlam));
+	}
+	if (tag = (Az > Azba)) {
+		cdlam = cos(sdlam = lp.lam + R110);
+		sdlam = sin(sdlam);
+		z = S20 * sphi + C20 * cphi * cdlam;
+		if (fabs(z) > 1.) {
+			if (fabs(z) > ONEEPS) F_ERROR
+			else z = z < 0. ? -1. : 1.;
+		} else
+			z = acos(z);
+		if (tphi != HUGE_VAL)
+			Az = atan2(sdlam, (C20 * tphi - S20 * cdlam));
+		Av = Azab;
+		xy.y = rhoc;
+	} else {
+		z = S45 * (sphi + cphi * cdlam);
+		if (fabs(z) > 1.) {
+			if (fabs(z) > ONEEPS) F_ERROR
+			else z = z < 0. ? -1. : 1.;
+		} else
+			z = acos(z);
+		Av = Azba;
+		xy.y = -rhoc;
+	}
+	if (z < 0.) F_ERROR;
+	r = F * (t = pow(tan(.5 * z), n));
+	if ((al = .5 * (R104 - z)) < 0.) F_ERROR;
+	al = (t + pow(al, n)) / T;
+	if (fabs(al) > 1.) {
+		if (fabs(al) > ONEEPS) F_ERROR
+		else al = al < 0. ? -1. : 1.;
+	} else
+		al = acos(al);
+	if (fabs(t = n * (Av - Az)) < al)
+		r /= cos(al + (tag ? t : -t));
+	xy.x = r * sin(t);
+	xy.y += (tag ? -r : r) * cos(t);
+	if (P->noskew) {
+		t = xy.x;
+		xy.x = -xy.x * cAzc - xy.y * sAzc; 
+		xy.y = -xy.y * cAzc + t * sAzc; 
+	}
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double t, r, rp, rl, al, z, fAz, Az, s, c, Av;
+	int neg, i;
+
+	if (P->noskew) {
+		t = xy.x;
+		xy.x = -xy.x * cAzc + xy.y * sAzc; 
+		xy.y = -xy.y * cAzc - t * sAzc; 
+	}
+	if (neg = (xy.x < 0.)) {
+		xy.y = rhoc - xy.y;
+		s = S20;
+		c = C20;
+		Av = Azab;
+	} else {
+		xy.y += rhoc;
+		s = S45;
+		c = C45;
+		Av = Azba;
+	}
+	rl = rp = r = hypot(xy.x, xy.y);
+	fAz = fabs(Az = atan2(xy.x, xy.y));
+	for (i = NITER; i ; --i) {
+		z = 2. * atan(pow(r / F,1 / n));
+		al = acos((pow(tan(.5 * z), n) +
+		   pow(tan(.5 * (R104 - z)), n)) / T);
+		if (fAz < al)
+			r = rp * cos(al + (neg ? Az : -Az));
+		if (fabs(rl - r) < EPS)
+			break;
+		rl = r;
+	}
+	if (! i) I_ERROR;
+	Az = Av - Az / n;
+	lp.phi = asin(s * cos(z) + c * sin(z) * cos(Az));
+	lp.lam = atan2(sin(Az), c / tan(z) - s * cos(Az));
+	if (neg)
+		lp.lam -= R110;
+	else
+		lp.lam = lamB - lp.lam;
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_bipc)
+	P->noskew = pj_param(P->params, "bns").i;
+	P->inv = s_inverse;
+	P->fwd = s_forward;
+	P->es = 0.;
+ENDENTRY(P)
diff --git a/proj/pj_boggs.c b/proj/pj_boggs.c
new file mode 100644
index 0000000..d7ceaed
--- /dev/null
+++ b/proj/pj_boggs.c
@@ -0,0 +1,35 @@
+/*  Boggs Eumorphic */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_boggs.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PJ_LIB__
+# include	<projects.h>
+# define NITER	20
+# define EPS	1e-7
+# define ONETOL 1.000001
+# define FXC	2.00276
+# define FXC2	1.11072
+# define FYC	0.49931
+# define FYC2	1.41421356237309504880
+FORWARD(s_forward); /* spheroid */
+	double theta, th1, c;
+	int i;
+
+	theta = lp.phi;
+	if (fabs(fabs(lp.phi) - HALFPI) < EPS)
+		xy.x = 0.;
+	else {
+		c = sin(theta) * PI;
+		for (i = NITER; i; --i) {
+			theta -= th1 = (theta + sin(theta) - c) /
+				(1. + cos(theta));
+			if (fabs(th1) < EPS) break;
+		}
+		theta *= 0.5;
+		xy.x = FXC * lp.lam / (1. / cos(lp.phi) + FXC2 / cos(theta));
+	}
+	xy.y = FYC * (lp.phi + FYC2 * sin(theta));
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_boggs) P->es = 0.; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_bonne.c b/proj/pj_bonne.c
new file mode 100644
index 0000000..2220758
--- /dev/null
+++ b/proj/pj_bonne.c
@@ -0,0 +1,87 @@
+/* Bonne projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_bonne.c	4.4	93/06/12	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double phi1; \
+	double cphi1; \
+	double am1; \
+	double m1; \
+	double *en;
+#define PJ_LIB__
+#include	<projects.h>
+#define EPS10	1e-10
+FORWARD(e_forward); /* ellipsoid */
+	double rh, E, c;
+
+	rh = P->am1 + P->m1 - pj_mlfn(lp.phi, E = sin(lp.phi), c = cos(lp.phi), P->en);
+	E = c * lp.lam / (rh * sqrt(1. - P->es * E * E));
+	xy.x = rh * sin(E);
+	xy.y = P->am1 - rh * cos(E);
+	return (xy);
+}
+FORWARD(s_forward); /* spheroid */
+	double E, rh;
+
+	rh = P->cphi1 + P->phi1 - lp.phi;
+	if (fabs(rh) > EPS10) {
+		xy.x = rh * sin(E = lp.lam * cos(lp.phi) / rh);
+		xy.y = P->cphi1 - rh * cos(E);
+	} else
+		xy.x = xy.y = 0.;
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double rh;
+
+	rh = hypot(xy.x, xy.y = P->cphi1 - xy.y);
+	lp.phi = P->cphi1 + P->phi1 - rh;
+	if (fabs(lp.phi) > HALFPI) I_ERROR;
+	if (fabs(fabs(lp.phi) - HALFPI) <= EPS10)
+		lp.lam = 0.;
+	else
+		lp.lam = rh * atan2(xy.x, xy.y) / cos(lp.phi);
+	return (lp);
+}
+INVERSE(e_inverse); /* ellipsoid */
+	double s, rh;
+
+	rh = hypot(xy.x, xy.y = P->am1 - xy.y);
+	lp.phi = pj_inv_mlfn(P->am1 + P->m1 - rh, P->es, P->en);
+	if ((s = fabs(lp.phi)) < HALFPI) {
+		s = sin(lp.phi);
+		lp.lam = rh * atan2(xy.x, xy.y) *
+		   sqrt(1. - P->es * s * s) / cos(lp.phi);
+	} else if (fabs(s - HALFPI) <= EPS10)
+		lp.lam = 0.;
+	else I_ERROR;
+	return (lp);
+}
+FREEUP;
+	if (P) {
+		if (P->en)
+			pj_dalloc(P->en);
+		pj_dalloc(P);
+	}
+}
+ENTRY1(pj_bonne, en)
+	double c;
+
+	P->phi1 = pj_param(P->params, "rlat_1").f;
+	if (fabs(P->phi1) < EPS10) E_ERROR(-23);
+	if (P->es) {
+		P->en = pj_enfn(P->es);
+		P->m1 = pj_mlfn(P->phi1, P->am1 = sin(P->phi1),
+			c = cos(P->phi1), P->en);
+		P->am1 = c / (sqrt(1. - P->es * P->am1 * P->am1) * P->am1);
+		P->inv = e_inverse;
+		P->fwd = e_forward;
+	} else {
+		if (fabs(P->phi1) + EPS10 >= HALFPI)
+			P->cphi1 = 0.;
+		else
+			P->cphi1 = 1. / tan(P->phi1);
+		P->inv = s_inverse;
+		P->fwd = s_forward;
+	}
+ENDENTRY(P)
diff --git a/proj/pj_cass.c b/proj/pj_cass.c
new file mode 100644
index 0000000..afe1b81
--- /dev/null
+++ b/proj/pj_cass.c
@@ -0,0 +1,82 @@
+/* Cassini projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_cass.c	4.3	93/06/12	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double m0; \
+	double n; \
+	double t; \
+	double a1; \
+	double c; \
+	double r; \
+	double dd; \
+	double d2; \
+	double a2; \
+	double tn; \
+	double *en;
+#define PJ_LIB__
+# include	<projects.h>
+# define EPS10	1e-10
+# define C1	.16666666666666666666
+# define C2	.00833333333333333333
+# define C3	.04166666666666666666
+# define C4	.33333333333333333333
+# define C5	.06666666666666666666
+FORWARD(e_forward); /* ellipsoid */
+	xy.y = pj_mlfn(lp.phi, P->n = sin(lp.phi), P->c = cos(lp.phi), P->en);
+	P->n = 1./sqrt(1. - P->es * P->n * P->n);
+	P->tn = tan(lp.phi); P->t = P->tn * P->tn;
+	P->a1 = lp.lam * P->c;
+	P->c *= P->es * P->c / (1 - P->es);
+	P->a2 = P->a1 * P->a1;
+	xy.x = P->n * P->a1 * (1. - P->a2 * P->t *
+		(C1 - (8. - P->t + 8. * P->c) * P->a2 * C2));
+	xy.y -= P->m0 - P->n * P->tn * P->a2 *
+		(.5 + (5. - P->t + 6. * P->c) * P->a2 * C3);
+	return (xy);
+}
+FORWARD(s_forward); /* spheroid */
+	xy.x = asin(cos(lp.phi) * sin(lp.lam));
+	xy.y = atan2(tan(lp.phi) , cos(lp.lam)) - P->phi0;
+	return (xy);
+}
+INVERSE(e_inverse); /* ellipsoid */
+	double ph1;
+
+	ph1 = pj_inv_mlfn(P->m0 + xy.y, P->es, P->en);
+	P->tn = tan(ph1); P->t = P->tn * P->tn;
+	P->n = sin(ph1);
+	P->r = 1. / (1. - P->es * P->n * P->n);
+	P->n = sqrt(P->r);
+	P->r *= (1. - P->es) * P->n;
+	P->dd = xy.x / P->n;
+	P->d2 = P->dd * P->dd;
+	lp.phi = ph1 - (P->n * P->tn / P->r) * P->d2 *
+		(.5 - (1. + 3. * P->t) * P->d2 * C3);
+	lp.lam = P->dd * (1. + P->t * P->d2 *
+		(-C4 + (1. + 3. * P->t) * P->d2 * C5)) / cos(ph1);
+	return (lp);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = asin(sin(P->dd = xy.y + P->phi0) * cos(xy.x));
+	lp.lam = atan2(tan(xy.x), cos(P->dd));
+	return (lp);
+}
+FREEUP;
+	if (P) {
+		if (P->en)
+			pj_dalloc(P->en);
+		pj_dalloc(P);
+	}
+}
+ENTRY1(pj_cass, en)
+	if (P->es) {
+		if (!(P->en = pj_enfn(P->es))) E_ERROR_0;
+		P->m0 = pj_mlfn(P->phi0, sin(P->phi0), cos(P->phi0), P->en);
+		P->inv = e_inverse;
+		P->fwd = e_forward;
+	} else {
+		P->inv = s_inverse;
+		P->fwd = s_forward;
+	}
+ENDENTRY(P)
diff --git a/proj/pj_cc.c b/proj/pj_cc.c
new file mode 100644
index 0000000..c1df188
--- /dev/null
+++ b/proj/pj_cc.c
@@ -0,0 +1,22 @@
+/* Central Cylindrical projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_cc.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double ap;
+#define PJ_LIB__
+#include	<projects.h>
+#define EPS10 1.e-10
+FORWARD(s_forward); /* spheroid */
+	if (fabs(fabs(lp.phi) - HALFPI) <= EPS10) F_ERROR;
+	xy.x = lp.lam;
+	xy.y = tan(lp.phi);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = atan(xy.y);
+	lp.lam = xy.x;
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_cc) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_cea.c b/proj/pj_cea.c
new file mode 100644
index 0000000..9886af6
--- /dev/null
+++ b/proj/pj_cea.c
@@ -0,0 +1,64 @@
+/* Equal Area Cylindrical projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_cea.c	4.4	93/06/12	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double qp; \
+	double *apa;
+#define PJ_LIB__
+# include	<projects.h>
+# define EPS	1e-10
+FORWARD(e_forward); /* spheroid */
+	xy.x = P->k0 * lp.lam;
+	xy.y = .5 * pj_qsfn(sin(lp.phi), P->e, P->one_es) / P->k0;
+	return (xy);
+}
+FORWARD(s_forward); /* spheroid */
+	xy.x = P->k0 * lp.lam;
+	xy.y = sin(lp.phi) / P->k0;
+	return (xy);
+}
+INVERSE(e_inverse); /* spheroid */
+	lp.phi = pj_authlat(asin( 2. * xy.y * P->k0 / P->qp), P->apa);
+	lp.lam = xy.x / P->k0;
+	return (lp);
+}
+INVERSE(s_inverse); /* spheroid */
+	double t;
+
+	if ((t = fabs(xy.y *= P->k0)) - EPS <= 1.) {
+		if (t >= 1.)
+			lp.phi = xy.y < 0. ? -HALFPI : HALFPI;
+		else
+			lp.phi = asin(xy.y);
+		lp.lam = xy.x / P->k0;
+	} else I_ERROR;
+	return (lp);
+}
+FREEUP;
+	if (P) {
+		if (P->apa)
+			pj_dalloc(P->apa);
+		pj_dalloc(P);
+	}
+}
+ENTRY1(pj_cea, apa)
+	double t;
+
+	if (pj_param(P->params, "tlat_ts").i &&
+		(P->k0 = cos(t = pj_param(P->params, "rlat_ts").f)) < 0.) E_ERROR(-24)
+	else
+		t = 0.;
+	if (P->es) {
+		t = sin(t);
+		P->k0 /= sqrt(1. - P->es * t * t);
+		P->e = sqrt(P->es);
+		if (!(P->apa = pj_authset(P->es))) E_ERROR_0;
+		P->qp = pj_qsfn(1., P->e, P->one_es);
+		P->inv = e_inverse;
+		P->fwd = e_forward;
+	} else {
+		P->inv = s_inverse;
+		P->fwd = s_forward;
+	}
+ENDENTRY(P)
diff --git a/proj/pj_chamb.c b/proj/pj_chamb.c
new file mode 100644
index 0000000..b02cbca
--- /dev/null
+++ b/proj/pj_chamb.c
@@ -0,0 +1,114 @@
+/*  Chamberlin Trimetric Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_chamb.c	4.5	93/06/13	GIE	REL";
+#endif
+typedef struct { double r, Az; } VECT;
+#define PROJ_PARMS__ \
+	struct { /* control point data */ \
+		double phi, lam; \
+		double cosphi, sinphi; \
+		VECT v; \
+		XY	p; \
+		double Az; \
+	} c[3]; \
+	XY p; \
+	double beta_0, beta_1, beta_2;
+#define PJ_LIB__
+#include	<projects.h>
+#include	<stdio.h>
+#define THIRD 0.333333333333333333
+#define TOL 1e-9
+	static VECT /* distance and azimuth from point 1 to point 2 */
+vect(double dphi, double c1, double s1, double c2, double s2, double dlam) {
+	VECT v;
+	double cdl, dp, dl;
+
+	cdl = cos(dlam);
+	if (fabs(dphi) > 1. || fabs(dlam) > 1.)
+		v.r = aacos(s1 * s2 + c1 * c2 * cdl);
+	else { /* more accurate for smaller distances */
+		dp = sin(.5 * dphi);
+		dl = sin(.5 * dlam);
+		v.r = 2. * aasin(sqrt(dp * dp + c1 * c2 * dl * dl));
+	}
+	if (fabs(v.r) > TOL)
+		v.Az = atan2(c2 * sin(dlam), c1 * s2 - s1 * c2 * cdl);
+	else
+		v.r = v.Az = 0.;
+	return v;
+}
+	static double /* law of cosines */
+lc(double b,double c,double a) {
+	return aacos(.5 * (b * b + c * c - a * a) / (b * c));
+}
+FORWARD(s_forward); /* spheroid */
+	double sinphi, cosphi, a;
+	VECT v[3];
+	int i, j;
+
+	sinphi = sin(lp.phi);
+	cosphi = cos(lp.phi);
+	for (i = 0; i < 3; ++i) { /* dist/azimiths from control */
+		v[i] = vect(lp.phi - P->c[i].phi, P->c[i].cosphi, P->c[i].sinphi,
+			cosphi, sinphi, lp.lam - P->c[i].lam);
+		if ( ! v[i].r)
+			break;
+		v[i].Az = adjlon(v[i].Az - P->c[i].v.Az);
+	}
+	if (i < 3) /* current point at control point */
+		xy = P->c[i].p;
+	else { /* point mean of intersepts */
+		xy = P->p;
+		for (i = 0; i < 3; ++i) {
+			j = i == 2 ? 0 : i + 1;
+			a = lc(P->c[i].v.r, v[i].r, v[j].r);
+			if (v[i].Az < 0.)
+				a = -a;
+			if (! i) { /* coord comp unique to each arc */
+				xy.x += v[i].r * cos(a);
+				xy.y -= v[i].r * sin(a);
+			} else if (i == 1) {
+				a = P->beta_1 - a;
+				xy.x -= v[i].r * cos(a);
+				xy.y -= v[i].r * sin(a);
+			} else {
+				a = P->beta_2 - a;
+				xy.x += v[i].r * cos(a);
+				xy.y += v[i].r * sin(a);
+			}
+		}
+		xy.x *= THIRD; /* mean of arc intercepts */
+		xy.y *= THIRD;
+	}
+	return xy;
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_chamb)
+	int i, j;
+	char line[10];
+
+	for (i = 0; i < 3; ++i) { /* get control point locations */
+		(void)sprintf(line, "rlat_%d", i+1);
+		P->c[i].phi = pj_param(P->params, line).f;
+		(void)sprintf(line, "rlon_%d", i+1);
+		P->c[i].lam = pj_param(P->params, line).f;
+		P->c[i].lam = adjlon(P->c[i].lam - P->lam0);
+		P->c[i].cosphi = cos(P->c[i].phi);
+		P->c[i].sinphi = sin(P->c[i].phi);
+	}
+	for (i = 0; i < 3; ++i) { /* inter ctl pt. distances and azimuths */
+		j = i == 2 ? 0 : i + 1;
+		P->c[i].v = vect(P->c[j].phi - P->c[i].phi, P->c[i].cosphi, P->c[i].sinphi,
+			P->c[j].cosphi, P->c[j].sinphi, P->c[j].lam - P->c[i].lam);
+		if (! P->c[i].v.r) E_ERROR(-25);
+		/* co-linearity problem ignored for now */
+	}
+	P->beta_0 = lc(P->c[0].v.r, P->c[2].v.r, P->c[1].v.r);
+	P->beta_1 = lc(P->c[0].v.r, P->c[1].v.r, P->c[2].v.r);
+	P->beta_2 = PI - P->beta_0;
+	P->p.y = 2. * (P->c[0].p.y = P->c[1].p.y = P->c[2].v.r * sin(P->beta_0));
+	P->c[2].p.y = 0.;
+	P->c[0].p.x = - (P->c[1].p.x = 0.5 * P->c[0].v.r);
+	P->p.x = P->c[2].p.x = P->c[0].p.x + P->c[2].v.r * cos(P->beta_0);
+	P->es = 0.; P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_collg.c b/proj/pj_collg.c
new file mode 100644
index 0000000..2af517d
--- /dev/null
+++ b/proj/pj_collg.c
@@ -0,0 +1,32 @@
+/*  Collignon projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_collg.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PJ_LIB__
+# include	<projects.h>
+#define FXC	1.12837916709551257390
+#define FYC	1.77245385090551602729
+#define ONEEPS	1.0000001
+FORWARD(s_forward); /* spheroid */
+	if ((xy.y = 1. - sin(lp.phi)) <= 0.)
+		xy.y = 0.;
+	else
+		xy.y = sqrt(xy.y);
+	xy.x = FXC * lp.lam * xy.y;
+	xy.y = FYC * (1. - xy.y);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = xy.y / FYC - 1.;
+	if (fabs(lp.phi = 1. - lp.phi * lp.phi) < 1.)
+		lp.phi = asin(lp.phi);
+	else if (fabs(lp.phi) > ONEEPS) I_ERROR
+	else	lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
+	if ((lp.lam = 1. - sin(lp.phi)) <= 0.)
+		lp.lam = 0.;
+	else
+		lp.lam = xy.x / (FXC * sqrt(lp.lam));
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_collg) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_dense.c b/proj/pj_dense.c
new file mode 100644
index 0000000..21d5c84
--- /dev/null
+++ b/proj/pj_dense.c
@@ -0,0 +1,21 @@
+/*  Denoyer Semi-Elliptical */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_dense.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define C0	0.95
+#define C1	-.08333333333333333333
+#define C3	.00166666666666666666
+#define D1	0.9
+#define D5	0.03
+FORWARD(s_forward); /* spheroid */
+	xy.y = lp.phi;
+	xy.x = lp.lam;
+	lp.lam = fabs(lp.lam);
+	xy.x *= cos((C0 + lp.lam * (C1 + lp.lam * lp.lam * C3)) *
+		(lp.phi * (D1 + D5 * lp.phi * lp.phi * lp.phi * lp.phi)));
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_dense) P->es = 0.; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_deriv.c b/proj/pj_deriv.c
new file mode 100644
index 0000000..f6477b0
--- /dev/null
+++ b/proj/pj_deriv.c
@@ -0,0 +1,36 @@
+/* dervative of (*P->fwd) projection */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_deriv.c	4.4	93/06/12	GIE	REL";
+#endif
+#define PJ_LIB__
+#include "projects.h"
+	int
+pj_deriv(LP lp, double h, PJ *P, struct DERIVS *der) {
+	XY t;
+
+	lp.lam += h;
+	lp.phi += h;
+	if (fabs(lp.phi) > HALFPI) return 1;
+	h += h;
+	t = (*P->fwd)(lp, P);
+	if (t.x == HUGE_VAL) return 1;
+	der->x_l = t.x; der->y_p = t.y; der->x_p = -t.x; der->y_l = -t.y;
+	lp.phi -= h;
+	if (fabs(lp.phi) > HALFPI) return 1;
+	t = (*P->fwd)(lp, P);
+	if (t.x == HUGE_VAL) return 1;
+	der->x_l += t.x; der->y_p -= t.y; der->x_p += t.x; der->y_l -= t.y;
+	lp.lam -= h;
+	t = (*P->fwd)(lp, P);
+	if (t.x == HUGE_VAL) return 1;
+	der->x_l -= t.x; der->y_p -= t.y; der->x_p += t.x; der->y_l += t.y;
+	lp.phi += h;
+	t = (*P->fwd)(lp, P);
+	if (t.x == HUGE_VAL) return 1;
+	der->x_l -= t.x; der->y_p += t.y; der->x_p -= t.x; der->y_l += t.y;
+	der->x_l /= (h += h);
+	der->y_p /= h;
+	der->x_p /= h;
+	der->y_l /= h;
+	return 0;
+}
diff --git a/proj/pj_eck1.c b/proj/pj_eck1.c
new file mode 100644
index 0000000..96b7fa2
--- /dev/null
+++ b/proj/pj_eck1.c
@@ -0,0 +1,20 @@
+/*  Eckert I Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_eck1.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define FC	.92131773192356127802
+#define RP	.31830988618379067154
+FORWARD(s_forward); /* spheroid */
+	xy.x = FC * lp.lam * (1. - RP * fabs(lp.phi));
+	xy.y = FC * lp.phi;
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = xy.y / FC;
+	lp.lam = xy.x / (FC * (1. - RP * fabs(lp.phi)));
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_eck1) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_eck2.c b/proj/pj_eck2.c
new file mode 100644
index 0000000..fc1d32d
--- /dev/null
+++ b/proj/pj_eck2.c
@@ -0,0 +1,31 @@
+/*  Eckert II Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_eck2.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PJ_LIB__
+# include	<projects.h>
+#define FXC	0.46065886596178063902
+#define FYC	1.44720250911653531871
+#define C13	0.33333333333333333333
+#define ONEEPS	1.0000001
+FORWARD(s_forward); /* spheroid */
+	xy.x = FXC * lp.lam * (xy.y = sqrt(4. - 3. * sin(fabs(lp.phi))));
+	xy.y = FYC * (2. - xy.y);
+	if ( lp.phi < 0.) xy.y = -xy.y;
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.lam = xy.x / (FXC * ( lp.phi = 2. - fabs(xy.y) / FYC) );
+	lp.phi = (4. - lp.phi * lp.phi) * C13;
+	if (fabs(lp.phi) >= 1.) {
+		if (fabs(lp.phi) > ONEEPS)	I_ERROR
+		else
+			lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
+	} else
+		lp.phi = asin(lp.phi);
+	if (xy.y < 0)
+		lp.phi = -lp.phi;
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_eck2) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_eck3.c b/proj/pj_eck3.c
new file mode 100644
index 0000000..60734e8
--- /dev/null
+++ b/proj/pj_eck3.c
@@ -0,0 +1,28 @@
+/*  Eckert III */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_eck3.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define XF	.42223820031577120149
+#define RXF	2.36833142821314873781
+#define YF	.84447640063154240298
+#define RYF	1.18416571410657436890
+FORWARD(s_forward); /* spheroid */
+	if (fabs(xy.x = lp.phi / HALFPI) >= 1.)
+		xy.x = XF * lp.lam;
+	else
+		xy.x = XF * (1. + sqrt(1. - xy.x*xy.x)) * lp.lam;
+	xy.y = YF * lp.phi;
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double t;
+
+	lp.lam = xy.x * RXF;
+	if (fabs(t = (lp.phi = RYF * xy.y) / HALFPI) < 1.)
+		lp.lam /= 1. + sqrt(1. - t*t);
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_eck3) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_eck4.c b/proj/pj_eck4.c
new file mode 100644
index 0000000..7b0f6a9
--- /dev/null
+++ b/proj/pj_eck4.c
@@ -0,0 +1,52 @@
+/* Eckert IV projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_eck4.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define C1	.42223820031577120149
+#define C2	1.32650042817700232218
+#define RC2	.75386330736002178205
+#define C3	3.57079632679489661922
+#define RC3	.28004957675577868795
+#define EPS	1e-10
+#define EPS10	1e-10
+#define NITER	10
+	static double
+theta(double ph) {
+	double th, dth, s, c;
+	int i;
+
+	th = .5 * ph;
+	ph = C3 * sin(ph);
+	for (i = NITER; i ; --i) {
+		c = cos(th);
+		s = sin(th);
+		th += ( dth =
+		   (ph - th - (c + 2.) * s) / (2. * c * (1. + c)) );
+		if (fabs(dth) < EPS)
+			break;
+	}
+	return th;
+}
+FORWARD(s_forward); /* spheroid */
+	xy.x = C1 * lp.lam * (1. + cos(lp.phi = theta(lp.phi)));
+	xy.y = C2 * sin(lp.phi);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double c, s;
+
+	if ((s = fabs(xy.y *= RC2)) < 1.) {
+		c = cos(s = asin(xy.y));
+		lp.phi = asin((s + xy.y * (c + 2.)) * RC3);
+		lp.lam = xy.x / (C1 * (1. + c));
+	} else if ((s - EPS10) > 1. ) I_ERROR
+	else {
+		lp.lam = 0.;
+		lp.phi = xy.y < 0. ? - HALFPI : HALFPI;
+	}
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_eck4) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_eck5.c b/proj/pj_eck5.c
new file mode 100644
index 0000000..592bafc
--- /dev/null
+++ b/proj/pj_eck5.c
@@ -0,0 +1,21 @@
+/*  Eckert V */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_eck5.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PJ_LIB__
+# include	<projects.h>
+#define XF	0.44101277172455148219
+#define RXF	2.26750802723822639137
+#define YF	0.88202554344910296438
+#define RYF	1.13375401361911319568
+FORWARD(s_forward); /* spheroid */
+	xy.x = XF * (1. + cos(lp.phi)) * lp.lam;
+	xy.y = YF * lp.phi;
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.lam = RXF * xy.x / (1. + cos( lp.phi = RYF * xy.y));
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_eck5) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_eck6.c b/proj/pj_eck6.c
new file mode 100644
index 0000000..b2556fc
--- /dev/null
+++ b/proj/pj_eck6.c
@@ -0,0 +1,50 @@
+/* Eckert VI projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_eck6.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define C1R	.44101277172455148219
+#define C2R	.88202554344910296438
+#define RC2R	1.13375401361911319568
+#define C5	2.57079632679489661922
+#define RC5	.38898452964834271062
+#define EPS	1e-10
+#define EPS10	1e-10
+#define NITER	10
+	static double
+theta(double ph) {
+	double th, dth;
+	int i;
+
+	ph = C5 * sin(th = ph);
+	for (i = NITER; i ; --i) {
+		th += ( dth = (ph - th - sin(th)) / (1. + cos(th)) );
+		if (fabs(dth) < EPS)
+			break;
+	}
+	return th;
+}
+FORWARD(s_forward); /* spheroid */
+	double th;
+
+	xy.x = C1R * lp.lam * (1. + cos(th = theta(lp.phi)));
+	xy.y = C2R * th;
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double s, t;
+
+	t = (xy.y *= RC2R);
+	if ((s = fabs(xy.y = (xy.y + sin(xy.y)) * RC5)) < 1.) {
+		lp.lam = xy.x / (C1R * (1. + cos(t)));
+		lp.phi = asin(xy.y);
+	} else if ((s - EPS10) > 1.) I_ERROR
+	else {
+		lp.lam = 0.;
+		lp.phi = xy.y < 0. ? -HALFPI : HALFPI;
+	}
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_eck6) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_eisen.c b/proj/pj_eisen.c
new file mode 100644
index 0000000..68d6796
--- /dev/null
+++ b/proj/pj_eisen.c
@@ -0,0 +1,25 @@
+/*  Eisenlohr Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_eisen.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define RSQTWO	0.70710678118654752440
+#define FACT	5.82842712474619009760
+FORWARD(s_forward); /* spheroid */
+	double s1, c1, t, c, v, cp2, cps, cp;
+
+	s1 = sin(lp.lam *= 0.5);
+	c1 = cos(lp.lam);
+	cp = cos(lp.phi);
+	cp2 = cos(lp.phi *= 0.5);
+	t = sin(lp.phi)/(cp2 + 2. * (cps = RSQTWO * sqrt(cp)) * c1);
+	c = sqrt(2./(1. + t * t));
+	v = sqrt((cp2 + cps * (c1 + s1)) / ( cp2 +
+		cps * (c1 - s1)));
+	xy.x = FACT * ( -2. * log(v) + c * (v - 1./v));
+	xy.y = FACT * ( -2. * atan(t) + c * t * (v + 1./v));
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_eisen) P->es = 0.; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_ell_set.c b/proj/pj_ell_set.c
new file mode 100644
index 0000000..cc8be55
--- /dev/null
+++ b/proj/pj_ell_set.c
@@ -0,0 +1,109 @@
+/* set ellipsoid parameters a and es */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_ell_set.c	4.5	93/06/12	GIE	REL";
+#endif
+#include <projects.h>
+#include <string.h>
+#define SIXTH .1666666666666666667 /* 1/6 */
+#define RA4 .04722222222222222222 /* 17/360 */
+#define RA6 .02215608465608465608 /* 67/3024 */
+#define RV4 .06944444444444444444 /* 5/72 */
+#define RV6 .04243827160493827160 /* 55/1296 */
+	int /* initialize geographic shape parameters */
+pj_ell_set(paralist *pl, double *a, double *es) {
+	int i;
+	double b, e;
+	char *name;
+	paralist *start = 0, *curr;
+
+	b = 0;
+		/* check for varying forms of ellipsoid input */
+	*a = *es = 0.;
+	/* R takes precedence */
+	if (pj_param(pl, "tR").i)
+		*a = pj_param(pl, "dR").f;
+	else { /* probable elliptical figure */
+
+		/* check if ellps present and temporarily append its values to pl */
+		if (name = pj_param(pl, "sellps").s) {
+			char *s;
+
+			for (start = pl; start && start->next ; start = start->next) ;
+			curr = start;
+			for (i = 0; (s = pj_ellps[i].id) && strcmp(name, s) ; ++i) ;
+			if (!s) { pj_errno = -9; return 1; }
+			curr = curr->next = pj_mkparam(pj_ellps[i].major);
+			curr = curr->next = pj_mkparam(pj_ellps[i].ell);
+		}
+		*a = pj_param(pl, "da").f;
+		if (pj_param(pl, "tes").i) /* eccentricity squared */
+			*es = pj_param(pl, "des").f;
+		else if (pj_param(pl, "te").i) { /* eccentricity */
+			e = pj_param(pl, "de").f;
+			*es = e * e;
+		} else if (pj_param(pl, "trf").i) { /* recip flattening */
+			*es = pj_param(pl, "drf").f;
+			if (!*es) {
+				pj_errno = -10;
+				goto bomb;
+			}
+			*es = 1./ *es;
+			*es = *es * (2. - *es);
+		} else if (pj_param(pl, "tf").i) { /* flattening */
+			*es = pj_param(pl, "df").f;
+			*es = *es * (2. - *es);
+		} else if (pj_param(pl, "tb").i) { /* minor axis */
+			b = pj_param(pl, "db").f;
+			if (*a != 0.0)
+			  *es = 1. - (b * b) / (*a * *a);
+			else
+			  *es = 1.;
+		}     /* else *es == 0. and sphere of radius *a */
+		if (!b)
+			b = *a * sqrt(1. - *es);
+		/* following options turn ellipsoid into equivalent sphere */
+		if (pj_param(pl, "bR_A").i) { /* sphere--area of ellipsoid */
+			*a *= 1. - *es * (SIXTH + *es * (RA4 + *es * RA6));
+			*es = 0.;
+		} else if (pj_param(pl, "bR_V").i) { /* sphere--vol. of ellipsoid */
+			*a *= 1. - *es * (SIXTH + *es * (RV4 + *es * RV6));
+			*es = 0.;
+		} else if (pj_param(pl, "bR_a").i) { /* sphere--arithmetic mean */
+			*a = .5 * (*a + b);
+			*es = 0.;
+		} else if (pj_param(pl, "bR_g").i) { /* sphere--geometric mean */
+			*a = sqrt(*a * b);
+			*es = 0.;
+		} else if (pj_param(pl, "bR_h").i) { /* sphere--harmonic mean */
+			*a = 2. * *a * b / (*a + b);
+			*es = 0.;
+		} else if ((i = pj_param(pl, "tR_lat_a").i) || /* sphere--arith. */
+			pj_param(pl, "tR_lat_g").i) { /* or geom. mean at latitude */
+			double tmp;
+
+			tmp = sin(pj_param(pl, i ? "rR_lat_a" : "rR_lat_g").f);
+			if (fabs(tmp) > HALFPI) {
+				pj_errno = -11;
+				goto bomb;
+			}
+			tmp = 1. - *es * tmp * tmp;
+			*a *= i ? .5 * (1. - *es + tmp) / ( tmp * sqrt(tmp)) :
+				sqrt(1. - *es) / tmp;
+			*es = 0.;
+		}
+bomb:
+		if (start) { /* clean up temporary extension of list */
+			pj_dalloc(start->next->next);
+			pj_dalloc(start->next);
+			start->next = 0;
+		}
+		if (pj_errno)
+			return 1;
+	}
+	/* some remaining checks */
+	if (*es < 0.)
+		{ pj_errno = -12; return 1; }
+	if (*a <= 0.)
+		{ pj_errno = -13; return 1; }
+	return 0;
+}
diff --git a/proj/pj_ellps.c b/proj/pj_ellps.c
new file mode 100644
index 0000000..c921c68
--- /dev/null
+++ b/proj/pj_ellps.c
@@ -0,0 +1,51 @@
+/* definition of standard geoids */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_ellps.c	4.4	93/08/20	GIE	REL";
+#endif
+#define PJ_ELLPS__
+#include "projects.h"
+	struct PJ_ELLPS
+pj_ellps[] = {
+"MERIT",	"a=6378137.0", "rf=298.257", "MERIT 1983",
+"SGS85",	"a=6378136.0", "rf=298.257",  "SGS 85",
+"GRS80",	"a=6378137.0", "rf=298.257222101", "GRS 1980(IUGG, 1980)",
+"IAU76",	"a=6378140.0", "rf=298.257", "IAU 1976",
+"airy",		"a=6377563.396", "b=6356256.910", "Airy 1830",
+"APL4.9",	"a=6378137.0.",  "rf=298.25", "Appl. Physics. 1965",
+"NWL9D",	"a=6378145.0.",  "rf=298.25", "Naval Weapons Lab., 1965",
+"mod_airy",	"a=6377340.189", "b=6356034.446", "Modified Airy",
+"andrae",	"a=6377104.43",  "rf=300.0", 	"Andrae 1876 (Den., Iclnd.)",
+"aust_SA",	"a=6378160.0", "rf=298.25", "Australian Natl & S. Amer. 1969",
+"GRS67",	"a=6378160.0", "rf=247.247167", "GRS 67(IUGG 1967)",
+"bessel",	"a=6377397.155", "rf=299.1528128", "Bessel 1841",
+"bess_nam",	"a=6377483.865", "rf=299.1528128", "Bessel 1841 (Namibia)",
+"clrk66",	"a=6378206.4", "b=6356583.8", "Clarke 1866",
+"clrk80",	"a=6378249.145", "rf=293.4663", "Clarke 1880 mod.",
+"CPM",  	"a=6375738.7", "rf=334.29", "Comm. des Poids et Mesures 1799",
+"delmbr",	"a=6376428.",  "rf=311.5", "Delambre 1810 (Belgium)",
+"engelis",	"a=6378136.05", "rf=298.2566", "Engelis 1985",
+"evrst30",  "a=6377276.345", "rf=300.8017",  "Everest 1830",
+"evrst48",  "a=6377304.063", "rf=300.8017",  "Everest 1948",
+"evrst56",  "a=6377301.243", "rf=300.8017",  "Everest 1956",
+"evrst69",  "a=6377295.664", "rf=300.8017",  "Everest 1969",
+"evrstSS",  "a=6377298.556", "rf=300.8017",  "Everest (Sabah & Sarawak)",
+"fschr60",  "a=6378166.",   "rf=298.3", "Fischer (Mercury Datum) 1960",
+"fschr60m", "a=6378155.",   "rf=298.3", "Modified Fischer 1960",
+"fschr68",  "a=6378150.",   "rf=298.3", "Fischer 1968",
+"helmert",  "a=6378200.",   "rf=298.3", "Helmert 1906",
+"hough",	"a=6378270.0", "rf=297.", "Hough",
+"intl",		"a=6378388.0", "rf=297.", "International 1909 (Hayford)",
+"krass",	"a=6378245.0", "rf=298.3", "Krassovsky, 1942",
+"kaula",	"a=6378163.",  "rf=298.24", "Kaula 1961",
+"lerch",	"a=6378139.",  "rf=298.257", "Lerch 1979",
+"mprts",	"a=6397300.",  "rf=191.", "Maupertius 1738",
+"new_intl",	"a=6378157.5", "b=6356772.2", "New International 1967",
+"plessis",	"a=6376523.",  "b=6355863.", "Plessis 1817 (France)",
+"SEasia",	"a=6378155.0", "b=6356773.3205", "Southeast Asia",
+"walbeck",	"a=6376896.0", "b=6355834.8467", "Walbeck",
+"WGS60",    "a=6378165.0",  "rf=298.3", "WGS 60",
+"WGS66",	"a=6378145.0", "rf=298.25", "WGS 66",
+"WGS72",	"a=6378135.0", "rf=298.26", "WGS 72",
+"WGS84",    "a=6378137.0",  "rf=298.257223563", "WGS 84",
+0,0,0,0
+};
diff --git a/proj/pj_eqc.c b/proj/pj_eqc.c
new file mode 100644
index 0000000..32da68a
--- /dev/null
+++ b/proj/pj_eqc.c
@@ -0,0 +1,25 @@
+/* Equidistant Cylindrical projection (Plate Caree) */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_eqc.c	4.5	93/06/13	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double rc;
+#define PJ_LIB__
+# include	<projects.h>
+FORWARD(s_forward); /* spheroid */
+	xy.x = P->rc * lp.lam;
+	xy.y = lp.phi;
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = xy.y;
+	lp.lam = xy.x / P->rc;
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_eqc)
+	if ((P->rc = cos(pj_param(P->params, "rlat_ts").f)) <= 0.) E_ERROR(-24);
+	P->inv = s_inverse;
+	P->fwd = s_forward;
+	P->es = 0.;
+ENDENTRY(P)
diff --git a/proj/pj_eqdc.c b/proj/pj_eqdc.c
new file mode 100644
index 0000000..0273559
--- /dev/null
+++ b/proj/pj_eqdc.c
@@ -0,0 +1,78 @@
+/* Equidistant Conic */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_eqdc.c	4.5	93/06/13	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double phi1; \
+	double phi2; \
+	double n; \
+	double rho; \
+	double rho0; \
+	double c; \
+	double *en; \
+	int		ellips;
+#define PJ_LIB__
+#include	<projects.h>
+# define EPS10	1.e-10
+FORWARD(e_forward); /* sphere & ellipsoid */
+	P->rho = P->c - (P->ellips ? pj_mlfn(lp.phi, sin(lp.phi),
+		cos(lp.phi), P->en) : lp.phi);
+	xy.x = P->rho * sin( lp.lam *= P->n );
+	xy.y = P->rho0 - P->rho * cos(lp.lam);
+	return (xy);
+}
+INVERSE(e_inverse); /* sphere & ellipsoid */
+	if (P->rho = hypot(xy.x, xy.y = P->rho0 - xy.y)) {
+		if (P->n < 0.) {
+			P->rho = -P->rho;
+			xy.x = -xy.x;
+			xy.y = -xy.y;
+		}
+		lp.phi = P->c - P->rho;
+		if (P->ellips)
+			lp.phi = pj_inv_mlfn(lp.phi, P->es, P->en);
+		lp.lam = atan2(xy.x, xy.y) / P->n;
+	} else {
+		lp.lam = 0.;
+		lp.phi = P->n > 0. ? HALFPI : - HALFPI;
+	}
+	return (lp);
+}
+FREEUP; if (P) { if (P->en) pj_dalloc(P->en); pj_dalloc(P); } }
+ENTRY1(pj_eqdc, en)
+	double cosphi, sinphi;
+	int secant;
+
+	P->phi1 = pj_param(P->params, "rlat_1").f;
+	P->phi2 = pj_param(P->params, "rlat_2").f;
+	if (fabs(P->phi1 + P->phi2) < EPS10) E_ERROR(-21);
+	if (!(P->en = pj_enfn(P->es)))
+		E_ERROR_0;
+	P->n = sinphi = sin(P->phi1);
+	cosphi = cos(P->phi1);
+	secant = fabs(P->phi1 - P->phi2) >= EPS10;
+	if (P->ellips = P->es > 0.) {
+		double ml1, m1;
+
+		m1 = pj_msfn(sinphi, cosphi, P->es);
+		P->en = pj_enfn(P->es);
+		ml1 = pj_mlfn(P->phi1, sinphi, cosphi, P->en);
+		if (secant) { /* secant cone */
+			sinphi = sin(P->phi2);
+			cosphi = cos(P->phi2);
+			P->n = (m1 - pj_msfn(sinphi, cosphi, P->es)) /
+				(pj_mlfn(P->phi2, sinphi, cosphi, P->en) - ml1);
+		}
+		P->c = ml1 + m1 / P->n;
+		P->rho0 = P->c - pj_mlfn(P->phi0, sin(P->phi0),
+			cos(P->phi0), P->en);
+	} else {
+		if (secant)
+			P->n = (cosphi - cos(P->phi2)) / (P->phi2 - P->phi1);
+		P->c = P->phi1 + cos(P->phi1) / P->n;
+		P->rho0 = P->c - P->phi0;
+	}
+	P->inv = e_inverse;
+	P->fwd = e_forward;
+	P->es = 0.;
+ENDENTRY(P)
diff --git a/proj/pj_errno.c b/proj/pj_errno.c
new file mode 100644
index 0000000..6485609
--- /dev/null
+++ b/proj/pj_errno.c
@@ -0,0 +1,8 @@
+/* For full ANSI compliance of global variable */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_errno.c	4.2	93/06/12	GIE	REL";
+#endif
+
+int pj_errno;
+
+/* end */
diff --git a/proj/pj_factors.c b/proj/pj_factors.c
new file mode 100644
index 0000000..cb01071
--- /dev/null
+++ b/proj/pj_factors.c
@@ -0,0 +1,81 @@
+/* projection scale factors */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_factors.c	4.8	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include <projects.h>
+#include <errno.h>
+#ifndef DEFAULT_H
+#define DEFAULT_H   1e-5    /* radian default for numeric h */
+#endif
+#define EPS 1.0e-12
+	int
+pj_factors(LP lp, PJ *P, double h, struct FACTORS *fac) {
+	struct DERIVS der;
+	double cosphi, t, n, r;
+
+	/* check for forward and latitude or longitude overange */
+	if ((t = fabs(lp.phi)-HALFPI) > EPS || fabs(lp.lam) > 10.) {
+		pj_errno = -14;
+		return 1;
+	} else { /* proceed */
+		errno = pj_errno = 0;
+		if (fabs(t) <= EPS) /* adjust to pi/2 */
+			lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
+		else if (P->geoc)
+			lp.phi = atan(P->rone_es * tan(lp.phi));
+		lp.lam -= P->lam0;	/* compute del lp.lam */
+		if (!P->over)
+			lp.lam = adjlon(lp.lam); /* adjust del longitude */
+		if (h <= 0.)
+			h = DEFAULT_H;
+		if (P->spc)	/* get what projection analytic values */
+			P->spc(lp, P, fac);
+		if (((fac->code & (IS_ANAL_XL_YL+IS_ANAL_XP_YP)) !=
+			  (IS_ANAL_XL_YL+IS_ANAL_XP_YP)) &&
+			  pj_deriv(lp, h, P, &der))
+			return 1;
+		if (!(fac->code & IS_ANAL_XL_YL)) {
+			fac->der.x_l = der.x_l;
+			fac->der.y_l = der.y_l;
+		}
+		if (!(fac->code & IS_ANAL_XP_YP)) {
+			fac->der.x_p = der.x_p;
+			fac->der.y_p = der.y_p;
+		}
+		cosphi = cos(lp.phi);
+		if (!(fac->code & IS_ANAL_HK)) {
+			fac->h = hypot(fac->der.x_p, fac->der.y_p);
+			fac->k = hypot(fac->der.x_l, fac->der.y_l) / cosphi;
+			if (P->es) {
+				t = sin(lp.phi);
+				t = 1. - P->es * t * t;
+				n = sqrt(t);
+				fac->h *= t * n / P->one_es;
+				fac->k *= n;
+				r = t * t / P->one_es;
+			} else
+				r = 1.;
+		}
+		/* convergence */
+		if (!(fac->code * IS_ANAL_CONV)) {
+			fac->conv = atan2(fac->der.y_l, fac->der.x_l);
+			if (fac->code & IS_ANAL_XL_YL)
+				fac->code |= IS_ANAL_CONV;
+		}
+		/* areal scale factor */
+		fac->s = (fac->der.y_p * fac->der.x_l - fac->der.x_p * fac->der.y_l) *
+			r / cosphi;
+		/* meridian-parallel angle theta prime */
+		fac->thetap = aasin(fac->s / (fac->h * fac->k));
+		/* Tissot ellips axis */
+		t = fac->k * fac->k + fac->h * fac->h;
+		fac->a = sqrt(t + 2. * fac->s);
+		t = (t = t - 2. * fac->s) <= 0. ? 0. : sqrt(t);
+		fac->b = 0.5 * (fac->a - t);
+		fac->a = 0.5 * (fac->a + t);
+		/* omega */
+		fac->omega = 2. * aasin((fac->a - fac->b)/(fac->a + fac->b));
+	}
+	return 0;
+}
diff --git a/proj/pj_fourn.c b/proj/pj_fourn.c
new file mode 100644
index 0000000..684c716
--- /dev/null
+++ b/proj/pj_fourn.c
@@ -0,0 +1,40 @@
+/*  Fournier Globular I */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_fourn.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define EPS	1e-10
+#define C	2.46740110027233965467
+FORWARD(s_forward); /* spheroid */
+	if (fabs(lp.lam) < EPS) {
+		xy.x = 0;
+		xy.y = lp.phi;
+	} else if (fabs(lp.phi) < EPS) {
+		xy.x = lp.lam;
+		xy.y = 0.;
+	} else if (fabs(fabs(lp.lam) - HALFPI) < EPS) {
+		xy.x = lp.lam * cos(lp.phi);
+		xy.y = HALFPI * sin(lp.phi);
+	} else {
+		double p, s, at;
+
+		p = fabs(PI * sin(lp.phi));
+		s = (C - lp.phi * lp.phi)/(p - 2. * fabs(lp.phi));
+		at = lp.lam * lp.lam / C - 1.;
+		if ((xy.y = s * s - at * (C - p * s - lp.lam * lp.lam)) < 0.) {
+			if (xy.y < -EPS) F_ERROR
+			else xy.y = -s / at;
+		} else
+			xy.y = (sqrt(xy.y) - s) / at;
+		if (lp.phi < 0.) xy.y = -xy.y;
+		if ((xy.x = 1. - xy.y * xy.y / C) < 0.) {
+			if (xy.x < -EPS) F_ERROR
+			else xy.x = 0;
+		} else
+			xy.x = lp.lam * sqrt(xy.x);
+	}
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_fourn) P->es = 0.; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_fwd.c b/proj/pj_fwd.c
new file mode 100644
index 0000000..e88472a
--- /dev/null
+++ b/proj/pj_fwd.c
@@ -0,0 +1,37 @@
+/* general forward projection */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_fwd.c	4.4	93/06/12	GIE	REL";
+#endif
+#define PJ_LIB__
+#include <projects.h>
+#include <errno.h>
+# define EPS 1.0e-12
+	XY /* forward projection entry */
+pj_fwd(LP lp, PJ *P) {
+	XY xy;
+	double t;
+
+	/* check for forward and latitude or longitude overange */
+	if ((t = fabs(lp.phi)-HALFPI) > EPS || fabs(lp.lam) > 10.) {
+		xy.x = xy.y = HUGE_VAL;
+		pj_errno = -14;
+	} else { /* proceed with projection */
+		errno = pj_errno = 0;
+		if (fabs(t) <= EPS)
+			lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
+		else if (P->geoc)
+			lp.phi = atan(P->rone_es * tan(lp.phi));
+		lp.lam -= P->lam0;	/* compute del lp.lam */
+		if (!P->over)
+			lp.lam = adjlon(lp.lam); /* adjust del longitude */
+		xy = (*P->fwd)(lp, P); /* project */
+		if (pj_errno || (pj_errno = errno))
+			xy.x = xy.y = HUGE_VAL;
+		/* adjust for major axis and easting/northings */
+		else {
+			xy.x = P->fr_meter * (P->a * xy.x + P->x0);
+			xy.y = P->fr_meter * (P->a * xy.y + P->y0);
+		}
+	}
+	return xy;
+}
diff --git a/proj/pj_gall.c b/proj/pj_gall.c
new file mode 100644
index 0000000..947cd40
--- /dev/null
+++ b/proj/pj_gall.c
@@ -0,0 +1,22 @@
+/*  Gall (Stereographic) */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_gall.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define YF	1.70710678118654752440
+#define XF	0.70710678118654752440
+#define RYF	0.58578643762690495119
+#define RXF	1.41421356237309504880
+FORWARD(s_forward); /* spheroid */
+	xy.x = XF * lp.lam;
+	xy.y = YF * tan(.5 * lp.phi);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.lam = RXF * xy.x;
+	lp.phi = 2. * atan(xy.y * RYF);
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_gall) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_gnom.c b/proj/pj_gnom.c
new file mode 100644
index 0000000..70e47d1
--- /dev/null
+++ b/proj/pj_gnom.c
@@ -0,0 +1,108 @@
+/* Gnomonic projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_gnom.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	sinph0; \
+	double	cosph0; \
+	int		mode;
+#define PJ_LIB__
+#include	<projects.h>
+#define EPS10 1.e-10
+#define N_POLE	0
+#define S_POLE 1
+#define EQUIT	2
+#define OBLIQ	3
+FORWARD(s_forward); /* spheroid */
+	double  coslam, cosphi, sinphi;
+
+	sinphi = sin(lp.phi);
+	cosphi = cos(lp.phi);
+	coslam = cos(lp.lam);
+	switch (P->mode) {
+	case EQUIT:
+		xy.y = cosphi * coslam;
+		break;
+	case OBLIQ:
+		xy.y = P->sinph0 * sinphi + P->cosph0 * cosphi * coslam;
+		break;
+	case S_POLE:
+		xy.y = - sinphi;
+		break;
+	case N_POLE:
+		xy.y = sinphi;
+		break;
+	}
+	if (xy.y <= EPS10) F_ERROR;
+	xy.x = (xy.y = 1. / xy.y) * cosphi * sin(lp.lam);
+	switch (P->mode) {
+	case EQUIT:
+		xy.y *= sinphi;
+		break;
+	case OBLIQ:
+		xy.y *= P->cosph0 * sinphi - P->sinph0 * cosphi * coslam;
+		break;
+	case N_POLE:
+		coslam = - coslam;
+	case S_POLE:
+		xy.y *= cosphi * coslam;
+		break;
+	}
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double  rh, cosz, sinz;
+
+	rh = hypot(xy.x, xy.y);
+	sinz = sin(lp.phi = atan(rh));
+	cosz = sqrt(1. - sinz * sinz);
+	if (fabs(rh) <= EPS10) {
+		lp.phi = P->phi0;
+		lp.lam = 0.;
+	} else {
+		switch (P->mode) {
+		case OBLIQ:
+			lp.phi = cosz * P->sinph0 + xy.y * sinz * P->cosph0 / rh;
+			if (fabs(lp.phi) >= 1.)
+				lp.phi = lp.phi > 0. ? HALFPI : - HALFPI;
+			else
+				lp.phi = asin(lp.phi);
+			xy.y = (cosz - P->sinph0 * sin(lp.phi)) * rh;
+			xy.x *= sinz * P->cosph0;
+			break;
+		case EQUIT:
+			lp.phi = xy.y * sinz / rh;
+			if (fabs(lp.phi) >= 1.)
+				lp.phi = lp.phi > 0. ? HALFPI : - HALFPI;
+			else
+				lp.phi = asin(lp.phi);
+			xy.y = cosz * rh;
+			xy.x *= sinz;
+			break;
+		case S_POLE:
+			lp.phi -= HALFPI;
+			break;
+		case N_POLE:
+			lp.phi = HALFPI - lp.phi;
+			xy.y = -xy.y;
+			break;
+		}
+		lp.lam = atan2(xy.x, xy.y);
+	}
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_gnom)
+	if (fabs(fabs(P->phi0) - HALFPI) < EPS10)
+		P->mode = P->phi0 < 0. ? S_POLE : N_POLE;
+	else if (fabs(P->phi0) < EPS10)
+		P->mode = EQUIT;
+	else {
+		P->mode = OBLIQ;
+		P->sinph0 = sin(P->phi0);
+		P->cosph0 = cos(P->phi0);
+	}
+	P->inv = s_inverse;
+	P->fwd = s_forward;
+	P->es = 0.;
+ENDENTRY(P)
diff --git a/proj/pj_goode.c b/proj/pj_goode.c
new file mode 100644
index 0000000..5685013
--- /dev/null
+++ b/proj/pj_goode.c
@@ -0,0 +1,39 @@
+/*  Goode Homolosine Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_goode.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	struct PJconsts	*sinu; \
+	struct PJconsts	*moll;
+#define PJ_LIB__
+#include	<projects.h>
+	extern PJ
+*pj_sinu(PJ *), *pj_moll(PJ *);
+#define Y_COR		0.05280
+#define PHI_LIM	.71093078197902358062
+FORWARD(s_forward); /* spheroid */
+	if (fabs(lp.phi) <= PHI_LIM)
+		xy = P->sinu->fwd(lp, P->sinu);
+	else {
+		xy = P->moll->fwd(lp, P->sinu);
+		xy.y -= lp.phi >= 0.0 ? Y_COR : -Y_COR;
+	}
+	return (xy);
+}
+FREEUP;
+	if (P) {
+		if (P->sinu)
+			(*(P->sinu->pfree))(P->sinu);
+		if (P->moll)
+			(*(P->moll->pfree))(P->moll);
+		pj_dalloc(P);
+	}
+}
+ENTRY2(pj_goode, sinu, moll)
+	P->es = 0.;
+	if (!(P->sinu = pj_sinu(0)) || !(P->moll = pj_moll(0)))
+		E_ERROR_0;
+	if (!(P->sinu = pj_sinu(P->sinu)) || !(P->moll = pj_moll(P->moll)))
+		E_ERROR_0;
+	P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_hammer.c b/proj/pj_hammer.c
new file mode 100644
index 0000000..7aacd38
--- /dev/null
+++ b/proj/pj_hammer.c
@@ -0,0 +1,31 @@
+/*  Hammer & Eckert-Greifendorff Projections */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_hammer.c	4.7	93/06/16	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double w; \
+	double m, rm;
+#define PJ_LIB__
+# include	<projects.h>
+FORWARD(s_forward); /* spheroid */
+	double cosphi, d;
+
+	d = sqrt(2./(1. + (cosphi = cos(lp.phi)) * cos(lp.lam *= P->w)));
+	xy.x = P->m * d * cosphi * sin(lp.lam);
+	xy.y = P->rm * d * sin(lp.phi);
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_hammer)
+	if (pj_param(P->params, "tW").i) {
+		if ((P->w = fabs(pj_param(P->params, "dW").f)) <= 0.) E_ERROR(-27);
+	} else
+		P->w = .5;
+	if (pj_param(P->params, "tM").i) {
+		if ((P->m = fabs(pj_param(P->params, "dM").f)) <= 0.) E_ERROR(-27);
+	} else
+		P->m = 1.;
+	P->rm = 1. / P->m;
+	P->m /= P->w;
+	P->es = 0.; P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_hataea.c b/proj/pj_hataea.c
new file mode 100644
index 0000000..6296fab
--- /dev/null
+++ b/proj/pj_hataea.c
@@ -0,0 +1,54 @@
+/*  Hatano Asymmetrical Equal Area */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_hataea.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define NITER	20
+#define EPS	1e-7
+#define ONETOL 1.000001
+#define CN	2.67595
+#define CS	2.43763
+#define RCN	0.37369906014686373063
+#define RCS	0.41023453108141924738
+#define FYCN	1.75859
+#define FYCS	1.93052
+#define RYCN	0.56863737426006061674
+#define RYCS	0.51799515156538134803
+#define FXC	0.85
+#define RXC	1.17647058823529411764
+FORWARD(s_forward); /* spheroid */
+	double th1, c;
+	int i;
+
+	c = sin(lp.phi) * (lp.phi < 0. ? CS : CN);
+	for (i = NITER; i; --i) {
+		lp.phi -= th1 = (lp.phi + sin(lp.phi) - c) / (1. + cos(lp.phi));
+		if (fabs(th1) < EPS) break;
+	}
+	xy.x = FXC * lp.lam * cos(lp.phi *= .5);
+	xy.y = sin(lp.phi) * (lp.phi < 0. ? FYCS : FYCN);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double th;
+
+	th = xy.y * ( xy.y < 0. ? RYCS : RYCN);
+	if (fabs(th) > 1.)
+		if (fabs(th) > ONETOL)	I_ERROR
+		else			th = th > 0. ? HALFPI : - HALFPI;
+	else
+		th = asin(th);
+	lp.lam = RXC * xy.x / cos(th);
+	th += th;
+	lp.phi = (th + sin(th)) * (xy.y < 0. ? RCS : RCN);
+	if (fabs(lp.phi) > 1.)
+		if (fabs(lp.phi) > ONETOL)	I_ERROR
+		else			lp.phi = lp.phi > 0. ? HALFPI : - HALFPI;
+	else
+		lp.phi = asin(lp.phi);
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_hataea) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_init.c b/proj/pj_init.c
new file mode 100644
index 0000000..c85630a
--- /dev/null
+++ b/proj/pj_init.c
@@ -0,0 +1,190 @@
+/* projection initialization and closure */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_init.c	4.9   93/08/25 GIE REL";
+#endif
+#define PJ_LIB__
+#include <projects.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef errno
+#undef errno
+int errno;
+#endif
+
+#define HOME(x) # x
+	static paralist
+*start;
+	static char *
+proj_lib_name =
+#ifdef HOME_LIB
+HOME_LIB;
+#else
+0;
+#endif
+extern FILE *pj_open_lib(char *, char *);
+	static paralist *
+get_opt(FILE *fid, char *name, paralist *next) {
+	char sword[52], *word = sword+1, c;
+	int first = 1, len;
+
+	len = strlen(name);
+	*sword = 't';
+	while (fscanf(fid, "%50s", word) == 1)
+		if (*word == '#') /* skip comments */
+			while((c = fgetc(fid)) != EOF && c != '\n') ;
+		else if (*word == '<') { /* control name */
+			if (first && !strncmp(name, word + 1, len)
+				&& word[len + 1] == '>')
+				first = 0;
+			else if (!first && word[1] == '>')
+				break;
+		} else if (!first && !pj_param(start, sword).i)
+			next = next->next = pj_mkparam(word);
+	if (errno == 25)
+		errno = 0;
+	return next;
+}
+	static paralist *
+get_defaults(paralist *next, char *name) {
+	FILE *fid;
+
+	if (fid = pj_open_lib("proj_def.dat", "r")) {
+		next = get_opt(fid, "general", next);
+		rewind(fid);
+		next = get_opt(fid, name, next);
+		(void)fclose(fid);
+	}
+	if (errno == ENOENT)
+		errno = 0; /* don't care if can't open file */
+	return next;
+}
+	static paralist *
+get_init(paralist *next, char *name) {
+	char fname[FILENAME_MAX+ID_TAG_MAX+3], *opt;
+	FILE *fid;
+
+	(void)strncpy(fname, name, FILENAME_MAX + ID_TAG_MAX + 1);
+	if (opt = strrchr(fname, ':'))
+		*opt++ = '\0';
+	else { pj_errno = -3; return(0); }
+	if (fid = pj_open_lib(fname, "r"))
+		next = get_opt(fid, opt, next);
+	else
+		return(0);
+	(void)fclose(fid);
+	if (errno == 25)
+		errno = 0; /* unknown problem with some sys errno<-25 */
+	return next;
+}
+	PJ *
+pj_init(int argc, char **argv) {
+	char *s, *name;
+	void *(*proj)(PJ *);
+	paralist *curr;
+	int i;
+	PJ *PIN = 0;
+
+	errno = pj_errno = 0;
+	/* put arguments into internal linked list */
+	if (argc <= 0) { pj_errno = -1; goto bum_call; }
+	for (i = 0; i < argc; ++i)
+		if (i)
+			curr = curr->next = pj_mkparam(argv[i]);
+		else
+			start = curr = pj_mkparam(argv[i]);
+	if (pj_errno) goto bum_call;
+	/* check if +init present */
+	if (pj_param(start, "tinit").i) {
+		paralist *last = curr;
+
+		if (!(curr = get_init(curr, pj_param(start, "sinit").s)))
+			goto bum_call;
+		if (curr == last) { pj_errno = -2; goto bum_call; }
+	}
+	/* find projection selection */
+	if (!(name = pj_param(start, "sproj").s))
+		{ pj_errno = -4; goto bum_call; }
+	for (i = 0; (s = pj_list[i].id) && strcmp(name, s) ; ++i) ;
+	if (!s) { pj_errno = -5; goto bum_call; }
+	/* set defaults, unless inhibited */
+	if (!pj_param(start, "bno_defs").i)
+		curr = get_defaults(curr, name);
+	proj = pj_list[i].proj;
+	/* allocate projection structure */
+	if (!(PIN = (*proj)(0))) goto bum_call;
+	PIN->params = start;
+	/* set ellipsoid/sphere parameters */
+	if (pj_ell_set(start, &PIN->a, &PIN->es)) goto bum_call;
+	PIN->e = sqrt(PIN->es);
+	PIN->ra = 1. / PIN->a;
+	PIN->one_es = 1. - PIN->es;
+	if (PIN->one_es == 0.) { pj_errno = -6; goto bum_call; }
+	PIN->rone_es = 1./PIN->one_es;
+	/* set PIN->geoc coordinate system */
+	PIN->geoc = (PIN->es && pj_param(start, "bgeoc").i);
+	/* over-ranging flag */
+	PIN->over = pj_param(start, "bover").i;
+	/* central meridian */
+	PIN->lam0=pj_param(start, "rlon_0").f;
+	/* central latitude */
+	PIN->phi0 = pj_param(start, "rlat_0").f;
+	/* false easting and northing */
+	PIN->x0 = pj_param(start, "dx_0").f;
+	PIN->y0 = pj_param(start, "dy_0").f;
+	/* general scaling factor */
+	if (pj_param(start, "tk_0").i)
+		PIN->k0 = pj_param(start, "dk_0").f;
+	else if (pj_param(start, "tk").i)
+		PIN->k0 = pj_param(start, "dk").f;
+	else
+		PIN->k0 = 1.;
+	if (PIN->k0 <= 0.) {
+		pj_errno = -31;
+		goto bum_call;
+	}
+	/* set units */
+	s = 0;
+	if (name = pj_param(start, "sunits").s) { 
+		for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i) ;
+		if (!s) { pj_errno = -7; goto bum_call; }
+		s = pj_units[i].to_meter;
+	}
+	if (s || (s = pj_param(start, "sto_meter").s)) {
+		PIN->to_meter = strtod(s, &s);
+		if (*s == '/') /* ratio number */
+			PIN->to_meter /= strtod(++s, 0);
+		PIN->fr_meter = 1. / PIN->to_meter;
+	} else
+		PIN->to_meter = PIN->fr_meter = 1.;
+	/* projection specific initialization */
+	if (!(PIN = (*proj)(PIN)) || errno || pj_errno) {
+bum_call: /* cleanup error return */
+		if (!pj_errno)
+			pj_errno = errno;
+		if (PIN)
+			pj_free(PIN);
+		else
+			for ( ; start; start = curr) {
+				curr = start->next;
+				pj_dalloc(start);
+			}
+		PIN = 0;
+	}
+	return PIN;
+}
+	void
+pj_free(PJ *P) {
+	if (P) {
+		paralist *t = P->params, *n;
+
+		/* free parameter list elements */
+		for (t = P->params; t; t = n) {
+			n = t->next;
+			pj_dalloc(t);
+		}
+		/* free projection parameters */
+		P->pfree(P);
+	}
+}
diff --git a/proj/pj_inv.c b/proj/pj_inv.c
new file mode 100644
index 0000000..16dd90d
--- /dev/null
+++ b/proj/pj_inv.c
@@ -0,0 +1,32 @@
+/* general inverse projection */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_inv.c	4.5	93/06/12	GIE	REL";
+#endif
+#define PJ_LIB__
+#include <projects.h>
+#include <errno.h>
+# define EPS 1.0e-12
+	LP /* inverse projection entry */
+pj_inv(XY xy, PJ *P) {
+	LP lp;
+
+	/* can't do as much preliminary checking as with forward */
+	if (xy.x == HUGE_VAL || xy.y == HUGE_VAL) {
+		lp.lam = lp.phi = HUGE_VAL;
+		pj_errno = -15;
+	}
+	errno = pj_errno = 0;
+	xy.x = (xy.x * P->to_meter - P->x0) * P->ra; /* descale and de-offset */
+	xy.y = (xy.y * P->to_meter - P->y0) * P->ra;
+	lp = (*P->inv)(xy, P); /* inverse project */
+	if (pj_errno || (pj_errno = errno))
+		lp.lam = lp.phi = HUGE_VAL;
+	else {
+		lp.lam += P->lam0; /* reduce from del lp.lam */
+		if (!P->over)
+			lp.lam = adjlon(lp.lam); /* adjust longitude to CM */
+		if (P->geoc && fabs(fabs(lp.phi)-HALFPI) > EPS)
+			lp.phi = atan(P->one_es * tan(lp.phi));
+	}
+	return lp;
+}
diff --git a/proj/pj_labrd.c b/proj/pj_labrd.c
new file mode 100644
index 0000000..ecd01b8
--- /dev/null
+++ b/proj/pj_labrd.c
@@ -0,0 +1,112 @@
+/* Laborde */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_labrd.c	4.5	93/06/17	GIE	BETA";
+#endif
+#define PROJ_PARMS__ \
+	double	Az, kRg, p0s, A, C, Ca, Cb, Cc, Cd; \
+	int		rot;
+#define PJ_LIB__
+#include	<projects.h>
+#define EPS	1.e-10
+FORWARD(e_forward);
+	double V1, V2, ps, sinps, cosps, sinps2, cosps2, I1, I2, I3, I4, I5, I6,
+		x2, y2, t;
+
+	V1 = P->A * log( tan(FORTPI + .5 * lp.phi) );
+	t = P->e * sin(lp.phi);
+	V2 = .5 * P->e * P->A * log ((1. + t)/(1. - t));
+	ps = 2. * (atan(exp(V1 - V2 + P->C)) - FORTPI);
+	I1 = ps - P->p0s;
+	cosps = cos(ps);	cosps2 = cosps * cosps;
+	sinps = sin(ps);	sinps2 = sinps * sinps;
+	I4 = P->A * cosps;
+	I2 = .5 * P->A * I4 * sinps;
+	I3 = I2 * P->A * P->A * (5. * cosps2 - sinps2) / 12.;
+	I6 = I4 * P->A * P->A;
+	I5 = I6 * (cosps2 - sinps2) / 6.;
+	I6 *= P->A * P->A *
+		(5. * cosps2 * cosps2 + sinps2 * (sinps2 - 18. * cosps2)) / 120.;
+	t = lp.lam * lp.lam;
+	xy.x = P->kRg * lp.lam * (I4 + t * (I5 + t * I6));
+	xy.y = P->kRg * (I1 + t * (I2 + t * I3));
+	x2 = xy.x * xy.x;
+	y2 = xy.y * xy.y;
+	V1 = 3. * xy.x * y2 - xy.x * x2;
+	V2 = xy.y * y2 - 3. * x2 * xy.y;
+	xy.x += P->Ca * V1 + P->Cb * V2;
+	xy.y += P->Ca * V2 - P->Cb * V1;
+	return (xy);
+}
+INVERSE(e_inverse); /* ellipsoid & spheroid */
+	double x2, y2, V1, V2, V3, V4, t, t2, ps, pe, tpe, s,
+		I7, I8, I9, I10, I11, d, Re;
+	int i;
+
+	x2 = xy.x * xy.x;
+	y2 = xy.y * xy.y;
+	V1 = 3. * xy.x * y2 - xy.x * x2;
+	V2 = xy.y * y2 - 3. * x2 * xy.y;
+	V3 = xy.x * (5. * y2 * y2 + x2 * (-10. * y2 + x2 ));
+	V4 = xy.y * (5. * x2 * x2 + y2 * (-10. * x2 + y2 ));
+	xy.x += - P->Ca * V1 - P->Cb * V2 + P->Cc * V3 + P->Cd * V4;
+	xy.y +=   P->Cb * V1 - P->Ca * V2 - P->Cd * V3 + P->Cc * V4;
+	ps = P->p0s + xy.y / P->kRg;
+	pe = ps + P->phi0 - P->p0s;
+	for ( i = 20; i; --i) {
+		V1 = P->A * log(tan(FORTPI + .5 * pe));
+		tpe = P->e * sin(pe);
+		V2 = .5 * P->e * P->A * log((1. + tpe)/(1. - tpe));
+		t = ps - 2. * (atan(exp(V1 - V2 + P->C)) - FORTPI);
+		pe += t;
+		if (fabs(t) < EPS)
+			break;
+	}
+/*
+	if (!i) {
+	} else {
+	}
+*/
+	t = P->e * sin(pe);
+	t = 1. - t * t;
+	Re = P->one_es / ( t * sqrt(t) );
+	t = tan(ps);
+	t2 = t * t;
+	s = P->kRg * P->kRg;
+	d = Re * P->k0 * P->kRg;
+	I7 = t / (2. * d);
+	I8 = t * (5. + 3. * t2) / (24. * d * s);
+	d = cos(ps) * P->kRg * P->A;
+	I9 = 1. / d;
+	d *= s;
+	I10 = (1. + 2. * t2) / (6. * d);
+	I11 = (5. + t2 * (28. + 24. * t2)) / (120. * d * s);
+	x2 = xy.x * xy.x;
+	lp.phi = pe + x2 * (-I7 + I8 * x2);
+	lp.lam = xy.x * (I9 + x2 * (-I10 + x2 * I11));
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_labrd)
+	double Az, sinp, R, N, t;
+
+	P->rot	= pj_param(P->params, "bno_rot").i == 0;
+	Az = pj_param(P->params, "razi").f;
+	sinp = sin(P->phi0);
+	t = 1. - P->es * sinp * sinp;
+	N = 1. / sqrt(t);
+	R = P->one_es * N / t;
+	P->kRg = P->k0 * sqrt( N * R );
+	P->p0s = atan( sqrt(R / N) * tan(P->phi0) );
+	P->A = sinp / sin(P->p0s);
+	t = P->e * sinp;
+	P->C = .5 * P->e * P->A * log((1. + t)/(1. - t)) +
+		- P->A * log( tan(FORTPI + .5 * P->phi0))
+		+ log( tan(FORTPI + .5 * P->p0s));
+	t = Az + Az;
+	P->Ca = (1. - cos(t)) * ( P->Cb = 1. / (12. * P->kRg * P->kRg) );
+	P->Cb *= sin(t);
+	P->Cc = 3. * (P->Ca * P->Ca - P->Cb * P->Cb);
+	P->Cd = 6. * P->Ca * P->Cb;
+	P->inv = e_inverse;
+	P->fwd = e_forward;
+ENDENTRY(P)
diff --git a/proj/pj_laea.c b/proj/pj_laea.c
new file mode 100644
index 0000000..2a1bad6
--- /dev/null
+++ b/proj/pj_laea.c
@@ -0,0 +1,234 @@
+/* Lambert Azimuthal Equal Area projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_laea.c	4.3	93/06/12	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	sinb1; \
+	double	cosb1; \
+	double	xmf; \
+	double	ymf; \
+	double	mmf; \
+	double	qp; \
+	double	dd; \
+	double	rq; \
+	double	*apa; \
+	int		mode;
+#define PJ_LIB__
+#include	<projects.h>
+#define sinph0	P->sinb1
+#define cosph0	P->cosb1
+#define EPS10	1.e-10
+#define NITER	20
+#define CONV	1.e-10
+#define N_POLE	0
+#define S_POLE	1
+#define EQUIT	2
+#define OBLIQ	3
+FORWARD(e_forward); /* ellipsoid */
+	double coslam, sinlam, sinphi, q, sinb, cosb, b;
+
+	coslam = cos(lp.lam);
+	sinlam = sin(lp.lam);
+	sinphi = sin(lp.phi);
+	q = pj_qsfn(sinphi, P->e, P->one_es);
+	if (P->mode == OBLIQ || P->mode == EQUIT) {
+		sinb = q / P->qp;
+		cosb = sqrt(1. - sinb * sinb);
+	}
+	switch (P->mode) {
+	case OBLIQ:
+		b = 1. + P->sinb1 * sinb + P->cosb1 * cosb * coslam;
+		break;
+	case EQUIT:
+		b = 1. + cosb * coslam;
+		break;
+	case N_POLE:
+		b = HALFPI + lp.phi;
+		q = P->qp - q;
+		break;
+	case S_POLE:
+		b = lp.phi - HALFPI;
+		q = P->qp + q;
+		break;
+	}
+	if (fabs(b) < EPS10) F_ERROR;
+	switch (P->mode) {
+	case OBLIQ:
+		xy.y = P->ymf * ( b = sqrt(2. / b) )
+		   * (P->cosb1 * sinb - P->sinb1 * cosb * coslam);
+		goto eqcon;
+		break;
+	case EQUIT:
+		xy.y = (b = sqrt(2. / (1. + cosb * coslam))) * sinb * P->ymf; 
+eqcon:
+		xy.x = P->xmf * b * cosb * sinlam;
+		break;
+	case N_POLE:
+	case S_POLE:
+		if (q >= 0.) {
+			xy.x = (b = sqrt(q)) * sinlam;
+			xy.y = coslam * (P->mode == S_POLE ? b : -b);
+		} else
+			xy.x = xy.y = 0.;
+		break;
+	}
+	return (xy);
+}
+FORWARD(s_forward); /* spheroid */
+	double  coslam, cosphi, sinphi;
+
+	sinphi = sin(lp.phi);
+	cosphi = cos(lp.phi);
+	coslam = cos(lp.lam);
+	switch (P->mode) {
+	case EQUIT:
+		xy.y = 1. + cosphi * coslam;
+		goto oblcon;
+	case OBLIQ:
+		xy.y = 1. + sinph0 * sinphi + cosph0 * cosphi * coslam;
+oblcon:
+		if (xy.y <= EPS10) F_ERROR;
+		xy.x = (xy.y = sqrt(2. / xy.y)) * cosphi * sin(lp.lam);
+		xy.y *= P->mode == EQUIT ? sinphi :
+		   cosph0 * sinphi - sinph0 * cosphi * coslam;
+		break;
+	case N_POLE:
+		coslam = -coslam;
+	case S_POLE:
+		if (fabs(lp.phi + P->phi0) < EPS10) F_ERROR;
+		xy.y = FORTPI - lp.phi * .5;
+		xy.y = 2. * (P->mode == S_POLE ? cos(xy.y) : sin(xy.y));
+		xy.x = xy.y * sin(lp.lam);
+		xy.y *= coslam;
+		break;
+	}
+	return (xy);
+}
+INVERSE(e_inverse); /* ellipsoid */
+	double cCe, sCe, q, rho, ab;
+	extern errno;
+
+	errno = 0;
+	switch (P->mode) {
+	case EQUIT:
+	case OBLIQ:
+		if ((rho = hypot(xy.x /= P->dd, xy.y *=  P->dd)) < EPS10) {
+			lp.lam = 0.;
+			lp.phi = P->phi0;
+			return (lp);
+		}
+		cCe = cos(sCe = 2. * asin(.5 * rho / P->rq));
+		xy.x *= (sCe = sin(sCe));
+		if (P->mode == OBLIQ) {
+			q = P->qp * (ab = cCe * P->sinb1 + xy.y * sCe * P->cosb1 / rho);
+			xy.y = rho * P->cosb1 * cCe - xy.y * P->sinb1 * sCe;
+		} else {
+			q = P->qp * (ab = xy.y * sCe / rho);
+			xy.y = rho * cCe;
+		}
+		break;
+	case N_POLE:
+		xy.y = -xy.y;
+	case S_POLE:
+		if (!(q = (xy.x * xy.x + xy.y * xy.y)) ) {
+			lp.lam = 0.;
+			lp.phi = P->phi0;
+			return (lp);
+		}
+		/*
+		q = P->qp - q;
+		*/
+		ab = 1. - q / P->qp;
+		if (P->mode == S_POLE)
+			ab = - ab;
+		break;
+	}
+	lp.lam = atan2(xy.x, xy.y);
+	lp.phi = pj_authlat(asin(ab), P->apa);
+	if (errno)
+		I_ERROR;
+	return (lp);
+}
+INVERSE(s_inverse); /* spheroid */
+	double  cosz, rh, sinz;
+
+	rh = hypot(xy.x, xy.y);
+	if ((lp.phi = rh * .5 ) > 1.) I_ERROR;
+	lp.phi = 2. * asin(lp.phi);
+	if (P->mode == OBLIQ || P->mode == EQUIT) {
+		sinz = sin(lp.phi);
+		cosz = cos(lp.phi);
+	}
+	switch (P->mode) {
+	case EQUIT:
+		lp.phi = fabs(rh) <= EPS10 ? 0. : asin(xy.y * sinz / rh);
+		xy.x *= sinz;
+		xy.y = cosz * rh;
+		break;
+	case OBLIQ:
+		lp.phi = fabs(rh) <= EPS10 ? P->phi0 :
+		   asin(cosz * sinph0 + xy.y * sinz * cosph0 / rh);
+		xy.x *= sinz * cosph0;
+		xy.y = (cosz - sin(lp.phi) * sinph0) * rh;
+		break;
+	case N_POLE:
+		xy.y = -xy.y;
+		lp.phi = HALFPI - lp.phi;
+		break;
+	case S_POLE:
+		lp.phi -= HALFPI;
+		break;
+	}
+	lp.lam = (xy.y == 0. && (P->mode == EQUIT || P->mode == OBLIQ)) ?
+		0. : atan2(xy.x, xy.y);
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_laea)
+	double t;
+
+	if (fabs((t = fabs(P->phi0)) - HALFPI) < EPS10)
+		P->mode = P->phi0 < 0. ? S_POLE : N_POLE;
+	else if (fabs(t) < EPS10)
+		P->mode = EQUIT;
+	else
+		P->mode = OBLIQ;
+	if (P->es) {
+		double sinphi;
+
+		P->e = sqrt(P->es);
+		P->qp = pj_qsfn(1., P->e, P->one_es);
+		P->mmf = .5 / (1. - P->es);
+		P->apa = pj_authset(P->es);
+		switch (P->mode) {
+		case N_POLE:
+		case S_POLE:
+			P->dd = 1.;
+			break;
+		case EQUIT:
+			P->dd = 1. / (P->rq = sqrt(.5 * P->qp));
+			P->xmf = 1.;
+			P->ymf = .5 * P->qp;
+			break;
+		case OBLIQ:
+			P->rq = sqrt(.5 * P->qp);
+			sinphi = sin(P->phi0);
+			P->sinb1 = pj_qsfn(sinphi, P->e, P->one_es) / P->qp;
+			P->cosb1 = sqrt(1. - P->sinb1 * P->sinb1);
+			P->dd = cos(P->phi0) / (sqrt(1. - P->es * sinphi * sinphi) *
+			   P->rq * P->cosb1);
+			P->ymf = (P->xmf = P->rq) / P->dd;
+			P->xmf *= P->dd;
+			break;
+		}
+		P->inv = e_inverse;
+		P->fwd = e_forward;
+	} else {
+		if (P->mode == OBLIQ) {
+			sinph0 = sin(P->phi0);
+			cosph0 = cos(P->phi0);
+		}
+		P->inv = s_inverse;
+		P->fwd = s_forward;
+	}
+ENDENTRY(P)
diff --git a/proj/pj_lagrng.c b/proj/pj_lagrng.c
new file mode 100644
index 0000000..49c90ae
--- /dev/null
+++ b/proj/pj_lagrng.c
@@ -0,0 +1,38 @@
+/*  Lagrange Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_lagrng.c	4.5	93/06/14	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	hrw; \
+	double	rw; \
+	double	a1;
+#define TOL	1e-10
+#define PJ_LIB__
+#include	<projects.h>
+FORWARD(s_forward); /* spheroid */
+	double v, c;
+
+	if (fabs(fabs(lp.phi) - HALFPI) < TOL) {
+		xy.x = 0;
+		xy.y = lp.phi < 0 ? -2. : 2.;
+	} else {
+		lp.phi = sin(lp.phi);
+		v = P->a1 * pow((1. + lp.phi)/(1. - lp.phi), P->hrw);
+		if ((c = 0.5 * (v + 1./v) + cos(lp.lam *= P->rw)) < TOL)
+			F_ERROR;
+		xy.x = 2. * sin(lp.lam) / c;
+		xy.y = (v - 1./v) / c;
+	}
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_lagrng)
+	double phi1;
+
+	if ((P->rw = pj_param(P->params, "dW").f) <= 0) E_ERROR(-27);
+	P->hrw = 0.5 * (P->rw = 1. / P->rw);
+	phi1 = pj_param(P->params, "rlat_1").f;
+	if (fabs(fabs(phi1 = sin(phi1)) - 1.) < TOL) E_ERROR(-22);
+	P->a1 = pow((1. - phi1)/(1. + phi1), P->hrw);
+	P->es = 0.; P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_lcc.c b/proj/pj_lcc.c
new file mode 100644
index 0000000..9c454d1
--- /dev/null
+++ b/proj/pj_lcc.c
@@ -0,0 +1,90 @@
+/* Lambert Conformal Conic */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_lcc.c	4.5	93/06/12	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	phi1; \
+	double	phi2; \
+	double	n; \
+	double	rho; \
+	double	rho0; \
+	double	c; \
+	int		ellips;
+#define PJ_LIB__
+#include	<projects.h>
+# define EPS10	1.e-10
+FORWARD(e_forward); /* ellipsoid & spheroid */
+	if (fabs(fabs(lp.phi) - HALFPI) < EPS10) {
+		if ((lp.phi * P->n) <= 0.) F_ERROR;
+		P->rho = 0.;
+		}
+	else
+		P->rho = P->c * (P->ellips ? pow(pj_tsfn(lp.phi, sin(lp.phi),
+			P->e), P->n) : pow(tan(FORTPI + .5 * lp.phi), -P->n));
+	xy.x = P->k0 * (P->rho * sin( lp.lam *= P->n ) );
+	xy.y = P->k0 * (P->rho0 - P->rho * cos(lp.lam) );
+	return (xy);
+}
+INVERSE(e_inverse); /* ellipsoid & spheroid */
+	xy.x /= P->k0;
+	xy.y /= P->k0;
+	if (P->rho = hypot(xy.x, xy.y = P->rho0 - xy.y)) {
+		if (P->n < 0.) {
+			P->rho = -P->rho;
+			xy.x = -xy.x;
+			xy.y = -xy.y;
+		}
+		if (P->ellips) {
+			if ((lp.phi = pj_phi2(pow(P->rho / P->c, 1./P->n), P->e))
+				== HUGE_VAL)
+				I_ERROR;
+		} else
+			lp.phi = 2. * atan(pow(P->c / P->rho, 1./P->n)) - HALFPI;
+		lp.lam = atan2(xy.x, xy.y) / P->n;
+	} else {
+		lp.lam = 0.;
+		lp.phi = P->n > 0. ? HALFPI : - HALFPI;
+	}
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_lcc)
+	double cosphi, sinphi;
+	int secant;
+
+	P->phi1 = pj_param(P->params, "rlat_1").f;
+	if (pj_param(P->params, "tlat_2").i)
+		P->phi2 = pj_param(P->params, "rlat_2").f;
+	else {
+		P->phi2 = P->phi1;
+		if (!pj_param(P->params, "tlat_0").i)
+			P->phi0 = P->phi1;
+	}
+	if (fabs(P->phi1 + P->phi2) < EPS10) E_ERROR(-21);
+	P->n = sinphi = sin(P->phi1);
+	cosphi = cos(P->phi1);
+	secant = fabs(P->phi1 - P->phi2) >= EPS10;
+	if (P->ellips = (P->es != 0.)) {
+		double ml1, m1;
+
+		P->e = sqrt(P->es);
+		m1 = pj_msfn(sinphi, cosphi, P->es);
+		ml1 = pj_tsfn(P->phi1, sinphi, P->e);
+		if (secant) { /* secant cone */
+			P->n = log(m1 /
+			   pj_msfn(sinphi = sin(P->phi2), cos(P->phi2), P->es));
+			P->n /= log(ml1 / pj_tsfn(P->phi2, sinphi, P->e));
+		}
+		P->c = (P->rho0 = m1 * pow(ml1, -P->n) / P->n);
+		P->rho0 *= pow(pj_tsfn(P->phi0, sin(P->phi0), P->e), P->n);
+	} else {
+		if (secant)
+			P->n = log(cosphi / cos(P->phi2)) /
+			   log(tan(FORTPI + .5 * P->phi2) /
+			   tan(FORTPI + .5 * P->phi1));
+		P->c = cosphi * pow(tan(FORTPI + .5 * P->phi1), P->n) / P->n;
+		P->rho0 = P->c * pow(tan(FORTPI + .5 * P->phi0), -P->n);
+	}
+	P->inv = e_inverse;
+	P->fwd = e_forward;
+ENDENTRY(P)
diff --git a/proj/pj_list.c b/proj/pj_list.c
new file mode 100644
index 0000000..d235abc
--- /dev/null
+++ b/proj/pj_list.c
@@ -0,0 +1,117 @@
+#ifndef lint
+static const char SCCSID[]="@(#)pj_list.c	4.5	93/06/12	GIE	REL";
+#endif
+/* Projection System: List of projections
+** When adding a projection both of the following statements
+** need to be updated.
+*/
+#include "projects.h"
+	/* Prototypes */
+extern void
+	*pj_aea(), *pj_aeqd(), *pj_bipc(), *pj_bonne(), *pj_ob_tran(),
+	*pj_cea(), *pj_eck4(), *pj_eck6(), *pj_eqc(),
+	*pj_eqdc(), *pj_gnom(), *pj_laea(), *pj_lcc(),
+	*pj_merc(), *pj_mill(), *pj_moll(), *pj_nsper(),
+	*pj_omerc(), *pj_ortho(), *pj_poly(), *pj_sinu(),
+	*pj_stere(), *pj_tmerc(), *pj_ups(), *pj_utm(), *pj_mtm(),
+	*pj_vandg(), *pj_cass(), *pj_tpers(), *pj_tcea(),
+	*pj_ocea(), *pj_parab(), *pj_gall(), *pj_eck5(),
+	*pj_wink1(), *pj_hammer(), *pj_august(), *pj_hataea(),
+	*pj_mbtfps(), *pj_mbtfpq(), *pj_putp2(), *pj_eck3(),
+	*pj_mbtfpp(), *pj_putp5(), *pj_quau(), *pj_dense(),
+	*pj_robin(), *pj_aitoff(), *pj_wintri(), *pj_eck1(),
+	*pj_eck2(), *pj_boggs(), *pj_pconic(), *pj_rpoly(),
+	*pj_airy(), *pj_bacon(), *pj_eisen(), *pj_fourn(),
+	*pj_lagrng(), *pj_nicol(), *pj_ortel(), *pj_vandg2(),
+	*pj_vandg3(), *pj_vandg4(), *pj_wag7(), *pj_leac(),
+	*pj_loxim(), *pj_apian(), *pj_cc(), *pj_tcc(),
+	*pj_collg(), *pj_goode(), *pj_chamb(), *pj_lsat(),
+	*pj_alsk(), *pj_gs50(), *pj_tpeqd(), *pj_mil_os(),
+	*pj_lee_os(), *pj_nzmg(), *pj_gs48(), *pj_labrd();
+
+	struct PJ_LIST
+pj_list[] = {
+	"aea",		pj_aea,		"Albers Egual Area - Inv",
+	"aeqd",		pj_aeqd,	"Azimuthal equidistant - Inv",
+	"airy",		pj_airy,	"Airy",
+	"aitoff",	pj_aitoff,	"Aitoff",
+	"alsk",		pj_alsk,	"Alaska Mod.-Stereographics - Inv",
+	"apian",	pj_apian,	"Apian Globular - Inv",
+	"august",	pj_august,	"August Epicycloidal",
+	"bacon",	pj_bacon,	"Bacon Globular",
+	"bipc",		pj_bipc,	"Bipolar Conic - Inv",
+	"boggs",	pj_boggs,	"Boggs Eumorphic",
+	"bonne",	pj_bonne,	"Bonne - Inv",
+	"cass",		pj_cass,	"Cassini - Inv",
+	"cc",		pj_cc,		"Central Cylindrical - Inv",
+	"cea",		pj_cea,		"Cylindrical Equal Area - Inv",
+	"chamb",	pj_chamb,	"Chamberlin Trimetric",
+	"collg",	pj_collg,	"Collignon - Inv",
+	"dense",	pj_dense,	"Denoyer Semi-Elliptical",
+	"eck1",		pj_eck1,	"Eckert I - Inv",
+	"eck2",		pj_eck2,	"Eckert II - Inv",
+	"eck3",		pj_eck3,	"Eckert III - Inv",
+	"eck4",		pj_eck4,	"Eckert IV - Inv",
+	"eck5",		pj_eck5,	"Eckert V - Inv",
+	"eck6",		pj_eck6,	"Eckert VI - Inv",
+	"eisen",	pj_eisen,	"Eisenlohr",
+	"eqc",		pj_eqc,		"Equidistant Cylindrical - Inv",
+	"eqdc",		pj_eqdc,	"Equidistant Conic - Inv",
+	"fourn",	pj_fourn,	"Fournier Globular",
+	"gall",		pj_gall,	"Gall (Stereographic) - Inv",
+	"goode",	pj_goode,	"Goode Homolosine",
+	"gnom",		pj_gnom,	"Gnomonic - Inv",
+	"gs50",		pj_gs50,	"50 State U.S. Mod.-Stereographic - Inv",
+	"gs48",		pj_gs48,	"48 State U.S. Mod.-Stereographic - Inv",
+	"hammer",	pj_hammer,	"Hammer (Elliptical)",
+	"hataea",	pj_hataea,	"Hatano Asymmetrical Equal Area - Inv",
+	"labrd",	pj_labrd,	"Laborde - Inv",
+	"lagrng",	pj_lagrng,	"Lagrange",
+	"laea",		pj_laea,	"Lambert Azimuthal Equal Area - Inv",
+	"leac",		pj_leac,	"Lambert Equal Area Conic - Inv",
+	"lee_os",	pj_lee_os,	"Lee Oblate Stereographics Pacific - Inv",
+	"lcc",		pj_lcc,		"Lambert Conformal Conic - Inv",
+	"loxim",	pj_loxim,	"Loximuthal - Inv",
+	"lsat",		pj_lsat,	"LANDSAT Space Oblique Mercator - Inv",
+	"mbtfpp",	pj_mbtfpp,	"McBryde-Thomas Flat-Polar Parabolic - Inv",
+	"mbtfps",	pj_mbtfps,	"McBryde-Thomas Flat-Polar Sinusoidal - Inv",
+	"mbtfpq",	pj_mbtfpq,	"McBryde-Thomas Flat-Polar Quartic - Inv",
+	"merc",		pj_merc,	"Mercator - Inv",
+	"mill",		pj_mill,	"Miller - Inv",
+	"mill_os",	pj_mil_os,	"Miller Oblate Stereographics Eur-Africa - Inv",
+	"moll",		pj_moll,	"Mollweides - Inv",
+	"mtm",		pj_mtm,		"Mercator Transverse Modifiee (Quebec) - Inv",
+	"nicol",	pj_nicol,	"Nicolosi Globular",
+	"nsper",	pj_nsper,	"General Vertical Persepective - Inv",
+	"nzmg",		pj_nzmg,	"New Zealand Map Grid - Inv",
+	"ob_tran",	pj_ob_tran,	"General Oblique/Transverse translator",
+	"ocea",		pj_ocea,	"Oblique Cylindrical Equal Area - Inv",
+	"omerc",	pj_omerc,	"Oblique Mercator - Inv",
+	"ortel",	pj_ortel,	"Ortelius",
+	"ortho",	pj_ortho,	"Orthographic - Inv",
+	"parab",	pj_parab,	"Caster Parabolic - Inv",
+	"pconic",	pj_pconic,	"Perspective Conic",
+	"poly",		pj_poly,	"Polyconic (American) - Inv",
+	"putp2",	pj_putp2,	"Putnins P2' - Inv",
+	"putp5",	pj_putp5,	"Putnins P5 - Inv",
+	"rpoly",	pj_rpoly,	"Rectangular Polyconic",
+	"quau",		pj_quau,	"Quartic Authalic - Inv",
+	"robin",	pj_robin,	"Robinson - Inv",
+	"sinu",		pj_sinu,	"Sinusoidal - Inv",
+	"stere",	pj_stere,	"Stereographic - Inv",
+	"tcc",		pj_tcc,		"Transverse Central Cylindrical - Inv",
+	"tcea",		pj_tcea,	"Transverse Cylindrical Equal Area - Inv",
+	"tmerc",	pj_tmerc,	"Transverse Mercator - Inv",
+	"tpeqd",	pj_tpeqd,	"Two Point Equidistant",
+	"tpers",	pj_tpers,	"Tilted perspective - Inv",
+	"ups",		pj_ups,		"Universal Polar Stereographic - Inv",
+	"utm",		pj_utm,		"Universal Transverse Mercator - Inv",
+	"vandg",	pj_vandg,	"Van der Grinten - Inv",
+	"vandg2",	pj_vandg2,	"Van der Grinten II",
+	"vandg3",	pj_vandg3,	"Van der Grinten III",
+	"vandg4",	pj_vandg4,	"Van der Grinten IV",
+	"wag7",		pj_wag7,	"Wagner VII",
+	"wink1",	pj_wink1,	"Winkel I - Inv",
+	"wintri",	pj_wintri,	"Winkel Tripel",
+	0,		0,	"list terminator"
+};
diff --git a/proj/pj_loxim.c b/proj/pj_loxim.c
new file mode 100644
index 0000000..a8afe3b
--- /dev/null
+++ b/proj/pj_loxim.c
@@ -0,0 +1,44 @@
+/*  Loximuthal Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_loxim.c	4.5	93/06/14	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double phi1; \
+	double cosphi1; \
+	double tanphi1;
+#define PJ_LIB__
+#include	<projects.h>
+#define EPS	1e-8
+FORWARD(s_forward); /* spheroid */
+	xy.y = lp.phi - P->phi1;
+	if (fabs(xy.y) < EPS)
+		xy.x = lp.lam * P->cosphi1;
+	else {
+		xy.x = FORTPI + 0.5 * lp.phi;
+		if (fabs(xy.x) < EPS || fabs(fabs(xy.x) - HALFPI) < EPS)
+			xy.x = 0.;
+		else
+			xy.x = lp.lam * xy.y / log( tan(xy.x) / P->tanphi1 );
+	}
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = xy.y + P->phi1;
+	if (fabs(xy.y) < EPS)
+		lp.lam = xy.x / P->cosphi1;
+	else
+		if (fabs( lp.lam = FORTPI + 0.5 * lp.phi ) < EPS ||
+			fabs(fabs(lp.lam) - HALFPI) < EPS)
+			lp.lam = 0.;
+		else
+			lp.lam = xy.x * log( tan(lp.lam) / P->tanphi1 ) / xy.y ;
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_loxim)
+	P->phi1 = pj_param(P->params, "rlat_1").f;
+	if ((P->cosphi1 = cos(P->phi1)) < EPS) E_ERROR(-22);
+	P->tanphi1 = tan(FORTPI + 0.5 * P->phi1);
+	P->inv = s_inverse; P->fwd = s_forward;
+	P->es = 0.;
+ENDENTRY(P)
diff --git a/proj/pj_lsat.c b/proj/pj_lsat.c
new file mode 100644
index 0000000..35377dc
--- /dev/null
+++ b/proj/pj_lsat.c
@@ -0,0 +1,173 @@
+/*  Space oblique for LANDSAT */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_lsat.c	4.4	93/06/12	GIE	REL";
+#endif
+/* based upon Snyder and Linck, USGS-NMD */
+#define PROJ_PARMS__ \
+    double a2, a4, b, c1, c3; \
+    double q, t, u, w, p22, sa, ca, xj, rlm, rlm2;
+#define PJ_LIB__
+#include	<projects.h>
+#define TOL 1e-7
+#define PI_HALFPI 4.71238898038468985766
+#define TWOPI_HALFPI 7.85398163397448309610
+	static void
+seraz0(double lam, double mult, PJ *P) {
+    double sdsq, h, s, fc, sd, sq, d__1;
+
+    lam *= DEG_TO_RAD;
+    sd = sin(lam);
+    sdsq = sd * sd;
+    s = P->p22 * P->sa * cos(lam) * sqrt((1. + P->t * sdsq) / ((
+	    1. + P->w * sdsq) * (1. + P->q * sdsq)));
+    d__1 = 1. + P->q * sdsq;
+    h = sqrt((1. + P->q * sdsq) / (1. + P->w * sdsq)) * ((1. + 
+	    P->w * sdsq) / (d__1 * d__1) - P->p22 * P->ca);
+    sq = sqrt(P->xj * P->xj + s * s);
+    P->b += fc = mult * (h * P->xj - s * s) / sq;
+    P->a2 += fc * cos(lam + lam);
+    P->a4 += fc * cos(lam * 4.);
+    fc = mult * s * (h + P->xj) / sq;
+    P->c1 += fc * cos(lam);
+    P->c3 += fc * cos(lam * 3.);
+}
+FORWARD(e_forward); /* ellipsoid */
+    int l, nn;
+    double lamt, xlam, sdsq, c, d, s, lamdp, phidp, lampp, tanph,
+		lamtp, cl, sd, sp, fac, sav, tanphi;
+
+	if (lp.phi > HALFPI)
+	    lp.phi = HALFPI;
+	else if (lp.phi < -HALFPI)
+	    lp.phi = -HALFPI;
+	lampp = lp.phi >= 0. ? HALFPI : PI_HALFPI;
+	tanphi = tan(lp.phi);
+	for (nn = 0;;) {
+		sav = lampp;
+		lamtp = lp.lam + P->p22 * lampp;
+		cl = cos(lamtp);
+		if (fabs(cl) < TOL)
+		    lamtp -= TOL;
+		fac = lampp - sin(lampp) * (cl < 0. ? -HALFPI : HALFPI);
+		for (l = 50; l; --l) {
+			lamt = lp.lam + P->p22 * sav;
+			if (fabs(c = cos(lamt)) < TOL)
+			    lamt -= TOL;
+			xlam = (P->one_es * tanphi * P->sa + sin(lamt) * P->ca) / c;
+			lamdp = atan(xlam) + fac;
+			if (fabs(fabs(sav) - fabs(lamdp)) < TOL)
+			    break;
+			sav = lamdp;
+		}
+		if (!l || ++nn >= 3 || (lamdp > P->rlm && lamdp < P->rlm2))
+			break;
+		if (lamdp <= P->rlm)
+		    lampp = TWOPI_HALFPI;
+		else if (lamdp >= P->rlm2)
+		    lampp = HALFPI;
+	}
+	if (l) {
+		sp = sin(lp.phi);
+		phidp = aasin((P->one_es * P->ca * sp - P->sa * cos(lp.phi) * 
+			sin(lamt)) / sqrt(1. - P->es * sp * sp));
+		tanph = log(tan(FORTPI + .5 * phidp));
+		sd = sin(lamdp);
+		sdsq = sd * sd;
+		s = P->p22 * P->sa * cos(lamdp) * sqrt((1. + P->t * sdsq)
+			 / ((1. + P->w * sdsq) * (1. + P->q * sdsq)));
+		d = sqrt(P->xj * P->xj + s * s);
+		xy.x = P->b * lamdp + P->a2 * sin(2. * lamdp) + P->a4 *
+			sin(lamdp * 4.) - tanph * s / d;
+		xy.y = P->c1 * sd + P->c3 * sin(lamdp * 3.) + tanph * P->xj / d;
+	} else
+		xy.x = xy.y = HUGE_VAL;
+	return xy;
+}
+INVERSE(e_inverse); /* ellipsoid */
+    int nn;
+    double lamt, sdsq, s, lamdp, phidp, sppsq, dd, sd, sl, fac, scl, sav, spp;
+
+	lamdp = xy.x / P->b;
+	nn = 50;
+	do {
+		sav = lamdp;
+		sd = sin(lamdp);
+		sdsq = sd * sd;
+		s = P->p22 * P->sa * cos(lamdp) * sqrt((1. + P->t * sdsq)
+			 / ((1. + P->w * sdsq) * (1. + P->q * sdsq)));
+		lamdp = xy.x + xy.y * s / P->xj - P->a2 * sin(
+			2. * lamdp) - P->a4 * sin(lamdp * 4.) - s / P->xj * (
+			P->c1 * sin(lamdp) + P->c3 * sin(lamdp * 3.));
+		lamdp /= P->b;
+	} while (fabs(lamdp - sav) >= TOL && --nn);
+	sl = sin(lamdp);
+	fac = exp(sqrt(1. + s * s / P->xj / P->xj) * (xy.y - 
+		P->c1 * sl - P->c3 * sin(lamdp * 3.)));
+	phidp = 2. * (atan(fac) - FORTPI);
+	dd = sl * sl;
+	if (fabs(cos(lamdp)) < TOL)
+	    lamdp -= TOL;
+	spp = sin(phidp);
+	sppsq = spp * spp;
+	lamt = atan(((1. - sppsq * P->rone_es) * tan(lamdp) * 
+		P->ca - spp * P->sa * sqrt((1. + P->q * dd) * (
+		1. - sppsq) - sppsq * P->u) / cos(lamdp)) / (1. - sppsq 
+		* (1. + P->u)));
+	sl = lamt >= 0. ? 1. : -1.;
+	scl = cos(lamdp) >= 0. ? 1. : -1;
+	lamt -= HALFPI * (1. - scl) * sl;
+	lp.lam = lamt - P->p22 * lamdp;
+	if (fabs(P->sa) < TOL)
+	    lp.phi = aasin(spp / sqrt(P->one_es * P->one_es + P->es * sppsq));
+	else
+		lp.phi = atan((tan(lamdp) * cos(lamt) - P->ca * sin(lamt)) /
+			(P->one_es * P->sa));
+	return lp;
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_lsat)
+    int land, path;
+    double lam, alf, esc, ess;
+
+	land = pj_param(P->params, "ilsat").i;
+	if (land <= 0 || land > 5) E_ERROR(-28);
+	path = pj_param(P->params, "ipath").i;
+	if (path <= 0 || path > (land <= 3 ? 251 : 233)) E_ERROR(-29);
+	if (land <= 3) {
+		P->lam0 = DEG_TO_RAD * 128.87 - TWOPI / 251. * path;
+	    P->p22 = 103.2669323;
+	    alf = DEG_TO_RAD * 99.092;
+	} else {
+		P->lam0 = DEG_TO_RAD * 129.3 - TWOPI / 233. * path;
+	    P->p22 = 98.8841202;
+	    alf = DEG_TO_RAD * 98.2;
+	}
+	P->p22 /= 1440.;
+	P->sa = sin(alf);
+	P->ca = cos(alf);
+	if (fabs(P->ca) < 1e-9)
+	    P->ca = 1e-9;
+	esc = P->es * P->ca * P->ca;
+	ess = P->es * P->sa * P->sa;
+	P->w = (1. - esc) * P->rone_es;
+	P->w = P->w * P->w - 1.;
+	P->q = ess * P->rone_es;
+	P->t = ess * (2. - P->es) * P->rone_es * P->rone_es;
+	P->u = esc * P->rone_es;
+	P->xj = P->one_es * P->one_es * P->one_es;
+	P->rlm = PI * (1. / 248. + .5161290322580645);
+	P->rlm2 = P->rlm + TWOPI;
+    P->a2 = P->a4 = P->b = P->c1 = P->c3 = 0.;
+	seraz0(0., 1., P);
+	for (lam = 9.; lam <= 81.0001; lam += 18.)
+	    seraz0(lam, 4., P);
+	for (lam = 18; lam <= 72.0001; lam += 18.)
+	    seraz0(lam, 2., P);
+	seraz0(90., 1., P);
+	P->a2 /= 30.;
+	P->a4 /= 60.;
+	P->b /= 30.;
+	P->c1 /= 15.;
+	P->c3 /= 45.;
+	P->inv = e_inverse; P->fwd = e_forward;
+ENDENTRY(P)
diff --git a/proj/pj_malloc.c b/proj/pj_malloc.c
new file mode 100644
index 0000000..6beb502
--- /dev/null
+++ b/proj/pj_malloc.c
@@ -0,0 +1,16 @@
+/* allocate and deallocate memory */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_malloc.c	4.3   93/06/12 GIE REL";
+#endif
+/* These routines are used so that applications can readily replace
+** projection system memory allocation/deallocation call with custom
+** application procedures.  */
+#include <projects.h>
+	void *
+pj_malloc(size_t size) {
+	return(malloc(size));
+}
+	void
+pj_dalloc(void *ptr) {
+	free(ptr);
+}
diff --git a/proj/pj_mbtfpp.c b/proj/pj_mbtfpp.c
new file mode 100644
index 0000000..123e7b6
--- /dev/null
+++ b/proj/pj_mbtfpp.c
@@ -0,0 +1,36 @@
+/*  McBride-Thomas Flat-Polar Parabolic */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_mbtfpp.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define CS	.95257934441568037152
+#define FXC	.92582009977255146156
+#define FYC	3.40168025708304504493
+#define C23	.66666666666666666666
+#define C13	.33333333333333333333
+#define ONEEPS	1.0000001
+FORWARD(s_forward); /* spheroid */
+	lp.phi = asin(CS * sin(lp.phi));
+	xy.x = FXC * lp.lam * (2. * cos(C23 * lp.phi) - 1.);
+	xy.y = FYC * sin(C13 * lp.phi);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = xy.y / FYC;
+	if (fabs(lp.phi) >= 1.) {
+		if (fabs(lp.phi) > ONEEPS)	I_ERROR
+		else	lp.phi = (lp.phi < 0.) ? -HALFPI : HALFPI;
+	} else
+		lp.phi = asin(lp.phi);
+	lp.lam = xy.x / ( FXC * (2. * cos(C23 * (lp.phi *= 3.)) - 1.) );
+	if (fabs(lp.phi = sin(lp.phi) / CS) >= 1.) {
+		if (fabs(lp.phi) > ONEEPS)	I_ERROR
+		else	lp.phi = (lp.phi < 0.) ? -HALFPI : HALFPI;
+	} else
+		lp.phi = asin(lp.phi);
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_mbtfpp) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_mbtfpq.c b/proj/pj_mbtfpq.c
new file mode 100644
index 0000000..f35f230
--- /dev/null
+++ b/proj/pj_mbtfpq.c
@@ -0,0 +1,51 @@
+/*  McBryde-Thomas Flat-Polar Quartic */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_mbtfpq.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define NITER	20
+#define EPS	1e-7
+#define ONETOL 1.000001
+#define C	1.70710678118654752440
+#define RC	0.58578643762690495119
+#define FYC	1.87475828462269495505
+#define RYC	0.53340209679417701685
+#define FXC	0.31245971410378249250
+#define RXC	3.20041258076506210122
+FORWARD(s_forward); /* spheroid */
+	double th1, c;
+	int i;
+
+	c = C * sin(lp.phi);
+	for (i = NITER; i; --i) {
+		lp.phi -= th1 = (sin(.5*lp.phi) + sin(lp.phi) - c) /
+			(.5*cos(.5*lp.phi)  + cos(lp.phi));
+		if (fabs(th1) < EPS) break;
+	}
+	xy.x = FXC * lp.lam * (1.0 + 2. * cos(lp.phi)/cos(0.5 * lp.phi));
+	xy.y = FYC * sin(0.5 * lp.phi);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double t;
+
+	lp.phi = RYC * xy.y;
+	if (fabs(lp.phi) > 1.) {
+		if (fabs(lp.phi) > ONETOL)	I_ERROR
+		else if (lp.phi < 0.) { t = -1.; lp.phi = -PI; }
+		else { t = 1.; lp.phi = PI; }
+	} else
+		lp.phi = 2. * asin(t = lp.phi);
+	lp.lam = RXC * xy.x / (1. + 2. * cos(lp.phi)/cos(0.5 * lp.phi));
+	lp.phi = RC * (t + sin(lp.phi));
+	if (fabs(lp.phi) > 1.)
+		if (fabs(lp.phi) > ONETOL)	I_ERROR
+		else			lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
+	else
+		lp.phi = asin(lp.phi);
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_mbtfpq) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_mbtfps.c b/proj/pj_mbtfps.c
new file mode 100644
index 0000000..3fbf1e8
--- /dev/null
+++ b/proj/pj_mbtfps.c
@@ -0,0 +1,42 @@
+/*  McBryde-Thomas Flat-Polar Sinusoidal */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_mbtfps.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define NITER	20
+#define EPS	1e-7
+#define ONETOL 1.000001
+#define C	1.78539816339744830961
+#define RC	0.56009915351155737591
+#define FYC	0.91659627441275150748
+#define RYC	1.09099286994231339007
+#define FXC	0.61106418294183433832
+#define RXC	1.63648930491347008510
+FORWARD(s_forward); /* spheroid */
+	double th1, c;
+	int i;
+
+	c = C * sin(lp.phi);
+	for (i = NITER; i; --i) {
+		lp.phi -= th1 = (0.5 * lp.phi + sin(lp.phi) - c )/(0.5 + cos(lp.phi));
+		if (fabs(th1) < EPS) break;
+	}
+	xy.x = FXC * lp.lam * (0.5 + cos(lp.phi));
+	xy.y = FYC * lp.phi;
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = RYC * xy.y;
+	lp.lam = RXC * xy.x / (0.5 + cos(lp.phi));
+	lp.phi = RC * (0.5 * lp.phi + sin(lp.phi));
+	if (fabs(lp.phi) > 1.)
+		if (fabs(lp.phi) > ONETOL)	I_ERROR
+		else			lp.phi = lp.phi > 0. ? HALFPI : - HALFPI;
+	else
+		lp.phi = asin(lp.phi);
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_mbtfps) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_merc.c b/proj/pj_merc.c
new file mode 100644
index 0000000..0d91896
--- /dev/null
+++ b/proj/pj_merc.c
@@ -0,0 +1,50 @@
+/* Mercator projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_merc.c	4.4	93/06/12	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define EPS10 1.e-10
+FORWARD(e_forward); /* ellipsoid */
+	if (fabs(fabs(lp.phi) - HALFPI) <= EPS10) F_ERROR;
+	xy.x = P->k0 * lp.lam;
+	xy.y = - P->k0 * log(pj_tsfn(lp.phi, sin(lp.phi), P->e));
+	return (xy);
+}
+FORWARD(s_forward); /* spheroid */
+	if (fabs(fabs(lp.phi) - HALFPI) <= EPS10) F_ERROR;
+	xy.x = P->k0 * lp.lam;
+	xy.y = P->k0 * log(tan(FORTPI + .5 * lp.phi));
+	return (xy);
+}
+INVERSE(e_inverse); /* ellipsoid */
+	if ((lp.phi = pj_phi2(exp(- xy.y / P->k0), P->e)) == HUGE_VAL) I_ERROR;
+	lp.lam = xy.x / P->k0;
+	return (lp);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = HALFPI - 2. * atan(exp(-xy.y / P->k0));
+	lp.lam = xy.x / P->k0;
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_merc)
+	double phits;
+	int is_phits;
+
+	if (is_phits = pj_param(P->params, "tlat_ts").i) {
+		phits = fabs(pj_param(P->params, "rlat_ts").f);
+		if (phits >= HALFPI) E_ERROR(-24);
+	}
+	if (P->es) { /* ellipsoid */
+		if (is_phits)
+			P->k0 = pj_msfn(sin(phits), cos(phits), P->es);
+		P->inv = e_inverse;
+		P->fwd = e_forward;
+	} else { /* sphere */
+		if (is_phits)
+			P->k0 = cos(phits);
+		P->inv = s_inverse;
+		P->fwd = s_forward;
+	}
+ENDENTRY(P)
diff --git a/proj/pj_mill.c b/proj/pj_mill.c
new file mode 100644
index 0000000..1324998
--- /dev/null
+++ b/proj/pj_mill.c
@@ -0,0 +1,18 @@
+/* Miller Cylindrical projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_mill.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+# include	<projects.h>
+FORWARD(s_forward); /* spheroid */
+	xy.x = lp.lam;
+	xy.y = log(tan(FORTPI + lp.phi * .4)) * 1.25;
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.lam = xy.x;
+	lp.phi = 2.5 * (atan(exp(.8 * xy.y)) - FORTPI);
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_mill) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_mlfn.c b/proj/pj_mlfn.c
new file mode 100644
index 0000000..e1c7803
--- /dev/null
+++ b/proj/pj_mlfn.c
@@ -0,0 +1,62 @@
+#ifndef lint
+static const char SCCSID[]="@(#)pj_mlfn.c	4.3	93/06/12	GIE	REL";
+#endif
+#include <projects.h>
+/* meridinal distance for ellipsoid and inverse
+**	8th degree - accurate to < 1e-5 meters when used in conjuction
+**		with typical major axis values.
+**	Inverse determines phi to EPS (1e-11) radians, about 1e-6 seconds.
+*/
+#define C00 1.
+#define C02 .25
+#define C04 .046875
+#define C06 .01953125
+#define C08 .01068115234375
+#define C22 .75
+#define C44 .46875
+#define C46 .01302083333333333333
+#define C48 .00712076822916666666
+#define C66 .36458333333333333333
+#define C68 .00569661458333333333
+#define C88 .3076171875
+#define EPS 1e-11
+#define MAX_ITER 10
+#define EN_SIZE 5
+	double *
+pj_enfn(double es) {
+	double t, *en;
+
+	if (en = (double *)pj_malloc(EN_SIZE * sizeof(double))) {
+		en[0] = C00 - es * (C02 + es * (C04 + es * (C06 + es * C08)));
+		en[1] = es * (C22 - es * (C04 + es * (C06 + es * C08)));
+		en[2] = (t = es * es) * (C44 - es * (C46 + es * C48));
+		en[3] = (t *= es) * (C66 - es * C68);
+		en[4] = t * es * C88;
+	} /* else return NULL if unable to allocate memory */
+	return en;
+}
+	double
+pj_mlfn(double phi, double sphi, double cphi, double *en) {
+	cphi *= sphi;
+	sphi *= sphi;
+	return(en[0] * phi - cphi * (en[1] + sphi*(en[2]
+		+ sphi*(en[3] + sphi*en[4]))));
+}
+	double
+pj_inv_mlfn(double arg, double es, double *en) {
+	double s, t, phi, k = 1.-es;
+	int i;
+
+	phi = arg;
+	for (i = MAX_ITER; i ; --i) { /* rarely goes over 5 iterations */
+		s = sin(phi);
+		t = 1. - es * s * s;
+		t = (pj_mlfn(phi, s, cos(phi), en) - arg) / ( k * t * sqrt(t));
+		phi -= t;
+		if (fabs(t) < EPS)
+			break;
+	}
+	if (i <= 0)
+		pj_errno = -17;
+	return phi;
+}
diff --git a/proj/pj_mod_ster.c b/proj/pj_mod_ster.c
new file mode 100644
index 0000000..3c25660
--- /dev/null
+++ b/proj/pj_mod_ster.c
@@ -0,0 +1,210 @@
+/*  Modified Stereographic projections */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_mod_ster.c	4.4	93/06/17	GIE	REL";
+#endif
+/* based upon Snyder and Linck, USGS-NMD */
+#define PROJ_PARMS__ \
+    COMPLEX	*zcoeff; \
+	double	cchio, schio; \
+	int		n;
+#define PJ_LIB__
+#include	<projects.h>
+#define EPSLN 1e-10
+
+FORWARD(e_forward); /* ellipsoid */
+	double sinlon, coslon, esphi, chi, schi, cchi, s;
+	COMPLEX p;
+
+	sinlon = sin(lp.lam);
+	coslon = cos(lp.lam);
+	esphi = P->e * sin(lp.phi);
+	chi = 2. * atan(tan((HALFPI + lp.phi) * .5) *
+		pow((1. - esphi) / (1. + esphi), P->e * .5)) - HALFPI;
+	schi = sin(chi);
+	cchi = cos(chi);
+	s = 2. / (1. + P->schio * schi + P->cchio * cchi * coslon);
+	p.r = s * cchi * sinlon;
+	p.i = s * (P->cchio * schi - P->schio * cchi * coslon);
+	p = pj_zpoly1(p, P->zcoeff, P->n);
+	xy.x = p.r;
+	xy.y = p.i;
+	return xy;
+}
+INVERSE(e_inverse); /* ellipsoid */
+	int nn;
+	COMPLEX p, fxy, fpxy, dp;
+	double den, rh, z, sinz, cosz, chi, phi, dphi, esphi;
+
+	p.r = xy.x;
+	p.i = xy.y;
+	for (nn = 20; nn ;--nn) {
+		fxy = pj_zpolyd1(p, P->zcoeff, P->n, &fpxy);
+		fxy.r -= xy.x;
+		fxy.i -= xy.y;
+		den = fpxy.r * fpxy.r + fpxy.i * fpxy.i;
+		dp.r = -(fxy.r * fpxy.r + fxy.i * fpxy.i) / den;
+		dp.i = -(fxy.i * fpxy.r - fxy.r * fpxy.i) / den;
+		p.r += dp.r;
+		p.i += dp.i;
+		if ((fabs(dp.r) + fabs(dp.i)) <= EPSLN)
+			break;
+	}
+	if (nn) {
+		rh = hypot(p.r, p.i);
+		z = 2. * atan(.5 * rh);
+		sinz = sin(z);
+		cosz = cos(z);
+		lp.lam = P->lam0;
+		if (fabs(rh) <= EPSLN) {
+			lp.phi = P->phi0;
+			return lp;
+		}
+		chi = aasin(cosz * P->schio + p.i * sinz * P->cchio / rh);
+		phi = chi;
+		for (nn = 20; nn ;--nn) {
+			esphi = P->e * sin(phi);
+			dphi = 2. * atan(tan((HALFPI + chi) * .5) *
+				pow((1. + esphi) / (1. - esphi), P->e * .5)) - HALFPI - phi;
+			phi += dphi;
+			if (fabs(dphi) <= EPSLN)
+				break;
+		}
+	}
+	if (nn) {
+		lp.phi = phi;
+		lp.lam = atan2(p.r * sinz, rh * P->cchio * cosz - p.i * 
+			P->schio * sinz);
+    } else
+		lp.lam = lp.phi = HUGE_VAL;
+	return lp;
+}
+FREEUP; if (P) pj_dalloc(P); }
+	static PJ *
+setup(PJ *P) { /* general initialization */
+	double esphi, chio;
+
+	if (P->es) {
+		esphi = P->e * sin(P->phi0);
+		chio = 2. * atan(tan((HALFPI + P->phi0) * .5) *
+			pow((1. - esphi) / (1. + esphi), P->e * .5)) - HALFPI;
+	} else
+		chio = P->phi0;
+	P->schio = sin(chio);
+	P->cchio = cos(chio);
+	P->inv = e_inverse; P->fwd = e_forward;
+	return P;
+}
+ENTRY0(pj_mil_os)
+	static COMPLEX /* Miller Oblated Stereographic */
+AB[] = {
+	0.924500,	0.,
+	0.,			0.,
+	0.019430,	0.
+};
+
+	P->n = 2;
+	P->lam0 = DEG_TO_RAD * 20.;
+	P->phi0 = DEG_TO_RAD * 18.;
+	P->zcoeff = AB;
+	P->es = 0.;
+ENDENTRY(setup(P))
+ENTRY0(pj_lee_os)
+	static COMPLEX /* Lee Oblated Stereographic */
+AB[] = {
+	0.721316,	0.,
+	0.,			0.,
+	-0.0088162,	 -0.00617325
+};
+
+	P->n = 2;
+	P->lam0 = DEG_TO_RAD * -165.;
+	P->phi0 = DEG_TO_RAD * -10.;
+	P->zcoeff = AB;
+	P->es = 0.;
+ENDENTRY(setup(P))
+ENTRY0(pj_gs48)
+	static COMPLEX /* 48 United States */
+AB[] = {
+	0.98879,	0.,
+	0.,			0.,
+	-0.050909,	0.,
+	0.,			0.,
+	0.075528,	0.
+};
+
+	P->n = 4;
+	P->lam0 = DEG_TO_RAD * -96.;
+	P->phi0 = DEG_TO_RAD * -39.;
+	P->zcoeff = AB;
+	P->es = 0.;
+	P->a = 6370997.;
+ENDENTRY(setup(P))
+ENTRY0(pj_alsk)
+	static COMPLEX
+ABe[] = { /* Alaska ellipsoid */
+	.9945303,	0.,
+	.0052083,	-.0027404,
+	.0072721,	.0048181,
+	-.0151089,	-.1932526,
+	.0642675,	-.1381226,
+	.3582802,	-.2884586},
+ABs[] = { /* Alaska sphere */
+	.9972523,	0.,
+	.0052513,	-.0041175,
+	.0074606,	.0048125,
+	-.0153783,	-.1968253,
+	.0636871,	-.1408027,
+	.3660976,	-.2937382
+};
+
+	P->n = 5;
+	P->lam0 = DEG_TO_RAD * -152.;
+	P->phi0 = DEG_TO_RAD * 64.;
+	if (P->es) { /* fixed ellipsoid/sphere */
+		P->zcoeff = ABe;
+		P->a = 6378206.4;
+		P->e = sqrt(P->es = 0.00676866);
+	} else {
+		P->zcoeff = ABs;
+		P->a = 6370997.;
+	}
+ENDENTRY(setup(P))
+ENTRY0(pj_gs50)
+	static COMPLEX
+ABe[] = { /* GS50 ellipsoid */
+	.9827497,	0.,
+	.0210669,	.0053804,
+	-.1031415,	-.0571664,
+	-.0323337,	-.0322847,
+	.0502303,	.1211983,
+	.0251805,	.0895678,
+	-.0012315,	-.1416121,
+	.0072202,	-.1317091,
+	-.0194029,	.0759677,
+	-.0210072,	.0834037
+},
+ABs[] = { /* GS50 sphere */
+	.9842990,	0.,
+	.0211642,	.0037608,
+	-.1036018,	-.0575102,
+	-.0329095,	-.0320119,
+	.0499471,	.1223335,
+	.0260460,	.0899805,
+	.0007388,	-.1435792,
+	.0075848,	-.1334108,
+	-.0216473,	.0776645,
+	-.0225161,	.0853673
+};
+
+	P->n = 9;
+	P->lam0 = DEG_TO_RAD * -120.;
+	P->phi0 = DEG_TO_RAD * 45.;
+	if (P->es) { /* fixed ellipsoid/sphere */
+		P->zcoeff = ABe;
+		P->a = 6378206.4;
+		P->e = sqrt(P->es = 0.00676866);
+	} else {
+		P->zcoeff = ABs;
+		P->a = 6370997.;
+	}
+ENDENTRY(setup(P))
diff --git a/proj/pj_moll.c b/proj/pj_moll.c
new file mode 100644
index 0000000..be151ae
--- /dev/null
+++ b/proj/pj_moll.c
@@ -0,0 +1,48 @@
+/* Mollweide projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_moll.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define C1R	.90031631615710606956
+#define C2R	1.41421356237309504880
+#define EPS	1e-15
+#define EPS10	1e-10
+#define NITER	10
+	static double
+theta(double ph) {
+	double th, dth;
+	int i;
+
+	ph = PI * sin(th = ph);
+	for (i = NITER; i ; --i) {
+		th += ( dth = (ph - th - sin(th)) / (1. + cos(th)) );
+		if (fabs(dth) < EPS)
+			break;
+	}
+	return (.5 * th);
+}
+FORWARD(s_forward); /* spheroid */
+	double th;
+
+	xy.x = C1R * lp.lam * cos(th = theta(lp.phi));
+	xy.y = C2R * sin(th);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double th, s;
+
+	if ((s = fabs(th = xy.y / C2R)) < 1.) {
+		lp.lam = xy.x / (C1R * cos(th = asin(th)));
+		th += th;
+		lp.phi = asin((th + sin(th)) / PI);
+	} else if ((s - EPS10) > 1.)
+		lp.lam = lp.phi = HUGE_VAL;
+	else {
+		lp.lam = 0.;
+		lp.phi = th < 0. ? -HALFPI : HALFPI;
+	}
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_moll) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_msfn.c b/proj/pj_msfn.c
new file mode 100644
index 0000000..55e3983
--- /dev/null
+++ b/proj/pj_msfn.c
@@ -0,0 +1,9 @@
+/* determine constant small m */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_msfn.c	4.3	93/06/12	GIE	REL";
+#endif
+#include <math.h>
+	double
+pj_msfn(double sinphi, double cosphi, double es) {
+	return (cosphi / sqrt (1. - es * sinphi * sinphi));
+}
diff --git a/proj/pj_nocol.c b/proj/pj_nocol.c
new file mode 100644
index 0000000..2bc7949
--- /dev/null
+++ b/proj/pj_nocol.c
@@ -0,0 +1,41 @@
+/*  Nicolosi Globular */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_nocol.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define EPS	1e-10
+FORWARD(s_forward); /* spheroid */
+	if (fabs(lp.lam) < EPS) {
+		xy.x = 0;
+		xy.y = lp.phi;
+	} else if (fabs(lp.phi) < EPS) {
+		xy.x = lp.lam;
+		xy.y = 0.;
+	} else if (fabs(fabs(lp.lam) - HALFPI) < EPS) {
+		xy.x = lp.lam * cos(lp.phi);
+		xy.y = HALFPI * sin(lp.phi);
+	} else if (fabs(fabs(lp.phi) - HALFPI) < EPS) {
+		xy.x = 0;
+		xy.y = lp.phi;
+	} else {
+		double tb, c, d, m, n, r2, sp;
+
+		tb = HALFPI / lp.lam - lp.lam / HALFPI;
+		c = lp.phi / HALFPI;
+		d = (1 - c * c)/((sp = sin(lp.phi)) - c);
+		r2 = tb / d;
+		r2 *= r2;
+		m = (tb * sp / d - 0.5 * tb)/(1. + r2);
+		n = (sp / r2 + 0.5 * d)/(1. + 1./r2);
+		xy.x = cos(lp.phi);
+		xy.x = sqrt(m * m + xy.x * xy.x / (1. + r2));
+		xy.x = HALFPI * ( m + (lp.lam < 0. ? -xy.x : xy.x));
+		xy.y = sqrt(n * n - (sp * sp / r2 + d * sp - 1.) /
+			(1. + 1./r2));
+		xy.y = HALFPI * ( n + (lp.phi < 0. ? xy.y : -xy.y ));
+	}
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_nicol) P->es = 0.; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_nsper.c b/proj/pj_nsper.c
new file mode 100644
index 0000000..ef412ac
--- /dev/null
+++ b/proj/pj_nsper.c
@@ -0,0 +1,151 @@
+/* Near-sided perspective */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_nsper.c	4.5	93/06/14	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	height; \
+	double	sinph0; \
+	double	cosph0; \
+	double	p; \
+	double	rp; \
+	double	pn1; \
+	double	pfact; \
+	double	h; \
+	double	cg; \
+	double	sg; \
+	double	sw; \
+	double	cw; \
+	int		mode; \
+	int		tilt;
+#define PJ_LIB__
+#include	<projects.h>
+# define EPS10 1.e-10
+# define N_POLE	0
+# define S_POLE 1
+# define EQUIT	2
+# define OBLIQ	3
+FORWARD(s_forward); /* spheroid */
+	double  coslam, cosphi, sinphi;
+
+	sinphi = sin(lp.phi);
+	cosphi = cos(lp.phi);
+	coslam = cos(lp.lam);
+	switch (P->mode) {
+	case OBLIQ:
+		xy.y = P->sinph0 * sinphi + P->cosph0 * cosphi * coslam;
+		break;
+	case EQUIT:
+		xy.y = cosphi * coslam;
+		break;
+	case S_POLE:
+		xy.y = - sinphi;
+		break;
+	case N_POLE:
+		xy.y = sinphi;
+		break;
+	}
+	if (xy.y < P->rp) F_ERROR;
+	xy.y = P->pn1 / (P->p - xy.y);
+	xy.x = xy.y * cosphi * sin(lp.lam);
+	switch (P->mode) {
+	case OBLIQ:
+		xy.y *= (P->cosph0 * sinphi -
+		   P->sinph0 * cosphi * coslam);
+		break;
+	case EQUIT:
+		xy.y *= sinphi;
+		break;
+	case N_POLE:
+		coslam = - coslam;
+	case S_POLE:
+		xy.y *= cosphi * coslam;
+		break;
+	}
+	if (P->tilt) {
+		double yt, ba;
+
+		yt = xy.y * P->cg + xy.x * P->sg;
+		ba = 1. / (yt * P->sw * P->h + P->cw);
+		xy.x = (xy.x * P->cg - xy.y * P->sg) * P->cw * ba;
+		xy.y = yt * ba;
+	}
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double  rh, cosz, sinz;
+
+	if (P->tilt) {
+		double bm, bq, yt;
+
+		yt = 1./(P->pn1 - xy.y * P->sw);
+		bm = P->pn1 * xy.x * yt;
+		bq = P->pn1 * xy.y * P->cw * yt;
+		xy.x = bm * P->cg + bq * P->sg;
+		xy.y = bq * P->cg - bm * P->sg;
+	}
+	rh = hypot(xy.x, xy.y);
+	if ((sinz = 1. - rh * rh * P->pfact) < 0.) I_ERROR;
+	sinz = (P->p - sqrt(sinz)) / (P->pn1 / rh + rh / P->pn1);
+	cosz = sqrt(1. - sinz * sinz);
+	if (fabs(rh) <= EPS10) {
+		lp.lam = 0.;
+		lp.phi = P->phi0;
+	} else {
+		switch (P->mode) {
+		case OBLIQ:
+			lp.phi = asin(cosz * P->sinph0 + xy.y * sinz * P->cosph0 / rh);
+			xy.y = (cosz - P->sinph0 * sin(lp.phi)) * rh;
+			xy.x *= sinz * P->cosph0;
+			break;
+		case EQUIT:
+			lp.phi = asin(xy.y * sinz / rh);
+			xy.y = cosz * rh;
+			xy.x *= sinz;
+			break;
+		case N_POLE:
+			lp.phi = asin(cosz);
+			xy.y = -xy.y;
+			break;
+		case S_POLE:
+			lp.phi = - asin(cosz);
+			break;
+		}
+		lp.lam = atan2(xy.x, xy.y);
+	}
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+	static PJ *
+setup(PJ *P) {
+	if ((P->height = pj_param(P->params, "dh").f) <= 0.) E_ERROR(-30);
+	if (fabs(fabs(P->phi0) - HALFPI) < EPS10)
+		P->mode = P->phi0 < 0. ? S_POLE : N_POLE;
+	else if (fabs(P->phi0) < EPS10)
+		P->mode = EQUIT;
+	else {
+		P->mode = OBLIQ;
+		P->sinph0 = sin(P->phi0);
+		P->cosph0 = cos(P->phi0);
+	}
+	P->pn1 = P->height / P->a; /* normalize by radius */
+	P->p = 1. + P->pn1;
+	P->rp = 1. / P->p;
+	P->h = 1. / P->pn1;
+	P->pfact = (P->p + 1.) * P->h;
+	P->inv = s_inverse;
+	P->fwd = s_forward;
+	P->es = 0.;
+	return P;
+}
+ENTRY0(pj_nsper)
+	P->tilt = 0;
+ENDENTRY(setup(P))
+ENTRY0(pj_tpers)
+	double omega, gamma;
+
+	omega = pj_param(P->params, "dtilt").f * DEG_TO_RAD;
+	gamma = pj_param(P->params, "dazi").f * DEG_TO_RAD;
+	P->tilt = 1;
+	P->cg = cos(gamma); P->sg = sin(gamma);
+	P->cw = cos(omega); P->sw = sin(omega);
+ENDENTRY(setup(P))
diff --git a/proj/pj_nzmg.c b/proj/pj_nzmg.c
new file mode 100644
index 0000000..5fb5b6b
--- /dev/null
+++ b/proj/pj_nzmg.c
@@ -0,0 +1,77 @@
+/*  New Zealand Map Grid projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_nzmg.c	4.3	93/06/12	GIE	REL";
+#endif
+/* very loosely based upon DMA code by Bradford W. Drew */
+#define PJ_LIB__
+#include	<projects.h>
+#define EPSLN 1e-10
+#define SEC5_TO_RAD 0.4848136811095359935899141023
+#define RAD_TO_SEC5 2.062648062470963551564733573
+	static COMPLEX
+bf[] = {
+	.7557853228,	0.0,
+	.249204646,		.003371507,
+	-.001541739,	.041058560,
+	-.10162907,		.01727609,
+	-.26623489,		-.36249218,
+	-.6870983,		-1.1651967 };
+	static double
+tphi[] = { 1.5627014243, .5185406398, -.03333098, -.1052906, -.0368594,
+	.007317, .01220, .00394, -.0013 },
+tpsi[] = { .6399175073, -.1358797613, .063294409, -.02526853, .0117879,
+	-.0055161, .0026906, -.001333, .00067, -.00034 };
+#define Nbf 5
+#define Ntpsi 9
+#define Ntphi 8
+FORWARD(e_forward); /* ellipsoid */
+	COMPLEX p;
+	double *C;
+	int i;
+
+	lp.phi = (lp.phi - P->phi0) * RAD_TO_SEC5;
+	for (p.r = *(C = tpsi + (i = Ntpsi)); i ; --i)
+		p.r = *--C + lp.phi * p.r;
+	p.r *= lp.phi;
+	p.i = lp.lam;
+	p = pj_zpoly1(p, bf, Nbf);
+	xy.x = p.i;
+	xy.y = p.r;
+	return xy;
+}
+INVERSE(e_inverse); /* ellipsoid */
+	int nn, i;
+	COMPLEX p, f, fp, dp;
+	double den, *C;
+
+	p.r = xy.y;
+	p.i = xy.x;
+	for (nn = 20; nn ;--nn) {
+		f = pj_zpolyd1(p, bf, Nbf, &fp);
+		f.r -= xy.y;
+		f.i -= xy.x;
+		den = fp.r * fp.r + fp.i * fp.i;
+		p.r += dp.r = -(f.r * fp.r + f.i * fp.i) / den;
+		p.i += dp.i = -(f.i * fp.r - f.r * fp.i) / den;
+		if ((fabs(dp.r) + fabs(dp.i)) <= EPSLN)
+			break;
+	}
+	if (nn) {
+		lp.lam = p.i;
+		for (lp.phi = *(C = tphi + (i = Ntphi)); i ; --i)
+			lp.phi = *--C + p.r * lp.phi;
+		lp.phi = P->phi0 + p.r * lp.phi * SEC5_TO_RAD;
+	} else
+		lp.lam = lp.phi = HUGE_VAL;
+	return lp;
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_nzmg)
+	/* force to International major axis */
+	P->ra = 1. / (P->a = 6378388.0);
+	P->lam0 = DEG_TO_RAD * 173.;
+	P->phi0 = DEG_TO_RAD * -41.;
+	P->x0 = 2510000.;
+	P->y0 = 6023150.;
+	P->inv = e_inverse; P->fwd = e_forward;
+ENDENTRY(P)
diff --git a/proj/pj_ob_tran.c b/proj/pj_ob_tran.c
new file mode 100644
index 0000000..31d7a3f
--- /dev/null
+++ b/proj/pj_ob_tran.c
@@ -0,0 +1,143 @@
+/* Oblique Equidistant Cylindrical */
+#ifndef lint
+static char SCCSID[]="@(#)PJ_ob_tran.c	4.2	93/08/20	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	struct PJconsts *link; \
+	double	lamp; \
+	double	cphip, sphip;
+#define PJ_LIB__
+#include	<projects.h>
+#define TOL 1e-10
+#define ATOL 1e-50
+	static double
+aatan2(double n, double d) {
+	return ((fabs(n) < ATOL && fabs(d) < ATOL) ? 0. : atan2(n,d));
+}
+FORWARD(o_forward); /* spheroid */
+	double coslam, sinphi, cosphi;
+
+	coslam = cos(lp.lam);
+	sinphi = sin(lp.phi);
+	cosphi = cos(lp.phi);
+	lp.lam = adjlon(aatan2(cosphi * sin(lp.lam), P->sphip * cosphi * coslam +
+		P->cphip * sinphi) + P->lamp);
+	lp.phi = aasin(P->sphip * sinphi - P->cphip * cosphi * coslam);
+	return (P->link->fwd(lp, P->link));
+}
+FORWARD(t_forward); /* spheroid */
+	double cosphi, coslam;
+
+	cosphi = cos(lp.phi);
+	coslam = cos(lp.lam);
+	lp.lam = adjlon(aatan2(cosphi * sin(lp.lam), sin(lp.phi)) + P->lamp);
+	lp.phi = aasin(- cosphi * coslam);
+	return (P->link->fwd(lp, P->link));
+}
+INVERSE(o_inverse); /* spheroid */
+	double coslam, sinphi, cosphi;
+
+	lp = P->link->inv(xy, P->link);
+	if (lp.lam != HUGE_VAL) {
+		coslam = cos(lp.lam -= P->lamp);
+		sinphi = sin(lp.phi);
+		cosphi = cos(lp.phi);
+		lp.phi = aasin(P->sphip * sinphi + P->cphip * cosphi * coslam);
+		lp.lam = aatan2(cosphi * sin(lp.lam), P->sphip * cosphi * coslam -
+			P->cphip * sinphi);
+	}
+	return (lp);
+}
+INVERSE(t_inverse); /* spheroid */
+	double cosphi, t;
+
+	lp = P->link->inv(xy, P->link);
+	if (lp.lam != HUGE_VAL) {
+		cosphi = cos(lp.phi);
+		t = lp.lam - P->lamp;
+		lp.lam = aatan2(cosphi * sin(t), - sin(lp.phi));
+		lp.phi = aasin(cosphi * cos(t));
+	}
+	return (lp);
+}
+FREEUP;
+	if (P) {
+		if (P->link)
+			(*(P->link->pfree))(P->link);
+		pj_dalloc(P);
+	}
+}
+ENTRY1(pj_ob_tran, link)
+	int i;
+	double phip;
+	char *name, *s;
+
+	/* get name of projection to be translated */
+	if (!(name = pj_param(P->params, "so_proj").s)) E_ERROR(-26);
+	for (i = 0; (s = pj_list[i].id) && strcmp(name, s) ; ++i) ;
+	if (!s || !(P->link = (*pj_list[i].proj)(0))) E_ERROR(-37);
+	/* copy existing header into new */
+	P->es = 0.; /* force to spherical */
+	P->link->params = P->params;
+	P->link->over = P->over;
+	P->link->geoc = P->geoc;
+	P->link->a = P->a;
+	P->link->es = P->es;
+	P->link->ra = P->ra;
+	P->link->lam0 = P->lam0;
+	P->link->phi0 = P->phi0;
+	P->link->x0 = P->x0;
+	P->link->y0 = P->y0;
+	P->link->k0 = P->k0;
+	/* force spherical earth */
+	P->link->one_es = P->link->rone_es = 1.;
+	P->link->es = P->link->e = 0.;
+	if (!(P->link = pj_list[i].proj(P->link))) {
+		freeup(P);
+		return 0;
+	}
+	if (pj_param(P->params, "to_alpha").i) {
+		double lamc, phic, alpha;
+
+		lamc	= pj_param(P->params, "ro_lon_c").f;
+		phic	= pj_param(P->params, "ro_lat_c").f;
+		alpha	= pj_param(P->params, "ro_alpha").f;
+/*
+		if (fabs(phic) <= TOL ||
+			fabs(fabs(phic) - HALFPI) <= TOL ||
+			fabs(fabs(alpha) - HALFPI) <= TOL)
+*/
+		if (fabs(fabs(phic) - HALFPI) <= TOL)
+			E_ERROR(-32);
+		P->lamp = lamc + aatan2(-cos(alpha), -sin(alpha) * sin(phic));
+		phip = aasin(cos(phic) * sin(alpha));
+	} else if (pj_param(P->params, "to_lat_p").i) { /* specified new pole */
+		P->lamp = pj_param(P->params, "ro_lon_p").f;
+		phip = pj_param(P->params, "ro_lat_p").f;
+	} else { /* specified new "equator" points */
+		double lam1, lam2, phi1, phi2, con;
+
+		lam1 = pj_param(P->params, "ro_lon_1").f;
+		phi1 = pj_param(P->params, "ro_lat_1").f;
+		lam2 = pj_param(P->params, "ro_lon_2").f;
+		phi2 = pj_param(P->params, "ro_lat_2").f;
+		if (fabs(phi1 - phi2) <= TOL ||
+			(con = fabs(phi1)) <= TOL ||
+			fabs(con - HALFPI) <= TOL ||
+			fabs(fabs(phi2) - HALFPI) <= TOL) E_ERROR(-33);
+		P->lamp = atan2(cos(phi1) * sin(phi2) * cos(lam1) -
+			sin(phi1) * cos(phi2) * cos(lam2),
+			sin(phi1) * cos(phi2) * sin(lam2) -
+			cos(phi1) * sin(phi2) * sin(lam1));
+		phip = atan(-cos(P->lamp - lam1) / tan(phi1));
+	}
+	if (fabs(phip) > TOL) { /* oblique */
+		P->cphip = cos(phip);
+		P->sphip = sin(phip);
+		P->fwd = o_forward;
+		P->inv = P->link->inv ? o_inverse : 0;
+	} else { /* transverse */
+		P->fwd = t_forward;
+		P->inv = P->link->inv ? t_inverse : 0;
+	}
+ENDENTRY(P)
diff --git a/proj/pj_ocea.c b/proj/pj_ocea.c
new file mode 100644
index 0000000..5ac3eae
--- /dev/null
+++ b/proj/pj_ocea.c
@@ -0,0 +1,71 @@
+/*  Oblique Cylindrical Equal Area */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_ocea.c	4.6	93/08/04	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	rok; \
+	double	rtk; \
+	double	sinphi; \
+	double	cosphi; \
+	double	singam; \
+	double	cosgam;
+#define PJ_LIB__
+#include	<projects.h>
+FORWARD(s_forward); /* spheroid */
+	double t;
+
+	xy.y = sin(lp.lam);
+/*
+	xy.x = atan2((tan(lp.phi) * P->cosphi + P->sinphi * xy.y) , cos(lp.lam));
+*/
+	t = cos(lp.lam);
+	xy.x = atan((tan(lp.phi) * P->cosphi + P->sinphi * xy.y) / t);
+	if (t < 0.)
+		xy.x += PI;
+	xy.x *= P->rtk;
+	xy.y = P->rok * (P->sinphi * sin(lp.phi) - P->cosphi * cos(lp.phi) * xy.y);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double t, s;
+
+	xy.y /= P->rok;
+	xy.x /= P->rtk;
+	t = sqrt(1. - xy.y * xy.y);
+	lp.phi = asin(xy.y * P->sinphi + t * P->cosphi * (s = sin(xy.x)));
+	lp.lam = atan2(t * P->sinphi * s - xy.y * P->cosphi,
+		t * cos(xy.x));
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_ocea)
+	double phi_0, phi_1, phi_2, lam_1, lam_2, lonz, alpha;
+
+	P->rok = P->a / P->k0;
+	P->rtk = P->a * P->k0;
+	phi_0 = pj_param(P->params, "rlat_0").f;
+	phi_1 = pj_param(P->params, "rlat_1").f;
+	phi_2 = pj_param(P->params, "rlat_2").f;
+	lam_1 = pj_param(P->params, "rlon_1").f;
+	lam_2 = pj_param(P->params, "rlon_2").f;
+	lonz = pj_param(P->params, "rlonc").f;
+	alpha	= pj_param(P->params, "ralpha").f;
+	if ( pj_param(P->params, "bazi").i) {
+		P->singam = atan(-cos(alpha)/(-sin(phi_0) * sin(alpha))) + lonz;
+		P->sinphi = asin(cos(phi_0) * sin(alpha));
+	} else {
+		P->singam = atan2(cos(phi_1) * sin(phi_2) * cos(lam_1) -
+			sin(phi_1) * cos(phi_2) * cos(lam_2),
+			sin(phi_1) * cos(phi_2) * sin(lam_2) -
+			cos(phi_1) * sin(phi_2) * sin(lam_1) );
+		P->sinphi = atan(-cos(P->singam - lam_1) / tan(phi_1));
+	}
+	P->lam0 = P->singam + HALFPI;
+	P->cosphi = cos(P->sinphi);
+	P->sinphi = sin(P->sinphi);
+	P->cosgam = cos(P->singam);
+	P->singam = sin(P->singam);
+	P->inv = s_inverse;
+	P->fwd = s_forward;
+	P->es = 0.;
+ENDENTRY(P)
diff --git a/proj/pj_omerc.c b/proj/pj_omerc.c
new file mode 100644
index 0000000..7e8b6b0
--- /dev/null
+++ b/proj/pj_omerc.c
@@ -0,0 +1,167 @@
+/* Oblique Mercator */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_omerc.c	4.5	93/06/12	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	alpha, lamc, lam1, phi1, lam2, phi2, Gamma, al, bl, el, \
+		singam, cosgam, sinrot, cosrot, u_0; \
+	int		ellips, rot;
+#define PJ_LIB__
+#include	<projects.h>
+#define TOL	1.e-7
+#define EPS	1.e-10
+#define TSFN0(x)	tan(.5 * (HALFPI - (x)))
+FORWARD(e_forward); /* ellipsoid & spheroid */
+	double  con, q, s, ul, us, vl, vs;
+
+	vl = sin(P->bl * lp.lam);
+	if (fabs(fabs(lp.phi) - HALFPI) <= EPS) {
+		ul = lp.phi < 0. ? -P->singam : P->singam;
+		us = P->al * lp.phi / P->bl;
+	} else {
+		q = P->el / (P->ellips ? pow(pj_tsfn(lp.phi, sin(lp.phi), P->e), P->bl)
+			: TSFN0(lp.phi));
+		s = .5 * (q - 1. / q);
+		ul = 2. * (s * P->singam - vl * P->cosgam) / (q + 1. / q);
+		con = cos(P->bl * lp.lam);
+		if (fabs(con) >= TOL) {
+			us = P->al * atan((s * P->cosgam + vl * P->singam) / con) / P->bl;
+			if (con < 0.)
+				us += PI * P->al / P->bl;
+		} else
+			us = P->al * P->bl * lp.lam;
+	}
+	if (fabs(fabs(ul) - 1.) <= EPS) F_ERROR;
+	vs = .5 * P->al * log((1. - ul) / (1. + ul)) / P->bl;
+	us -= P->u_0;
+	if (! P->rot) {
+		xy.x = us;
+		xy.y = vs;
+	} else {
+		xy.x = vs * P->cosrot + us * P->sinrot;
+		xy.y = us * P->cosrot - vs * P->sinrot;
+	}
+	return (xy);
+}
+INVERSE(e_inverse); /* ellipsoid & spheroid */
+	double  q, s, ul, us, vl, vs;
+
+	if (! P->rot) {
+		us = xy.x;
+		vs = xy.y;
+	} else {
+		vs = xy.x * P->cosrot - xy.y * P->sinrot;
+		us = xy.y * P->cosrot + xy.x * P->sinrot;
+	}
+	us += P->u_0;
+	q = exp(- P->bl * vs / P->al);
+	s = .5 * (q - 1. / q);
+	vl = sin(P->bl * us / P->al);
+	ul = 2. * (vl * P->cosgam + s * P->singam) / (q + 1. / q);
+	if (fabs(fabs(ul) - 1.) < EPS) {
+		lp.lam = 0.;
+		lp.phi = ul < 0. ? -HALFPI : HALFPI;
+	} else {
+		lp.phi = P->el / sqrt((1. + ul) / (1. - ul));
+		if (P->ellips) {
+			if ((lp.phi = pj_phi2(pow(lp.phi, 1. / P->bl), P->e)) == HUGE_VAL)
+				I_ERROR;
+		} else
+			lp.phi = HALFPI - 2. * atan(lp.phi);
+		lp.lam = - atan2((s * P->cosgam -
+			vl * P->singam), cos(P->bl * us / P->al)) / P->bl;
+	}
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_omerc)
+	double con, com, cosph0, d, f, h, l, sinph0, p, j;
+	int azi;
+
+	P->rot	= pj_param(P->params, "bno_rot").i == 0;
+	if (azi	= pj_param(P->params, "talpha").i) {
+		P->lamc	= pj_param(P->params, "rlonc").f;
+		P->alpha	= pj_param(P->params, "ralpha").f;
+		if (fabs(P->phi0) <= TOL ||
+			fabs(fabs(P->phi0) - HALFPI) <= TOL ||
+			fabs(fabs(P->alpha) - HALFPI) <= TOL)
+			E_ERROR(-32);
+	} else {
+		P->lam1	= pj_param(P->params, "rlon_1").f;
+		P->phi1	= pj_param(P->params, "rlat_1").f;
+		P->lam2	= pj_param(P->params, "rlon_2").f;
+		P->phi2	= pj_param(P->params, "rlat_2").f;
+		if (fabs(P->phi1 - P->phi2) <= TOL ||
+			(con = fabs(P->phi1)) <= TOL ||
+			fabs(con - HALFPI) <= TOL ||
+			fabs(fabs(P->phi0) - HALFPI) <= TOL ||
+			fabs(fabs(P->phi2) - HALFPI) <= TOL) E_ERROR(-33);
+	}
+	com = (P->ellips = P->es > 0.) ? sqrt(P->one_es) : 1.;
+	if (fabs(P->phi0) > EPS) {
+		sinph0 = sin(P->phi0);
+		cosph0 = cos(P->phi0);
+		if (P->ellips) {
+			con = 1. - P->es * sinph0 * sinph0;
+			P->bl = cosph0 * cosph0;
+			P->bl = sqrt(1. + P->es * P->bl * P->bl / P->one_es);
+			P->al = P->bl * P->k0 * com / con;
+			d = P->bl * com / (cosph0 * sqrt(con));
+		} else {
+			P->bl = 1.;
+			P->al = P->k0;
+			d = 1. / cosph0;
+		}
+		if ((f = d * d - 1.) <= 0.)
+			f = 0.;
+		else {
+			f = sqrt(f);
+			if (P->phi0 < 0.)
+				f = -f;
+		}
+		P->el = f += d;
+		if (P->ellips)	P->el *= pow(pj_tsfn(P->phi0, sinph0, P->e), P->bl);
+		else		P->el *= TSFN0(P->phi0);
+	} else {
+		P->bl = 1. / com;
+		P->al = P->k0;
+		P->el = d = f = 1.;
+	}
+	if (azi) {
+		P->Gamma = asin(sin(P->alpha) / d);
+		P->lam0 = P->lamc - asin((.5 * (f - 1. / f)) *
+		   tan(P->Gamma)) / P->bl;
+	} else {
+		if (P->ellips) {
+			h = pow(pj_tsfn(P->phi1, sin(P->phi1), P->e), P->bl);
+			l = pow(pj_tsfn(P->phi2, sin(P->phi2), P->e), P->bl);
+		} else {
+			h = TSFN0(P->phi1);
+			l = TSFN0(P->phi2);
+		}
+		f = P->el / h;
+		p = (l - h) / (l + h);
+		j = P->el * P->el;
+		j = (j - l * h) / (j + l * h);
+		if ((con = P->lam1 - P->lam2) < -PI)
+			P->lam2 -= TWOPI;
+		else if (con > PI)
+			P->lam2 += TWOPI;
+		P->lam0 = adjlon(.5 * (P->lam1 + P->lam2) - atan(
+		   j * tan(.5 * P->bl * (P->lam1 - P->lam2)) / p) / P->bl);
+		P->Gamma = atan(2. * sin(P->bl * adjlon(P->lam1 - P->lam0)) /
+		   (f - 1. / f));
+		P->alpha = asin(d * sin(P->Gamma));
+	}
+	P->singam = sin(P->Gamma);
+	P->cosgam = cos(P->Gamma);
+	f = pj_param(P->params, "brot_conv").i ? P->Gamma : P->alpha;
+	P->sinrot = sin(f);
+	P->cosrot = cos(f);
+	P->u_0 = pj_param(P->params, "bno_uoff").i ? 0. :
+		fabs(P->al * atan(sqrt(d * d - 1.) / P->cosrot) / P->bl);
+	if (P->phi0 < 0.)
+		P->u_0 = - P->u_0;
+	P->inv = e_inverse;
+	P->fwd = e_forward;
+ENDENTRY(P)
diff --git a/proj/pj_open_lib.c b/proj/pj_open_lib.c
new file mode 100644
index 0000000..ccf2319
--- /dev/null
+++ b/proj/pj_open_lib.c
@@ -0,0 +1,67 @@
+/* standard location file open procedure */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_open_lib.c	4.2   93/08/25 GIE REL";
+#endif
+#define PJ_LIB__
+#include <projects.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+static char *
+proj_lib_name =
+#ifdef HOME_LIB
+HOME_LIB;
+#else
+0;
+#endif
+FILE *
+pj_open_lib(char *name, char *mode) {
+  char fname[FILENAME_MAX+1], *sysname;
+  FILE *fid;
+  int n = 0;
+  
+  /*	
+     if (*name == '~' && name[1] == DIR_CHAR)
+     if (sysname = getenv("HOME")) {
+     (void)strcpy(fname, sysname);
+     fname[n = strlen(fname)] = DIR_CHAR;
+     fname[++n] = '\0';
+     (void)strcpy(fname+n, name + 1);
+     sysname = fname;
+     } else
+     return NULL;
+     else if (*name == DIR_CHAR || (*name == '.' && name[1] == DIR_CHAR) ||
+     (!strncmp(name, "..", 2) && name[2] == DIR_CHAR) )
+     sysname = name;
+     else if ((sysname = getenv("PROJ_LIB")) || (sysname = proj_lib_name)) {
+     (void)strcpy(fname, sysname);
+     fname[n = strlen(fname)] = DIR_CHAR;
+     fname[++n] = '\0';
+     (void)strcpy(fname+n, name);
+     sysname = fname;
+     } else 
+     sysname = name;
+     */
+
+  errno = 0;
+  if (!(fid = fopen(name,mode))) {
+    if ((sysname = getenv("GRASSLAND"))) {
+      (void)strcpy(fname, sysname);
+      fname[n = strlen(fname)] = DIR_CHAR;
+      fname[++n] = '\0';
+      (void)strcat(fname+n,"misc");
+      fname[n = strlen(fname)] = DIR_CHAR;
+      fname[++n] = '\0';
+      (void)strcpy(fname+n, name);
+      sysname = fname;    
+    } else {
+      sysname = name;
+    }
+    
+    if (fid = fopen(sysname, mode))
+      errno = 0;
+  }
+  return(fid);
+}
+
+
diff --git a/proj/pj_ortho.c b/proj/pj_ortho.c
new file mode 100644
index 0000000..8d5e0f7
--- /dev/null
+++ b/proj/pj_ortho.c
@@ -0,0 +1,92 @@
+/* Orthographic projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_ortho.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	sinph0; \
+	double	cosph0; \
+	int		mode;
+#define PJ_LIB__
+#include	<projects.h>
+#define EPS10 1.e-10
+#define N_POLE	0
+#define S_POLE 1
+#define EQUIT	2
+#define OBLIQ	3
+FORWARD(s_forward); /* spheroid */
+	double  coslam, cosphi, sinphi;
+
+	cosphi = cos(lp.phi);
+	coslam = cos(lp.lam);
+	switch (P->mode) {
+	case EQUIT:
+		if (cosphi * coslam < - EPS10) F_ERROR;
+		xy.y = sin(lp.phi);
+		break;
+	case OBLIQ:
+		if (P->sinph0 * (sinphi = sin(lp.phi)) +
+		   P->cosph0 * cosphi * coslam < - EPS10) F_ERROR;
+		xy.y = P->cosph0 * sinphi - P->sinph0 * cosphi * coslam;
+		break;
+	case N_POLE:
+		coslam = - coslam;
+	case S_POLE:
+		if (fabs(lp.phi - P->phi0) - EPS10 > HALFPI) F_ERROR;
+		xy.y = cosphi * coslam;
+		break;
+	}
+	xy.x = cosphi * sin(lp.lam);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double  rh, cosc, sinc;
+
+	if ((sinc = (rh = hypot(xy.x, xy.y))) > 1.) {
+		if ((sinc - 1.) > EPS10) I_ERROR;
+		sinc = 1.;
+	}
+	cosc = sqrt(1. - sinc * sinc); /* in this range OK */
+	if (fabs(rh) <= EPS10)
+		lp.phi = P->phi0;
+	else switch (P->mode) {
+	case N_POLE:
+		xy.y = -xy.y;
+		lp.phi = acos(sinc);
+		break;
+	case S_POLE:
+		lp.phi = - acos(sinc);
+		break;
+	case EQUIT:
+		lp.phi = xy.y * sinc / rh;
+		xy.x *= sinc;
+		xy.y = cosc * rh;
+		goto sinchk;
+	case OBLIQ:
+		lp.phi = cosc * P->sinph0 + xy.y * sinc * P->cosph0 / rh;
+		xy.y = (cosc - P->sinph0 * lp.phi) * rh;
+		xy.x *= sinc * P->cosph0;
+sinchk:
+		if (fabs(lp.phi) >= 1.)
+			lp.phi = lp.phi < 0. ? -HALFPI : HALFPI;
+		else
+			lp.phi = asin(lp.phi);
+		break;
+	}
+	lp.lam = (xy.y == 0. && (P->mode == OBLIQ || P->mode == EQUIT)) ?
+		 (xy.x == 0. ? 0. : xy.x < 0. ? -HALFPI : HALFPI) : atan2(xy.x, xy.y);
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_ortho)
+	if (fabs(fabs(P->phi0) - HALFPI) <= EPS10)
+		P->mode = P->phi0 < 0. ? S_POLE : N_POLE;
+	else if (fabs(P->phi0) > EPS10) {
+		P->mode = OBLIQ;
+		P->sinph0 = sin(P->phi0);
+		P->cosph0 = cos(P->phi0);
+	} else
+		P->mode = EQUIT;
+	P->inv = s_inverse;
+	P->fwd = s_forward;
+	P->es = 0.;
+ENDENTRY(P)
diff --git a/proj/pj_parab.c b/proj/pj_parab.c
new file mode 100644
index 0000000..0fc254a
--- /dev/null
+++ b/proj/pj_parab.c
@@ -0,0 +1,24 @@
+/*  Craster Parabolic Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_parab.c	4.5	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+# include	<projects.h>
+#define XM	0.97720502380583984317
+#define RXM	1.02332670794648848847
+#define YM	3.06998012383946546542
+#define RYM	0.32573500793527994772
+#define THIRD	0.333333333333333333
+FORWARD(s_forward); /* spheroid */
+	lp.phi *= THIRD;
+	xy.x = XM * lp.lam * (2. * cos(lp.phi + lp.phi) - 1.);
+	xy.y = YM * sin(lp.phi);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = 3. * asin(xy.y * RYM);
+	lp.lam = xy.x * RXM / (2. * cos((lp.phi + lp.phi) * THIRD) - 1);
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_parab) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_param.c b/proj/pj_param.c
new file mode 100644
index 0000000..c3d8d52
--- /dev/null
+++ b/proj/pj_param.c
@@ -0,0 +1,89 @@
+/* put parameters in linked list and retrieve */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_param.c	4.4	93/06/12	GIE	REL";
+#endif
+#include <projects.h>
+#include <stdio.h>
+#include <string.h>
+	paralist * /* create parameter list entry */
+pj_mkparam(char *str) {
+	paralist *new;
+
+	if (new = (paralist *)pj_malloc(sizeof(paralist) + strlen(str))) {
+		new->used = 0;
+		new->next = 0;
+		if (*str == '+')
+			++str;
+		(void)strcpy(new->param, str);
+	}
+	return new;
+}
+	PROJVALUE /* test for presence or get parameter value */
+pj_param(paralist *pl, char *opt) {
+	int type;
+	unsigned l;
+	PROJVALUE value;
+
+	type = *opt++;
+	/* simple linear lookup */
+	l = strlen(opt);
+	while (pl && !(!strncmp(pl->param, opt, l) &&
+	  (!pl->param[l] || pl->param[l] == '=')))
+		pl = (paralist *) pl->next;
+	if (type == 't')
+		value.i = pl != 0;
+	else if (pl) {
+		pl->used |= 1;
+		opt = pl->param + l;
+		if (*opt == '=')
+			++opt;
+		switch (type) {
+		case 'i':	/* integer input */
+			value.i = atoi(opt);
+			break;
+		case 'd':	/* simple real input */
+			value.f = atof(opt);
+			break;
+		case 'r':	/* degrees input */
+			value.f = dmstor(opt, 0);
+			break;
+		case 's':	/* char string */
+			value.s = opt;
+			break;
+		case 'b':	/* boolean */
+			switch (*opt) {
+			case 'F': case 'f':
+				value.i = 0;
+				break;
+			case '\0': case 'T': case 't':
+				value.i = 1;
+				break;
+			default:
+				pj_errno = -8;
+				value.i = 0;
+				break;
+			}
+			break;
+		default:
+bum_type:	/* note: this is an error in parameter, not a user error */
+			fprintf(stderr, "invalid request to pj_param, fatal\n");
+			exit(1);
+		}
+	} else /* not given */
+		switch (type) {
+		case 'b':
+		case 'i':
+			value.i = 0;
+			break;
+		case 'd':
+		case 'r':
+			value.f = 0.;
+			break;
+		case 's':
+			value.s = 0;
+			break;
+		default:
+			goto bum_type;
+		}
+	return value;
+}
diff --git a/proj/pj_pconic.c b/proj/pj_pconic.c
new file mode 100644
index 0000000..e323204
--- /dev/null
+++ b/proj/pj_pconic.c
@@ -0,0 +1,39 @@
+/* Perspective Conic */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_pconic.c	4.5	93/06/14	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	phi1; \
+	double	phi2; \
+	double	n; \
+	double	rho; \
+	double	rho0; \
+	double	c2; \
+	double	check; \
+	int		negative;
+#define PJ_LIB__
+# include	<projects.h>
+# define EPS10	1.e-10
+FORWARD(s_forward); /* sphere & ellipsoid */
+	
+	if ((P->negative && lp.phi >= P->check) ||
+	    (!P->negative && lp.phi <= P->check)) F_ERROR;
+	P->rho = P->rho0 - P->c2 * tan(lp.phi - P->phi0);
+	xy.x = P->rho * sin( lp.lam *= P->n );
+	xy.y = P->rho0 - P->rho * cos(lp.lam);
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_pconic)
+	double cosphi, sinphi;
+
+	P->phi1 = pj_param(P->params, "rlat_1").f;
+	P->phi2 = pj_param(P->params, "rlat_2").f;
+	if (fabs(P->phi0 = 0.5 * (P->phi1 + P->phi2)) < EPS10) E_ERROR(-21);
+	P->check = P->phi0 + ((P->negative = P->phi0 < 0.) ? HALFPI : -HALFPI);
+	P->n = sinphi = sin(P->phi0);
+	cosphi = cos(P->phi0);
+	P->c2 = cos(0.5 * (P->phi2 - P->phi1));
+	P->rho0 = P->c2 * cosphi / sinphi;
+	P->es = 0.; P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_phi2.c b/proj/pj_phi2.c
new file mode 100644
index 0000000..dbb79d4
--- /dev/null
+++ b/proj/pj_phi2.c
@@ -0,0 +1,28 @@
+/* determine latitude angle phi-2 */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_phi2.c	4.3	93/06/12	GIE	REL";
+#endif
+#include <projects.h>
+
+#define HALFPI		1.5707963267948966
+#define TOL 1.0e-10
+#define N_ITER 15
+
+	double
+pj_phi2(double ts, double e) {
+	double eccnth, Phi, con, dphi;
+	int i;
+
+	eccnth = .5 * e;
+	Phi = HALFPI - 2. * atan (ts);
+	i = N_ITER;
+	do {
+		con = e * sin (Phi);
+		dphi = HALFPI - 2. * atan (ts * pow((1. - con) /
+		   (1. + con), eccnth)) - Phi;
+		Phi += dphi;
+	} while ( fabs(dphi) > TOL && --i);
+	if (i <= 0)
+		pj_errno = -18;
+	return Phi;
+}
diff --git a/proj/pj_poly.c b/proj/pj_poly.c
new file mode 100644
index 0000000..d44edb6
--- /dev/null
+++ b/proj/pj_poly.c
@@ -0,0 +1,101 @@
+/* Polyconic (American) projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_poly.c	4.3	93/06/12	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double ml0; \
+	double *en;
+#define PJ_LIB__
+#include <projects.h>
+#define TOL	1e-10
+#define CONV	1e-10
+#define N_ITER	10
+#define I_ITER 20
+#define ITOL 1.e-12
+FORWARD(e_forward); /* ellipsoid */
+	double  ms, sp, cp;
+
+	if (fabs(lp.phi) <= TOL) { xy.x = lp.lam; xy.y = -P->ml0; }
+	else {
+		sp = sin(lp.phi);
+		ms = fabs(cp = cos(lp.phi)) > TOL ? pj_msfn(sp, cp, P->es) / sp : 0.;
+		xy.x = ms * sin(lp.lam *= sp);
+		xy.y = (pj_mlfn(lp.phi, sp, cp, P->en) - P->ml0) + ms * (1. - cos(lp.lam));
+	}
+	return (xy);
+}
+FORWARD(s_forward); /* spheroid */
+	double  cot, E;
+
+	if (fabs(lp.phi) <= TOL) { xy.x = lp.lam; xy.y = P->ml0; }
+	else {
+		cot = 1. / tan(lp.phi);
+		xy.x = sin(E = lp.lam * sin(lp.phi)) * cot;
+		xy.y = lp.phi - P->phi0 + cot * (1. - cos(E));
+	}
+	return (xy);
+}
+INVERSE(e_inverse); /* ellipsoid */
+	xy.y += P->ml0;
+	if (fabs(xy.y) <= TOL) { lp.lam = xy.x; lp.phi = 0.; }
+	else {
+		double r, c, sp, cp, s2ph, ml, mlb, mlp, dPhi;
+		int i;
+
+		r = xy.y * xy.y + xy.x * xy.x;
+		for (lp.phi = xy.y, i = I_ITER; i ; --i) {
+			sp = sin(lp.phi);
+			s2ph = sp * ( cp = cos(lp.phi));
+			if (fabs(cp) < ITOL)
+				I_ERROR;
+			c = sp * (mlp = sqrt(1. - P->es * sp * sp)) / cp;
+			ml = pj_mlfn(lp.phi, sp, cp, P->en);
+			mlb = ml * ml + r;
+			mlp = P->one_es / (mlp * mlp * mlp);
+			lp.phi += ( dPhi =
+				( ml + ml + c * mlb - 2. * xy.y * (c * ml + 1.) ) / (
+				P->es * s2ph * (mlb - 2. * xy.y * ml) / c +
+				2.* (xy.y - ml) * (c * mlp - 1. / s2ph) - mlp - mlp ));
+			if (fabs(dPhi) <= ITOL)
+				break;
+		}
+		if (!i)
+			I_ERROR;
+		c = sin(lp.phi);
+		lp.lam = asin(xy.x * tan(lp.phi) * sqrt(1. - P->es * c * c)) / sin(lp.phi);
+	}
+	return (lp);
+}
+INVERSE(s_inverse); /* spheroid */
+	double B, dphi, tp;
+	int i;
+
+	if (fabs(xy.y = P->phi0 + xy.y) <= TOL) { lp.lam = xy.x; lp.phi = 0.; }
+	else {
+		lp.phi = xy.y;
+		B = xy.x * xy.x + xy.y * xy.y;
+		i = N_ITER;
+		do {
+			tp = tan(lp.phi);
+			lp.phi -= (dphi = (xy.y * (lp.phi * tp + 1.) - lp.phi -
+				.5 * ( lp.phi * lp.phi + B) * tp) /
+				((lp.phi - xy.y) / tp - 1.));
+		} while (fabs(dphi) > CONV && --i);
+		if (! i) I_ERROR;
+		lp.lam = asin(xy.x * tan(lp.phi)) / sin(lp.phi);
+	}
+	return (lp);
+}
+FREEUP; if (P) { if (P->en) pj_dalloc(P->en); pj_dalloc(P); } }
+ENTRY1(pj_poly, en)
+	if (P->es) {
+		if (!(P->en = pj_enfn(P->es))) E_ERROR_0;
+		P->ml0 = pj_mlfn(P->phi0, sin(P->phi0), cos(P->phi0), P->en);
+		P->inv = e_inverse;
+		P->fwd = e_forward;
+	} else {
+		P->ml0 = -P->phi0;
+		P->inv = s_inverse;
+		P->fwd = s_forward;
+	}
+ENDENTRY(P)
diff --git a/proj/pj_pr_list.c b/proj/pj_pr_list.c
new file mode 100644
index 0000000..c949ad9
--- /dev/null
+++ b/proj/pj_pr_list.c
@@ -0,0 +1,38 @@
+/* print projection's list of parameters */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_pr_list.c	4.4   93/08/05 GIE REL";
+#endif
+#include <projects.h>
+#include <stdio.h>
+#include <string.h>
+#define LINE_LEN 72
+	static int
+pr_list(PJ *P, int not_used) {
+	paralist *t;
+	int l, n = 1, flag = 0;
+
+	putchar('#');
+	for (t = P->params; t; t = t->next)
+		if ((!not_used && t->used) || (not_used && !t->used)) {
+			l = strlen(t->param) + 1;
+			if (n + l > LINE_LEN) {
+				(void)fputs("\n#", stdout);
+				n = 1;
+			}
+			putchar(' ');
+			if (*(t->param) != '+')
+				putchar('+');
+			(void)fputs(t->param, stdout);
+			n += l;
+		} else
+			flag = 1;
+	putchar('\n');
+	return flag;
+}
+	void /* print link list of projection parameters */
+pj_pr_list(PJ *P) {
+	if (pr_list(P, 0)) {
+		fputs("# following specified but NOT used\n", stdout);
+		(void)pr_list(P, 1);
+	}
+}
diff --git a/proj/pj_putp2.c b/proj/pj_putp2.c
new file mode 100644
index 0000000..b578dfc
--- /dev/null
+++ b/proj/pj_putp2.c
@@ -0,0 +1,47 @@
+/*  Putnins P2' */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_putp2.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define NITER	20
+#define EPS	1e-7
+#define ONETOL 1.000001
+#define C	2.96042050617763413905
+#define RC	0.33778985043282124554
+#define FYC	1.56548
+#define RYC	0.63878171551217517949
+#define FXC	0.86310
+#define RXC	1.15861429730042868729
+FORWARD(s_forward); /* spheroid */
+	double th1, c;
+	int i;
+
+	c = C * sin(lp.phi);
+	for (i = NITER; i; --i) {
+		lp.phi -= th1 = (lp.phi + sin(lp.phi) - c) / (1. + cos(lp.phi));
+		if (fabs(th1) < EPS) break;
+	}
+	xy.x = FXC * lp.lam * cos(lp.phi *= 0.5);
+	xy.y = FYC * sin(lp.phi);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = RYC * xy.y;
+	if (fabs(lp.phi) > 1.)
+		if (fabs(lp.phi) > ONETOL)	I_ERROR
+		else lp.phi = lp.phi > 0. ? HALFPI : - HALFPI;
+	else
+		lp.phi = asin(lp.phi);
+	lp.lam = RXC * xy.x / cos(lp.phi);
+	lp.phi += lp.phi;
+	lp.phi = RC * (lp.phi + sin(lp.phi));
+	if (fabs(lp.phi) > 1.)
+		if (fabs(lp.phi) > ONETOL)	I_ERROR
+		else lp.phi = lp.phi > 0. ? HALFPI : - HALFPI;
+	else
+		lp.phi = asin(lp.phi);
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_putp2) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_putp5.c b/proj/pj_putp5.c
new file mode 100644
index 0000000..e0ecadc
--- /dev/null
+++ b/proj/pj_putp5.c
@@ -0,0 +1,21 @@
+/*  Putnins P5 Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_putp5.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define FXC	1.01346
+#define FYC	1.01346
+#define CS	1.21585420370805325734
+FORWARD(s_forward); /* spheroid */
+	xy.x = FXC * lp.lam * (2. - sqrt(1. + CS * lp.phi * lp.phi));
+	xy.y = FYC * lp.phi;
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = xy.y / FYC;
+	lp.lam = xy.x / (FXC * (2. - sqrt(1. + CS * lp.phi * lp.phi)));
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_putp5) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_qsfn.c b/proj/pj_qsfn.c
new file mode 100644
index 0000000..c0610be
--- /dev/null
+++ b/proj/pj_qsfn.c
@@ -0,0 +1,17 @@
+/* determine small q */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_qsfn.c	4.3	93/06/12	GIE	REL";
+#endif
+#include <math.h>
+# define EPSILON 1.0e-7
+	double
+pj_qsfn(double sinphi, double e, double one_es) {
+	double con;
+
+	if (e >= EPSILON) {
+		con = e * sinphi;
+		return (one_es * (sinphi / (1. - con * con) -
+		   (.5 / e) * log ((1. - con) / (1. + con))));
+	} else
+		return (sinphi + sinphi);
+}
diff --git a/proj/pj_quau.c b/proj/pj_quau.c
new file mode 100644
index 0000000..a8fc556
--- /dev/null
+++ b/proj/pj_quau.c
@@ -0,0 +1,27 @@
+/*  Quartic Authalic */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_quau.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+# include	<projects.h>
+#define ONEEPS	1.0000001
+FORWARD(s_forward); /* spheroid */
+	xy.x = lp.lam * cos(lp.phi);
+	xy.x /= cos(lp.phi *= 0.5);
+	xy.y = 2. * sin(lp.phi);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	if (fabs(xy.y *= .5) >= 1.)
+		if (fabs(xy.y) > ONEEPS)	I_ERROR
+		else		lp.phi = xy.y < 0. ? PI : -PI;
+	else
+		lp.phi = 2. * asin(xy.y);
+	if ((lp.lam = cos(lp.phi)) == 0.)
+		lp.lam = 0.;
+	else
+		lp.lam = xy.x * cos(.5 * lp.phi) / lp.lam;
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_quau) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_robin.c b/proj/pj_robin.c
new file mode 100644
index 0000000..06a05dd
--- /dev/null
+++ b/proj/pj_robin.c
@@ -0,0 +1,108 @@
+/*  Robinson Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_robin.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define V(C,z) (C.c0 + z * (C.c1 + z * (C.c2 + z * C.c3)))
+#define DV(C,z) (C.c1 + z * (C.c2 + C.c2 + z * 3. * C.c3))
+/* note: following terms based upon 5 deg. intervals in degrees. */
+static struct COEFS {
+	float c0, c1, c2, c3;
+} X[] = {
+1,	-5.67239e-12,	-7.15511e-05,	3.11028e-06,
+0.9986,	-0.000482241,	-2.4897e-05,	-1.33094e-06,
+0.9954,	-0.000831031,	-4.4861e-05,	-9.86588e-07,
+0.99,	-0.00135363,	-5.96598e-05,	3.67749e-06,
+0.9822,	-0.00167442,	-4.4975e-06,	-5.72394e-06,
+0.973,	-0.00214869,	-9.03565e-05,	1.88767e-08,
+0.96,	-0.00305084,	-9.00732e-05,	1.64869e-06,
+0.9427,	-0.00382792,	-6.53428e-05,	-2.61493e-06,
+0.9216,	-0.00467747,	-0.000104566,	4.8122e-06,
+0.8962,	-0.00536222,	-3.23834e-05,	-5.43445e-06,
+0.8679,	-0.00609364,	-0.0001139,	3.32521e-06,
+0.835,	-0.00698325,	-6.40219e-05,	9.34582e-07,
+0.7986,	-0.00755337,	-5.00038e-05,	9.35532e-07,
+0.7597,	-0.00798325,	-3.59716e-05,	-2.27604e-06,
+0.7186,	-0.00851366,	-7.0112e-05,	-8.63072e-06,
+0.6732,	-0.00986209,	-0.000199572,	1.91978e-05,
+0.6213,	-0.010418,	8.83948e-05,	6.24031e-06,
+0.5722,	-0.00906601,	0.000181999,	6.24033e-06,
+0.5322, 0.,0.,0.  },
+Y[] = {
+0,	0.0124,	3.72529e-10,	1.15484e-09,
+0.062,	0.0124001,	1.76951e-08,	-5.92321e-09,
+0.124,	0.0123998,	-7.09668e-08,	2.25753e-08,
+0.186,	0.0124008,	2.66917e-07,	-8.44523e-08,
+0.248,	0.0123971,	-9.99682e-07,	3.15569e-07,
+0.31,	0.0124108,	3.73349e-06,	-1.1779e-06,
+0.372,	0.0123598,	-1.3935e-05,	4.39588e-06,
+0.434,	0.0125501,	5.20034e-05,	-1.00051e-05,
+0.4968,	0.0123198,	-9.80735e-05,	9.22397e-06,
+0.5571,	0.0120308,	4.02857e-05,	-5.2901e-06,
+0.6176,	0.0120369,	-3.90662e-05,	7.36117e-07,
+0.6769,	0.0117015,	-2.80246e-05,	-8.54283e-07,
+0.7346,	0.0113572,	-4.08389e-05,	-5.18524e-07,
+0.7903,	0.0109099,	-4.86169e-05,	-1.0718e-06,
+0.8435,	0.0103433,	-6.46934e-05,	5.36384e-09,
+0.8936,	0.00969679,	-6.46129e-05,	-8.54894e-06,
+0.9394,	0.00840949,	-0.000192847,	-4.21023e-06,
+0.9761,	0.00616525,	-0.000256001,	-4.21021e-06,
+1., 0.,0.,0 };
+#define FXC	0.8487
+#define FYC	1.3523
+#define C1	11.45915590261646417544
+#define RC1	0.08726646259971647884
+#define NODES	18
+#define ONEEPS	1.000001
+#define EPS	1e-8
+FORWARD(s_forward); /* spheroid */
+	int i;
+	double dphi;
+
+	i = floor((dphi = fabs(lp.phi)) * C1);
+	if (i >= NODES) i = NODES - 1;
+	dphi = RAD_TO_DEG * (dphi - RC1 * i);
+	xy.x = V(X[i], dphi) * FXC * lp.lam;
+	xy.y = V(Y[i], dphi) * FYC;
+	if (lp.phi < 0.) xy.y = -xy.y;
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	int i;
+	double t, t1;
+	struct COEFS T;
+
+	lp.lam = xy.x / FXC;
+	lp.phi = fabs(xy.y / FYC);
+	if (lp.phi >= 1.) { /* simple pathologic cases */
+		if (lp.phi > ONEEPS) I_ERROR
+		else {
+			lp.phi = xy.y < 0. ? -HALFPI : HALFPI;
+			lp.lam /= X[NODES].c0;
+		}
+	} else { /* general problem */
+		/* in Y space, reduce to table interval */
+		for (i = floor(lp.phi * NODES);;) {
+			if (Y[i].c0 > lp.phi) --i;
+			else if (Y[i+1].c0 <= lp.phi) ++i;
+			else break;
+		}
+		T = Y[i];
+		/* first guess, linear interp */
+		t = 5. * (lp.phi - T.c0)/(Y[i+1].c0 - T.c0);
+		/* make into root */
+		T.c0 -= lp.phi;
+		for (;;) { /* Newton-Raphson reduction */
+			t -= t1 = V(T,t) / DV(T,t);
+			if (fabs(t1) < EPS)
+				break;
+		}
+		lp.phi = (5 * i + t) * DEG_TO_RAD;
+		if (xy.y < 0.) lp.phi = -lp.phi;
+		lp.lam /= V(X[i], t);
+	}
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_robin) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_rpoly.c b/proj/pj_rpoly.c
new file mode 100644
index 0000000..7dc4c3e
--- /dev/null
+++ b/proj/pj_rpoly.c
@@ -0,0 +1,37 @@
+/*  Rectangular Polyconic */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_rpoly.c	4.5	93/06/14	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	phi1; \
+	double	fxa; \
+	double	fxb; \
+	int		mode;
+#define EPS	1e-9
+#define PJ_LIB__
+#include	<projects.h>
+FORWARD(s_forward); /* spheroid */
+	double fa;
+
+	if (P->mode)
+		fa = tan(lp.lam * P->fxb) * P->fxa;
+	else
+		fa = 0.5 * lp.lam;
+	if (fabs(lp.phi) < EPS) {
+		xy.x = fa + fa;
+		xy.y = - P->phi0;
+	} else {
+		xy.y = 1. / tan(lp.phi);
+		xy.x = sin(fa = 2. * atan(fa * sin(lp.phi))) * xy.y;
+		xy.y = lp.phi - P->phi0 + (1. - cos(fa)) * xy.y;
+	}
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_rpoly)
+	if ((P->mode = (P->phi1 = fabs(pj_param(P->params, "rlat_ts").f)) > EPS)) {
+		P->fxb = 0.5 * sin(P->phi1);
+		P->fxa = 0.5 / P->fxb;
+	}
+	P->es = 0.; P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_sinu.c b/proj/pj_sinu.c
new file mode 100644
index 0000000..4e196ba
--- /dev/null
+++ b/proj/pj_sinu.c
@@ -0,0 +1,64 @@
+/* Sinusoidal Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_sinu.c	4.4	93/06/13	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	*en;
+#define PJ_LIB__
+#include	<projects.h>
+#define EPS10	1e-10
+FORWARD(e_forward); /* ellipsoid */
+	double s, c;
+
+	xy.y = pj_mlfn(lp.phi, s = sin(lp.phi), c = cos(lp.phi), P->en);
+	xy.x = lp.lam * c / sqrt(1. - P->es * s * s);
+	return (xy);
+}
+FORWARD(s_forward); /* sphere */
+	xy.x = lp.lam * cos(xy.y = lp.phi);
+	return (xy);
+}
+INVERSE(e_inverse); /* ellipsoid */
+	double s;
+
+	if ((s = fabs(lp.phi = pj_inv_mlfn(xy.y, P->es, P->en))) < HALFPI) {
+		s = sin(lp.phi);
+		lp.lam = xy.x * sqrt(1. - P->es * s * s) / cos(lp.phi);
+	} else if ((s - EPS10) < HALFPI)
+		lp.lam = 0.;
+	else I_ERROR;
+	return (lp);
+}
+INVERSE(s_inverse); /* sphere */
+	double s;
+
+	if ((s = fabs(lp.phi = xy.y)) < HALFPI)
+		lp.lam = xy.x / cos(lp.phi);
+	else if ((s - EPS10) < HALFPI)
+		lp.lam = 0.;
+	else I_ERROR;
+	return (lp);
+}
+SPECIAL(spc) {
+	if (!P->es) {
+		fac->der.y_l = 0.;
+		fac->der.y_p = 1.;
+		fac->der.x_l = cos(lp.phi);
+		fac->der.x_p = - lp.lam * sin(lp.phi);
+		fac->code = IS_ANAL_XL_YL + IS_ANAL_XP_YP;
+	}
+}
+FREEUP; if (P) { if (P->en) pj_dalloc(P->en); pj_dalloc(P); } }
+ENTRY0(pj_sinu)
+	if (!(P->en = pj_enfn(P->es)))
+		E_ERROR_0;
+	if (P->es) {
+		P->en = pj_enfn(P->es);
+		P->inv = e_inverse;
+		P->fwd = e_forward;
+	} else {
+		P->inv = s_inverse;
+		P->fwd = s_forward;
+		P->spc = spc;
+	}
+ENDENTRY(P)
diff --git a/proj/pj_stere.c b/proj/pj_stere.c
new file mode 100644
index 0000000..ddf7b32
--- /dev/null
+++ b/proj/pj_stere.c
@@ -0,0 +1,239 @@
+/* Stereographic projection and Universal Polar Stereographic */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_stere.c	4.6	93/11/05	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double phits; \
+	double sinX1; \
+	double cosX1; \
+	double akm1; \
+	int	mode;
+#define PJ_LIB__
+#include	<projects.h>
+#define sinph0	P->sinX1
+#define cosph0	P->cosX1
+#define EPS10	1.e-10
+#define TOL	1.e-8
+#define NITER	8
+#define CONV	1.e-10
+#define S_POLE	0
+#define N_POLE	1
+#define OBLIQ	2
+#define EQUIT	3
+	static double
+ssfn_(double phit, double sinphi, double eccen) {
+	sinphi *= eccen;
+	return (tan (.5 * (HALFPI + phit)) *
+	   pow((1. - sinphi) / (1. + sinphi), .5 * eccen));
+}
+FORWARD(e_forward); /* ellipsoid */
+	double coslam, sinlam, sinX, cosX, X, A, sinphi;
+
+	coslam = cos(lp.lam);
+	sinlam = sin(lp.lam);
+	sinphi = sin(lp.phi);
+	if (P->mode == OBLIQ || P->mode == EQUIT) {
+		sinX = sin(X = 2. * atan(ssfn_(lp.phi, sinphi, P->e)) - HALFPI);
+		cosX = cos(X);
+	}
+	switch (P->mode) {
+	case OBLIQ:
+		A = P->akm1 / (P->cosX1 * (1. + P->sinX1 * sinX +
+		   P->cosX1 * cosX * coslam));
+		xy.y = A * (P->cosX1 * sinX - P->sinX1 * cosX * coslam);
+		goto xmul;
+	case EQUIT:
+		A = 2. * P->akm1 / (1. + cosX * coslam);
+		xy.y = A * sinX;
+xmul:
+		xy.x = A * cosX;
+		break;
+	case S_POLE:
+		lp.phi = -lp.phi;
+		coslam = - coslam;
+		sinphi = -sinphi;
+	case N_POLE:
+		xy.x = P->akm1 * pj_tsfn(lp.phi, sinphi, P->e);
+		xy.y = - xy.x * coslam;
+		break;
+	}
+	xy.x = xy.x * sinlam;
+	return (xy);
+}
+FORWARD(s_forward); /* spheroid */
+	double  sinphi, cosphi, coslam, sinlam;
+
+	sinphi = sin(lp.phi);
+	cosphi = cos(lp.phi);
+	coslam = cos(lp.lam);
+	sinlam = sin(lp.lam);
+	switch (P->mode) {
+	case EQUIT:
+		xy.y = 1. + cosphi * coslam;
+		goto oblcon;
+	case OBLIQ:
+		xy.y = 1. + sinph0 * sinphi + cosph0 * cosphi * coslam;
+oblcon:
+		if (xy.y <= EPS10) F_ERROR;
+		xy.x = (xy.y = P->akm1 / xy.y) * cosphi * sinlam;
+		xy.y *= (P->mode == EQUIT) ? sinphi :
+		   cosph0 * sinphi - sinph0 * cosphi * coslam;
+		break;
+	case N_POLE:
+		coslam = - coslam;
+		lp.phi = - lp.phi;
+	case S_POLE:
+		if (fabs(lp.phi - HALFPI) < TOL) F_ERROR;
+		xy.x = sinlam * ( xy.y = P->akm1 * tan(FORTPI + .5 * lp.phi) );
+		xy.y *= coslam;
+		break;
+	}
+	return (xy);
+}
+INVERSE(e_inverse); /* ellipsoid */
+	double cosphi, sinphi, tp, phi_l, rho, halfe, halfpi;
+	int i;
+
+	rho = hypot(xy.x, xy.y);
+	switch (P->mode) {
+	case OBLIQ:
+	case EQUIT:
+		cosphi = cos( tp = 2. * atan2(rho * P->cosX1 , P->akm1) );
+		sinphi = sin(tp);
+		phi_l = asin(cosphi * P->sinX1 + (xy.y * sinphi * P->cosX1 / rho));
+		tp = tan(.5 * (HALFPI + phi_l));
+		xy.x *= sinphi;
+		xy.y = rho * P->cosX1 * cosphi - xy.y * P->sinX1* sinphi;
+		halfpi = HALFPI;
+		halfe = .5 * P->e;
+		break;
+	case N_POLE:
+		xy.y = -xy.y;
+	case S_POLE:
+		phi_l = HALFPI - 2. * atan(tp = - rho / P->akm1);
+		halfpi = -HALFPI;
+		halfe = -.5 * P->e;
+		break;
+	}
+	for (i = NITER; i--; phi_l = lp.phi) {
+		sinphi = P->e * sin(phi_l);
+		lp.phi = 2. * atan(tp * pow((1.+sinphi)/(1.-sinphi),
+		   halfe)) - halfpi;
+		if (fabs(phi_l - lp.phi) < CONV) {
+			if (P->mode == S_POLE)
+				lp.phi = -lp.phi;
+			lp.lam = (xy.x == 0. && xy.y == 0.) ? 0. : atan2(xy.x, xy.y);
+			return (lp);
+		}
+	}
+	I_ERROR;
+}
+INVERSE(s_inverse); /* spheroid */
+	double  c, rh, sinc, cosc;
+
+	sinc = sin(c = 2. * atan((rh = hypot(xy.x, xy.y)) / P->akm1));
+	cosc = cos(c);
+	lp.lam = 0.;
+	switch (P->mode) {
+	case EQUIT:
+		if (fabs(rh) <= EPS10)
+			lp.phi = 0.;
+		else
+			lp.phi = asin(xy.y * sinc / rh);
+		if (cosc != 0. || xy.x != 0.)
+			lp.lam = atan2(xy.x * sinc, cosc * rh);
+		break;
+	case OBLIQ:
+		if (fabs(rh) <= EPS10)
+			lp.phi = P->phi0;
+		else
+			lp.phi = asin(cosc * sinph0 + xy.y * sinc * cosph0 / rh);
+		if ((c = cosc - sinph0 * sin(lp.phi)) != 0. || xy.x != 0.)
+			lp.lam = atan2(xy.x * sinc * cosph0, c * rh);
+		break;
+	case N_POLE:
+		xy.y = -xy.y;
+	case S_POLE:
+		if (fabs(rh) <= EPS10)
+			lp.phi = P->phi0;
+		else
+			lp.phi = asin(P->mode == S_POLE ? - cosc : cosc);
+		lp.lam = (xy.x == 0. && xy.y == 0.) ? 0. : atan2(xy.x, xy.y);
+		break;
+	}
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+	static PJ *
+setup(PJ *P) { /* general initialization */
+	double t;
+
+	if (fabs((t = fabs(P->phi0)) - HALFPI) < EPS10)
+		P->mode = P->phi0 < 0. ? S_POLE : N_POLE;
+	else
+		P->mode = t > EPS10 ? OBLIQ : EQUIT;
+	P->phits = fabs(P->phits);
+	if (P->es) {
+		double X;
+
+		switch (P->mode) {
+		case N_POLE:
+		case S_POLE:
+			if (fabs(P->phits - HALFPI) < EPS10)
+				P->akm1 = 2. * P->k0 /
+				   sqrt(pow(1+P->e,1+P->e)*pow(1-P->e,1-P->e));
+			else {
+				P->akm1 = cos(P->phits) /
+				   pj_tsfn(P->phits, t = sin(P->phits), P->e);
+				t *= P->e;
+				P->akm1 /= sqrt(1. - t * t);
+			}
+			break;
+		case EQUIT:
+			P->akm1 = 2. * P->k0;
+			break;
+		case OBLIQ:
+			t = sin(P->phi0);
+			X = 2. * atan(ssfn_(P->phi0, t, P->e)) - HALFPI;
+			t *= P->e;
+			P->akm1 = 2. * P->k0 * cos(P->phi0) / sqrt(1. - t * t);
+			P->sinX1 = sin(X);
+			P->cosX1 = cos(X);
+			break;
+		}
+		P->inv = e_inverse;
+		P->fwd = e_forward;
+	} else {
+		switch (P->mode) {
+		case OBLIQ:
+			sinph0 = sin(P->phi0);
+			cosph0 = cos(P->phi0);
+		case EQUIT:
+			P->akm1 = 2. * P->k0;
+			break;
+		case S_POLE:
+		case N_POLE:
+			P->akm1 = fabs(P->phits - HALFPI) >= EPS10 ?
+			   cos(P->phits) / tan(FORTPI - .5 * P->phits) :
+			   2. * P->k0 ;
+			break;
+		}
+		P->inv = s_inverse;
+		P->fwd = s_forward;
+	}
+	return P;
+}
+ENTRY0(pj_stere)
+	P->phits = pj_param(P->params, "tlat_ts").i ?
+		P->phits = pj_param(P->params, "rlat_ts").f : HALFPI;
+ENDENTRY(setup(P))
+ENTRY0(pj_ups)
+	/* International Ellipsoid */
+	P->phi0 = pj_param(P->params, "bsouth").i ? - HALFPI: HALFPI;
+	if (!P->es) E_ERROR(-34);
+	P->k0 = .994;
+	P->x0 = 2000000.;
+	P->y0 = 2000000.;
+	P->phits = HALFPI;
+	P->lam0 = 0.;
+ENDENTRY(setup(P))
diff --git a/proj/pj_strerrno.c b/proj/pj_strerrno.c
new file mode 100644
index 0000000..2ce9c2c
--- /dev/null
+++ b/proj/pj_strerrno.c
@@ -0,0 +1,67 @@
+/* list of projection system pj_errno values */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_strerrno.c	4.7   93/08/25 GIE REL";
+#endif
+#include <errno.h>
+#include <string.h>
+	static char *
+pj_err_list[] = {
+	"no arguments in initialization list",	/*  -1 */
+	"no options found in 'init' file",		/*  -2 */
+	"no colon in init= string",				/*  -3 */
+	"projection not named",					/*  -4 */
+	"unknown projection id",				/*  -5 */
+	"effective eccentricity = 1.",			/*  -6 */
+	"unknown unit conversion id",			/*  -7 */
+	"invalid boolean param argument",		/*  -8 */
+	"unknown elliptical parameter name",	/*  -9 */
+	"reciprocal flattening (1/f) = 0",		/* -10 */
+	"|radius reference latitude| > 90",		/* -11 */
+	"squared eccentricity < 0",				/* -12 */
+	"major axis or radius = 0 or not given",	/* -13 */
+	"latitude or longitude exceeded limits",	/* -14 */
+	"invalid x or y",						/* -15 */
+	"improperly formed DMS value",			/* -16 */
+	"non-convergent inverse meridinal dist",	/* -17 */
+	"non-convergent inverse phi2",			/* -18 */
+	"acos/asin: |arg| >1.+1e-14",			/* -19 */
+	"tolerance condition error",			/* -20 */
+	"conic lat_1 = -lat_2",					/* -21 */
+	"lat_1 >= 90",							/* -22 */
+	"lat_1 = 0",							/* -23 */
+	"lat_ts >= 90",							/* -24 */
+	"no distance between control points",	/* -25 */
+	"projection not selected to be rotated",	/* -26 */
+	"W <= 0 or M <= 0",						/* -27 */
+	"lsat not in 1-5 range",				/* -28 */
+	"path not in range",					/* -29 */
+	"h <= 0",								/* -30 */
+	"k <= 0",								/* -31 */
+	"lat_0 = 0 or 90 or alpha = 90",		/* -32 */
+	"lat_1=lat_2 or lat_1=0 or lat_2=90",	/* -33 */
+	"elliptical usage required",			/* -34 */
+	"invalid UTM zone number",				/* -35 */
+	"arg(s) out of range for Tcheby eval",	/* -36 */
+	"failed to find projection to be rotated",	/* -37 */
+	"failed to load NAD27-83 correction file",  /* -38 */
+};
+	char *
+pj_strerrno(int err) {
+	if (err > 0)
+#ifdef NO_STRERRNO
+		{   static char note[50];
+			sprintf(note,"no system list, errno: %d\n", err);
+			return note;
+		}
+#else
+		return strerror(err);
+#endif
+	else if (err < 0) {
+		err = - err - 1;
+		if (err < (sizeof(pj_err_list) / sizeof(char *)))
+			return(pj_err_list[err]);
+		else
+			return("invalid projection system error number");
+	} else
+		return 0;
+}
diff --git a/proj/pj_tcc.c b/proj/pj_tcc.c
new file mode 100644
index 0000000..361dfda
--- /dev/null
+++ b/proj/pj_tcc.c
@@ -0,0 +1,20 @@
+/* Transverse Central Cylindrical projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_tcc.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double ap;
+#define EPS10 1.e-10
+#define PJ_LIB__
+#include	<projects.h>
+FORWARD(s_forward); /* spheroid */
+	double b, bt;
+
+	b = cos(lp.phi) * sin(lp.lam);
+	if ((bt = 1. - b * b) < EPS10) F_ERROR;
+	xy.x = b / sqrt(bt);
+	xy.y = atan2(tan(lp.phi) , cos(lp.lam));
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_tcc) P->es = 0.; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_tcea.c b/proj/pj_tcea.c
new file mode 100644
index 0000000..f47707a
--- /dev/null
+++ b/proj/pj_tcea.c
@@ -0,0 +1,30 @@
+/*  Transverse Cylindrical Equal Area */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_tcea.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double rk0;
+#define PJ_LIB__
+#include	<projects.h>
+FORWARD(s_forward); /* spheroid */
+	xy.x = P->rk0 * cos(lp.phi) * sin(lp.lam);
+	xy.y = P->k0 * (atan2(tan(lp.phi), cos(lp.lam)) - P->phi0);
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double t;
+
+	xy.y = xy.y * P->rk0 + P->phi0;
+	xy.x *= P->k0;
+	t = sqrt(1. - xy.x * xy.x);
+	lp.phi = asin(t * sin(xy.y));
+	lp.lam = atan2(xy.x, t * cos(xy.y));
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_tcea)
+	P->rk0 = 1 / P->k0;
+	P->inv = s_inverse;
+	P->fwd = s_forward;
+	P->es = 0.;
+ENDENTRY(P)
diff --git a/proj/pj_tmerc.c b/proj/pj_tmerc.c
new file mode 100644
index 0000000..aa4ee30
--- /dev/null
+++ b/proj/pj_tmerc.c
@@ -0,0 +1,163 @@
+/* Transverse Mercator and Universal Transverse Mercator (UTM) */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_tmerc.c	4.4	93/06/12	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	esp; \
+	double	ml0; \
+	double	*en;
+#define PJ_LIB__
+#include	<projects.h>
+#define EPS10	1.e-10
+#define aks0	P->esp
+#define aks5	P->ml0
+#define FC1 1.
+#define FC2 .5
+#define FC3 .16666666666666666666
+#define FC4 .08333333333333333333
+#define FC5 .05
+#define FC6 .03333333333333333333
+#define FC7 .02380952380952380952
+#define FC8 .01785714285714285714
+FORWARD(e_forward); /* ellipse */
+	double al, als, n, cosphi, sinphi, t;
+
+	sinphi = sin(lp.phi); cosphi = cos(lp.phi);
+	t = fabs(cosphi) > 1e-10 ? sinphi/cosphi : 0.;
+	t *= t;
+	al = cosphi * lp.lam;
+	als = al * al;
+	al /= sqrt(1. - P->es * sinphi * sinphi);
+	n = P->esp * cosphi * cosphi;
+	xy.x = P->k0 * al * (FC1 +
+		FC3 * als * (1. - t + n +
+		FC5 * als * (5. + t * (t - 18.) + n * (14. - 58. * t)
+		+ FC7 * als * (61. + t * ( t * (179. - t) - 479. ) )
+		)));
+	xy.y = P->k0 * (pj_mlfn(lp.phi, sinphi, cosphi, P->en) - P->ml0 +
+		sinphi * al * lp.lam * FC2 * ( 1. +
+		FC4 * als * (5. - t + n * (9. + 4. * n) +
+		FC6 * als * (61. + t * (t - 58.) + n * (270. - 330 * t)
+		+ FC8 * als * (1385. + t * ( t * (543. - t) - 3111.) )
+		))));
+	return (xy);
+}
+FORWARD(s_forward); /* sphere */
+	double b, cosphi;
+
+	b = (cosphi = cos(lp.phi)) * sin(lp.lam);
+	if (fabs(fabs(b) - 1.) <= EPS10) F_ERROR;
+	xy.x = aks5 * log((1. + b) / (1. - b));
+	if ((b = fabs( xy.y = cosphi * cos(lp.lam) / sqrt(1. - b * b) )) >= 1.) {
+		if ((b - 1.) > EPS10) F_ERROR
+		else xy.y = 0.;
+	} else
+		xy.y = acos(xy.y);
+	if (lp.phi < 0.) xy.y = -xy.y;
+	xy.y = aks0 * (xy.y - P->phi0);
+	return (xy);
+}
+INVERSE(e_inverse); /* ellipsoid */
+	double n, con, cosphi, d, ds, sinphi, t;
+
+	lp.phi = pj_inv_mlfn(P->ml0 + xy.y / P->k0, P->es, P->en);
+	if (fabs(lp.phi) >= HALFPI) {
+		lp.phi = xy.y < 0. ? -HALFPI : HALFPI;
+		lp.lam = 0.;
+	} else {
+		sinphi = sin(lp.phi);
+		cosphi = cos(lp.phi);
+		t = fabs(cosphi) > 1e-10 ? sinphi/cosphi : 0.;
+		n = P->esp * cosphi * cosphi;
+		d = xy.x * sqrt(con = 1. - P->es * sinphi * sinphi) / P->k0;
+		con *= t;
+		t *= t;
+		ds = d * d;
+		lp.phi -= (con * ds / (1.-P->es)) * FC2 * (1. -
+			ds * FC4 * (5. + t * (3. - 9. *  n) + n * (1. - 4 * n) -
+			ds * FC6 * (61. + t * (90. - 252. * n +
+				45. * t) + 46. * n
+		   - ds * FC8 * (1385. + t * (3633. + t * (4095. + 1574. * t)) )
+			)));
+		lp.lam = d*(FC1 -
+			ds*FC3*( 1. + 2.*t + n -
+			ds*FC5*(5. + t*(28. + 24.*t + 8.*n) + 6.*n
+		   - ds * FC7 * (61. + t * (662. + t * (1320. + 720. * t)) )
+		))) / cosphi;
+	}
+	return (lp);
+}
+INVERSE(s_inverse); /* sphere */
+	double h, g;
+
+	h = exp(xy.x / aks0);
+	g = .5 * (h - 1. / h);
+	h = cos(P->phi0 + xy.y) / aks0;
+	lp.phi = asin(sqrt((1. - h * h) / (1. + g * g)));
+	if (xy.y < 0.) lp.phi = -lp.phi;
+	lp.lam = (g || h) ? atan2(g, h) : 0.;
+	return (lp);
+}
+FREEUP;
+	if (P) {
+		if (P->en)
+			pj_dalloc(P->en);
+		pj_dalloc(P);
+	}
+}
+	static PJ *
+setup(PJ *P) { /* general initialization */
+	if (P->es) {
+		if (!(P->en = pj_enfn(P->es)))
+			E_ERROR_0;
+		P->ml0 = pj_mlfn(P->phi0, sin(P->phi0), cos(P->phi0), P->en);
+		P->esp = P->es / (1. - P->es);
+		P->inv = e_inverse;
+		P->fwd = e_forward;
+	} else {
+		aks0 = P->k0;
+		aks5 = .5 * aks0;
+		P->inv = s_inverse;
+		P->fwd = s_forward;
+	}
+	return P;
+}
+ENTRY1(pj_tmerc, en)
+ENDENTRY(setup(P))
+ENTRY1(pj_utm, en)
+	int zone;
+
+	if (!P->es) E_ERROR(-34);
+	P->y0 = pj_param(P->params, "bsouth").i ? 10000000. : 0.;
+	P->x0 = 500000.;
+	if (pj_param(P->params, "tzone").i) /* zone input ? */
+		if ((zone = pj_param(P->params, "izone").i) > 0 && zone <= 60)
+			--zone;
+		else
+			E_ERROR(-35)
+	else /* nearest central meridian input */
+		if ((zone = (int) floor((adjlon(P->lam0) + PI) * 30. / PI)) < 0)
+			zone = 0;
+		else if (zone >= 60)
+			zone = 59;
+	P->lam0 = (zone + .5) * PI / 30. - PI;
+	P->k0 = 0.9996;
+	P->phi0 = 0.;
+ENDENTRY(setup(P))
+ENTRY1(pj_mtm, en)
+	int zone;
+
+	if (!P->es) E_ERROR(-34);
+	P->y0 = pj_param(P->params,"bsouth").i ? 10000000. : 0.;
+	P->x0 = 304800.;
+	zone = pj_param(P->params,"izone").i;
+	if (zone >= 3 && zone <= 10)
+		zone = 33 + (10 - zone);
+	else {
+		E_ERROR(-35);
+	}
+	P->lam0 = (zone + .5) * PI / 60. - PI;
+	P->k0 = 0.9999;
+	P->phi0 = 0.;
+ENDENTRY(setup(P))
+
diff --git a/proj/pj_tpeqd.c b/proj/pj_tpeqd.c
new file mode 100644
index 0000000..1381ed2
--- /dev/null
+++ b/proj/pj_tpeqd.c
@@ -0,0 +1,78 @@
+/*  Two Point Equidistant Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_tpeqd.c	4.5	93/06/14	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double cp1, sp1, cp2, sp2, ccs, cs, sc, r2z0, z02, dlam2; \
+	double hz0, thz0, rhshz0, ca, sa, lp, lamc;
+#define PJ_LIB__
+#include	<projects.h>
+FORWARD(s_forward); /* sphere */
+	double t, z1, z2, dl1, dl2, sp, cp;
+
+	sp = sin(lp.phi);
+	cp = cos(lp.phi);
+	z1 = aacos(P->sp1 * sp + P->cp1 * cp * cos(dl1 = lp.lam + P->dlam2));
+	z2 = aacos(P->sp2 * sp + P->cp2 * cp * cos(dl2 = lp.lam - P->dlam2));
+	z1 *= z1;
+	z2 *= z2;
+	xy.x = P->r2z0 * (t = z1 - z2);
+	t = P->z02 - t;
+	xy.y = P->r2z0 * asqrt(4. * P->z02 * z2 - t * t);
+	if ((P->ccs * sp - cp * (P->cs * sin(dl1) - P->sc * sin(dl2))) < 0.)
+		xy.y = -xy.y;
+	return xy;
+}
+INVERSE(s_inverse); /* sphere */
+	double cz1, cz2, s, d, cp, sp;
+
+	cz1 = cos(hypot(xy.y, xy.x + P->hz0));
+	cz2 = cos(hypot(xy.y, xy.x - P->hz0));
+	s = cz1 + cz2;
+	d = cz1 - cz2;
+	lp.lam = - atan2(d, (s * P->thz0));
+	lp.phi = aacos(hypot(P->thz0 * s, d) * P->rhshz0);
+	if ( xy.y < 0. )
+		lp.phi = - lp.phi;
+	/* lam--phi now in system relative to P1--P2 base equator */
+	sp = sin(lp.phi);
+	cp = cos(lp.phi);
+	lp.phi = aasin(P->sa * sp + P->ca * cp * (s = cos(lp.lam -= P->lp)));
+	lp.lam = atan2(cp * sin(lp.lam), P->sa * cp * s - P->ca * sp) + P->lamc;
+	return lp;
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_tpeqd)
+	double lam_1, lam_2, phi_1, phi_2, A12, pp;
+
+	/* get control point locations */
+	phi_1 = pj_param(P->params, "rlat_1").f;
+	lam_1 = pj_param(P->params, "rlon_1").f;
+	phi_2 = pj_param(P->params, "rlat_2").f;
+	lam_2 = pj_param(P->params, "rlon_2").f;
+	if (phi_1 == phi_2 && lam_1 == lam_2) E_ERROR(-25);
+	P->lam0 = adjlon(0.5 * (lam_1 + lam_2));
+	P->dlam2 = adjlon(lam_2 - lam_1);
+	P->cp1 = cos(phi_1);
+	P->cp2 = cos(phi_2);
+	P->sp1 = sin(phi_1);
+	P->sp2 = sin(phi_2);
+	P->cs = P->cp1 * P->sp2;
+	P->sc = P->sp1 * P->cp2;
+	P->ccs = P->cp1 * P->cp2 * sin(P->dlam2);
+	P->z02 = aacos(P->sp1 * P->sp2 + P->cp1 * P->cp2 * cos(P->dlam2));
+	P->hz0 = .5 * P->z02;
+	A12 = atan2(P->cp2 * sin(P->dlam2),
+		P->cp1 * P->sp2 - P->sp1 * P->cp2 * cos(P->dlam2));
+	P->ca = cos(pp = aasin(P->cp1 * sin(A12)));
+	P->sa = sin(pp);
+	P->lp = adjlon(atan2(P->cp1 * cos(A12), P->sp1) - P->hz0);
+	P->dlam2 *= .5;
+	P->lamc = HALFPI - atan2(sin(A12) * P->sp1, cos(A12)) - P->dlam2;
+	P->thz0 = tan(P->hz0);
+	P->rhshz0 = .5 / sin(P->hz0);
+	P->r2z0 = 0.5 / P->z02;
+	P->z02 *= P->z02;
+	P->inv = s_inverse; P->fwd = s_forward;
+	P->es = 0.;
+ENDENTRY(P)
diff --git a/proj/pj_tsfn.c b/proj/pj_tsfn.c
new file mode 100644
index 0000000..3c223e0
--- /dev/null
+++ b/proj/pj_tsfn.c
@@ -0,0 +1,12 @@
+/* determine small t */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_tsfn.c	4.3	93/06/12	GIE	REL";
+#endif
+#include <math.h>
+#define HALFPI		1.5707963267948966
+	double
+pj_tsfn(double phi, double sinphi, double e) {
+	sinphi *= e;
+	return (tan (.5 * (HALFPI - phi)) /
+	   pow((1. - sinphi) / (1. + sinphi), .5 * e));
+}
diff --git a/proj/pj_units.c b/proj/pj_units.c
new file mode 100644
index 0000000..a29b3a1
--- /dev/null
+++ b/proj/pj_units.c
@@ -0,0 +1,34 @@
+/* definition of standard cartesian units */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_units.c	4.6	93/06/12	GIE	REL";
+#endif
+#define PJ_UNITS__
+#include <projects.h>
+/* Field 2 that contains the multiplier to convert named units to meters
+** may be expressed by either a simple floating point constant or a
+** numerator/denomenator values (e.g. 1/1000) */
+	struct PJ_UNITS
+pj_units[] = {
+	"km",	"1000.",	"Kilometer",
+	"m",	"1.",		"Meter",
+	"dm",	"1/10",		"Decimeter",
+	"cm",	"1/100",	"Centimeter",
+	"mm",	"1/1000",	"Millimeter",
+	"kmi",	"1852.0",	"International Nautical Mile",
+	"in",	"0.0254",	"International Inch",
+	"ft",	"0.3048",	"International Foot",
+	"yd",	"0.9144",	"International Yard",
+	"mi",	"1609.344",	"International Statute Mile",
+	"fath",	"1.8288",	"International Fathom",
+	"ch",	"20.1168",	"International Chain",
+	"link",	"0.201168",	"International Link",
+	"us-in",	"1./39.37",	"U.S. Surveyor's Inch",
+	"us-ft",	"0.304800609601219",	"U.S. Surveyor's Foot",
+	"us-yd",	"0.914401828803658",	"U.S. Surveyor's Yard",
+	"us-ch",	"20.11684023368047",	"U.S. Surveyor's Chain",
+	"us-mi",	"1609.347218694437",	"U.S. Surveyor's Statute Mile",
+	"ind-yd",	"0.91439523",	"Indian Yard",
+	"ind-ft",	"0.30479841",	"Indian Foot",
+	"ind-ch",	"20.11669506",	"Indian Chain",
+(char *)0, (char *)0, (char *)0
+};
diff --git a/proj/pj_vandg.c b/proj/pj_vandg.c
new file mode 100644
index 0000000..e660d79
--- /dev/null
+++ b/proj/pj_vandg.c
@@ -0,0 +1,81 @@
+/* van der Grinten projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_vandg.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+# include	<projects.h>
+# define TOL		1.e-10
+# define THIRD		.33333333333333333333
+# define TWO_THRD	.66666666666666666666
+# define C2_27		.07407407407407407407
+# define PI4_3		4.18879020478639098458
+# define PISQ		9.86960440108935861869
+# define TPISQ		19.73920880217871723738
+# define HPISQ		4.93480220054467930934
+FORWARD(s_forward); /* spheroid */
+	double  al, al2, g, g2, p2;
+
+	p2 = fabs(lp.phi / HALFPI);
+	if ((p2 - TOL) > 1.) F_ERROR;
+	if (p2 > 1.)
+		p2 = 1.;
+	if (fabs(lp.phi) <= TOL) {
+		xy.x = lp.lam;
+		xy.y = 0.;
+	} else if (fabs(lp.lam) <= TOL || fabs(p2 - 1.) < TOL) {
+		xy.x = 0.;
+		xy.y = PI * tan(.5 * asin(p2));
+		if (lp.phi < 0.) xy.y = -xy.y;
+	} else {
+		al = .5 * fabs(PI / lp.lam - lp.lam / PI);
+		al2 = al * al;
+		g = sqrt(1. - p2 * p2);
+		g = g / (p2 + g - 1.);
+		g2 = g * g;
+		p2 = g * (2. / p2 - 1.);
+		p2 = p2 * p2;
+		xy.x = g - p2; g = p2 + al2;
+		xy.x = PI * (al * xy.x + sqrt(al2 * xy.x * xy.x - g * (g2 - p2))) / g;
+		if (lp.lam < 0.) xy.x = -xy.x;
+		xy.y = fabs(xy.x / PI);
+		xy.y = 1. - xy.y * (xy.y + 2. * al);
+		if (xy.y < -TOL) F_ERROR;
+		if (xy.y < 0.)	xy.y = 0.;
+		else		xy.y = sqrt(xy.y) * (lp.phi < 0. ? -PI : PI);
+	}
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	double t, c0, c1, c2, c3, al, r2, r, m, d, ay, x2, y2;
+
+	x2 = xy.x * xy.x;
+	if ((ay = fabs(xy.y)) < TOL) {
+		lp.phi = 0.;
+		t = x2 * x2 + TPISQ * (x2 + HPISQ);
+		lp.lam = fabs(xy.x) <= TOL ? 0. :
+		   .5 * (x2 - PISQ + sqrt(t)) / xy.x;
+		return (lp);
+	}
+	y2 = xy.y * xy.y;
+	r = x2 + y2;	r2 = r * r;
+	c1 = - PI * ay * (r + PISQ);
+	c3 = r2 + TWOPI * (ay * r + PI * (y2 + PI * (ay + HALFPI)));
+	c2 = c1 + PISQ * (r - 3. *  y2);
+	c0 = PI * ay;
+	c2 /= c3;
+	al = c1 / c3 - THIRD * c2 * c2;
+	m = 2. * sqrt(-THIRD * al);
+	d = C2_27 * c2 * c2 * c2 + (c0 * c0 - THIRD * c2 * c1) / c3;
+	if (((t = fabs(d = 3. * d / (al * m))) - TOL) <= 1.) {
+		d = t > 1. ? (d > 0. ? 0. : PI) : acos(d);
+		lp.phi = PI * (m * cos(d * THIRD + PI4_3) - THIRD * c2);
+		if (xy.y < 0.) lp.phi = -lp.phi;
+		t = r2 + TPISQ * (x2 - y2 + HPISQ);
+		lp.lam = fabs(xy.x) <= TOL ? 0. :
+		   .5 * (r - PISQ + (t <= 0. ? 0. : sqrt(t))) / xy.x;
+	} else
+		I_ERROR;
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_vandg) P->es = 0.; P->inv = s_inverse; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_vandg2.c b/proj/pj_vandg2.c
new file mode 100644
index 0000000..ef8b5d6
--- /dev/null
+++ b/proj/pj_vandg2.c
@@ -0,0 +1,47 @@
+/*  Van der Grinten II Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_vandg2.c	4.4	93/06/14	GIE	REL";
+#endif
+# define TOL	1e-10
+# define TWORPI	0.63661977236758134308
+#define PROJ_PARMS__ \
+	int	vdg3;
+#define PJ_LIB__
+#include	<projects.h>
+FORWARD(s_forward); /* spheroid */
+	double x1, at, bt, ct;
+
+	bt = fabs(TWORPI * lp.phi);
+	if ((ct = 1. - bt * bt) < 0.)
+		ct = 0.;
+	else
+		ct = sqrt(ct);
+	if (fabs(lp.lam) < TOL) {
+		xy.x = 0.;
+		xy.y = PI * (lp.phi < 0. ? -bt : bt) / (1. + ct);
+	} else {
+		at = 0.5 * fabs(PI / lp.lam - lp.lam / PI);
+		if (P->vdg3) {
+			x1 = bt / (1. + ct);
+			xy.x = PI * (sqrt(at * at + 1. - x1 * x1) - at);
+			xy.y = PI * x1;
+		} else {
+			x1 = (ct * sqrt(1. + at * at) - at * ct * ct) /
+				(1. + at * at * bt * bt);
+			xy.x = PI * x1;
+			xy.y = PI * sqrt(1. - x1 * (x1 + 2. * at) + TOL);
+		}
+		if ( lp.lam < 0.) xy.x = -xy.x;
+		if ( lp.phi < 0.) xy.y = -xy.y;
+	}
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_vandg2)
+	P->vdg3 = 0;
+	P->inv = 0; P->fwd = s_forward;
+ENDENTRY(P)
+ENTRY0(pj_vandg3)
+	P->vdg3 = 1;
+	P->es = 0.; P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_vandg4.c b/proj/pj_vandg4.c
new file mode 100644
index 0000000..8e161c4
--- /dev/null
+++ b/proj/pj_vandg4.c
@@ -0,0 +1,44 @@
+/*  Van der Grinten IV Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_vandg4.c	4.5	93/06/16	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define TOL	1e-10
+#define TWORPI	0.63661977236758134308
+FORWARD(s_forward); /* spheroid */
+	double x1, t, bt, ct, ft, bt2, ct2, dt, dt2;
+
+	if (fabs(lp.phi) < TOL) {
+		xy.x = lp.lam;
+		xy.y = 0.;
+	} else if (fabs(lp.lam) < TOL || fabs(fabs(lp.phi) - HALFPI) < TOL) {
+		xy.x = 0.;
+		xy.y = lp.phi;
+	} else {
+		bt = fabs(TWORPI * lp.phi);
+		bt2 = bt * bt;
+		ct = 0.5 * (bt * (8. - bt * (2. + bt2)) - 5.)
+			/ (bt2 * (bt - 1.));
+		ct2 = ct * ct;
+		dt = TWORPI * lp.lam;
+		dt = dt + 1. / dt;
+		dt = sqrt(dt * dt - 4.);
+		if ((fabs(lp.lam) - HALFPI) < 0.) dt = -dt;
+		dt2 = dt * dt;
+		x1 = bt + ct; x1 *= x1;
+		t = bt + 3.*ct;
+		ft = x1 * (bt2 + ct2 * dt2 - 1.) + (1.-bt2) * (
+			bt2 * (t * t + 4. * ct2) +
+			ct2 * (12. * bt * ct + 4. * ct2) );
+		x1 = (dt*(x1 + ct2 - 1.) + 2.*sqrt(ft)) /
+			(4.* x1 + dt2);
+		xy.x = HALFPI * x1;
+		xy.y = HALFPI * sqrt(1. + dt * fabs(x1) - x1 * x1);
+		if (lp.lam < 0.) xy.x = -xy.x;
+		if (lp.phi < 0.) xy.y = -xy.y;
+	}
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_vandg4) P->es = 0.; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_wag7.c b/proj/pj_wag7.c
new file mode 100644
index 0000000..ecffda1
--- /dev/null
+++ b/proj/pj_wag7.c
@@ -0,0 +1,19 @@
+/*  Wagner VII Projection */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_wag7.c	4.4	93/06/14	GIE	REL";
+#endif
+#define PJ_LIB__
+#include	<projects.h>
+#define THIRD	0.3333333333333333333
+FORWARD(s_forward); /* spheroid */
+	double s, c0, c1;
+
+	s = 0.90631 * sin(lp.phi);
+	c0 = sqrt(1. - s * s);
+	c1 = sqrt(2./(1. + c0 * cos(lp.lam *= THIRD)));
+	xy.x = 2.66723 * c0 * c1 * sin(lp.lam);
+	xy.y = 1.24104 * s * c1;
+	return (xy);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_wag7) P->es = 0.; P->fwd = s_forward; ENDENTRY(P)
diff --git a/proj/pj_wink1.c b/proj/pj_wink1.c
new file mode 100644
index 0000000..175a022
--- /dev/null
+++ b/proj/pj_wink1.c
@@ -0,0 +1,23 @@
+/*  Winkel I */
+#ifndef lint
+static const char SCCSID[]="@(#)PJ_wink1.c	4.5	93/06/14	GIE	REL";
+#endif
+#define PROJ_PARMS__ \
+	double	cosphi1;
+#define PJ_LIB__
+# include	<projects.h>
+FORWARD(s_forward); /* spheroid */
+	xy.x = .5 * lp.lam * (P->cosphi1 + cos(lp.phi));
+	xy.y = lp.phi;
+	return (xy);
+}
+INVERSE(s_inverse); /* spheroid */
+	lp.phi = xy.y;
+	lp.lam = 2. * xy.x / (P->cosphi1 + cos(lp.phi));
+	return (lp);
+}
+FREEUP; if (P) pj_dalloc(P); }
+ENTRY0(pj_wink1)
+	P->cosphi1 = cos(pj_param(P->params, "rlat_ts").f);
+	P->es = 0.; P->inv = s_inverse; P->fwd = s_forward;
+ENDENTRY(P)
diff --git a/proj/pj_zpoly1.c b/proj/pj_zpoly1.c
new file mode 100644
index 0000000..80d8546
--- /dev/null
+++ b/proj/pj_zpoly1.c
@@ -0,0 +1,49 @@
+/* evaluate complex polynomial */
+#ifndef lint
+static const char SCCSID[]="@(#)pj_zpoly1.c	4.3	93/06/12	GIE	REL";
+#endif
+#include <projects.h>
+/* note: coefficients are always from C_1 to C_n
+**	i.e. C_0 == (0., 0)
+**	n should always be >= 1 though no checks are made
+*/
+	COMPLEX
+pj_zpoly1(COMPLEX z, COMPLEX *C, int n) {
+	COMPLEX a;
+	double t;
+
+	a = *(C += n);
+	while (n-- > 0) {
+		a.r = (--C)->r + z.r * (t = a.r) - z.i * a.i;
+		a.i = C->i + z.r * a.i + z.i * t;
+	}
+	a.r = z.r * (t = a.r) - z.i * a.i;
+	a.i = z.r * a.i + z.i * t;
+	return a;
+}
+/* evaluate complex polynomial and derivative */
+	COMPLEX
+pj_zpolyd1(COMPLEX z, COMPLEX *C, int n, COMPLEX *der) {
+	COMPLEX a, b;
+	double t;
+	int first = 1;
+
+	a = *(C += n);
+	while (n-- > 0) {
+		if (first) {
+			first = 0;
+			b = a;
+		} else {
+			b.r = a.r + z.r * (t = b.r) - z.i * b.i;
+			b.i = a.i + z.r * b.i + z.i * t;
+		}
+		a.r = (--C)->r + z.r * (t = a.r) - z.i * a.i;
+		a.i = C->i + z.r * a.i + z.i * t;
+	}
+	b.r = a.r + z.r * (t = b.r) - z.i * b.i;
+	b.i = a.i + z.r * b.i + z.i * t;
+	a.r = z.r * (t = a.r) - z.i * a.i;
+	a.i = z.r * a.i + z.i * t;
+	*der = b;
+	return a;
+}
diff --git a/proj/pr_series.c b/proj/pr_series.c
new file mode 100644
index 0000000..27d6e58
--- /dev/null
+++ b/proj/pr_series.c
@@ -0,0 +1,41 @@
+/* print row coefficients of Tseries structure */
+#ifndef lint
+static const char SCCSID[]="@(#)pr_series.c	4.3	93/06/12	GIE	REL";
+#endif
+#include <stdio.h>
+#include <string.h>
+#include <projects.h>
+#define NF 20 /* length of final format string */
+#define CUT 60 /* check length of line */
+	void
+pr_series(Tseries *T, FILE *file, char *fmt) {
+	int i, j, n, L;
+	char format[NF+1] = {" "};
+
+	strncat(format, fmt, NF - 3);
+	strcat(format, "%n");
+	fprintf(file, "u: %d\n", T->mu+1);
+	for (i = 0; i <= T->mu; ++i)
+		if (T->cu[i].m) {
+			fprintf(file, "%d %d%n", i, T->cu[i].m, &L);
+			n = 0;
+			for (j = 0; j < T->cu[i].m; ++j) {
+				if ((L += n) > CUT)
+					fprintf(file, "\n %n", &L);
+				fprintf(file, format, T->cu[i].c[j], &n);
+			}
+			fputc('\n', file);
+		}
+	fprintf(file, "v: %d\n", T->mv+1);
+	for (i = 0; i <= T->mv; ++i)
+		if (T->cv[i].m) {
+			fprintf(file, "%d %d%n", i, T->cv[i].m, &L);
+			n = 0;
+			for (j = 0; j < T->cv[i].m; ++j) {
+				if ((L += n) > 60)
+					fprintf(file, "\n %n", &L);
+				fprintf(file, format, T->cv[i].c[j], &n);
+			}
+			fputc('\n', file);
+		}
+}
diff --git a/proj/proj.c b/proj/proj.c
new file mode 100644
index 0000000..56cf5ad
--- /dev/null
+++ b/proj/proj.c
@@ -0,0 +1,413 @@
+/* <<<< Cartographic projection filter program >>>> */
+#ifndef lint
+static const char SCCSID[]="@(#)proj.c	4.6	93/09/07	GIE	REL";
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <math.h>
+#include "projects.h"
+#include "emess.h"
+
+#define MAX_LINE 200
+#define MAX_PARGS 100
+#define PJ_INVERS(P) (P->inv ? 1 : 0)
+	static PJ
+*Proj;
+	static UV
+(*proj)(UV, PJ *);
+	static int
+reversein = 0,	/* != 0 reverse input arguments */
+reverseout = 0,	/* != 0 reverse output arguments */
+bin_in = 0,	/* != 0 then binary input */
+bin_out = 0,	/* != 0 then binary output */
+echoin = 0,	/* echo input data to output line */
+tag = '#',	/* beginning of line tag character */
+inverse = 0,	/* != 0 then inverse projection */
+prescale = 0,	/* != 0 apply cartesian scale factor */
+dofactors = 0,	/* determine scale factors */
+facs_bad = 0,	/* return condition from pj_factors */
+very_verby = 0, /* very verbose mode */
+postscale = 0;
+	static char
+*cheby_str,		/* string controlling Chebychev evaluation */
+*oform = (char *)0,	/* output format for x-y or decimal degrees */
+*oterr = "*\t*",	/* output line for unprojectable input */
+*usage =
+"REL 4.6 usage: %s [ -beEfiIlormsStTvVwW [args] ] [ +opts[=arg] ] [ files ]\n";
+	static struct FACTORS
+facs;
+	static double
+(*informat)(const char *, char **),	/* input data deformatter function */
+fscale = 0.;	/* cartesian scale factor */
+	static UV
+int_proj(data) UV data; {
+	if (prescale) { data.u *= fscale; data.v *= fscale; }
+	data = (*proj)(data, Proj);
+	if (postscale && data.u != HUGE_VAL)
+		{ data.u *= fscale; data.v *= fscale; }
+	return(data);
+}
+	static void	/* file processing function */
+process(FILE *fid) {
+	char line[MAX_LINE+3], *s, pline[40];
+	UV data;
+
+	for (;;) {
+		++emess_dat.File_line;
+		if (bin_in) {	/* binary input */
+			if (fread(&data, sizeof(UV), 1, fid) != 1)
+				break;
+		} else {	/* ascii input */
+			if (!(s = fgets(line, MAX_LINE, fid)))
+				break;
+			if (!strchr(s, '\n')) { /* overlong line */
+				int c;
+				(void)strcat(s, "\n");
+				/* gobble up to newline */
+				while ((c = fgetc(fid)) != EOF && c != '\n') ;
+			}
+			if (*s == tag) {
+				if (!bin_out)
+					(void)fputs(line, stdout);
+				continue;
+			}
+			if (reversein) {
+				data.v = (*informat)(s, &s);
+				data.u = (*informat)(s, &s);
+			} else {
+				data.u = (*informat)(s, &s);
+				data.v = (*informat)(s, &s);
+			}
+			if (data.v == HUGE_VAL)
+				data.u = HUGE_VAL;
+			if (!*s && (s > line)) --s; /* assumed we gobbled \n */
+			if (!bin_out && echoin) {
+				int t;
+				t = *s;
+				*s = '\0';
+				(void)fputs(line, stdout);
+				*s = t;
+				putchar('\t');
+			}
+		}
+		if (data.u != HUGE_VAL) {
+			if (prescale) { data.u *= fscale; data.v *= fscale; }
+			if (dofactors && !inverse)
+				facs_bad = pj_factors(data, Proj, 0., &facs);
+			data = (*proj)(data, Proj);
+			if (dofactors && inverse)
+				facs_bad = pj_factors(data, Proj, 0., &facs);
+			if (postscale && data.u != HUGE_VAL)
+				{ data.u *= fscale; data.v *= fscale; }
+		}
+		if (bin_out) { /* binary output */
+			(void)fwrite(&data, sizeof(UV), 1, stdout);
+			continue;
+		} else if (data.u == HUGE_VAL) /* error output */
+			(void)fputs(oterr, stdout);
+		else if (inverse && !oform) {	/*ascii DMS output */
+			if (reverseout) {
+				(void)fputs(rtodms(pline, data.v, 'N', 'S'), stdout);
+				putchar('\t');
+				(void)fputs(rtodms(pline, data.u, 'E', 'W'), stdout);
+			} else {
+				(void)fputs(rtodms(pline, data.u, 'E', 'W'), stdout);
+				putchar('\t');
+				(void)fputs(rtodms(pline, data.v, 'N', 'S'), stdout);
+			}
+		} else {	/* x-y or decimal degree ascii output */
+			if (inverse) {
+				data.v *= RAD_TO_DEG;
+				data.u *= RAD_TO_DEG;
+			}
+			if (reverseout) {
+				(void)printf(oform,data.v); putchar('\t');
+				(void)printf(oform,data.u);
+			} else {
+				(void)printf(oform,data.u); putchar('\t');
+				(void)printf(oform,data.v);
+			}
+		}
+		if (dofactors) /* print scale factor data */
+			if (!facs_bad)
+				(void)printf("\t<%g %g %g %g %g %g>",
+					facs.h, facs.k, facs.s,
+					facs.omega * RAD_TO_DEG, facs.a, facs.b);
+			else
+				(void)fputs("\t<* * * * * *>", stdout);
+		(void)fputs(bin_in ? "\n" : s, stdout);
+	}
+}
+	static void	/* file processing function --- verbosely */
+vprocess(FILE *fid) {
+	char line[MAX_LINE+3], *s, pline[40];
+	UV dat_ll, dat_xy;
+	int linvers;
+
+	if (!oform)
+		oform = "%.3f";
+	if (bin_in || bin_out)
+		emess(1,"binary I/O not available in -V option");	
+	for (;;) {
+		++emess_dat.File_line;
+		if (!(s = fgets(line, MAX_LINE, fid)))
+			break;
+		if (!strchr(s, '\n')) { /* overlong line */
+			int c;
+			(void)strcat(s, "\n");
+			/* gobble up to newline */
+			while ((c = fgetc(fid)) != EOF && c != '\n') ;
+		}
+		if (*s == tag) { /* pass on data */
+			(void)fputs(s, stdout);
+			continue;
+		}
+		/* check to override default input mode */
+		if (*s == 'I' || *s == 'i') {
+			linvers = 1;
+			++s;
+		} else if (*s == 'I' || *s == 'i') {
+			linvers = 0;
+			++s;
+		} else
+			linvers = inverse;
+		if (linvers) {
+			if (!PJ_INVERS(Proj)) {
+				emess(-1,"inverse for this projection not avail.\n");
+				continue;
+			}
+			dat_xy.u = strtod(s, &s);
+			dat_xy.v = strtod(s, &s);
+			if (dat_xy.u == HUGE_VAL || dat_xy.v == HUGE_VAL) {
+				emess(-1,"lon-lat input conversion failure\n");
+				continue;
+			}
+			if (prescale) { dat_xy.u *= fscale; dat_xy.v *= fscale; }
+			dat_ll = pj_inv(dat_xy, Proj);
+		} else {
+			dat_ll.u = dmstor(s, &s);
+			dat_ll.v = dmstor(s, &s);
+			if (dat_ll.u == HUGE_VAL || dat_ll.v == HUGE_VAL) {
+				emess(-1,"lon-lat input conversion failure\n");
+				continue;
+			}
+			dat_xy = pj_fwd(dat_ll, Proj);
+			if (postscale) { dat_xy.u *= fscale; dat_xy.v *= fscale; }
+		}
+		if (pj_errno) {
+			emess(-1, pj_strerrno(pj_errno));
+			continue;
+		}
+		if (!*s && (s > line)) --s; /* assumed we gobbled \n */
+		if (pj_factors(dat_ll, Proj, 0., &facs)) {
+			emess(-1,"failed to conpute factors\n\n");
+			continue;
+		}
+		if (*s != '\n')
+			(void)fputs(s, stdout);
+		(void)fputs("Longitude: ", stdout);
+		(void)fputs(rtodms(pline, dat_ll.u, 'E', 'W'), stdout);
+		(void)printf(" [ %.11g ]\n", dat_ll.u * RAD_TO_DEG);
+		(void)fputs("Latitude:  ", stdout);
+		(void)fputs(rtodms(pline, dat_ll.v, 'N', 'S'), stdout);
+		(void)printf(" [ %.11g ]\n", dat_ll.v * RAD_TO_DEG);
+		(void)fputs("Easting (x):   ", stdout);
+		(void)printf(oform, dat_xy.u); putchar('\n');
+		(void)fputs("Northing (y):  ", stdout);
+		(void)printf(oform, dat_xy.v); putchar('\n');
+		(void)printf("Meridian scale (h)%c: %.8f  ( %.4g %% error )\n",
+			facs.code & IS_ANAL_HK ? '*' : ' ', facs.h, (facs.h-1.)*100.);
+		(void)printf("Parallel scale (k)%c: %.8f  ( %.4g %% error )\n",
+			facs.code & IS_ANAL_HK ? '*' : ' ', facs.k, (facs.k-1.)*100.);
+		(void)printf("Areal scale (s):     %.8f  ( %.4g %% error )\n",
+			facs.s, (facs.s-1.)*100.);
+		(void)printf("Angular distortion (w): %.3f\n", facs.omega *
+			RAD_TO_DEG);
+		(void)printf("Meridian/Parallel angle: %.5f\n",
+			facs.thetap * RAD_TO_DEG);
+		(void)printf("Convergence%c: ",facs.code & IS_ANAL_CONV ? '*' : ' ');
+		(void)fputs(rtodms(pline, facs.conv, 0, 0), stdout);
+		(void)printf(" [ %.8f ]\n", facs.conv * RAD_TO_DEG);
+		(void)printf("Max-min (Tissot axis a-b) scale error: %.5f %.5f\n\n",
+			facs.a, facs.b);
+	}
+}
+	void
+main(int argc, char **argv) {
+	char *arg, **eargv = argv, *pargv[MAX_PARGS], **iargv = argv;
+	FILE *fid;
+	int pargc = 0, iargc = argc, eargc = 0, c, mon = 0;
+
+	if (emess_dat.Prog_name = strrchr(*argv,DIR_CHAR))
+		++emess_dat.Prog_name;
+	else emess_dat.Prog_name = *argv;
+	inverse = ! strncmp(emess_dat.Prog_name, "inv", 3);
+	if (argc <= 1 ) {
+		(void)fprintf(stderr, usage, emess_dat.Prog_name);
+		exit (0);
+	}
+		/* process run line arguments */
+	while (--argc > 0) { /* collect run line arguments */
+		if(**++argv == '-') for(arg = *argv;;) {
+			switch(*++arg) {
+			case '\0': /* position of "stdin" */
+				if (arg[-1] == '-') eargv[eargc++] = "-";
+				break;
+			case 'b': /* binary I/O */
+				bin_in = bin_out = 1;
+				continue;
+			case 'v': /* monitor dump of initialization */
+				mon = 1;
+				continue;
+			case 'i': /* input binary */
+				bin_in = 1;
+				continue;
+			case 'o': /* output binary */
+				bin_out = 1;
+				continue;
+			case 'I': /* alt. method to spec inverse */
+				inverse = 1;
+				continue;
+			case 'E': /* echo ascii input to ascii output */
+				echoin = 1;
+				continue;
+			case 'V': /* very verbose processing mode */
+				very_verby = 1;
+				mon = 1;
+			case 'S': /* compute scale factors */
+				dofactors = 1;
+				continue;
+			case 't': /* set col. one char */
+				if (arg[1]) tag = *++arg;
+				else emess(1,"missing -t col. 1 tag");
+				continue;
+			case 'l': /* list projections, ellipses or units */
+				if (!arg[1] || arg[1] == 'p') {
+					struct PJ_LIST *lp;
+					for (lp = pj_list ; lp->id ; ++lp)
+						(void)printf("%9s %s\n", lp->id, lp->name);
+				} else if (arg[1] == 'e') {
+					struct PJ_ELLPS *le;
+
+					for (le = pj_ellps; le->id ; ++le)
+						(void)printf("%9s %-16s %-16s %s\n",
+							le->id, le->major, le->ell, le->name);
+				} else if (arg[1] == 'u') {
+					struct PJ_UNITS *lu;
+
+					for (lu = pj_units; lu->id ; ++lu)
+						(void)printf("%12s %-20s %s\n",
+							lu->id, lu->to_meter, lu->name);
+				} else
+					emess(1,"invalid list option: l%c",arg[1]);
+				emess(1,"-l[p|e|u] terminates program");
+				continue; /* artificial */
+			case 'e': /* error line alternative */
+				if (--argc <= 0)
+noargument:			   emess(1,"missing argument for -%c",*arg);
+				oterr = *++argv;
+				continue;
+			case 'T': /* generate Chebyshev coefficients */
+				if (--argc <= 0) goto noargument;
+				cheby_str = *++argv;
+				continue;
+			case 'm': /* cartesian multiplier */
+				if (--argc <= 0) goto noargument;
+				postscale = 1;
+				if (!strncmp("1/",*++argv,2) || 
+				    !strncmp("1:",*argv,2)) {
+					if((fscale = atof((*argv)+2)) == 0.)
+						goto badscale;
+					fscale = 1. / fscale;
+				} else
+					if ((fscale = atof(*argv)) == 0.) {
+badscale:
+					      emess(1,"invalid scale argument");
+					}
+				continue;
+			case 'W': /* specify seconds precision */
+			case 'w': /* -W for constant field width */
+				if ((c = arg[1]) != 0 && isdigit(c)) {
+					set_rtodms(c - '0', *arg == 'W');
+					++arg;
+				} else
+				    emess(1,"-W argument missing or non-digit");
+				continue;
+			case 'f': /* alternate output format degrees or xy */
+				if (--argc <= 0) goto noargument;
+				oform = *++argv;
+				continue;
+			case 'r': /* reverse input */
+				reversein = 1;
+				continue;
+			case 's': /* reverse output */
+				reverseout = 1;
+				continue;
+			default:
+				emess(1, "invalid option: -%c",*arg);
+				break;
+			}
+			break;
+		} else if (**argv == '+') { /* + argument */
+			if (pargc < MAX_PARGS)
+				pargv[pargc++] = *argv + 1;
+			else
+				emess(1,"overflowed + argument table");
+		} else /* assumed to be input file name(s) */
+			eargv[eargc++] = *argv;
+	}
+	if (eargc == 0 && !cheby_str) /* if no specific files force sysin */
+		eargv[eargc++] = "-";
+	else if (eargc > 0 && cheby_str) /* warning */
+		emess(4, "data files when generating Chebychev prohibited");
+	/* done with parameter and control input */
+	if (inverse && postscale) {
+		prescale = 1;
+		postscale = 0;
+		fscale = 1./fscale;
+	}
+	if (!(Proj = pj_init(pargc, pargv)))
+		emess(3,"projection initialization failure\ncause: %s",
+			pj_strerrno(pj_errno));
+	if (inverse) {
+		if (!Proj->inv)
+			emess(3,"inverse projection not available");
+		proj = pj_inv;
+	} else
+		proj = pj_fwd;
+	if (cheby_str)
+		exit(gen_cheby(inverse, int_proj, cheby_str, Proj, iargc, iargv));
+	/* set input formating control */
+	if (mon)
+		pj_pr_list(Proj);
+	if (inverse)
+		informat = strtod;
+	else {
+		informat = dmstor;
+		if (!oform)
+			oform = "%.2f";
+	}
+	/* process input file list */
+	for ( ; eargc-- ; ++eargv) {
+		if (**eargv == '-') {
+			fid = stdin;
+			emess_dat.File_name = "<stdin>";
+		} else {
+			if ((fid = fopen(*eargv, "r")) == NULL) {
+				emess(-2, *eargv, "input file");
+				continue;
+			}
+			emess_dat.File_name = *eargv;
+		}
+		emess_dat.File_line = 0;
+		if (very_verby)
+			vprocess(fid);
+		else
+			process(fid);
+		(void)fclose(fid);
+		emess_dat.File_name = 0;
+	}
+	exit(0); /* normal completion */
+}
diff --git a/proj/proj.def b/proj/proj.def
new file mode 100644
index 0000000..b069140
--- /dev/null
+++ b/proj/proj.def
@@ -0,0 +1,17 @@
+LIBRARY   PROJ
+
+CODE      PRELOAD MOVEABLE DISCARDABLE
+DATA      PRELOAD SINGLE
+
+EXPORTS
+	pj_free
+	pj_init
+	pj_inv
+	pj_fwd
+        rtodms
+        set_rtodms
+	nad_cvt
+	nad_init
+	nad_free
+
+
diff --git a/proj/projects.h b/proj/projects.h
new file mode 100644
index 0000000..ad82057
--- /dev/null
+++ b/proj/projects.h
@@ -0,0 +1,216 @@
+/* General projections header file */
+#ifndef PROJECTS_H
+#define PROJECTS_H
+
+#ifndef lint
+static const char PROJECTS_H_ID[] = "@(#)projects.h	4.7	93/08/20	GIE	REL";
+#endif
+    /* standard inclusions */
+#include <math.h>
+#include <stdlib.h>
+	/* prototype hypot for systems where absent */
+#ifndef _WINDOWS
+extern double hypot(double, double);
+#endif
+	/* some useful constants */
+#define HALFPI		1.5707963267948966
+#define FORTPI		0.78539816339744833
+#ifndef PI
+#define PI		3.14159265358979323846
+#endif
+#define TWOPI		6.2831853071795864769
+#define RAD_TO_DEG	57.29577951308232
+#define DEG_TO_RAD	.0174532925199432958
+
+/* environment parameter name */
+#ifndef PROJ_LIB
+#define PROJ_LIB "PROJ_LIB"
+#endif
+/* maximum tag id length for +init and default files */
+#ifndef ID_TAG_MAX
+#define ID_TAG_MAX 50
+#endif
+
+/* directory delimiter for DOS support */
+#ifdef DOS
+#define DIR_CHAR '\\'
+#else
+#define DIR_CHAR '/'
+#endif
+
+typedef struct { double u, v; }	UV;
+typedef struct { double r, i; }	COMPLEX;
+
+#ifndef PJ_LIB__
+#define XY UV
+#define LP UV
+#else
+typedef struct { double x, y; }     XY;
+typedef struct { double lam, phi; } LP;
+#endif
+
+	extern int		/* global error return code */
+pj_errno;
+
+typedef union { double  f; int  i; char *s; } PROJVALUE;
+
+struct PJ_LIST {
+	char	*id;		/* projection keyword */
+	void	*(*proj)();	/* projection entry point */
+	char	*name;		/* basic projection full name */
+};
+struct PJ_ELLPS {
+	char	*id;	/* ellipse keyword name */
+	char	*major;	/* a= value */
+	char	*ell;	/* elliptical parameter */
+	char	*name;	/* comments */
+};
+struct PJ_UNITS {
+	char	*id;	/* units keyword */
+	char	*to_meter;	/* multiply by value to get meters */
+	char	*name;	/* comments */
+};
+struct FACTORS {
+	struct DERIVS {
+		double x_l, x_p; /* derivatives of x for lambda-phi */
+		double y_l, y_p; /* derivatives of y for lambda-phi */
+	} der;
+	double h, k;	/* meridinal, parallel scales */
+	double omega, thetap;	/* angular distortion, theta prime */
+	double conv;	/* convergence */
+	double s;		/* areal scale factor */
+	double a, b;	/* max-min scale error */
+	int code;		/* info as to analytics, see following */
+};
+#define IS_ANAL_XL_YL 01	/* derivatives of lon analytic */
+#define IS_ANAL_XP_YP 02	/* derivatives of lat analytic */
+#define IS_ANAL_HK	04		/* h and k analytic */
+#define IS_ANAL_CONV 010	/* convergence analytic */
+    /* parameter list struct */
+typedef struct ARG_list {
+	struct ARG_list *next;
+	char used;
+	char param[1]; } paralist;
+	/* base projection data structure */
+typedef struct PJconsts {
+	XY  (*fwd)(LP, struct PJconsts *);
+	LP  (*inv)(XY, struct PJconsts *);
+	void (*spc)(LP, struct PJconsts *, struct FACTORS *);
+	void (*pfree)(struct PJconsts *);
+	paralist *params;   /* parameter list */
+	int over;   /* over-range flag */
+	int geoc;   /* geocentric latitude flag */
+	double
+		a,  /* major axis or radius if es==0 */
+		e,  /* eccentricity */
+		es, /* e ^ 2 */
+		ra, /* 1/A */
+		one_es, /* 1 - e^2 */
+		rone_es, /* 1/one_es */
+		lam0, phi0, /* central longitude, latitude */
+		x0, y0, /* easting and northing */
+		k0,	/* general scaling factor */
+		to_meter, fr_meter; /* cartesian scaling */
+#ifdef PROJ_PARMS__
+PROJ_PARMS__
+#endif /* end of optional extensions */
+} PJ;
+
+#ifndef PJ_LIST__
+extern struct PJ_LIST pj_list[];
+#endif
+
+#ifndef PJ_ELLPS__
+extern struct PJ_ELLPS pj_ellps[];
+#endif
+
+#ifndef PJ_UNITS__
+extern struct PJ_UNITS pj_units[];
+#endif
+
+#ifdef PJ_LIB__
+    /* repeatative projection code */
+#define ENTRYA(name) PJ *name(PJ *P) { if (!P) { \
+	if (P = pj_malloc(sizeof(PJ))) { \
+	P->pfree = freeup; P->fwd = 0; P->inv = 0; P->spc = 0;
+#define ENTRYX } return P; } else {
+#define ENTRY0(name) ENTRYA(name) ENTRYX
+#define ENTRY1(name, a) ENTRYA(name) P->a = 0; ENTRYX
+#define ENTRY2(name, a, b) ENTRYA(name) P->a = 0; P->b = 0; ENTRYX
+#define ENDENTRY(p) } return (p); }
+#define E_ERROR(err) { pj_errno = err; freeup(P); return(0); }
+#define E_ERROR_0 { freeup(P); return(0); }
+#define F_ERROR { pj_errno = -20; return(xy); }
+#define I_ERROR { pj_errno = -20; return(lp); }
+#define FORWARD(name) static XY name(LP lp, PJ *P) { XY xy
+#define INVERSE(name) static LP name(XY xy, PJ *P) { LP lp
+#define FREEUP static void freeup(PJ *P) {
+#define SPECIAL(name) static void name(LP lp, PJ *P, struct FACTORS *fac)
+#endif
+#define MAX_TAB_ID 80
+typedef struct { float lam, phi; } FLP;
+typedef struct { int lam, phi; } ILP;
+struct CTABLE {
+	char id[MAX_TAB_ID]; /* ascii info */
+	LP ll;      /* lower left corner coordinates */
+	LP del;     /* size of cells */
+	ILP lim;    /* limits of conversion matrix */
+	FLP *cvs;   /* conversion matrix */
+};
+	/* procedure prototypes */
+double  dmstor(const char *, char **);
+void set_rtodms(int, int);
+char *rtodms(char *, double, int, int);
+double adjlon(double);
+double aacos(double), aasin(double), asqrt(double);
+PROJVALUE pj_param(paralist *, char *);
+paralist *pj_mkparam(char *);
+int pj_ell_set(paralist *, double *, double *);
+double *pj_enfn(double);
+double pj_mlfn(double, double, double, double *);
+double pj_inv_mlfn(double, double, double *);
+double pj_qsfn(double, double, double);
+double pj_tsfn(double, double, double);
+double pj_msfn(double, double, double);
+double pj_phi2(double, double);
+double pj_qsfn_(double, PJ *);
+double *pj_authset(double);
+double pj_authlat(double, double *);
+COMPLEX pj_zpoly1(COMPLEX, COMPLEX *, int);
+COMPLEX pj_zpolyd1(COMPLEX, COMPLEX *, int, COMPLEX *);
+int pj_deriv(LP, double, PJ *, struct DERIVS *);
+int pj_factors(LP, PJ *, double, struct FACTORS *);
+XY pj_fwd(LP, PJ *);
+LP pj_inv(XY, PJ *);
+void pj_pr_list(PJ *);
+void pj_free(PJ *);
+PJ *pj_init(int, char **);
+void *pj_malloc(size_t);
+void pj_dalloc(void *);
+char *pj_strerrno(int);
+/* Approximation structures and procedures */
+typedef struct {	/* Chebyshev or Power series structure */
+	UV a, b;		/* power series range for evaluation */
+					/* or Chebyshev argument shift/scaling */
+	struct PW_COEF {/* row coefficient structure */
+		int m;		/* number of c coefficients (=0 for none) */
+		double *c;	/* power coefficients */
+	} *cu, *cv;
+	int mu, mv;		/* maximum cu and cv index (+1 for count) */
+	int power;		/* != 0 if power series, else Chebyshev */
+} Tseries;
+Tseries *mk_cheby(UV, UV, double, UV *, UV (*)(UV), int, int, int);
+UV bpseval(UV, Tseries *);
+UV bcheval(UV, Tseries *);
+UV biveval(UV, Tseries *);
+void *vector1(int, int);
+void **vector2(int, int, int);
+int bchgen(UV, UV, int, int, UV **, UV(*)(UV));
+int bch2bps(UV a, UV b, UV **, int, int);
+/* nadcon related protos */
+LP nad_interp(LP, struct CTABLE *);
+LP nad_cvt(LP, int, struct CTABLE *);
+struct CTABLE *nad_init(char *);
+void nad_free(struct CTABLE *);
+
+#endif /* end of basic projections header */
diff --git a/proj/readme b/proj/readme
new file mode 100644
index 0000000..9e39177
--- /dev/null
+++ b/proj/readme
@@ -0,0 +1,80 @@
+             Installation README --- @(#)README	4.2 93/03/11 GIE REL"
+
+At the current time, installation only performed to PROJ.4 directory and
+information not transfered via normal "install(1)" function because of
+the diversity of system variations.
+
+There are occasional errors encountered with "ranlib."  Makefile tests
+for presence in either /bin or /usr/bin and will execute.  Even if found,
+some systems choke.  Such choking is ignored with no apparent ill results.
+
+As an alternative to editing the head of the Makefile, the following can
+be used on the run line:
+
+For Suns without vendor ANSI C compiler, use GNU's gcc and
+	make install CC=gcc COMP='-O -DFILENAME_MAX=1024 -DNO_STRERRNO'
+Apparently the name max is missing from gcc includes and the Sun
+library does not include the ANSI strerrno function.
+
+For DEC Ultrix: (brain damaged strtod implementation)
+	make install STRTOD='$L(strtod.o)'
+The DEC people just can't seem to forget the dinosaur FORTRAN.
+Ignore compiler warnings about "unimplemented const."
+
+For Silicon Graphics, use
+	make install COMP='-O -common'
+The cause for this is the global pj_errno in projects.h.  This may be
+hitting a ISO standards since SGI seems the most POSIX/ANSI compliant
+system encountered (along with Dell).  Leaving -common out causes
+a lot of warnings by ar.  Needs research.
+
+For Dell SVR4 issue 2.2 do
+	make install
+
+For Data General:
+	make install COMP='-O -ansi'
+Ranlib in system but execution denied(?)---error ignored.
+
+If repeatative compilations or linkages are expected, it is better
+to edit these flags into the beginning of the Makefile after saving
+a copy of the original.
+
+Check /usr/include/math.h for prototype of hypot.  If missing it is
+probably not in libm.a and it is necessary to use supplied version.
+
+	make install HYPOT='$L(hypot.o)'
+		or
+	make install HYPOT='$L(hypot.o)' STRTOD='$L(strtod.o)'
+
+To check for brain damaged versions of strtod try the following after
+using the local system's version (default):
+
+proj +proj=poly +ellps=clrk66 +no_defs <<EOF
+3.5 33.25
+3d30 33d15
+EOF
+
+Both geographic coordinates should produce the same cartesian result.
+If not, then it is almost a certainty that libc.a has a version modified
+to accept d | D as an alternative to e | E.  This "extension" to ANSI
+specifications causes untold grief.  Use the ANSI compliant GNU version
+included.
+
+The default installation library is set at /usr/local/lib even though
+actual transfer of files not made.  To set to an alternative library
+use LIB=<library path> on the make run-line or edit Makefile.
+
+To truely install:
+
+	BIN=<favorite executable area?
+	LIB=<basic library area, same as in Makefile's>
+	INC=<include file area>
+	cp proj $BIN
+	ln ${BIN}/proj ${BIN}/invproj
+	cp geod $BIN
+	cp proj_def.dat $LIB/proj
+	cp libproj.a $LIB
+	cp projects.h $INC
+	cd ../nad
+	cp nad27 $LIB/proj
+	cp nad83 $LIB/proj
diff --git a/proj/rtodms.c b/proj/rtodms.c
new file mode 100644
index 0000000..8d9f210
--- /dev/null
+++ b/proj/rtodms.c
@@ -0,0 +1,74 @@
+/* Convert radian argument to DMS ascii format */
+#ifndef lint
+static const char SCCSID[]="@(#)rtodms.c	4.3	93/06/12	GIE	REL";
+#endif
+#include <projects.h>
+#include <stdio.h>
+#include <string.h>
+/*
+** RES is fractional second figures
+** RES60 = 60 * RES
+** CONV = 180 * 3600 * RES / PI (radians to RES seconds)
+*/
+	static double
+RES = 1000.,
+RES60 = 60000.,
+CONV = 206264806.24709635515796003417;
+	static char
+format[50] = "%dd%d'%.3f\"%c";
+	static int
+dolong = 0;
+	void
+set_rtodms(int fract, int con_w) {
+	int i;
+
+	if (fract >= 0 && fract < 9 ) {
+		RES = 1.;
+		/* following not very elegant, but used infrequently */
+		for (i = 0; i < fract; ++i)
+			RES *= 10.;
+		RES60 = RES * 60.;
+		CONV = 180. * 3600. * RES / PI;
+		if (! con_w)
+			(void)sprintf(format,"%%dd%%d'%%.%df\"%%c", fract);
+		else
+			(void)sprintf(format,"%%dd%%02d'%%0%d.%df\"%%c",
+				fract+2+(fract?1:0), fract);
+		dolong = con_w;
+	}
+}
+	char *
+rtodms(char *s, double r, int pos, int neg) {
+	int deg, min, sign;
+	char *ss = s;
+	double sec;
+
+	if (r < 0) {
+		r = -r;
+		if  (!pos) { *ss++ = '-'; sign = 0; }
+		else sign = neg;
+	} else
+		sign = pos;
+	r = floor(r * CONV + .5);
+	sec = fmod(r / RES, 60.);
+	r = floor(r / RES60);
+	min = fmod(r, 60.);
+	deg = r / 60.;
+	if (dolong)
+		sprintf(ss,format,deg,min,sec,sign);
+	else if (sec) {
+		char *p, *q;
+
+		sprintf(ss,format,deg,min,sec,sign);
+		for (q = p = ss + strlen(ss) - (sign ? 3 : 2); *p == '0'; --p) ;
+		if (*p != '.')
+			++p;
+		if (++q != p)
+			(void)strcpy(p, q);
+	} else if (min)
+		sprintf(ss,"%dd%d'%c",deg,min,sign);
+	else
+		sprintf(ss,"%dd%c",deg, sign);
+	return s;
+}
+
diff --git a/proj/strtod.c b/proj/strtod.c
new file mode 100644
index 0000000..08368d0
--- /dev/null
+++ b/proj/strtod.c
@@ -0,0 +1,149 @@
+#ifndef lint
+static const char SCCSID[]="@(#)strtod.c	4.4	93/06/12	GIE	REL";
+#endif
+/* THIS CODE HAS BEEN MODIFIED from the distribution made by the FSF.
+** However, "licensing" and header information are retained.
+*/
+/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+
+The GNU C Library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public License as
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.  */
+
+#include <errno.h>
+#include <float.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+/* Convert NPTR to a double.  If ENDPTR is not NULL, a pointer to the
+   character after the last one used in the number is put in *ENDPTR.  */
+#ifdef DOS
+typedef int wchar_t;
+#define NULL 0
+#endif
+	double
+strtod(const char *nptr, char **endptr) {
+	const char *s;
+	short int	sign;
+	/* The number so far.  */
+	double	num;
+	int	got_dot;		/* Found a decimal point.  */
+	int	got_digit;	/* Seen any digits.  */
+	/* The exponent of the number.  */
+	long int	exponent;
+
+	if (nptr == NULL) {
+		errno = EINVAL;
+		goto noconv;
+	}
+	s = nptr;
+	/* Eat whitespace.  */
+	while (isspace(*s))
+		++s;
+	/* Get the sign.  */
+	sign = *s == '-' ? -1 : 1;
+	if (*s == '-' || *s == '+')
+		++s;
+	num = 0.0;
+	got_dot = 0;
+	got_digit = 0;
+	exponent = 0;
+	for (; ; ++s) {
+		if (isdigit (*s)) {
+			got_digit = 1;
+			/* Make sure that multiplication by 10 will not overflow.  */
+			if (num > DBL_MAX * 0.1)
+				/* The value of the digit doesn't matter, since we have already
+			       gotten as many digits as can be represented in a `double'.
+			       This doesn't necessarily mean the result will overflow.
+			       The exponent may reduce it to within range.
+
+			       We just need to record that there was another
+			       digit so that we can multiply by 10 later.  */
+				++exponent;
+				else
+				num = (num * 10.0) + (*s - '0');
+			/* Keep track of the number of digits after the decimal point.
+			     If we just divided by 10 here, we would lose precision.  */
+			if (got_dot)
+				--exponent;
+		} else if (!got_dot && (wchar_t) * s == '.')
+			/* Record that we have found the decimal point.  */
+			got_dot = 1;
+			else
+			/* Any other character terminates the number.  */
+			break;
+	}
+	if (!got_digit)
+		goto noconv;
+	if (tolower(*s) == 'e') {
+		/* Get the exponent specified after the `e' or `E'.  */
+		int	save = errno;
+		char	*end;
+		long int	exp;
+
+		errno = 0;
+		++s;
+		exp = strtol(s, &end, 10);
+		if (errno == ERANGE) {
+			/* The exponent overflowed a `long int'.  It is probably a safe
+		     assumption that an exponent that cannot be represented by
+		     a `long int' exceeds the limits of a `double'.  */
+			if (endptr != NULL)
+				*endptr = end;
+			if (exp < 0)
+				goto underflow;
+				else
+				goto overflow;
+		} else if (end == s)
+			/* There was no exponent.  Reset END to point to
+				   the 'e' or 'E', so *ENDPTR will be set there.  */
+			end = (char *) s - 1;
+		errno = save;
+		s = end;
+		exponent += exp;
+	}
+	if (endptr != NULL)
+		*endptr = (char *) s;
+	if (num == 0.0)
+		return 0.0;
+	/* Multiply NUM by 10 to the EXPONENT power,
+	   checking for overflow and underflow.  */
+	if (exponent < 0) {
+		if (num < DBL_MIN * pow(10.0, (double) -exponent))
+			goto underflow;
+	} else if (exponent > 0) {
+		if (num > DBL_MAX * pow(10.0, (double) -exponent))
+			goto overflow;
+	}
+	num *= pow(10.0, (double) exponent);
+	return num * sign;
+overflow:
+	/* Return an overflow error.  */
+	errno = ERANGE;
+	return HUGE_VAL * sign;
+underflow:
+	/* Return an underflow error.  */
+	if (endptr != NULL)
+		*endptr = (char *) nptr;
+	errno = ERANGE;
+	return 0.0;
+noconv:
+	/* There was no number.  */
+	if (endptr != NULL)
+		*endptr = (char *) nptr;
+	return 0.0;
+}
diff --git a/proj/vector1.c b/proj/vector1.c
new file mode 100644
index 0000000..468b127
--- /dev/null
+++ b/proj/vector1.c
@@ -0,0 +1,29 @@
+/* make storage for one and two dimensional matricies */
+#ifndef lint
+static const char SCCSID[]="@(#)vector1.c	4.3	93/06/12	GIE	REL";
+#endif
+#include <stdlib.h>
+#include <projects.h>
+	void * /* one dimension array */
+vector1(int hi, int size) { return((void *)pj_malloc(size * (hi + 1))); }
+	void ** /* two dimension array */
+vector2(int uhi, int vhi, int size) {
+	char **s;
+	int nu, nv;
+
+	nu = uhi + 1;
+	nv = vhi + 1;
+	if (s = (char **)pj_malloc(sizeof(void *) * nu + size * nv * nu)) {
+		char *t;
+		char **r;
+		int i;
+
+		t = (char *)(s + nu);
+		r = s;
+		for (i = 0; i < nu; ++i) {
+			*r++ = t;
+			t += nv * size;
+		}
+	}
+	return ((void **)s);
+}
diff --git a/vpflib/include/machine.h b/vpflib/include/machine.h
index b3edc8d..808522d 100644
--- a/vpflib/include/machine.h
+++ b/vpflib/include/machine.h
@@ -31,7 +31,10 @@ typedef struct
 
 #ifndef __INT32DEF__
 #define __INT32DEF__
-#ifdef _ALPHA
+#ifdef _MSC_VER
+typedef signed int int32;
+typedef unsigned int uint32;
+#elif defined(_ALPHA)
 typedef int32_t int32;
 typedef uint32_t uint32;
 #else
diff --git a/vpflib/makefile b/vpflib/makefile
index b3fc68b..e2451f9 100644
--- a/vpflib/makefile
+++ b/vpflib/makefile
@@ -35,6 +35,10 @@ CFLAGS 	= $(INCLUDES) $(COMMON_CFLAGS) $(UNIX_DEFINE) \
 
 include $(TOPDIR)/config/common.mak
 
+ifeq ($(HAVE_ICONV),yes)
+CFLAGS := $(CFLAGS) -DHAVE_ICONV
+endif
+
 all: MKOBJECTDIR 
 	$(MAKE) --directory $(OBJDIR) -f ../makefile PASS='depend' $(TARGETGEN)
 
diff --git a/vpflib/musedir.h b/vpflib/musedir.h
index 2717cd9..3439da0 100644
--- a/vpflib/musedir.h
+++ b/vpflib/musedir.h
@@ -67,11 +67,7 @@ ERRSTATUS dir_current();
 ERRSTATUS file_spec_to_string ();
 FILE *muse_file_open ();
 int muse_access ();
-#ifdef _ALPHA
-int32_t muse_filelength ();
-#else
-int32_t muse_filelength ();
-#endif
+int muse_filelength ();
 void muse_check_path ();
 #endif
 
diff --git a/vpflib/vpfdproj.c b/vpflib/vpfdproj.c
index 1a8d5a9..e0047e7 100644
--- a/vpflib/vpfdproj.c
+++ b/vpflib/vpfdproj.c
@@ -70,6 +70,7 @@ vpf_projection_type proj;
    vpf_projection_type dummy;
    NOREF (code);
    NOREF (extent);
+   memset(&dummy, 0, sizeof(dummy));
    return (dummy);
    }
 
@@ -81,6 +82,7 @@ vpf_projection_type proj;
 
    {
    vpf_projection_type dummy;
+   memset(&dummy, 0, sizeof(dummy));
    return (dummy);
    }
 
@@ -92,6 +94,7 @@ vpf_projection_type proj;
 
    {
    vpf_projection_type dummy;
+   memset(&dummy, 0, sizeof(dummy));
    return (dummy);
    }
 
diff --git a/vpflib/vpfquery.c b/vpflib/vpfquery.c
index a4cbf15..de470cb 100644
--- a/vpflib/vpfquery.c
+++ b/vpflib/vpfquery.c
@@ -295,13 +295,13 @@ int32 *token_value;
    {
    register int32 i, stopflag;
 
-   *token_type = (int32)NULL;
+   *token_type = 0;
 
    /* Test for no expression (NULL) */
-   if (*expression == (int32)NULL)
+   if (*expression == '\0')
       {
       *token_type = FINISHED;
-      *token_value = (int32)NULL;
+      *token_value = 0;
       return expression;
       }
 
@@ -336,10 +336,10 @@ int32 *token_value;
    return_token (expression, token);
    expression += strlen(token);
 
-   if (*token == (int32)NULL)
+   if (*token == '\0')
       {
       *token_type = FINISHED;
-      *expression = (int32)NULL;
+      *expression = '\0';
       return expression;
       }
 
@@ -386,7 +386,7 @@ See http://sourceforge.net/bugs/?func=detailbug&bug_id=122597&group_id=11181
          token[i] = *expression;
          i++;
          expression++;
-         if (*expression == (int32)NULL)
+         if (*expression == '\0')
             {
             *token_type = ERRORTOKEN;
             *token_value = ERRORTOKEN;
@@ -427,7 +427,7 @@ See http://sourceforge.net/bugs/?func=detailbug&bug_id=122597&group_id=11181
       }
 
    *token_type = VALUE;
-   *token_value = (int32)NULL;
+   *token_value = '\0';
 
    return expression;
    }
diff --git a/vpflib/vpfread.c b/vpflib/vpfread.c
index a128f5a..9c19e6f 100644
--- a/vpflib/vpfread.c
+++ b/vpflib/vpfread.c
@@ -58,7 +58,9 @@
 #include <dos.h>
 #endif
 
+#ifdef HAVE_ICONV
 #include <iconv.h>
+#endif
 
 #ifdef _UNIX
 #include <sys/stat.h>
@@ -403,14 +405,14 @@ vpf_table_type table;
            printf ("\nindex_length: error reading index.") ;
 #endif
 
-           len = (int32)NULL ;
+           len = 0 ;
          }
 
          if ( ! Read_Vpf_Int(&ulen,table.xfp,1) ) {
 #if 0
            printf ("\nindex_length: error reading index.");
 #endif
-           return (int32)NULL ;
+           return 0 ;
          }
          len = ulen;
          break;
@@ -422,7 +424,7 @@ vpf_table_type table;
            /* Just an error check, should never get here in writing */
            xvt_note ("index_length: error trying to access row %d",
                    (int) row_number ) ;
-           len = (int32)NULL;
+           len = 0;
         }
         break;
    }
@@ -485,12 +487,18 @@ vpf_table_type table;
 #endif
 {
    int32 recsize;
-   uint32 pos = (uint32) NULL;   /* Intergraph solution TR#GX323 */
+   uint32 pos = 0;   /* Intergraph solution TR#GX323 */
 
    STORAGE_BYTE_ORDER = table.byte_order;
 
-   if (row_number < 1) row_number = 1;
-   if (row_number > table.nrows) row_number = table.nrows;
+   /* ERO: previously clamped row_number to [1, table.nrows] but does not */
+   /* seam to be sane, especially if table.nrows = 0 */
+   if (row_number < 1 || row_number > table.nrows)
+   {
+     xvt_note ("index_pos: error trying to access row %d/%d in table %s\n",
+                   (int) row_number, table.nrows, table.path ) ;
+     return 0;
+   }
 
    switch (table.xstorage) {
       case COMPUTE:
@@ -503,7 +511,7 @@ vpf_table_type table;
 #if 0
            printf ("\nindex_length: error reading index.");
 #endif
-           pos = (int32)NULL ;
+           pos = 0 ;
          }
          break;
       case RAM:
@@ -512,9 +520,9 @@ vpf_table_type table;
       default:
          if ( table.mode == Write && table.nrows != row_number ) {
            /* Just an error check, should never get here in writing */
-           xvt_note ("index_length: error trying to access row %d",
+           xvt_note ("index_pos: error trying to access row %d",
                    (int) row_number ) ;
-           pos = (int32)NULL;
+           pos = 0;
          }
          break;
    }
@@ -760,6 +768,7 @@ vpf_table_type table;
   row_type row;
   id_triplet_type * keys;
   coordinate_type dummycoord;
+  int32 id = -1;
 
   if (feof(table.fp))
     {
@@ -769,6 +778,11 @@ vpf_table_type table;
   STORAGE_BYTE_ORDER = table.byte_order;
 
   row = (row_type)xvt_zmalloc (((size_t)table.nfields+1) * sizeof(column_type));
+  if( row == NULL )
+  {
+      xvt_note ("Out of memory in read_next_row()\n");
+      return NULL;
+  }
 
   for (i=0;i<table.nfields;i++) row[i].ptr = NULL;
 
@@ -780,6 +794,14 @@ vpf_table_type table;
 	  Read_Vpf_Int (&count, table.fp, 1);
 
 	  if ((unsigned int) count > 2000000) {
+            char szMessage[256];
+            if( strlen(table.path) < 128 )
+                sprintf(szMessage, "Repeat count for field %d of record %d of table %s is %d\n",
+                        i, id, table.path, (unsigned int)count);
+            else
+                sprintf(szMessage, "Repeat count for field %d of record %d of table %s is %d\n",
+                        i, id, table.path + strlen(table.path) - 128, (unsigned int)count);
+            xvt_note ("%s", szMessage);
 	    free_row ( row, table ) ;
 	    return (row_type) NULL;
 	  }	 
@@ -796,38 +818,83 @@ vpf_table_type table;
       case 'L':
 	if (count == 1) {
 	  row[i].ptr = (char *)xvt_zmalloc(sizeof(char));
+          if( row[i].ptr == NULL )
+          {
+              xvt_note ("Out of memory in read_next_row()\n");
+              free_row ( row, table ) ;
+              return (row_type) NULL;
+          }
 	  Read_Vpf_Char(row[i].ptr, table.fp, 1) ;
 	} else {
 	  size = count*sizeof(char);
 	  row[i].ptr = (char*) xvt_zmalloc((size_t)size+2);
 	  tptr = (char*)xvt_zmalloc ((size_t)size+2);
+          if( row[i].ptr == NULL || tptr == NULL )
+          {
+              xvt_note ("Out of memory in read_next_row()\n");
+              xvt_free(tptr);
+              free_row ( row, table ) ;
+              return (row_type) NULL;
+          }
 	  Read_Vpf_Char(tptr,table.fp,count) ;
 	  tptr[count] = '\0';
 	  strcpy(row[i].ptr,tptr);
-	  if(tptr != (char *)NULL)
-	    {xvt_free(tptr);tptr = (char *)NULL;}
+	  xvt_free(tptr);
+          tptr = (char *)NULL;
 	}
 	break;
       case 'I':
 	row[i].ptr = (int32*)xvt_zmalloc((size_t)count * sizeof (int32));
-	Read_Vpf_Int (row[i].ptr, table.fp, count ) ;
+	if( row[i].ptr == NULL )
+        {
+            xvt_note ("Out of memory in read_next_row()\n");
+            free_row ( row, table ) ;
+            return (row_type) NULL;
+        }
+        Read_Vpf_Int (row[i].ptr, table.fp, count ) ;
+        if( i == 0 && count == 1 )
+            id = ((int32*)row[i].ptr)[0];
 	break;
       case 'S':
 	row[i].ptr = (short*)xvt_zmalloc ((size_t)count * sizeof (short));
-	Read_Vpf_Short (row[i].ptr, table.fp, count ) ;
+	if( row[i].ptr == NULL )
+        {
+            xvt_note ("Out of memory in read_next_row()\n");
+            free_row ( row, table ) ;
+            return (row_type) NULL;
+        }
+        Read_Vpf_Short (row[i].ptr, table.fp, count ) ;
 	break;
       case 'F':
 	row[i].ptr = (float*)xvt_zmalloc ((size_t)count * sizeof (float));
-	Read_Vpf_Float (row[i].ptr, table.fp, count ) ;
+	if( row[i].ptr == NULL )
+        {
+            xvt_note ("Out of memory in read_next_row()\n");
+            free_row ( row, table ) ;
+            return (row_type) NULL;
+        }
+        Read_Vpf_Float (row[i].ptr, table.fp, count ) ;
 	break;
       case 'R':
 	row[i].ptr = (double*)xvt_zmalloc ((size_t)count * sizeof (double));
-	Read_Vpf_Double (row[i].ptr, table.fp, count ) ;
+	if( row[i].ptr == NULL )
+        {
+            xvt_note ("Out of memory in read_next_row()\n");
+            free_row ( row, table ) ;
+            return (row_type) NULL;
+        }
+        Read_Vpf_Double (row[i].ptr, table.fp, count ) ;
 	break;
       case 'D':
 	row[i].ptr = (date_type*)xvt_zmalloc ((size_t)count *
 					      sizeof (date_type));
-	Read_Vpf_Date (row[i].ptr, table.fp, count ) ;
+	if( row[i].ptr == NULL )
+        {
+            xvt_note ("Out of memory in read_next_row()\n");
+            free_row ( row, table ) ;
+            return (row_type) NULL;
+        }
+        Read_Vpf_Date (row[i].ptr, table.fp, count ) ;
 	break;
       case 'C':
 	/* Coordinate strings may be quite large.          */
@@ -836,7 +903,13 @@ vpf_table_type table;
 	/* coordinate at a time in higher level functions. */
 	row[i].ptr = (coordinate_type*)xvt_zmalloc ((size_t)count *
 						    sizeof(coordinate_type));
-	if (row[i].ptr)
+	if( row[i].ptr == NULL )
+        {
+            xvt_note ("Out of memory in read_next_row()\n");
+            free_row ( row, table ) ;
+            return (row_type) NULL;
+        }
+        if (row[i].ptr)
 	  Read_Vpf_Coordinate(row[i].ptr,table.fp,count);
 	else
 	  for (j=0;j<count;j++)
@@ -845,16 +918,34 @@ vpf_table_type table;
       case 'Z':
 	row[i].ptr = (tri_coordinate_type*)xvt_zmalloc ((size_t)count *
 							sizeof (tri_coordinate_type));
+        if( row[i].ptr == NULL )
+        {
+            xvt_note ("Out of memory in read_next_row()\n");
+            free_row ( row, table ) ;
+            return (row_type) NULL;
+        }
 	Read_Vpf_CoordinateZ(row[i].ptr,table.fp,count);
 	break;
       case 'B':
 	row[i].ptr = (double_coordinate_type*)xvt_zmalloc ((size_t)count *
 							   sizeof (double_coordinate_type));
-	Read_Vpf_DoubleCoordinate(row[i].ptr,table.fp,count);
+	if( row[i].ptr == NULL )
+        {
+            xvt_note ("Out of memory in read_next_row()\n");
+            free_row ( row, table ) ;
+            return (row_type) NULL;
+        }
+        Read_Vpf_DoubleCoordinate(row[i].ptr,table.fp,count);
 	break;
       case 'Y':
 	row[i].ptr = (double_tri_coordinate_type*)xvt_zmalloc ((size_t)count *
 							       sizeof (double_tri_coordinate_type));
+        if( row[i].ptr == NULL )
+        {
+            xvt_note ("Out of memory in read_next_row()\n");
+            free_row ( row, table ) ;
+            return (row_type) NULL;
+        }
 	Read_Vpf_DoubleCoordinateZ(row[i].ptr,table.fp,count);
 	break;
       case 'K':   /* ID Triplet */
@@ -862,13 +953,20 @@ vpf_table_type table;
                                                     sizeof (id_triplet_type));
 	keys = (id_triplet_type*)xvt_zmalloc ((size_t)count *
 					      sizeof (id_triplet_type));
+        if( row[i].ptr == NULL || keys == NULL )
+        {
+            xvt_note ("Out of memory in read_next_row()\n");
+            xvt_free ((char*)keys);
+            free_row ( row, table ) ;
+            return (row_type) NULL;
+        }
 	for (j=0;j<count;j++) {
 	  keys[j] = read_key(table);
 	}
 	memcpy (row[i].ptr, keys, (size_t)count *
 		sizeof(id_triplet_type));
-	if(keys != (id_triplet_type*)NULL)
-	  {xvt_free ((char*)keys);keys = (id_triplet_type*)NULL;}
+	xvt_free ((char*)keys);
+        keys = (id_triplet_type*)NULL;
 	break;
       case 'X':
 	row[i].ptr = NULL;
@@ -1374,6 +1472,7 @@ int32  *count;
    int32   col;
    char     * tptr;
    void     * retvalue;
+#ifdef HAVE_ICONV
    static int do_iconv = -1;
    static iconv_t iconvd = (iconv_t)-1;
 
@@ -1385,6 +1484,7 @@ int32  *count;
        iconvd = iconv_open("UTF-8", "ISO-8859-1");
      }
    }
+#endif
 
    retvalue = NULL;
    col = field_number;
@@ -1425,6 +1525,9 @@ int32  *count;
                 break;
               }
             }
+#ifndef HAVE_ICONV
+            strcpy((char *)retvalue,tptr);
+#else
             if (ascii == 1 || iconvd == (iconv_t)-1)
               strcpy((char *)retvalue,tptr);
             else
@@ -1448,6 +1551,7 @@ int32  *count;
                 //fprintf(stderr, "UTF-8 text : '%s'\n", (char*)retvalue);
               }
             }
+#endif
             if(tptr != (char *)NULL)
               {xvt_free(tptr);tptr = (char *)NULL;}
          }
diff --git a/vpflib/vpfrelat.c b/vpflib/vpfrelat.c
index ccaf871..da6ab43 100644
--- a/vpflib/vpfrelat.c
+++ b/vpflib/vpfrelat.c
@@ -340,13 +340,10 @@ int32 tile_id;
    short int sval;
    row_type row;
    int32 KEY2_,TILE_;
-   char cval, *tval, path[255], *keystring, dir_separator[2];
+   char cval, *tval, path[255], *keystring;
    set_type idxset, tileset, searchset;
    id_triplet_type idtrip;
 
-   dir_separator[0] = DIR_SEPARATOR;
-   dir_separator[1] = '\0';
-
    if (strcmp(key2,"ID")==0) {
       memcpy( &rowid, keyval1, sizeof(rowid) );
       return rowid;
@@ -560,12 +557,9 @@ int32 tile_id;
    short short_tile, sval;
    row_type row;
    int32 KEY2_, TILE_;
-   char cval, *tval, path[255], *keystring, dir_separator[2];
+   char cval, *tval, path[255], *keystring;
    id_triplet_type idtrip = {' ',0,0,0};
 
-   dir_separator[0] = DIR_SEPARATOR;
-   dir_separator[1] = '\0';
-
    rowlist = ll_init ();
 
    if (strcmp (key2, "ID") == 0)
diff --git a/vpflib/vpftable.c b/vpflib/vpftable.c
index 9875189..522c84b 100644
--- a/vpflib/vpftable.c
+++ b/vpflib/vpftable.c
@@ -394,7 +394,7 @@ int32 parse_data_def (vpf_table_type *table)
       if (ddlen < 0)
 	{
 	  xvt_note ("parse_data_def: Bad VPF file.");
-	  return ((int32)NULL);
+	  return (0);
 	}
 
       /* header without first 4 bytes */
@@ -404,7 +404,7 @@ int32 parse_data_def (vpf_table_type *table)
       if (buf == NULL)
 	{
 	  xvt_note ("Parse_data_definition: malloc failed.");
-	  return ((int32)NULL);
+	  return (0);
 	}
 
       buf[0] = byte;		/* already have the first byte of the buffer */
@@ -419,7 +419,7 @@ int32 parse_data_def (vpf_table_type *table)
       if (buf == NULL)
 	{
 	  xvt_note ("Parse_data_definition: Malloc failed.");
-	  return ((int32)NULL);
+	  return (0);
 	}
 
       strncpy (buf, table->defstr, (size_t)ddlen);
@@ -478,7 +478,7 @@ int32 parse_data_def (vpf_table_type *table)
   if (table->header == NULL)
     {
       xvt_note ("Parse_data_definition: malloc failed.");
-      return ((int32)NULL);
+      return (0);
     }
 
   /* Loop the the number of fields in the record */
@@ -494,7 +494,7 @@ int32 parse_data_def (vpf_table_type *table)
 	    (strcmp (table->header[0].name, "id") != 0))
           {
 	    xvt_note ("parse_data_def: No 'ID' in header definition.");
-	    return ((int32)NULL);
+	    return (0);
           }
 
       /* Get the "type" field */
@@ -596,7 +596,7 @@ int32 parse_data_def (vpf_table_type *table)
         } /* switch type */
 
       if (status)
-        return ((int32)NULL);
+        return (0);
 
       /* Get "keytype" field */
       table->header[i].keytype  = parse_get_char (&p, buf);
@@ -1001,6 +1001,13 @@ vpf_table_type vpf_open_table (char *tablename, storage_type storage,
 	{
 	  Read_Vpf_Int (&(table.nrows), table.xfp, 1L);
 	  Read_Vpf_Int (&ulval, table.xfp, 1L);
+          if( (unsigned int)table.nrows > 100 * 1024 * 1024 )
+          {
+            xvt_note ("vpf_open_table: <%s> : table.nrows = %d\n",tablepath, table.nrows);
+            fclose(table.xfp);
+            table.nrows = 0;
+            return table;
+          }
 	  idxsize = table.nrows * sizeof (index_cell) + 10L;
 
 	  /* Load the index into RAM */
diff --git a/vpflib/vpftidx.c b/vpflib/vpftidx.c
index 7f83ea9..98f246d 100644
--- a/vpflib/vpftidx.c
+++ b/vpflib/vpftidx.c
@@ -577,10 +577,9 @@ char *idx_set;
   d[loc].num_items = 0 ; }
 
 #define INCR_ID(loc,id) { \
-  int rtrn; \
-  rtrn = fwrite(&loc,sizeof(int32),1,tmpfp); \
+  UNUSED_RET(fwrite(&loc,sizeof(int32),1,tmpfp)); \
   j = d[loc].num_items; \
-  rtrn = fwrite(&j,sizeof(int32),1,tmpfp); \
+  UNUSED_RET(fwrite(&j,sizeof(int32),1,tmpfp)); \
   d[loc].num_items++ ; \
   if (d[loc].num_items == 1) \
     d[loc].start_offset = id; \
@@ -881,9 +880,8 @@ char *idx_set;
   qsort ((void*)d, (size_t)h.nbins, sizeof(ThematicIndexDirectory), bincmp);
 
   for ( j=1; j <= table.nrows; j++ ) {
-     int result;
-     result = fread(&bin,sizeof(bin),1,tmpfp);
-     result = fread(&binoff,sizeof(binoff),1,tmpfp);
+     UNUSED_RET(fread(&bin,sizeof(bin),1,tmpfp));
+     UNUSED_RET(fread(&binoff,sizeof(binoff),1,tmpfp));
      if (d[bin].num_items == 1) continue;
      if ( h.id_data_type == 'I' ) {
 	fseek(ifp, d[bin].start_offset + (binoff*sizeof(int32)), 0);
@@ -2427,9 +2425,9 @@ FILE *ifp;
   if ( ! Read_Vpf_Char ( &h->vpf_table_name, ifp, 12 ) )
     RWhimper() ;
   h->vpf_table_name[12] = '\0';
-  if ( ! Read_Vpf_Char ( &h->vpf_column_name, ifp, 25 ) )
+  if ( ! Read_Vpf_Char ( &h->vpf_column_name, ifp, 24 ) )
     RWhimper() ;
-  h->vpf_column_name[25] = '\0';
+  h->vpf_column_name[24] = '\0';
   if ( ! Read_Vpf_Char ( &h->sort, ifp, 1 ) )
     RWhimper() ;
   h->sort = (char)toupper(h->sort);
diff --git a/vpflib/xvt.h b/vpflib/xvt.h
index ff3d67a..40b2b63 100644
--- a/vpflib/xvt.h
+++ b/vpflib/xvt.h
@@ -47,3 +47,4 @@ extern  void G_warning (char *msg);
 #define BOOLEAN unsigned char
 /* typedef unsigned char BOOLEAN; */
 
+#define UNUSED_RET(x) do { if(x) {} } while(0)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/ogdi-dfsg.git



More information about the Pkg-grass-devel mailing list