]> Pileus Git - ~andy/fetchmail/commitdiff
Merge branch 'legacy_63'
authorMatthias Andree <matthias.andree@gmx.de>
Wed, 5 Sep 2012 00:53:54 +0000 (02:53 +0200)
committerMatthias Andree <matthias.andree@gmx.de>
Wed, 5 Sep 2012 00:53:54 +0000 (02:53 +0200)
Conflicts:
Makefile.am
NEWS
conf.c
configure.ac
contrib/rawlog.patch
fetchmail-SA-2011-01.txt
fetchmail.man
fm_md5.h
kerberos.c
socket.c
socket.h

134 files changed:
.gitignore
Doxyfile
INSTALL
Makefile.am
NEWS
README
README.PWMD [new file with mode: 0644]
TODO-7.0 [new file with mode: 0644]
TODO.txt
berlios3116.patch [new file with mode: 0644]
checkalias.c
conf.c
configure.ac
contrib/README
contrib/debian_rc [deleted file]
contrib/delete-later [deleted file]
contrib/delete-later.README [deleted file]
contrib/domino [deleted file]
contrib/fetchmail-mode.el
contrib/fetchmaildistrib [deleted file]
contrib/fetchmailnochda.pl [deleted file]
contrib/fetchsetup [deleted file]
contrib/fetchspool [deleted file]
contrib/getfetchmail [deleted file]
contrib/getfetchmail.pl [deleted file]
contrib/multidrop [deleted file]
contrib/poptest [deleted file]
contrib/preauth-harness [deleted file]
contrib/rawlog.patch
contrib/redhat_rc [deleted file]
contrib/sm-hybrid [deleted file]
contrib/start_dynamic_ppp [deleted file]
contrib/toprocmail [deleted file]
contrib/zsh-completion [deleted file]
cram.c
daemon.c
design-notes.html
driver.c
env.c
esrs-design-notes.html
etrn.c
fetchmail-FAQ.html
fetchmail-features.html
fetchmail.c
fetchmail.h
fetchmail.man
fetchmailconf.py
fm_getaddrinfo.c
fm_md5.h
genlsm.sh.in
getpass.c
gettext.h [new file with mode: 0644]
gssapi.c
i18n.h [deleted file]
idle.c
idlist.c
imap.c
interface.c
kerberos.c [deleted file]
kerberos.h
libesmtp/gethostbyname.c
libesmtp/gethostbyname.h
lock.c
lock.h
md5c.c
md5ify.c
memmove.c [deleted file]
mx.h [deleted file]
mxget.c [deleted file]
netrc.c
netrc.h
ntlmsubr.c
odmr.c
opie.c
options.c
po/POTFILES.in
pop2.c [deleted file]
pop3.c
rcfile_l.l
rcfile_y.y
report.c
rfc822.c
rpa.c
servport.c
sink.c
smbencrypt.c
smtp.c
socket.c
socket.h
specgen.sh
strcasecmp.c [deleted file]
strlcat.c
strlcpy.c
strstr.c [deleted file]
tls.c
transact.c
trio/CHANGES [deleted file]
trio/FILES [deleted file]
trio/Makefile.in [deleted file]
trio/README [deleted file]
trio/autogen.sh [deleted file]
trio/compare.c [deleted file]
trio/configure.in [deleted file]
trio/doc/doc.h [deleted file]
trio/doc/doc_dynamic.h [deleted file]
trio/doc/doc_nan.h [deleted file]
trio/doc/doc_printf.h [deleted file]
trio/doc/doc_register.h [deleted file]
trio/doc/doc_scanf.h [deleted file]
trio/doc/doc_static.h [deleted file]
trio/doc/footer.html [deleted file]
trio/doc/header.html [deleted file]
trio/doc/trio.cfg [deleted file]
trio/doc/trio.css [deleted file]
trio/example.c [deleted file]
trio/install-sh [deleted file]
trio/maketgz [deleted file]
trio/regression.c [deleted file]
trio/strio.h [deleted file]
trio/trio.c [deleted file]
trio/trio.h [deleted file]
trio/triodef.h [deleted file]
trio/trionan.c [deleted file]
trio/trionan.h [deleted file]
trio/triop.h [deleted file]
trio/triostr.c [deleted file]
trio/triostr.h [deleted file]
ucs/norm_charmap.c
uid.c
uid_db.c [new file with mode: 0644]
uid_db.h [new file with mode: 0644]
unmime.c
xmalloc.c
xmalloc.h

index 53f325d71059de77cd4073d3fbf5e45a98ce0841..a3b2417822280daa25843f3fbc324770e18e456e 100644 (file)
@@ -1,14 +1,10 @@
-*.o
 *~
-.autotools
-.cproject
-.deps/
-.project
-.rsyncs
+\#*#
 ABOUT-NLS
 aclocal.m4
 autobuild/
 autom4te.cache
+.autotools
 build*
 build*/
 compile
@@ -22,18 +18,22 @@ config.status
 config.sub
 configure
 configure.lineno
+.cproject
 cscope.out
 depcomp
+.deps/
 dox/
 FAQ
 FEATURES
 fetchmail
-fetchmail-*.tar.*
+fetchmailconf
 fetchmail-FAQ.pdf
 fetchmail-man.html
 fetchmail.spec
-fetchmailconf
+fetchmail-*.tar.*
+fetchmail-*.tar.xz
 genlsm.sh
+IMAPCapa
 install-sh
 libfm.a
 m4/
@@ -45,9 +45,12 @@ mkinstalldirs
 mxget
 netrc
 NOTES
+*.o
 po/Makefile
 po/POTFILES
+po/remove-potcdate.sed
 po/stamp-po
+.project
 py-compile
 rcfile_l.c
 rcfile_y.c
@@ -55,10 +58,10 @@ rcfile_y.h
 rfc2047e
 rfc822
 rfc822valid
+.rsyncs
 stamp-h1
 tags
 TODO
 unmime
 x509_name_match
 ylwrap
-\#*#
index 8fddc867c1ad619e13ed1846e3779f0f3056cc76..2f2422b53eea635c17b871c9d0edefca08aaff84 100644 (file)
--- a/Doxyfile
+++ b/Doxyfile
@@ -1293,8 +1293,7 @@ SEARCH_INCLUDES        = YES
 
 INCLUDE_PATH           = /usr/include \
                         /usr/include/lsb3 \
-                         build \
-                         trio
+                         build
 
 # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
 # patterns (like *.h and *.hpp) to filter out the header-files in the 
diff --git a/INSTALL b/INSTALL
index a0b7520420def7e0cf14f1164f75a5883940e205..b361a921a3ded9a8a221d5cc4ba1fe5acea13341 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -15,6 +15,9 @@ distribution, answers the most common questions about configuring and
 running fetchmail.
 ---------------------------------------------------------------------
 
+NOTE  This is an alpha version that has not been thoroughly tested!
+=====
+
 
 1. PREPARATIONS: USEFUL THINGS TO INSTALL FIRST
 
@@ -82,11 +85,6 @@ The configure script accepts certain standard configuration options.
 These include --prefix, --exec-prefix, --bindir, --infodir, --mandir,
 and --srcdir.  Do 'configure --help' for more.
 
-POP2 support is no longer compiled in by default, as POP2 is way obsolete
-and there don't seem to be any live servers for it anymore.  You can
-configure it back in if you want with 'configure --enable-POP2', but
-leaving it out cuts the executable's size slightly.
-
 Support for CompuServe's RPA authentication method (rather similar to
 APOP) is available but also not included in the standard build.  You
 can compile it in with 'configure --enable-RPA'.
index 6f247daec90fa12bb11c033fc3093b857003b4a6..42fd08900c31ea88563046b69f6a97b5571a5ec0 100644 (file)
@@ -1,7 +1,7 @@
 # Makefile for fetchmail
 
 SUBDIRS=               . po
-AUTOMAKE_OPTIONS=      1.11 foreign no-dist-gzip dist-bzip2 dist-xz
+AUTOMAKE_OPTIONS=      1.11 foreign no-dist-gzip dist-xz
 
 AM_CPPFLAGS=           -I$(srcdir)/libesmtp
 ACLOCAL_AMFLAGS=       -I m4 -I m4-local
@@ -16,6 +16,12 @@ dist_man1_MANS=              fetchmail.man
 pys=                   fetchmailconf.py
 pym=                   fetchmailconf.man
 
+if HAVE_LIBPWMD
+CFLAGS += @libpwmd_CFLAGS@
+LDFLAGS += @libpwmd_LIBS@
+endif
+
+if HAVE_PYTHON
 nodist_bin_SCRIPTS=    fetchmailconf
 python_PYTHON=         $(pys)
 dist_man1_MANS+=       $(pym)
@@ -47,32 +53,18 @@ check_PROGRAMS=
 TESTS=                 t.smoke t.validate-xhtml10 t.validate-xhtml t.x509_name_match
 TESTS_ENVIRONMENT=     srcdir="$(srcdir)" LC_ALL=C TZ=UTC SHELL="$(SHELL)" $(SHELL)
 
-if NEED_TRIO
-noinst_LIBRARIES+=     libtrio.a
-libtrio_a_SOURCES=     trio/triostr.c trio/trio.c trio/trionan.c \
-                       trio/trio.h trio/triop.h trio/triodef.h \
-                       trio/trionan.h trio/triostr.h
-check_PROGRAMS+=       regression
-regression_SOURCES=    trio/regression.c
-LDADD+=                        libtrio.a -lm
-TESTS+=                        t.regression
-endif
-
 fetchmail_SOURCES=     fetchmail.h getopt.h \
-               i18n.h kerberos.h fm_md5.h mx.h netrc.h smtp.h \
+               gettext.h kerberos.h fm_md5.h netrc.h smtp.h \
                socket.h tunable.h \
                socket.c getpass.c \
                fetchmail.c env.c idle.c options.c daemon.c \
                driver.c transact.c sink.c smtp.c \
-               idlist.c uid.c mxget.c md5ify.c cram.c gssapi.c \
+               idlist.c uid.c md5ify.c cram.c gssapi.c \
                opie.c interface.c netrc.c \
-               unmime.c conf.c checkalias.c \
+               unmime.c conf.c checkalias.c uid_db.h uid_db.c\
                lock.h lock.c \
                rcfile_l.l rcfile_y.y \
                ucs/norm_charmap.c ucs/norm_charmap.h
-if POP2_ENABLE
-fetchmail_SOURCES += pop2.c
-endif
 if POP3_ENABLE
 fetchmail_SOURCES += pop3.c
 endif
@@ -85,9 +77,6 @@ endif
 if ODMR_ENABLE
 fetchmail_SOURCES += odmr.c
 endif
-if KERBEROS_V4_ENABLE
-fetchmail_SOURCES += kerberos.c
-endif
 if RPA_ENABLE
 fetchmail_SOURCES += rpa.c
 endif
@@ -98,7 +87,7 @@ if NEED_GETADDRINFO
 fetchmail_SOURCES += libesmtp/getaddrinfo.h libesmtp/getaddrinfo.c
 endif
 
-check_PROGRAMS +=      rfc822 unmime netrc rfc2047e mxget rfc822valid \
+check_PROGRAMS +=      rfc822 unmime netrc rfc2047e rfc822valid \
                        x509_name_match
 
 rfc2047e_CFLAGS=       -DTEST
@@ -115,9 +104,6 @@ unmime_CFLAGS=      -DSTANDALONE -DHAVE_CONFIG_H -I$(builddir)
 netrc_SOURCES= netrc.c xmalloc.c report.c
 netrc_CFLAGS=  -DSTANDALONE -DHAVE_CONFIG_H -I$(builddir)
 
-mxget_SOURCES= mxget.c
-mxget_CFLAGS=  -DSTANDALONE -DHAVE_CONFIG_H -I$(builddir)
-
 @SET_MAKE@
 
 fetchmail.spec: Makefile.in specgen.sh
@@ -151,7 +137,6 @@ distdirs = rh-config contrib beos
 
 EXTRA_DIST=    $(DISTDOCS) $(distdirs) \
                fetchmail.spec fetchmail.xpm \
-               trio/CHANGES trio/README \
                strlcpy.3 bighand.png \
                m4/codeset.m4 \
                m4/gettext.m4 \
diff --git a/NEWS b/NEWS
index a0705cd8c223a9183a69889d87c4bb5b492ff8bf..a10dd50a0dbab4c0e8ed8ca7aa88e03ac9710523 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -10,18 +10,11 @@ change.  MA = Matthias Andree, ESR = Eric S. Raymond, RF = Rob Funk.)
 
 # ADVANCE WARNING OF FEATURES TO BE REMOVED OR CHANGED IN FUTURE VERSIONS
 (There are no plans to remove features from a 6.3.X release, but they may be
-removed from a 6.4.0 or newer release.)
-* The MX and host alias DNS lookups that fetchmail performs in multidrop mode
-  are based on assumptions that are rarely met in practice, somewhat defective,
-  deprecated and may be removed from a future fetchmail version.
-  They have never supported IPv6 (including IPv6-mapped IPv4).
-  Non-DNS based alias keywords such as "aka" will remain in fetchmail.
+removed from a 7.0.0 or newer release.)
 * The monitor and interface options may be removed from a future fetchmail
   version as they are not reasonably portable across operating systems.
-* POP2 is obsolete, support will be removed from a future fetchmail version.
-* IMAP2 and IMAP4 (not IMAP4r1) are obsolete, support may be removed from a
+* IMAP4 (not IMAP4r1) is obsolete, support may be removed from a
   future fetchmail version.
-* RPOP is obsolete, support will be removed from a future fetchmail release.
 * --sslcertck will become a default setting in a future fetchmail version.
 * The multidrop To/Cc guessing code along with the fragile duplicate suppressor
   is deprecated and may be removed from a future release.
@@ -36,26 +29,100 @@ removed from a 6.4.0 or newer release.)
   inconsistent and confusing.
 * The "protocol auto" default inside fetchmail may be removed from a future
   fetchmail release. Explicit configuration of the protocol is recommended.
-* Kerberos IV support may be removed from a future fetchmail release.
 * Kerberos 5 support may be removed from a future fetchmail release.
-* The --principal option may be removed from a future fetchmail release.
 * SIGHUP wakeup support may be removed from a future fetchmail release and
   cause fetchmail to terminate - it was broken for many years.
-* Support for operating systems that are not sufficiently POSIX compliant may be
-  removed or operation on such systems may be suboptimal for future releases.
-  This means that fetchmail may only continue to work on C99 and POSIX 2001
-  based systems.
 * The maintainer may migrate fetchmail to C++ with STL or C#, and impose further
   requirements (dependencies), such as Boost or other class libraries.
-* The softbounce option default will change to "false" in the next release.
 * The --bsmtp - mode of operation may be removed in a future release.
 * Given that OpenSSL is severely underdocumented, and needs license exceptions,
   fetchmail may switch to a different SSL library.
-* SSLv2 support will be removed from a future fetchmail release. It has been
-  obsolete for more than a decade.
 
 --------------------------------------------------------------------------------
 
+fetchmail-7.0.0 (not yet released):
+
+NOTE THIS IS AN ALPHA RELEASE THAT HAS NOT BEEN THOROUGHLY TESTED!
+
+# MAJOR CHANGES
+* The UIDL handler code is now much faster, especially noticable with lots of
+  mail kept on a POP3 server. Where the 6.3.X code was of O(n^2) complexity,
+  we're down to O(n log n).
+  Contributed by Rainer Weikusat, MAD Partners Ltd./MSS GmbH.
+* The POP3 code now always uses UIDL, except if "fetchall" is in effect.
+  Fixes BerliOS Bug #16172. Fixes Debian Bug#345788.
+* Fetchmail now enables SSL support by default. If this is undesired,
+  ./configure --without-ssl should help.
+* The OpenSSL code now excludes the SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS option.
+  This can cause interoperability problems with certain buggy servers, but is
+  required to defang chosen-plaintext attacks against AES.  While probably hard
+  to mount against fetchmail, let's play it safe rather than be sorry later.
+
+# FEATURES ADDED
+* Fetchmail can now retrieve credentials from PWMD. This needs to be enabled at
+  compile-time and requires run-time configuration. See README.PWMD for details.
+  Contributed by Ben Kibbey, author of libpwmd and pwmd.
+* Fetchmail now supports a retrieve-error command line or rcfile option that
+  takes exactly one argument, abort (default), continue or markseen.  This
+  specifies the policy used by fetchmail to handle messages whose bodies
+  fail to be retrieved due to server errors.  Both the continue and markseen
+  options will skip the message with errors and allow the session to
+  continue so that subsequent messages can be retrieved.  The markseen
+  option will also mark the message with errors as seen.
+  The default policy is to abort the session whenever a server error occurs.
+  Contributed by Craig Brown.
+* Fetchmailconf offers cram-md5 and apop authentication.
+
+# REMOVED FEATURES
+* IMAP2 protocol support was removed.
+* POP2 protocol support was removed.
+* RPOP (not actually a protocol, but a variant of POP3) was removed
+* POP3: the uidl option has been removed. It is always on.
+* POP3: LAST is no longer used. It was removed from POP3 in 1994, and it could
+  cause mail loss when the connection was interrupted or if clients besides
+  fetchmail polled the mailbox.
+* Trio was removed, fetchmail expects reasonable stdio.h quality levels.
+* Support for systems that do not conform to C89 and POSIX 2001 was removed,
+  this means that BeOS, EMX, NeXTSTEP quirks are no longer worked around.
+* The MX and host alias DNS lookups that fetchmail performs in multidrop mode
+  have been removed. They were based on the mistaken assumption that the
+  IMAP/POP3 server was also the MX server, which is rarely the case.  They have
+  never supported IPv6 (including IPv6-mapped IPv4) either.
+  Non-DNS based alias keywords such as "aka" remain.
+* Kerberos IV support was removed.
+* fetchmail no longer supports SSL v2, nor the corresponding SSL2 option to
+  --sslproto. SSLv2 is insecure and had been deprecated 15 years ago. fetchmail
+  will actively forbid SSLv2 negotiation by means of SSL_OP_NO_SSLv2.
+  To fix Debian Bug#622054.
+* A lot of outdated and/or unsafe-to-use material got dropped from contrib/.
+
+# REGRESSION FIXES
+* The mimedecode feature now properly detects multipart/mixed-type matches, so
+  that quoted-printable-encoded multipart messages can get decoded.
+  (Regression in 5.0.0 on 1999-03-27, as a side effect of a PGP-mimedecode fix
+  attributed to Henrik Storner.)
+
+# BUG FIXES
+* The mimedecode feature failed to ship the last line of the body if it was
+  encoded as quoted-printable and had a MIME soft line break in the very last
+  line.  Reported by Lars Hecking in June 2011.
+  Bug introduced on 1998-03-20 when the mimedecode support was added by ESR
+  before release 4.4.1 through code contributed by Henrik Storner.
+  Workaround for older releases: do not use mimedecode feature.
+* Fetchmail now detects singly-quoted % expansions in the mda option and refuses
+  to deliver for safety reasons. Fixes Debian Bug#347909.
+* The Server certificate: message in verbose mode now appears on stdout like the
+  remainder of the output. Reported by Henry Jensen, to fix Debian Bug #639807.
+
+# CHANGES
+* A foreground fetchmail can now accept a few more options while another copy is
+  running in the background.
+* APOP is no longer a protocol, but an authentication method. In order to use
+  it, use protocol POP3 auth APOP, or on the commandline, -p pop3 --auth apop.
+  If no authentication method is specified, APOP is automatically tried if
+  offered by the server before we resort to sending the password as clear text.
+
+--------------------------------------------------------------------------------
 fetchmail-6.3.23 (not yet released)
 
 # NOTE THAT THE RELEASE OF FUTURE FETCHMAIL 6.3.X VERSIONS IS UNCLEAR.
@@ -190,7 +257,6 @@ fetchmail-6.3.21 (released 2011-08-21, 26011 LoC):
   log (and hexdump non-printing characters) raw socket data to a file. It proved
   useful to debug Antoine's bug described above.
 
-
 fetchmail-6.3.20 (released 2011-06-06, 26005 LoC):
 
 # SECURITY BUG FIXES
diff --git a/README b/README
index 6faa58a782103e5a7719c47f943c715c441496f4..f64c7ab1b3d4038faddbf4b881abcee5a2ee7fea 100644 (file)
--- a/README
+++ b/README
@@ -12,8 +12,8 @@ can then be be read by normal mail user agents such as mutt(1), elm(1) or
 Mail(1).
 
 Fetchmail supports all standard mail-retrieval protocols in use on the 
-Internet: POP3 (including some variants such as RPOP, APOP, KPOP), IMAP4rev1 
-(also IMAP4, IMAP2bis), POP2, IMAP4, ETRN, and ODMR. On the output side, 
+Internet: POP3 (including some variants such as APOP, KPOP), IMAP4rev1 
+(also IMAP4, IMAP2bis), IMAP4, ETRN, and ODMR. On the output side, 
 fetchmail supports ESMTP/SMTP, LMTP, and invocation of a local delivery agent.
 
 Fetchmail also fully supports authentication via GSSAPI, Kerberos 4 and 5, 
@@ -29,15 +29,9 @@ such as --sslcertck to tighten certificate checking.
 Portability
 -----------
 
-The fetchmail code was developed under Linux, but has also been extensively 
-tested under the BSD variants, AIX, HP-UX versions 9 and 10, SunOS, Solaris, 
-NEXTSTEP, OSF 3.2, IRIX, and Rhapsody.
-
-It should be readily portable to other Unix variants and Unix-like operating 
-systems (it uses GNU autoconf).  It has been ported to Cygwin, LynxOS and BeOS 
-and will build there without special action.  It has also been ported to QNX; 
-to build under QNX, see the header comments in the Makefile.  It is reported to 
-build and run under AmigaOS.
+The fetchmail code was developed under Linux, but has also been tested under
+Cygwin, FreeBSD, NetBSD, Solaris.  It should be readily portable to other IEEE
+Std 1003.1 (2001 or later) compliant operating systems.
 
 Further reading
 ---------------
diff --git a/README.PWMD b/README.PWMD
new file mode 100644 (file)
index 0000000..13cbb2b
--- /dev/null
@@ -0,0 +1,82 @@
+When compiled with pwmd (Password Manager Daemon) support (--enable-pwmd)
+fetchmail can retrieve server details from pwmd. pwmd v2.0 and libpwmd v6.0.0
+or later are required.
+
+Three new configuration parameters are added: pwmd_socket (optional) to
+specify the socket to connect to (default is ~/.pwmd/socket), pwmd_file
+(required) which specifies the filename on the server to open, and a global
+parameter pinentry_timeout (optional) which specifies the number of seconds
+until pinentry is cancelled while waiting for the password.
+
+Three new command line options are also added:
+    --pwmd-socket, -C     same as pwmd_socket
+    --pwmd-file, -G       same as pwmd_file
+    --pinentry_timeout, -O same as pinentry_timeout
+
+If no pinentry timeout value is specified then the server default will be
+used.
+
+The format of pwmd_socket and --pwmd-socket can be either a URL string in the
+form of:
+       file://[path/to/socket]
+
+       or
+
+       ssh[46]://[username@]hostname[:port],identity_file,known_hosts_file
+
+If neither file:// or ssh[46]:// are specified it is assumed to be a local
+UNIX domain socket to connect to (file://~/.pwmd/socket).
+
+See the pwmc(1) manual page for details about the identity and known_hosts
+files. Note that if connecting to a remote pwmd server, pwmd's pinentry will
+be disabled and a local pinentry will be tried.
+
+The data that pwmd uses to serve clients is stored in an (encrypted) XML file.
+You'll need to create the file you want fetchmail to use by connecting to the
+server with a pwmd client (socat or pwmc from libpwmd) and send commands to
+store the data. See COMMANDS included with pwmd for details.
+
+The password, if any, to open the encrypted data file is either cached on the
+server (the file has been opened before), or gotten from pinentry(1). See the
+pwmd(1) manual page for information about the ~/.pwmd/pinentry.conf file which
+may contain DISPLAY and TTYNAME settings to let pinentry(1) know where to
+prompt for the password.
+
+An account (e.g., pollname) may be an element path. Instead of separating the
+elements with a TAB character, separate them with a '^'.
+
+Here are the elements that fetchmail uses:
+
+    [...]elements in the element path (^ separated)[...]
+    <pollname>
+       <username>              - Optional (--username/username)
+       <password>              - Optional (--password/password)
+       <POP3|IMAP|etc..>       - Server protocol (must match the protocol
+                                 keyword from the rcfile or command line)
+           <hostname>          - Required (servername/via)
+           <port>              - Required (--service/protocol)
+           <ssl>               - Optional (--ssl/ssl)
+           <sslfingerprint>    - Optional (--sslfingerprint/sslfingerprint)
+       </POP3|IMAP|etc..>
+    </pollname>
+
+
+A minimal fetchmailrc might look like this:
+
+    set pinentry_timeout 30
+    poll isp proto POP3:
+       pwmd_file default
+
+    poll myaccounts^isp proto IMAP:
+       pwmd_file default
+       pwmd_socket "ssh://user@host,~/.pwmd/fetchmail,~/.pwmd/known_hosts"
+
+
+Or from the command line:
+
+    fetchmail -f fetchmailrc isp
+    fetchmail --pwmd-file somefile -p POP3 isp
+
+
+Ben Kibbey <bjk@luxsci.net>
+http://bjk.sourceforge.net/pwmd/.
diff --git a/TODO-7.0 b/TODO-7.0
new file mode 100644 (file)
index 0000000..393beb7
--- /dev/null
+++ b/TODO-7.0
@@ -0,0 +1,49 @@
+Return PS_ERROR, not PS_SYNTAX, on failures for preconnect/postconnect.
+Credit to Gene Heskett, 2012-07-31, fetchmail-users@ list.
+
+support SHA1 (and possibly other algorithm) finger prints
+(grarpamp, fetchmail-users 2012-06-23)
+
+add a "send test mail" mode, see message by Stanley Dziegiel
+<stanley@stronglg.demon.co.uk> in fetchmail-users, 2012-05-30
+
+fix NUL generation (see 6.3.21 release) and possibly string length
+handling
+
+review retrieveerrorsemantic contribution to avoid mail loss (cf. POP3
+LAST)
+
+clean up KPOP, SSL options
+
+fix versions in features.html (6.4 vs. 7.0)
+
+update README
+
+check for other 6.2/6.3-specific documentation
+
+merge libpwmd updates
+
+fix versions 7.0/6.4/6.3.20 in fetchmail.man, want 7.0 for this release,
+and 8.0 for C++
+
+SSL fixes:
+- write .man documentation, adjust FAQ (check diffs for what needs to be
+  documented)
+- debug sslcertck default (gets disabled somehow)
+
+Debian #632479 - doesn't accept -f and --pidfile options when waking up
+BG daemon (watch out for idfile though!)
+
+- debug mode fix: one switch to kill running daemon and enable -Nvvv -d0
+  --nosyslog options
+
+- write email to flat files? (variant of bsmtp)
+
+- probably 8.0 stuff: IMAP sink
+
+- remove bouncemail feature?
+
+- validate addresses to avoid invalid address issues
+    + consider if a bad-header interaction is desired
+
+- merge up 6.3.20-6.3.22 fixes and NEWS
index f5c3456261c4f25d1c6ce72375f6d6654508d49b..f317b3813ac10e48ebb741abda0b25b3aa06282a 100644 (file)
--- a/TODO.txt
+++ b/TODO.txt
@@ -66,7 +66,7 @@ questionable:
 - fetch IMAP message in one go (fetchmail-devel by Adam Simpkins
   <simpkins@cisco.com> around Nov 2nd)?
 
-6.4:
+7.0:
 - Properly free host/user entries (through C++ class instantiation and destructors...)
 - Remove stupid options, such as spambounce, or deferred bounces for anything
   but wrong addresses
diff --git a/berlios3116.patch b/berlios3116.patch
new file mode 100644 (file)
index 0000000..c4e38f7
--- /dev/null
@@ -0,0 +1,20 @@
+*** transact.c~ 2010-10-22 06:51:13.000000000 -0500\r
+--- transact.c  2011-01-08 19:58:23.867000090 -0600\r
+***************\r
+*** 924,930 ****\r
+                if (ctl->server.envelope \r
+                    && strcasecmp(ctl->server.envelope, "Received"))\r
+                {\r
+!                   if (env_offs == -1 && !strncasecmp(ctl->server.envelope,\r
+                                                       line,\r
+                                                       strlen(ctl->server.envelope)))\r
+                    {\r
+--- 924,931 ----\r
+                if (ctl->server.envelope \r
+                    && strcasecmp(ctl->server.envelope, "Received"))\r
+                {\r
+!                   if (((env_offs == -1) || (ctl->server.envskip == -1))\r
+!                       && !strncasecmp(ctl->server.envelope,\r
+                                                       line,\r
+                                                       strlen(ctl->server.envelope)))\r
+                    {\r
index 2e50ea09222d3cd61b469b953839e41a6665c027..6437db4c7c7f979b535e564bc9e5859fb7a583b2 100644 (file)
@@ -9,90 +9,12 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/types.h>
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#else
-#include <sys/socket.h>
-#endif
-#include <netinet/in.h>
-#ifdef HAVE_ARPA_INET_H
-#include <arpa/inet.h>
-#endif
-#include <netdb.h>
-#include "i18n.h"
-#include "mx.h"
-#include "fetchmail.h"
-#include "getaddrinfo.h"
-
-#define MX_RETRIES     3
-
-typedef unsigned char address_t[sizeof (struct in_addr)];
-
-#ifdef HAVE_RES_SEARCH
-static int getaddresses(struct addrinfo **result, const char *name)
-{
-    struct addrinfo hints;
-
-    memset(&hints, 0, sizeof(hints));
-    hints.ai_socktype=SOCK_STREAM;
-    hints.ai_protocol=PF_UNSPEC;
-    hints.ai_family=AF_UNSPEC;
-    return fm_getaddrinfo(name, NULL, &hints, result);
-}
-
-/* XXX FIXME: doesn't detect if an IPv6-mapped IPv4 address
- * matches a real IPv4 address */
-static int compareaddr(const struct addrinfo *a1, const struct addrinfo *a2)
-{
-    if (a1->ai_family != a2->ai_family) return FALSE;
-    if (a1->ai_addrlen != a2->ai_addrlen) return FALSE;
-    return (!memcmp(a1->ai_addr, a2->ai_addr, a1->ai_addrlen));
-}
-
-static int is_ip_alias(const char *name1,const char *name2)
-/*
- * Given two hostnames as arguments, returns TRUE if they
- * have at least one IP address in common.
- * No check is done on errors returned by gethostbyname,
- * the calling function does them.
- */
-{
-    int rc = FALSE;
 
-    struct addrinfo *res1 = NULL, *res2 = NULL, *ii, *ij;
-
-    if (getaddresses(&res1, name1))
-       goto found;
-
-    if (getaddresses(&res2, name2))
-       goto found;
-
-    for (ii = res1 ; ii ; ii = ii -> ai_next) {
-       for (ij = res2 ; ij ; ij = ij -> ai_next) {
-           if (compareaddr(ii, ij)) {
-               rc = TRUE;
-               goto found;
-           }
-       }
-    }
-
-found:
-    if (res2)
-       fm_freeaddrinfo(res2);
-    if (res1)
-       fm_freeaddrinfo(res1);
-    return rc;
-}
-#endif
+#include "fetchmail.h"
 
 int is_host_alias(const char *name, struct query *ctl, struct addrinfo **res)
 /* determine whether name is a DNS alias of the mailserver for this query */
 {
-#ifdef HAVE_RES_SEARCH
-    struct mxentry     *mxp, *mxrecords;
-    int                        e;
-    struct addrinfo    hints, *res_st;
-#endif
     struct idlist      *idl;
     size_t             namelen;
 
@@ -146,103 +68,8 @@ int is_host_alias(const char *name, struct query *ctl, struct addrinfo **res)
 
     if (!ctl->server.dns)
        return(FALSE);
-#ifndef HAVE_RES_SEARCH
     (void)res;
     return(FALSE);
-#else
-    /*
-     * The only code that calls the BIND library is here and in the
-     * start-of-run probe with gethostbyname(3) under ETRN/Kerberos.
-     *
-     * We know DNS service was up at the beginning of the run.
-     * If it's down, our nameserver has crashed.  We don't want to try
-     * delivering the current message or anything else from the
-     * current server until it's back up.
-     */
-    memset(&hints, 0, sizeof hints);
-    hints.ai_family=AF_UNSPEC;
-    hints.ai_protocol=PF_UNSPEC;
-    hints.ai_socktype=SOCK_STREAM;
-    hints.ai_flags=AI_CANONNAME;
-
-    e = fm_getaddrinfo(name, NULL, &hints, res);
-    if (e == 0)
-    {
-       int rr = (strcasecmp(ctl->server.truename, (*res)->ai_canonname) == 0);
-       fm_freeaddrinfo(*res); *res = NULL;
-       if (rr)
-           goto match;
-        else if (ctl->server.checkalias && 0 == fm_getaddrinfo(ctl->server.truename, NULL, &hints, &res_st))
-       {
-           fm_freeaddrinfo(res_st);
-           if (outlevel >= O_DEBUG)
-               report(stdout, GT_("Checking if %s is really the same node as %s\n"),ctl->server.truename,name);
-           if (is_ip_alias(ctl->server.truename,name) == TRUE)
-           {
-               if (outlevel >= O_DEBUG)
-                   report(stdout, GT_("Yes, their IP addresses match\n"));
-               goto match;
-           }
-           if (outlevel >= O_DEBUG)
-               report(stdout, GT_("No, their IP addresses don't match\n"));
-           return(FALSE);
-       } else {
-           return(FALSE);
-       }
-    }
-    else
-       switch (e)
-       {
-           case EAI_NONAME:    /* specified host is unknown */
-               break;
-
-           default:
-               if (outlevel != O_SILENT)
-                   report_complete(stdout, "\n");      /* terminate the progress message */
-               report(stderr,
-                       GT_("nameserver failure while looking for '%s' during poll of %s: %s\n"),
-                       name, ctl->server.pollname, gai_strerror(e));
-               ctl->errcount++;
-               break;
-       }
-
-    /*
-     * We're only here if DNS was OK but the gethostbyname() failed
-     * with a HOST_NOT_FOUND or NO_ADDRESS error.
-     * Search for a name match on MX records pointing to the server.
-     */
-    h_errno = 0;
-    if ((mxrecords = getmxrecords(name)) == (struct mxentry *)NULL)
-    {
-       switch (h_errno)
-       {
-       case HOST_NOT_FOUND:    /* specified host is unknown */
-#ifdef NO_ADDRESS
-       case NO_ADDRESS:        /* valid, but does not have an IP address */
-           return(FALSE);
-#endif
-       case NO_RECOVERY:       /* non-recoverable name server error */
-       case TRY_AGAIN:         /* temporary error on authoritative server */
-       default:
-           report(stderr,
-               GT_("nameserver failure while looking for `%s' during poll of %s.\n"),
-               name, ctl->server.pollname);
-           ctl->errcount++;
-           break;
-       }
-    } else {
-       for (mxp = mxrecords; mxp->name; mxp++)
-           if (strcasecmp(ctl->server.truename, mxp->name) == 0
-                   || is_ip_alias(ctl->server.truename, mxp->name) == TRUE)
-               goto match;
-       return(FALSE);
-    match:;
-    }
-
-    /* add this name to relevant server's `also known as' list */
-    save_str(&lead_server->akalist, name, 0);
-    return(TRUE);
-#endif /* HAVE_RES_SEARCH */
 }
 
 /* checkalias.c ends here */
diff --git a/conf.c b/conf.c
index e51c7ccb3ef609bd9b8ea673a7ce1875af9d6aaf..167aac118039b8a11cfd0f7c8c66c99516d4a945 100644 (file)
--- a/conf.c
+++ b/conf.c
@@ -9,12 +9,8 @@
 
 #include <stdio.h>
 #include <ctype.h>
-#if defined(STDC_HEADERS)
 #include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
 #include <string.h>
 #include <pwd.h>
 #include <errno.h>
@@ -151,9 +147,6 @@ void dump_config(struct runctl *runp, struct query *querylist)
      * in fetchmail.c.
      */
     features = "feature_options = ("
-#ifdef POP2_ENABLE
-    "'pop2',"
-#endif /* POP2_ENABLE */
 #ifdef POP3_ENABLE
     "'pop3',"
 #endif /* POP3_ENABLE */
@@ -163,9 +156,6 @@ void dump_config(struct runctl *runp, struct query *querylist)
 #ifdef GSSAPI
     "'gssapi',"
 #endif /* GSSAPI */
-#if defined(KERBEROS_V4)
-    "'kerberos',"
-#endif /* defined(IMAP4) */
 #ifdef RPA_ENABLE
     "'rpa',"
 #endif /* RPA_ENABLE */
@@ -248,7 +238,7 @@ void dump_config(struct runctl *runp, struct query *querylist)
            using_kpop =
                (ctl->server.protocol == P_POP3 &&
                 ctl->server.service && !strcmp(ctl->server.service, KPOP_PORT ) &&
-                ctl->server.authenticate == A_KERBEROS_V4);
+                ctl->server.authenticate == A_KERBEROS_V5);
 
            stringdump("pollname", ctl->server.pollname); 
            booldump("active", !ctl->server.skip); 
@@ -268,32 +258,31 @@ void dump_config(struct runctl *runp, struct query *querylist)
            numdump("envskip", ctl->server.envskip);
            stringdump("qvirtual", ctl->server.qvirtual);
  
-           if (ctl->server.authenticate == A_ANY)
-               stringdump("auth", "any");
-           else if (ctl->server.authenticate == A_PASSWORD)
-               stringdump("auth", "password");
-           else if (ctl->server.authenticate == A_NTLM)
-               stringdump("auth", "ntlm");
-           else if (ctl->server.authenticate == A_CRAM_MD5)
-               stringdump("auth", "cram-md5");
-           else if (ctl->server.authenticate == A_GSSAPI)
-               stringdump("auth", "gssapi");
-           else if (ctl->server.authenticate == A_KERBEROS_V4)
-               stringdump("auth", "kerberos_v4");
-           else if (ctl->server.authenticate == A_KERBEROS_V5)
-               stringdump("auth", "kerberos_v5");
-           else if (ctl->server.authenticate == A_SSH)
-               stringdump("auth", "ssh");
-           else if (ctl->server.authenticate == A_OTP)
-               stringdump("auth", "otp");
-           else if (ctl->server.authenticate == A_MSN)
-               stringdump("auth", "msn");
+           switch (ctl->server.authenticate) {
+               case A_ANY:
+                   stringdump("auth", "any"); break;
+               case A_PASSWORD:
+                   stringdump("auth", "password"); break;
+               case A_OTP:
+                   stringdump("auth", "otp"); break;
+               case A_NTLM:
+                   stringdump("auth", "ntlm"); break;
+               case A_CRAM_MD5:
+                   stringdump("auth", "cram-md5"); break;
+               case A_GSSAPI:
+                   stringdump("auth", "gssapi"); break;
+               case A_KERBEROS_V5:
+                   stringdump("auth", "kerberos_v5"); break;
+               case A_SSH:
+                   stringdump("auth", "ssh"); break;
+               case A_MSN:
+                   stringdump("auth", "msn"); break;
+               default: abort();
+           }
 
 #ifdef HAVE_RES_SEARCH
            booldump("dns", ctl->server.dns);
 #endif /* HAVE_RES_SEARCH */
-           booldump("uidl", ctl->server.uidl);
-
            listdump("aka", ctl->server.akalist);
            listdump("localdomains", ctl->server.localdomains);
 
@@ -318,6 +307,12 @@ void dump_config(struct runctl *runp, struct query *querylist)
                case BHACCEPT: puts("'badheader': TRUE,"); break;
            }
 
+           switch (ctl->server.retrieveerror) {
+               case RE_ABORT: stringdump("retrieveerror", "abort"); break;
+               case RE_CONTINUE: stringdump("retrieveerror", "continue"); break;
+               case RE_MARKSEEN: stringdump("retrieveerror", "markseen"); break;
+           }
+
            indent(0);
            fputs("'users': ", stdout);
            indent('[');
index f19bdc51d8badba9d431b14a25dbc9566792c14d..dd66cdbd7890745bfd05f24bb75bd721497ca34d 100644 (file)
@@ -9,15 +9,18 @@ dnl Process this file with autoconf to produce a configure script.
 dnl
 
 dnl XXX - if bumping version here, check fetchmail.man, too!
-AC_INIT([fetchmail],[6.3.22.1],[fetchmail-users@lists.berlios.de])
+AC_INIT([fetchmail],[7.0.0-alpha3],[fetchmail-devel@lists.berlios.de])
 AC_CONFIG_SRCDIR([fetchmail.h])
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_LIBOBJ_DIR([.])
 
 AC_CANONICAL_HOST
 
+dnl keep this before stuff that runs the compiler!
+AC_USE_SYSTEM_EXTENSIONS
+
 dnl automake options are in Makefile.am
-AC_PREREQ(2.60)
+AC_PREREQ(2.64)
 dnl 2.60 required for AC_USE_SYSTEM_EXTENSIONS
 AM_INIT_AUTOMAKE
 
@@ -31,21 +34,12 @@ AM_PATH_PYTHON(2.0,,AC_MSG_WARN([Disabling fetchmailconf: python 2.0 or greater
 AM_CONDITIONAL([HAVE_PYTHON], [test "$PYTHON" != :])
 
 AC_PROG_AWK
-AC_PROG_CC
-AM_PROG_CC_C_O
+AC_PROG_CC_C99
 AC_PROG_INSTALL
-AC_PROG_CPP                    dnl Later checks need this.
+AM_PROG_LEX
+AC_PROG_MAKE_SET
 AC_PROG_RANLIB
-AM_PROG_CC_C_O
-AC_USE_SYSTEM_EXTENSIONS
-
-AC_ISC_POSIX
-dnl AC_ISC_POSIX: - XXX FIXME: remove in fetchmail 6.4.
-dnl This macro adds `-lcposix' to output variable `LIBS' if necessary
-dnl for Posix facilities.  Sun dropped support for the obsolete
-dnl INTERACTIVE Systems Corporation Unix on 2006-07-23.  New programs
-dnl need not use this macro.  It is implemented as
-dnl `AC_SEARCH_LIBS([strerror], [cposix])'
+AC_PROG_YACC
 
 dnl check for b0rked Solaris (and other shells) and find one that works
 AC_MSG_CHECKING(for a working shell...)
@@ -64,31 +58,11 @@ if test "x$SHELL" = "x" ; then
     AC_MSG_ERROR(no SUS compliant shell found - on Solaris, install SUNWxcu4)
 fi
 
+AC_CHECK_HEADERS([arpa/nameser.h])
 
-AC_HEADER_STDC
-AC_HEADER_TIME
-AC_TYPE_SIZE_T
-AC_TYPE_PID_T
-AC_TYPE_SIGNAL
-AC_CHECK_HEADERS([unistd.h termios.h termio.h sgtty.h stdarg.h \
-       sys/itimer.h fcntl.h sys/fcntl.h memory.h sys/wait.h \
-       arpa/inet.h arpa/nameser.h netinet/in.h net/socket.h netdb.h \
-       sys/select.h sys/socket.h sys/time.h langinfo.h])
-if test _$ac_cv_header_stdarg_h != _yes ; then
-AC_MSG_WARN([stdarg.h is not defined. Unsupported configuration, proceed at your own risk.])
-fi
-AC_CHECK_TYPE(u_int32_t,,
-       AC_DEFINE(u_int32_t,unsigned int,
-               [Define to unsigned int if <sys/types.h> does not define.]),
-       [AC_INCLUDES_DEFAULT
-#ifdef HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
-#endif])
 AC_CHECK_HEADERS([resolv.h],,,[
 #include <sys/types.h>
-#ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
-#endif
 #ifdef HAVE_ARPA_NAMESER_H
 #include <arpa/nameser.h>
 #endif
@@ -96,17 +70,9 @@ AC_CHECK_HEADERS([resolv.h],,,[
 
 AC_CHECK_DECLS([h_errno],,,[
        AC_INCLUDES_DEFAULT
-       #ifdef HAVE_NETDB_H
        #include <netdb.h>
-       #endif
 ])
 
-AC_C_CONST                     dnl getopt needs this.
-
-AM_PROG_LEX
-AC_PROG_MAKE_SET
-AC_PROG_YACC
-
 # Check for OS special cases
 case $host_os in
 darwin*)
@@ -118,20 +84,6 @@ freebsd*)
     AC_MSG_NOTICE(found FreeBSD - Adding -lkvm -lcom_err to standard libraries)
     LIBS="$LIBS -lkvm -lcom_err"
     ;;
-# Check for LynxOS special case: -lbsd needed (at least on 2.3.0) and -s
-# not working.
-lynxos*)
-    AC_MSG_NOTICE(found LynxOS - Adding -lbsd to standard libraries)
-    LIBS="$LIBS -lbsd"
-    LDFLAGS=`echo $LDFLAGS | sed "s/-s //"`
-    AC_MSG_NOTICE(found LynxOS - Prepending standard include path to gcc flags)
-    CPPFLAGS="$CPPFLAGS -I/usr/include"
-    ;;
-# Check for Rhapsody special case: it doesn't like -s
-rhapsody*)
-    AC_MSG_NOTICE(found Rhapsody - Removing -s load flag)
-    LDFLAGS=`echo $LDFLAGS | sed "s/-s //"`
-    ;;
 esac
 
 AC_CACHE_SAVE
@@ -155,46 +107,22 @@ AC_CHECK_FUNC(inet_addr,
     AC_MSG_RESULT(using libc's inet_addr),
     AC_CHECK_LIB(nsl,inet_addr))
 
-dnl Port hack for Interactive UNIX System V/386 Release 3.2
-AC_CHECK_LIB(cposix, strchr,
-               [DEFS="$DEFS -D_SYSV3"
-               LIBS="$LIBS -lcposix"])
-
-dnl Port hack for Sparc/NetBSD-1.5
-dnl
-dnl NB: this has been disabled as it causes the unconditional
-dnl addition of libintl to the build, which is both undesired
-dnl and breaks on Solaris/Blastwave.org machines.
-dnl
-dnl AC_CHECK_LIB(intl, gettext,
-dnl            [LIBS="$LIBS -lintl"])
-
-AC_REPLACE_FUNCS([strstr strcasecmp memmove stpcpy strlcpy strlcat])
+AC_REPLACE_FUNCS([stpcpy strlcpy strlcat])
 
 AC_CHECK_FUNC(getopt_long, [],
               [AC_LIBSOURCES([getopt.c, getopt1.c])
               EXTRAOBJ="$EXTRAOBJ getopt.\$(OBJEXT) getopt1.\$(OBJEXT)"])
 
-AC_FUNC_VPRINTF
-
 AC_SUBST(EXTRAOBJ)
 
-AC_CHECK_FUNCS(tcsetattr stty setsid geteuid seteuid dnl
-  strerror syslog snprintf vprintf vsnprintf vsyslog dnl
-  atexit inet_aton strftime setrlimit socketpair dnl
-  sigaction strdup setlocale)
+AC_CHECK_FUNCS(vsyslog inet_aton)
 
-AC_CHECK_DECLS([strerror,getenv])
 dnl INET6 is used by KAME/getnameinfo
 AC_CACHE_CHECK(for AF_INET6/PF_INET6,ac_cv_inet6,
 AC_COMPILE_IFELSE([
   AC_LANG_PROGRAM([[
-    #ifdef HAVE_SYS_TYPES_H
     #include <sys/types.h>
-    #endif
-    #ifdef HAVE_SYS_SOCKET_H
     #include <sys/socket.h>
-    #endif
   ]],[[
     int foo = AF_INET6;
     int bar = PF_INET6;
@@ -220,9 +148,7 @@ for lib in '' -lresolv; do
     LIBS="$old_LIBS $lib"
     AC_LINK_IFELSE([AC_LANG_PROGRAM([[
 #include <sys/types.h>
-#ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
-#endif
 #ifdef HAVE_ARPA_NAMESER_H
 #include <arpa/nameser.h>
 #endif
@@ -241,50 +167,29 @@ done
 dnl Check for libcrypt -- it may live in libc or libcrypt, as on IRIX
 AC_CHECK_FUNC(crypt, , AC_CHECK_LIB(crypt,crypt))
 
-dnl Check for usable void pointer type
-AC_MSG_CHECKING(use of void pointer type)
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[char *p;
-    void *xmalloc();
-    p = (char *) xmalloc(1);
-   ]])],[AC_DEFINE(HAVE_VOIDPOINTER,1,[Define if your C compiler allows void * as a function result]) AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
-
-dnl Check for ANSI volatile
-AC_C_VOLATILE
-
-dnl Check out the wait reality.  We have to assume sys/wait.h is present.
-AC_CHECK_FUNCS(waitpid wait3)
-AC_MSG_CHECKING(for union wait);
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
-#include <sys/wait.h>]], [[union wait status; int pid; pid = wait (&status);
-#ifdef WEXITSTATUS
-/* Some POSIXoid systems have both the new-style macros and the old
-   union wait type, and they do not work together.  If union wait
-   conflicts with WEXITSTATUS et al, we don't want to use it at all.  */
-if (WEXITSTATUS (status) != 0) pid = -1;
-#endif
-#ifdef HAVE_WAITPID
-/* Make sure union wait works with waitpid.  */
-pid = waitpid (-1, &status, 0);
-#endif
-]])],[AC_DEFINE(HAVE_UNION_WAIT,1,Define if 'union wait' is the type of the first arg to wait functions.) AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
-
 AC_MSG_CHECKING(sys_siglist declaration in signal.h or unistd.h)
 AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <signal.h>
 /* NetBSD declares sys_siglist in <unistd.h>.  */
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif]], [[char *msg = *(sys_siglist + 1);]])],[AC_DEFINE(SYS_SIGLIST_DECLARED,1,[Define if 'sys_siglist' is declared by <signal.h>.]) AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
-
-# Find the right directory to put the root-mode PID file in
-for dir in "/var/run" "/etc"
-do
-       if test -d $dir 
-       then
-               break;
-       fi
-done
-AC_MSG_RESULT(root-mode pid file will go in $dir)
-AC_DEFINE_UNQUOTED(PID_DIR, "$dir", directory for PID lock files)
+]], [[char *msg = *(sys_siglist + 1);]])],[AC_DEFINE(SYS_SIGLIST_DECLARED,1,[Define if 'sys_siglist' is declared by <signal.h>.]) AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
+
+AC_DEFINE_UNQUOTED(PID_DIR, "/var/run", directory for PID lock files)
+
+AC_ARG_ENABLE(pwmd,
+       [  --enable-pwmd           enable Password Manager Daemon support],
+       , [enable_pwmd=no])
+
+if test "$enable_pwmd" = "yes"; then
+    PKG_CHECK_EXISTS([libpwmd], have_libpwmd=1,
+                    AC_MSG_ERROR([Could not find libpwmd pkg-config module.]))
+
+
+    PKG_CHECK_MODULES([libpwmd], [libpwmd >= 6.0.0])
+    AM_CONDITIONAL(HAVE_LIBPWMD, true)
+    AC_DEFINE(HAVE_LIBPWMD, 1, [Define if you have libPWMD installed.])
+else
+    AM_CONDITIONAL(HAVE_LIBPWMD, false)
+fi
 
 # We may have a fallback MDA available in case the socket open to the 
 # local SMTP listener fails.  Best to use procmail for this, as we know
@@ -375,18 +280,6 @@ case "$enable_fallback" in
                        ;;
 esac
 
-AC_CHECK_SIZEOF(short)
-AC_CHECK_SIZEOF(int)
-AC_CHECK_SIZEOF(long)
-
-###    use option --enable-POP2 to compile in the POP2 support
-AC_ARG_ENABLE(POP2,
-       [  --enable-POP2           compile in POP2 protocol support (obsolete)],
-       [with_POP2=$enableval],
-       [with_POP2=no])
-test "$with_POP2" = "yes" && AC_DEFINE(POP2_ENABLE,1,Define if you want POP2 support compiled in)
-AM_CONDITIONAL(POP2_ENABLE, test "$with_POP2" = yes)
-
 ###    use option --disable-POP3 to omit the POP3 support
 AC_ARG_ENABLE(POP3,
        [  --disable-POP3          don't compile in POP3 protocol support],
@@ -448,9 +341,8 @@ if test "$with_SDPS" = yes ; then
        AC_DEFINE(SDPS_ENABLE,1,Define if you want SDPS support compiled in)
    fi
 fi
-if test "$with_POP3" != yes && test "$with_POP2" != yes \
-    && test "$with_IMAP"  != yes ; then
-    AC_MSG_ERROR([You must enable at least one of POP2, POP3 and IMAP.])
+if test "$with_POP3" != yes && test "$with_IMAP"  != yes ; then
+    AC_MSG_ERROR([You must enable at least one of POP3 and IMAP.])
 fi
 
 AC_CACHE_SAVE
@@ -467,17 +359,11 @@ test "$with_opie" = "yes" && AC_DEFINE(OPIE_ENABLE,1,Define if you want OPIE sup
 dnl Mostly stolen from gnulib's getaddrinfo.m4
 AC_SEARCH_LIBS(getaddrinfo, [nsl socket])
 AC_CACHE_CHECK([for getaddrinfo],[fm_cv_getaddrinfo],[
-  AC_TRY_LINK([
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([[
 #include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
-#endif
-#ifdef HAVE_NETDB_H
 #include <netdb.h>
-#endif
-  ], [getaddrinfo(0, 0, 0, 0);],
-    [ fm_cv_getaddrinfo=yes],
-    [ fm_cv_getaddrinfo=no ])
+  ]], [[getaddrinfo(0, 0, 0, 0);]])],[ fm_cv_getaddrinfo=yes],[ fm_cv_getaddrinfo=no ])
 ])
 
 if test x"$fm_cv_getaddrinfo" = "xyes"; then  
@@ -486,20 +372,14 @@ if test x"$fm_cv_getaddrinfo" = "xyes"; then
 fi
 
 AC_CACHE_CHECK([for getnameinfo],[fm_cv_getnameinfo],[
-  AC_TRY_LINK([
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([[
 #include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
-#endif
-#ifdef HAVE_NETDB_H
 #include <netdb.h>
-#endif
 #ifndef NULL
 #define NULL 0
 #endif
-  ], [getnameinfo(NULL,0, NULL,0, NULL, 0, 0);],
-    [ fm_cv_getnameinfo=yes],
-    [ fm_cv_getnameinfo=no ])
+  ]], [[getnameinfo(NULL,0, NULL,0, NULL, 0, 0);]])],[ fm_cv_getnameinfo=yes],[ fm_cv_getnameinfo=no ])
 ])
 if test $fm_cv_getnameinfo = yes ; then
     AC_DEFINE(HAVE_GETNAMEINFO,1,[Define to 1 if your system has getnameinfo()])
@@ -526,20 +406,10 @@ if test "$fm_cv_getaddrinfo" = yes ; then
     fi
 fi
 
-# This version of the Kerberos 4 and 5 options addresses the follwing issues:
+# This version of the Kerberos 5 options addresses the follwing issues:
 # 
 # * Build correctly under Heimdal kerberos if it is compiled with db2 and
 #   OpenSSL support (Debian's is)
-# * Build the kerberos.c stuff (KPOP) only for kerberosIV, to avoid breakage.
-#   I don't know if this is 100% correct, but now at least IMAP and POP3
-#   behave the same way regarding kerberosV.
-# * Build without any fuss for both kerberosIV and V at the same time.
-# * Move all the kerberos header mess to kerberos.h, and #include that
-#   in driver.c and kerberos.c.
-# 
-# Tested using the Heimdal Kerberos V libs, Kungliga Tekniska Högskolan (the
-# Royal Institute of Technology in Stockholm, Sweden)'s kerberos IV libs, and
-# the MIT reference implementation of KerberosV (all as packaged in Debian).
 
 ###    use option --with-kerberos5=DIR to point at a Kerberos 5 directory
 ### make sure --with-ssl is run before --with-kerberos* !
@@ -629,102 +499,11 @@ fi
 fi
 ]) dnl --with-kerberos5=DIR
 
-###    use option --with-kerberos=DIR to point at a Kerberos 4 directory
-KERBEROS_V4=0
-AC_ARG_WITH(kerberos,
-       [  --with-kerberos=DIR     point fetchmail compilation at a Kerberos 4 directory],
-[
-if test "$with_kerberos" != "no"
-then
-    AC_MSG_WARN([Kerberos IV support is obsolete. Use --with-kerberos5 if possible.])
-# Check for a NetBSD/OpenBSD special case
-if test "$with_kerberos" = "yes" && ( test `uname` = "NetBSD" || test `uname` = "OpenBSD" )
-then
-  AS_MESSAGE(checking kerberosIV for `uname`...)
-  KERBEROS_V4=1
-  CFLAGS="$CFLAGS -I/usr/include/kerberosIV"
-  case `uname` in
-      NetBSD)  LIBS="$LIBS -lkrb -ldes -lroken -lcom_err" ;;
-      OpenBSD) LIBS="$LIBS -lkrb -ldes" ;;
-  esac
-elif krb4-config 2> /dev/null >/dev/null ; then
-  krb4_prefix=`krb4-config --prefix`
-  AC_MSG_RESULT([krb4-config points to kerberosIV under $krb4_prefix])
-  unset krb4_prefix
-  CFLAGS="$CFLAGS `krb4-config --cflags`"
-  LIBS="$LIBS `krb4-config --libs`"
-  KERBEROS_V4=1
-elif krb5-config 2> /dev/null >/dev/null ; then
-  krb4_prefix=`krb5-config --prefix krb4`
-  AC_MSG_RESULT([krb5-config points to kerberosIV under $krb4_prefix])
-  if test -f ${krb4_prefix}/include/kerberosIV/krb.h ; then
-    AC_DEFINE(KERBEROS_V4_V5,1,Define if you have Kerberos V4 headers under a kerberosIV directory)
-  fi
-  unset krb4_prefix
-  CFLAGS="$CFLAGS `krb5-config --cflags krb4`"
-  LIBS="$LIBS `krb5-config --libs krb4`"
-  KERBEROS_V4=1
-else
-  #we need to detect when we're building under a kerberosV compatibility
-  #layer, btw...
-  if test "$with_kerberos" != "yes" ; then
-     searchdirs="$with_kerberos"
-  else
-     searchdirs="$with_kerberos5 /usr/kerberos /usr/kerberosIV /usr/athena /usr"
-  fi
-  with_kerberos=
-  ac_saveLDFLAGS="$LDFLAGS"
-  for dir in $searchdirs
-  do
-     AC_MSG_CHECKING([for Kerberos IV in $dir])
-     if test -f "$dir/include/krb.h" || test -f "$dir/include/krb4.h" \
-            || test -f "$dir/include/kerberosIV/krb.h"
-     then
-        AC_MSG_RESULT([found])
-     else
-        AC_MSG_RESULT([not found])
-       continue
-     fi
-     #Find libs
-     if test -f "$with_kerberos5/roken.h" ; then
-       AC_CHECK_LIB(45, krb_mk_req)
-     fi
-     LDFLAGS="-L$dir/lib $ac_saveLDFLAGS"
-     if test `uname` = "FreeBSD"; then
-        AC_SEARCH_LIBS(_ossl_old_des_string_to_key, [des425 des crypto], [], continue)
-     else
-        AC_SEARCH_LIBS(des_string_to_key, [crypto], [], continue)
-     fi
-     AC_SEARCH_LIBS(krb_realmofhost, [krb4 krb], [], continue)
-     with_kerberos="$dir"
-     if test -f "$dir/include/kerberosIV/krb.h" ; then
-        dir="$dir/include/kerberosIV"
-     else
-       dir="$dir/include"
-     fi
-     KERBEROS_V4=1
-     test -f "$with_kerberos5/roken.h" && AC_DEFINE(HEIMDAL)
-     test "$dir" != "/usr/include" && CFLAGS="$CFLAGS -I$dir"
-     LDFLAGS="$LDFLAGS -L$with_kerberos/lib"
-     break
-  done
-  if test -z "$with_kerberos" ; then
-     AC_MSG_ERROR([Kerberos 4 libraries not found])
-  fi
-  LDFLAGS="$ac_saveLDFLAGS"
-fi
-fi
-]) dnl --with-kerberos=DIR
-if test "$KERBEROS_V4" = 1 ; then
-    AC_DEFINE(KERBEROS_V4,1,Define if you have Kerberos V4)
-fi
-AM_CONDITIONAL(KERBEROS_V4_ENABLE, test "$KERBEROS_V4" = 1)
-
 ###    use option --with-ssl to compile in the SSL support
 AC_ARG_WITH(ssl,
        [  --with-ssl=[DIR]        enable SSL support using libraries in DIR],
        [with_ssl=$withval],
-       [with_ssl=no])
+       [with_ssl=yes])
 test "$with_ssl" != "no" && AC_DEFINE(SSL_ENABLE,1,Define if you want SSL support compiled in)
 
 if test "$with_ssl" = "yes"
@@ -915,58 +694,6 @@ then
     ])
 fi])
 
-dnl ,------------------------------------------------------------------
-dnl Check if we need TRIO
-needtrio=0
-if test "$FORCE_TRIO" = "yes" ; then
-    needtrio=1
-    ac_cv_func_vsnprintf=no
-    ac_cv_func_snprintf=no
-fi
-if test "x$ac_cv_func_snprintf" != "xyes" ; then
-    AC_DEFINE(snprintf, trio_snprintf,
-             [Define to trio_snprintf if your system lacks snprintf])
-    needtrio=1
-fi
-if test "x$ac_cv_func_vsnprintf" != "xyes" ; then
-    AC_DEFINE(vsnprintf, trio_vsnprintf,
-             [Define to trio_vsnprintf if your system lacks vsnprintf])
-    needtrio=1
-fi
-AM_CONDITIONAL(NEED_TRIO, test "$needtrio" = 1)
-
-dnl TRIO IEEE compiler option for Alpha
-dnl
-if test "$needtrio" = 1 ; then
-    AC_MSG_CHECKING(for IEEE compilation options)
-    AC_CACHE_VAL(ac_cv_ieee_option, [
-    AC_TRY_COMPILE(,[
-    #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__))) && (defined(VMS) || defined(__VMS)))
-    # error "Option needed"
-    #endif
-    ],ac_cv_ieee_option="/IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE",
-    AC_TRY_COMPILE(,[
-    #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__))) && !(defined(VMS) || defined(__VMS)) && !defined(_CFE))
-    # error "Option needed"
-    #endif
-    ],ac_cv_ieee_option="-ieee",
-    AC_TRY_COMPILE(,[
-    #if !(defined(__alpha) && (defined(__GNUC__) && (defined(__osf__) || defined(__linux__))))
-    # error "Option needed"
-    #endif
-    ],ac_cv_ieee_option="-mieee",
-    ac_cv_ieee_option="none"
-    )
-    )
-    )
-    ])
-    AC_MSG_RESULT($ac_cv_ieee_option)
-    if test $ac_cv_ieee_option != none; then
-      CFLAGS="${CFLAGS} ${ac_cv_ieee_option}"
-    fi
-fi
-dnl ----------------------------------------------------------------'
-
 AC_CONFIG_FILES([Makefile po/Makefile.in genlsm.sh])
 AC_OUTPUT
 
index 7c6e6e8f859c0d88369c5c8c4c3634aba0fa317c..096e24b8b4b32ec76caed9518702155f687a178b 100644 (file)
@@ -66,21 +66,6 @@ A shellscript front end for fetchmail that mails you various statistics on
 the downloaded mail and the state of your folders.  A good example of what
 you can do with your own front end.
 
-### fetchspool:
-
-If you find that the speed of forwarding to port 25 is limited by the
-SMTP listener's speed, it may make sense to locally spool all the mail
-first and feed it to sendmail after you hang up the network link.
-This shellscript aims to do exactly that.  It would be smarter to
-figure out why sendmail is slow, however.
-
-### fetchsetup:
-
-This is a shell script for creating a $HOME/.fetchmailrc file, it will ask
-you some questions and based on your answers it will create a .fetchmailrc
-file. fetchsetup is linux specific so it may not work on another operating
-system.
-
 ### mailqueue.pl:
 
 This script will connect to your ISP (if not already connected),
@@ -89,98 +74,12 @@ program made the connection, it will also break the connection
 when it is done.  By Bill Adams, <bill@evil.inetarena.com>.  The
 latest version is carried at <http://evil.inetarena.com/>.
 
-### redhat_rc:
-
-A fetchmail boot-time init file compatible with RedHat 5.1.  It leaves
-fetchmail in background to get messages when you connect to your ISP.
-The invoked fetchmail expects to find its configuration in
-/etc/fetchmailrc, and must include the proper "interface" directive.
-
-### debian_rc:
-
-A fetchmail boot-time init file compatible with Debian.  It leaves
-fetchmail in background to get messages when you connect to your ISP.
-The invoked fetchmail expects to find its configuration in
-/root/.fetchmailrc, and must include the proper "interface" directive.
-
-Matthias Andree adds: note that current Debian packages (as of January
-2007) ship with their own init files.
-
-### start_dynamic_ppp:
-
-An admittedly scratchy ip-up script that Ryan Murray wrote to cope with
-dynamic PPP addressing.  Will need some customizing.
-
-       http://www.inetarena.com/~badams/linux/programs/mailqueue.pl
-
-### getfetchmail:
-
-Here's a script that gets Eric's most recent fetchmail source rpm,
-downloads it and (if the rpm's not broken) rebuilds it.
-
-With fairly simple changes it can be used to download the latest i386 rpm
-or tar.gz.
-
-Those who are addicted to having the latest of everything could filter mail
-from fetchmail announce through it and get new versions as they're
-announced. However, if we all did that, Eric's ftp server might feel a
-little stressed.
-
-The script as written works on bash 2.  By John Summerfield
-<summer@os2.ami.com.au>.
-
-### zsh-completion:
-
-These commands set up command completion for fetchmail under zsh.
-Jay Kominek <jay.kominek@colorado.edu>.
-
 ### getmail/gotmail:
 
 These scripts are front ends for fetchmail in daemon mode that can gather
 log statistics and generate text or HTML reports.  See README.getmail for
 details.  Scripts by Thomas Nesges <ThomaNesges@TNT-Computer.de>.
 
-### fetchmaildistrib:
-
-This script resolves the issue where the sysadmin polls for mail with fetchmail
-only at set intervals, but where a user wishes to see his email right
-away. The duplication in /etc/fetchmailrc and ~/.fetchmailrc files is
-automated with this script; whenever /etc/fetchmailrc is changed, this
-script is run to distribute the stuff into all user's ~/.fetchmailrc
-files.
-
-### multidrop:
-
-Martijn Lievaart's sendmail hacks to make multidrop reliable.
-
-### domino:
-
-Gustavo Chaves <gustavo@cpqd.com.br> wrote this script to deal with 
-the boundary-mismatch bug in Domino (see FAQ item X5).  If you use
-this with --mda, the broken boundaries will be fixed and the result
-passed to procmail.
-
-### toprocmail:
-
-John Lim Eng Hooi <jleh@mail.com> wrote this script, yet another 
-mda plugin, to be used with fetchmail in foreground mode.  It displays
-some header lines to stdout in color, passing them (and the rest of the
-message content) to procmail.
-
-### preauth-harness:
-
-Emmanuel Dreyfus's Perl test script for exercising IMAP PREAUTH
-connections.  You'll have to patch in your username and password.
-
-### sm-hybrid:
-
-Peter 'Rattacresh' Backes sent this patch to improve the behavior of 
-sendmail 8.11.0 with multidrop.
-
-### fetchmailnochda.pl
-
-Watchdog script to check whether fetchmail is working in daemon mode.
-
 ### mold-remover.py
 
 A short python script to remove old read mail from a pop3 mailserver.
@@ -197,8 +96,8 @@ A logrotate configuration file developped by Daniel Leidert for Debian,
 when he wanted to use /var/log/fetchmail instead of the usual syslog.
 It probably needs to be adjusted for use on other systems.
 
-### delete-later (added 2007-03-17, --ma)
+### rawlog.patch (added 2011-06-17, --ma)
 
-A MySQL/Tcl/Expect-based client-side script to remove messages at a
-certain age.  See delete-later.README for details.
-(By Carsten Ralle, Yoo GmbH, Germany.)
+A patch against fetchmail 6.3.20 to allow creating a raw socket log if
+configured through an environment variable, to assist debugging and
+troubleshooting.  Documentation at the beginning of the file.
diff --git a/contrib/debian_rc b/contrib/debian_rc
deleted file mode 100755 (executable)
index 7bbdbdc..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/sh
-#
-# To start fetchmail as a system service, copy this file to
-# /etc/init.d/fetchmail and run "update-rc.d fetchmail
-# defaults".  A fetchmailrc file containg hosts and
-# passwords for all local users should be placed in /root
-# and should contain a line of the form "set daemon <nnn>".
-#
-# To remove the service, delete /etc/init.d/fetchmail and run
-# "update-rc.d fetchmail remove".
-
-DAEMON=/usr/bin/fetchmail
-
-set -e
-test -f $DAEMON || exit 0
-
-case "$1" in
-  start)
-        echo -n "Starting mail retrieval agent: "
-        if start-stop-daemon --start --quiet --exec $DAEMON; then echo "fetchmail."
-        else echo "fetchmail already running."; fi
-        ;;
-  stop)
-        echo -n "Stopping mail retrieval agent: "
-        start-stop-daemon --stop --quiet --exec $DAEMON
-        echo "fetchmail."
-        ;;
-  force-reload|restart)
-        echo -n "Restarting mail retrieval agent: "
-        start-stop-daemon --stop --quiet --exec $DAEMON
-        start-stop-daemon --start --quiet --exec $DAEMON
-        echo "fetchmail."
-        ;;
-  *)
-        echo "Usage: /etc/init.d/fetchmail {start|stop|restart}"
-        exit 1
-        ;;
-esac
-
-exit 0
diff --git a/contrib/delete-later b/contrib/delete-later
deleted file mode 100644 (file)
index 4db6973..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/expect -f
-
-# MySQL database connection settings
-set CRDB_host     localhost
-set CRDB_DB       test
-set CRDB_username root
-set CRDB_password root
-
-# set eiter one to 1 for verbose output
-log_user 0
-set comments 0
-
-package require mysqltcl
-
-# connect to MySQL database
-set handle [::mysql::connect -host $CRDB_host -user $CRDB_username -password $CRDB_password]
-
-# get server/usernames to clean up
-set userlist [::mysql::sel $handle "SELECT UserID, server, username, password, retaindays from $CRDB_DB.fetchmail_user" -flatlist]
-
-# loop through all users in database
-foreach {userid server username password days} $userlist {
-  if {$comments==1} { send_user "\r\nWorking on accound #$userid\r\n*******************************\r\n" }
-  eval spawn telnet -l fetchmail_cleanup $server 110
-  expect "ready"
-  send "USER $username\r"
-  expect "password"
-  send "PASS $password\r"
-  expect "OK"
-  send "STAT\r"
-  expect "+OK "
-  expect -re "\[0-9]* "
-  set anz $expect_out(0,string)
-  if {$comments==1} { send_user "message count: $anz \r\n" }
-  set i 0
-  while { $i < $anz } {
-    incr i
-    send "UIDL $i\r"
-    expect -re "\\\+OK $i \(.*\)\r"
-    set uid $expect_out(1,string)
-    ::mysql::exec $handle "insert ignore into $CRDB_DB.fetchmail values ($userid,'$uid',now());"
-    set age [::mysql::sel $handle "SELECT DATEDIFF(now(),Fetchdate) from $CRDB_DB.fetchmail where UserID=$userid and UID='$uid'" -list]
-    if {$comments==1} { send_user "Message #$i: UID: $uid , age: $age \r\n" }
-    if {$age > $days} {
-      send "DELE $i\r"
-      expect "deleted"
-      if {$comments==1} { send_user "Message $i deleted.\r\n" }
-    }
-  }
-  send "quit\r"
-  expect "signing off"
-  ::mysql::exec $handle "delete from $CRDB_DB.fetchmail where DATEDIFF(now(),Fetchdate)>($days*2) and UserID=$userid;"
-}
-::mysql::close $handle
-exit
-
diff --git a/contrib/delete-later.README b/contrib/delete-later.README
deleted file mode 100644 (file)
index a5f7972..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-*******************  DELETE - LATER ********************
-
-    version 0.11  2007-02-06
-
-
-    A tool for deleting email messages on POP3 accounts
-    after a given period of time (in days)
-
-    E.g. if you want to keep the messages 30 days to
-    have webmail access while on the road
-
-********************************************************
-
-  The script queries the current contents of a POP3 mailbox,
-  stores the message IDs of that run and saves them to a
-  MySQL database.
-
-  On each run, it compares the date on which the message was
-  first seen with the current date and deletes the message,
-  if that difference is greater than the value of the column
-  "retaindays".
-
-  The script stores account settings in a separate MySQL
-  table for easy maintenance each email account needs an
-  unique ID.
-
-  The script scales well on large installations with several
-  thousands of messages a day if you run it at a time of low
-  email volume (e.g. at 4 am).
-
-
-
-REQUIREMENTS
-------------
-
-- MySQL database server and client software (v4.x or later,
-  www.mysql.com)
-
-  MySQL sources (for compiling mysqltcl only)
-
-- mysqltcl script (www.xdobry.de/mysqltcl/)
-
-- libexpect (v5 or later)
-
-
-
-INSTALLATION
-------------
-
-1. create the tables "fetchmail" and "fetchmail_users" on a
-   MySQL server by running
-
-   CREATE TABLE `fetchmail` ( `UserID` BIGINT UNSIGNED NOT NULL DEFAULT 0, `UID` VARCHAR(255) NOT NULL DEFAULT '',  `Fetchdate` DATE NOT NULL DEFAULT 0,  PRIMARY KEY(`UserID`, `UID`));
-
-   CREATE TABLE `fetchmail_user` ( `UserID` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `server` VARCHAR(255) NOT NULL DEFAULT '', `username` VARCHAR(63) NOT NULL DEFAULT '', `password` VARCHAR(63) NOT NULL DEFAULT '',  `retaindays` INTEGER UNSIGNED NOT NULL DEFAULT 0, PRIMARY KEY(`UserID`));
-
-2. Fill the table "fetchmail_users" with the settings of the
-   email accounts you wish to handle
-
-3. copy the script "delete-later" to a safe place, (on
-   Linux/Unix: make it executable) and edit the first lines to
-   match your MySQL setup
-
-4. run "delete-later" via cron AFTER you fetched your emails
-   with settings that keep the messages on the server (e.g. via
-   fetchmail --keep)
-
-
-
-KNOWN ISSUES
-------------
-
-The mysqltcl libraries sometimes don't compile against
-earlier versions of MySQL 4.x.
-
-If you are experiencing any problems with compiling
-mysqltcl, please look for pre-compiled binaries for your
-distribution (or contact mail@xdobry.de), the win32 binaries
-work out of the box on most M$ systems.
-
-As most linux distributions don't include mysqltcl, get the
-latest precompiled 5.x series MySQL binariesand the matching
-source code from www.mysql.com, install them onto a separate
-location and run "configure && make && make install" to
-compile mysqltcl yourself.
-
-
-
-NOTES
------
-
-The age of an email message is calculated by the difference
-in days between the run of "delete-later" it was first seen
-on and the current date, not the actual date the message was
-sent. So if you run the script every week, the period after
-which a message is delete may vary up to 14 days.
-
-This was implemented that way, because of the common
-practice of spammers to change the message date to some date
-in the far future to place the message first in your inbox.
-
-
-
-COPYRIGHT
----------
-
-Copyright (c) 2007 Yoo GmbH
-                   Zellwaldring 51
-                   09603 GROSSVOIGTSBERG
-                   GERMANY
-
-Permission to use, copy, modify, distribute, and sell this software
-and its documentation for any purpose is hereby granted without fee,
-provided that the content of this README file appears in all copies
-of the software and related documentation.
-
-
-
-DISCLAIMER
-----------
-
-THE SCRIPT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
-
-WE (YOO) HEREBY DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD
-TO THIS README AND SCRIPT, INCLUDING ALL WARRANTIES AND CONDITIONS
-OF MERCHANTABILITY, WHETHER EXPRESS, IMPLIED OR STATUTORY, FITNESS
-FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT.
-
-IN NO EVENT SHALL YOO AND/OR ITS REPRESENTATIVES AND/OR RESPECTIVE
-SUPPLIERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
-DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
-OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
-TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
-PERFORMANCE OF THIS README OR SCRIPT.
-
-
-
-CONTACT
--------
-
-For help, bug reports or other request regarding "delete-later" please
-contact Carsten Ralle (English/German) by writing an e-mail to
-
-                   cr <at> i4yoo <dot> de
-
-with a subject starting with "DELETE-LATER: "
-
-Please note that messages containing HTML or images will be
-automatically deleted.
-
-
-
-********************************************************************************
-Yoo GmbH, Zellwaldring 51, D-09603 Grossvoigtsberg, Germany
-
-                                                                  www.yoogmbh.de
-********************************************************************************
diff --git a/contrib/domino b/contrib/domino
deleted file mode 100644 (file)
index a580271..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/usr/bin/perl -w
-# correct-domino-mime-conversion - does it!
-# $Id: domino,v 1.1 2004/06/08 03:59:00 rfunk Exp $
-
-use strict;
-
-# Any arguments are expected to be an mda invocation.
-if (@ARGV) {
-    my $mda = join(' ', @ARGV);
-    open(MDA, "| $mda") or die "Can't exec $mda: $!\n";
-    select(MDA);
-}
-
-# Look for a Boundary declaration in the message header
-my $decltag;
-while (<STDIN>) {
-    print;
-    if (/boundary=\"(.*)\"$/i) {
-       $decltag = $1;
-    } elsif (/^$/) {
-       # An empty line marks the end of the headers.
-       last;
-    }
-}
-
-# If we didn't find a Boundary declaration just pipe the rest of the
-# message unchanged.
-if (!defined $decltag) {
-    while (<STDIN>) {
-       print;
-    }
-    exit 0;
-}
-
-# Substitute $decltag for every ocurrence of an outer-level boundary
-# string found in the body of the message.
-my $usedtag;
-while (<STDIN>) {
-    if (/^--(.*)$/) {
-       $usedtag = $1 unless defined $usedtag;
-       if ($1 eq $usedtag) {
-           $_ =  "--$decltag\n";
-       } elsif ($1 eq "$usedtag--") {
-           $_ = "--$decltag--\n";
-       }
-    }
-    print;
-}
-
-=pod
-
-This script can be used to bypass a bug in the Domino-5.0.2b IMAP
-service that manifests itself when you use fetchmail as the IMAP
-client.  The problem is that fetchmail (differently from other IMAP
-clients) fetches messages in two parts, first the headers and then the
-body.  It seems that Domino converts the messages from its internal
-format into MIME twice.  In doing so, it declared a boundary string in
-the messages Content-type header and uses another one to separate the
-parts in the body.
-
-This script should be used as a mda option for fetchmail.  As
-arguments to it, pass the former mda you used.  I, for example, use the following entry in my .fetchmailrc:
-
-       poll server ... mda "/usr/bin/procmail -d %T";
-
-To use this filter, I changed the above into the following:
-
-       poll server ... mda "/home/gustavo/bin/correct-domino-mime-conversion /usr/bin/procmail -d %T";
-
-If you do not use a mda normally, you can try the following to call sendmail directly:
-
-       poll server ... mda "/home/gustavo/bin/correct-domino-mime-conversion //wherever/is/your/sendmail -oem -f %F %T";
-
-Without argumets this script is a filter that reads from its stdin and
-outputs the result into its stdout.
-
-I should mention that this bug seems to be solved in Domino 5.0.3
-(http://www.notes.net/46dom.nsf/434e319a66960d8385256857005cd97b/4499e0db6e43732b852568b2006ef7e9?OpenDocument)
-but I have not checked it.
-
-Gustavo.
-<gustavo@cpqd.com.br>
-
-=cut
index d22ebcafe3b203f034311b405b688e917defc3b1..53f69266bb4e83ee4772e85f923a5035e76b63f3 100644 (file)
@@ -75,7 +75,7 @@
 
 (unless fetchmail-keywords
    (setq fetchmail-keywords
-          '("poll" "skip" "via" "in" "proto" "protocol" "uidl" "no" "port" "auth" "authenticate" "timeout" "envelope" "qvirtual" "envelope" "aka" "localdomains" "interface" "monitor" "dns" "user" "username" "is" "folder" "pass" "password" "smtp" "smtphost" "smtpaddress" "antispam" "mda" "pre" "preconnect" "post" "postconnect" "keep" "flush" "fetchall" "rewrite" "forcecr" "stripcr" "pass8bits" "dropstatus" "limit" "fetchlimit" "batchlimit" "expunge" "pop2" "POP2" "pop3" "POP3" "imap" "IMAP" "imap-k4" "IMAP-K4" "apop" "APOP" "rpop" "RPOP" "kpop" "KPOP" "etrn" "ETRN" "login" "kerberos" "kerberos_v5" "logfile" "daemon" "syslog" "invisible" "and" "with" "has" "wants" "options" "here" "there" "aka" "set")))
+          '("poll" "skip" "via" "in" "proto" "protocol" "uidl" "no" "port" "auth" "authenticate" "timeout" "envelope" "qvirtual" "envelope" "aka" "localdomains" "interface" "monitor" "dns" "user" "username" "is" "folder" "pass" "password" "smtp" "smtphost" "smtpaddress" "antispam" "mda" "pre" "preconnect" "post" "postconnect" "keep" "flush" "fetchall" "rewrite" "forcecr" "stripcr" "pass8bits" "dropstatus" "limit" "fetchlimit" "batchlimit" "expunge" "pop3" "POP3" "imap" "IMAP" "imap-k4" "IMAP-K4" "apop" "APOP" "rpop" "RPOP" "kpop" "KPOP" "etrn" "ETRN" "login" "kerberos" "kerberos_v5" "logfile" "daemon" "syslog" "invisible" "and" "with" "has" "wants" "options" "here" "there" "aka" "set")))
 
 (defvar fetchmail-keyword-table nil
   "Completion table for fetchmail-mode" )
diff --git a/contrib/fetchmaildistrib b/contrib/fetchmaildistrib
deleted file mode 100644 (file)
index 00cc191..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-#/bin/bash
-#
-# fetchmaildistrib --- Distribute central fetchmail knowledge.
-#
-# The central fetchmail database, /etc/fetchmail, contains all accounts that
-# are to be fetched by the root's daemon. Often, a user desires quicker
-# access (e.g., when testing some email path). In such cases, the destination
-# user (marked as is USER here in the poll lines) should set up a ~/.fetchmailrc
-# for himself. This scripts generates such lines from the central file.
-#
-# By Rick van Rein.
-
-# From stdin, select poll lines for user $1
-function selectuser () {
-       grep ^poll | grep "is $1 here"
-}
-
-
-for i in `cut -d: -f1 </etc/passwd`
-do     homedir=`grep ^$i: /etc/passwd | cut -d: -f6`
-       fetchfile=`selectuser $i </etc/fetchmailrc`
-       if [ -z "$fetchfile" ]
-       then    rm -f $homedir/.fetchmailrc
-       else    cp /dev/null $homedir/.fetchmailrc
-               chmod go-rwx $homedir/.fetchmailrc
-               grep ^defaults /etc/fetchmailrc >>$homedir/.fetchmailrc
-               selectuser $i </etc/fetchmailrc >>$homedir/.fetchmailrc
-       fi
-done
diff --git a/contrib/fetchmailnochda.pl b/contrib/fetchmailnochda.pl
deleted file mode 100755 (executable)
index b0a8960..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/perl
-
-# User contribution to fetchmail by Torsten Mueller torsten@archesoft.de
-# v1.1 22/may/2001
-
-# the reason for this script is to check, if fetchmail (in daemon mode) works
-# you should have perl and the perlmodule File::Compare installed
-# File::Compare you can find at http://www.cpan.org/
-
-# installation:
-# edit the config part of this script
-# create a cronjob , the time it should run should be higher than the pollintervall !!
-
-# possible problems:
-# you have set the cron intervall to short
-# the script doesn't have permissions to write to directories or to execute fetchmail
-# you didn't start fetchmail in daemon mode but use cron to fetch mail
-# you can't read my english
-
-# how does it work
-# really simple, the script checks, if there was a change to the logfile of fetchmail
-# to find this out, the script makes a backup of the original logfile and compares 
-# the size of the original and the backup logfile
-# i know it's a dirty way, but hey, it works ...
-use File::Compare;
-
-# config
-# where lives fetchmail on your system
-$fetchmail = '/usr/bin/fetchmail';
-# where should be the logfile for fetchmail
-$fetchmaillog = '/var/log/fetchmail.log';
-# where could the script write the backup of the logfile
-$fetchmailwatch = '/var/log/fetchmailwatch';
-# after how many seconds fetchmail should get mail, the poll intervall
-$fetchmailtime = '3600';
-# which config file should fetchmail use for retrieval
-$fetchmailconf = '/root/.fetchmailrc';
-# where lives your cp program 
-$copycp = 'cp';
-#end config
-
-if (!(-e "$fetchmaillog")) {
-# es existiert keine logdatei von fetchmail
-# there isn't a logfile of fetchmail
-print "There seems to be a problem with the fetchmail daemon\n
-I couldn't find a logfile of fetchmail.\n
-I try to stop and to start fetchmail in daemon mode.\n
-If you get this mail more then once, then check your system !\n
-------------------------------------------------------------\n
-Es ist ein Fehler aufgetreten bei der Ueberwachung des fetchmail Daemons\n
-Es existiert keine Logdatei. Ich versuche jetzt fetchmail zu stoppen und neu zu \n
-starten. Sollte das Problem nochmal auftreten, dann genaue Systeminspektion !\n
-------------------------------------------------------------\n
-Das fetchmail Ueberwachungsscript Copyright 2001 by T. Mueller torsten\@archesoft.de\n\n";
-
-system "$fetchmail -q";
-sleep 3 ;
-system "$fetchmail -f $fetchmailconf -d $fetchmailtime -L $fetchmaillog";
-sleep 2 ;
-
-}
-
-if (!(-e "$fetchmailwatch")) {
-# die kopie der logdatei existiert nicht
-# the copy of the original logfile doesn't exists
-print "There seems to be a problem with the fetchmail daemon\n
-I couldn't find the copy of the original logfile of fetchmail.\n
-If this is this the first run of this script, then this is no problem!\n
-If you get this mail more then once, then check your system !\n
-------------------------------------------------------------\n
-Es ist ein Fehler aufgetreten bei der Ueberwachung des fetchmail Daemons\n
-Es existiert keine Kopie der Logdatei. Wenn das Script das erste Mal aufgerufen wurde,\n
-dann ist dies kein Problem. Sollte dieses Problem nochmal auftreten, dann genaue Systeminspektion !\n
-------------------------------------------------------------\n
-Das fetchmail Ueberwachungsscript Copyright 2001 by T. Mueller torsten\@archesoft.de\n\n";
-&copylog;
-exit; }
-
-
-$vergleich = compare("$fetchmaillog","$fetchmailwatch");
-
-if ($vergleich == -1) {
-# irgendein fehler ist aufgetreten
-# unknown error
-print "There seems to be a problem with the fetchmail daemon or this script\n
-I don't know, why this error happens.
-Please check the script and your system
-------------------------------------------------------------\n
-Es ist ein Fehler aufgetreten bei der Ueberwachung des fetchmail Daemons\n
-Bitte die notwendigen Schritte unternehmen, z.B. Festplattenspeicherplatz pruefen\n
-noch eine kommt.\n
-------------------------------------------------------------\n
-Das fetchmail Ueberwachungsscript Copyright 2001 by T. Mueller torsten\@archesoft.de\n\n";
-}
-
-
-if ($vergleich == 0) {
-# dateien sind gleich also also eine aktion starten
-# the copy and the original logfile have the same size
-print "There seems to be a problem with the fetchmail daemon\n
-The logfile seems the be the same as the last logfile i have seen.
-That could mean, that fetchmail hangs, or permissionproblems or disk full.
-I try to stop and to start fetchmail in daemon mode.\n
-If you get this mail more then once, then check your system !\n
-------------------------------------------------------------\n
-Scheinbar gab es ein Problem mit dem Programm fetchmail\n
-Die Logdatei war identisch mit der Logdatei beim  letzten Lauf diese Scriptes\n
-Daraus schlussfolgere ich, dass nichts mehr geloggt wurde -> fetchmail hat ein Problem\n
-Ich habe fetchmail versucht zu stoppen, und wieder neu zu starten.\n
-Sollte diese Mail heute noch mehrfach erscheinen, dann ist eine genauere Inspektion\n
-der Umstaende notwendig. Ist dies die erste Mail, dann einfach mal abwarten, ob\n
-noch eine kommt.\n
-------------------------------------------------------------\n
-Das fetchmail Ueberwachungsscript Copyright 2001 by T. Mueller torsten\@archesoft.de\n\n";
-
-system "$fetchmail -q";
-sleep 3 ;
-system "$fetchmail -f $fetchmailconf -d $fetchmailtime -L $fetchmaillog";
-sleep 2 ;
-
-}
-
-
-&copylog;
-
-sub copylog {
-system "$copycp $fetchmaillog $fetchmailwatch";
-}
-
-
diff --git a/contrib/fetchsetup b/contrib/fetchsetup
deleted file mode 100755 (executable)
index 83223a1..0000000
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/bin/sh
-
-MSG() {
-cat << EOF
-
-# Fetchsetup is a shell script for creating a .fetchmailrc file, that will be
-# used by the program "fetchmail" to connect to your mail domain and retrieve
-# your mail.
-# This script is linux specific, so it may not work on another system.
-# Kent Robotti <krobot@erols.com> (3-31-99)
-
-EOF
-}
-
-if [ "$(id -ur)" != "0" ]; then
-    echo >&2 "$0: You need to be root [found $(id -un)] to run this script."
-    echo >&2 "You could login as root"
-    echo >&2 "You could also try one of these: # sudo fetchsetup"
-    echo >&2 "                                 # su root -c fetchsetup"
-    exit 1
-fi
-
-MSG
-echo -n "Continue? (Y/n) : "
-read ans
-if [ "$ans" = "n" -o "$ans" = "N" ]; then
-    echo "Cancelled."
-    exit 0
-fi
-
-stty erase "^?" 2>/dev/null
-
-echo
-echo "Remote mail site?: pop.boo.com   <Your service providers mail domain name>"
-echo -n "Remote mail site?: "
-read SITE
-echo
-echo "Protocol?: pop3   <My service provider uses the 'pop3' mail protocol>"
-echo "Protocol?: auto   <If not sure put: auto>"
-echo "Choices: apop auto etrn imap imap-gss imap-k4 kpop pop2 pop3 rpop sdps"
-echo -n "Protocol?: "
-read PROTO
-echo
-echo "Remote username?: jerry   <My username or login is jerry>"
-echo -n "Remote username?: "
-read USR
-echo
-echo "Remote password?: ?       <What's the password for?: $USR>"
-echo -n "Remote password?: "
-read PASS
-
-echo
-echo -n "Create $HOME/.fetchmailrc file? (Y/n) : "
-read ans
-if [ "$ans" = "n" -o "$ans" = "N" ]; then
-    echo
-    echo "Fetchsetup cancelled."
-    echo
-    exit 0
-fi
-
-echo 'poll "'$SITE'"' > $HOME/.fetchmailrc
-echo "protocol $PROTO" >> $HOME/.fetchmailrc
-echo 'username "'$USR'"' >> $HOME/.fetchmailrc
-echo 'password "'$PASS'"' >> $HOME/.fetchmailrc
-
-PROCMAIL=`type -all procmail | sed -n "1 p" | cut -d' ' -f3`
-SENDMAIL=`type -all sendmail | sed -n "1 p" | cut -d' ' -f3`
-
-if [ ! "$PROCMAIL" = "" ]; then
-    echo 'mda "'$PROCMAIL -d %s'"' >> $HOME/.fetchmailrc
-    MDA="1"
-elif [ ! "$SENDMAIL" = "" ]; then
-    echo 'mda "'$SENDMAIL %s'"' >> $HOME/.fetchmailrc
-    MDA="2"
-else
-    MDA="3"
-fi
-
-echo >> $HOME/.fetchmailrc
-echo
-echo "This is your $HOME/.fetchmailrc file."
-
-chmod 600 $HOME/.fetchmailrc
-
-echo
-cat $HOME/.fetchmailrc
-
-if [ ! "$MAIL" = "" ]; then
-    echo "Fetchmail will retrieve your mail and put it in:"
-    echo "$MAIL"
-    if [ ! -f "$MAIL" ]; then
-       touch $MAIL 2>/dev/null
-       chmod 600 $MAIL 2>/dev/null
-    fi
-fi
-
-echo
-if [ "$MDA" = "1" ]; then
-    echo "I put that (m)ail (d)elivery (a)gent in .fetchmailrc"
-    echo "because i found it on your system, this doesn't mean"
-    echo "it's correct or the one you want to use."
-    echo
-    echo "The first time you run fetchmail, you should run it"
-    echo "this way: # fetchmail -k"
-    echo
-elif [ "$MDA" = "2" ]; then
-    echo "You seem to have sendmail, sendmail will be used"
-    echo "as the (m)ail (d)elivery (a)gent for fetchmail."
-    echo
-    echo "WARNING! There's no way to know if sendmail is set up"
-    echo "properly for local mail delivery, so the first time you"
-    echo "run fetchmail run it this way: # fetchmail -k"
-    echo
-    echo "If the mail that fetchmail retrieves is not put in your mailbox,"
-    echo "you'll know that sendmail is not set up properly for the delivery"
-    echo "of local mail."
-    echo
-elif [ "$MDA" = "3" ]; then
-    echo "I Don't know what (m)ail (d)elivery (a)gent you're going to use."
-    echo "You need a <mda> to deliver the mail to you, after <fetchmail> retrieves it."
-    echo
-    echo "Put the <mda> in your .fetchmailrc file, like below."
-    echo "password $PASS"
-    echo mda '"/usr/bin/procmail -d %s"'
-    echo mda '"/usr/sbin/sendmail %s"'
-    echo
-    echo "The first time you run fetchmail, you should run it"
-    echo "this way: # fetchmail -k"
-    echo
-fi
diff --git a/contrib/fetchspool b/contrib/fetchspool
deleted file mode 100644 (file)
index cd6c2c8..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/sh -
-#
-# Quick hack for fetchmail to locally spool messages.
-#
-# To spool:
-#     fetchmail --mda "fetchspool -t %T %F"
-# To de-spool
-#     fetchspool -f
-#
-# Robert de Bath  <robert@mayday.cix.co.uk>
-# updated by william boughton <bill@xencat.demon.co.uk>
-# 4th/10/1998 and tested
-#
-# William Boughton comments:
-# Still has some potential problems, with using inline from address.
-# The use of _ is bad because fetchmails uses this if it notices
-# shell escapes.
-# 10th/11/1998
-# Changed to using 3 _@@s to delimit the message, i hope this is ok.
-# Whilst i have tested and used this script, with my demon account and
-# SDPS, it may still have serious problems, that i've not noticed etc.
-
-MAILSPOOL=/tmp/spool
-
-if [ "$1" != "-f" ]
-then
-   if [ "$1" = "-t" ]
-   then 
-       ADDR="$2"
-       FROM="$3"
-   else 
-       ADDR="$1"
-       FROM="$2"
-   fi
-
-   cat - > $MAILSPOOL/tmp.$$                              || exit 1
-   mv $MAILSPOOL/tmp.$$ "$MAILSPOOL/msg.`date +%j%H%M%S`$$.to.${ADDR}_@@${FROM}"  || exit 1
-
-   exit 0
-else
-   for i in $MAILSPOOL/msg.*.to.*
-   do
-      [ -f "$i" ] || continue
-     # TO="`echo \"$i\" | sed 's/^msg.[^.]*.to.//'`"
-       TO=$(basename $i | sed -e 's/^msg.[^.]*.to.//' -e 's/_@@.*$//')
-       FROM=$(basename $i | sed 's/^msg.[^.]*.to.*_@@//')
-# need the \<\> so for bounces to have a proper from addr
-echo the to was \<$TO\>  and the from \<$FROM\>
-      /usr/lib/sendmail -f \<${FROM}\> -oem "$TO" < "$i" ||
-      {
-         echo "Sendmail failed on `basename \"$i\"`"
-        continue
-      }
-      rm -f "$i"
-   done
-   exit 0
-fi
-
diff --git a/contrib/getfetchmail b/contrib/getfetchmail
deleted file mode 100644 (file)
index bcac9d3..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/bash 
-RH=ftp.ccil.org
-p=`\
-echo dir /pub/esr/fetchmail/f\*src.rpm \
-   | ftp $RH \
-   | grep /pub/esr/fetchmail/fetchmail-[45] \
-   | tail -1`
-#p='-rw-r--r-- 1 23 wheel 478424 Dec 18 03:54 /pub/esr/fetchmail/fetchmail-4.7.1-1.src.rpm'
-#echo $p | sed -e "s=^.^/pub=pub="
-p1=`echo $p | sed -e "s=^.*/pub=pub="`
-#echo $p1
-#basename  $p1
-#dirname $p1
-d=`dirname $p1`
-f=`basename $p1`
-cd /work/incoming
-email=$LOGNAME\@`hostname`
-ftp -n <<ZZ
-open $RH
-user anonymous $email
-cd /$d
-get $f
-bye
-ZZ
-rpm -K $f >/dev/null 2>&1 \
-   || {
-         rpm -K $f 2>&1 | mail $email -s "error getting $f"
-         exit 
-      }
-rpm --rebuild  $f 2>&1 |\
-   mail $email -s "Rebuilding $f"
diff --git a/contrib/getfetchmail.pl b/contrib/getfetchmail.pl
deleted file mode 100644 (file)
index 45bd3c6..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/perl -w
-# Copyright 2001 John Summerfield, summer@summer.ami.com.au
-# GPL 2 applies.
-#
-($flags, $links, $owner, $gowner, $size, $month, $day, $timeOrDate, $name, $junk, $junk2, $junk1) ='';
-$RemoteHost="ftp.ccil.org";
-$LocalDir="/home/u03/incoming/";
-$FilePattern="/pub/esr/fetchmail/fetchmail\*src.rpm";
-$GrepArgs="fetchmail-[5-9]";
-$no=0;
-$TempFile=`mktemp /var/tmp/getfetchmail.XXXXXX`;
-@files=`echo dir $FilePattern | ftp $RemoteHost  | egrep $GrepArgs`;
-chomp @files;
-open(FTP, "| ftp -d -v $RemoteHost | egrep '^213|MDTM'  >$TempFile");
-foreach $L (@files)
-{
-       ++$no;
-       $L =~ s/  */,/g;
-       ($flags, $links, $owner, $gowner, $size, $month, $day, $timeOrDate, $name, $junk) = split /,/,$L;
-       next unless substr($timeOrDate,2,1) eq ':';
-       print FTP "modtime $name\n";
-#      last if $no > 4;
-}
-close FTP;
-
-$SavedTime=0;
-$time=1;
-$SavedName='';
-open (FILES,$TempFile);
-while ($rec = <FILES>)
-{
-       chomp $rec;
-       ($junk1, $junk2, $filename) = split / /,$rec if substr($rec,0,4) eq '--->';
-       $time = substr($rec,4) if substr($rec,0,3) eq '213';
-       if (($time > $SavedTime) && (substr($rec,0,3) eq '213'))
-       {
-               $SavedTime=$time;
-               $SavedName=$filename;
-       }
-}
-close FILES;
-$LocalName = $SavedName; $LocalName =~ s=.*/==;
-$LocalName = $LocalDir . $LocalName;
-$Y=substr($SavedTime,0,4);
-$M=substr($SavedTime,4,2);
-$D=substr($SavedTime,6,2);
-$h=substr($SavedTime,8,2);
-$m=substr($SavedTime,10,2);
-$s=substr($SavedTime,12,2);
-print "I should get $SavedName and store it in $LocalName\n";
-open(SH,"|/bin/bash");
-print SH <<zz
-set -x
-echo get $SavedName $LocalName \| ftp $RemoteHost 
-rpm -K $LocalName \|\| exit $?
-touch -t $Y$M$D$h$m.$s  $LocalName
-rpm --rebuild $LocalName
-zz
-;
-close SH;
-
diff --git a/contrib/multidrop b/contrib/multidrop
deleted file mode 100644 (file)
index 37f87b4..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-From mlievaart@orion.nl  Mon Jan 10 10:46:33 2000
-From: Martijn Lievaart <mlievaart@orion.nl>
-To: Eric S. Raymond <esr@thyrsus.com>
-Date: zondag 9 januari 2000 0:38
-Subject: Re: Thanks for fetchmail and a solution to the multidrop problem (I
-Status: O
-Content-Length: 8086
-Lines: 226
-
-think)
-
-Hello Eric,
-
-Let me first state that I'm no sendmail nor unix guru, so although this
-seems to work, I certainly would not say this is the "best" solution. In
-fact I would welcome all comments to make this better. In particular, it
-seems that that the mailertable feature was made just for this, but I'm
-still studying that.
-
-Also, This mail will have lines wrapped. I will put up this on a website
-asap, so people can download the relevant portions. In the meantime, I'm
-using (stuck on) Outlook, so I won't even attempt to format this mail.
-Accept my apoligies and try to mentally reconnect the lines.
-
-Finally, this mail is a bit lengthy, but I guess it is better to get all
-information in, so please bear with me.
-
-After some very frustrating attempts to get multidrop to work reliably, it
-suddenly hit me. When sendmail has translated the recipient to the mailbox,
-the recipient is gone (in the cases we're talking about). So the solution is
-not to let sendmail do this translation (completely).
-
-The trick is to let a custom MDA be called with both the mailbox and the
-full recipient name. This MDA then just stuffs it in the correct mailbox
-after adding the appropriate headers. Luckily I hit on the formail utility.
-It reformats a mailmessage and does just what I wanted. Specifically my
-script uses it to:
-- add a custom header (default: "Delivered-To:") with the recipient
-- rewrite the message-ID, so fetchmail will download the same message
-multiple times.
-- add another header, just for fun.
-
-The rewriting of the message-ID is needed because fetchmail will suppress
-multiple messages with the same ID, normally a good idea, but now it gets in
-the way. A switch on fetchmail to suppress this behaviour would be great.
-
-At first I hardcoded the domains in the sendmail.cf, but I quickly set out
-to do one better and came up with the following solution. In sendmail.cf,
-add the following line somewhere at the top.
-
-Kmultidroptable hash -o /etc/mail/multidroptable
-
-this defines a table for all domains we want to use multidrop for. The
-format of this file is multiple lines of the format:
-<domain>    <mailbox>
-
-e.g:
-mailtest.orion.nl       mailtest
-mailtest2.orion.nl      mailtest
-mailtest3.orion.nl      mailtest
-bvh-communicatie.nl     b.bvh
-krakatau.nl             b.bvh
-personeelzaak.nl        b.bvh
-maslowassociates.nl     b.bvh
-rtij.nl                 rtij
-
-Of course, create a .db file with makemap. Also, the domains must be added
-to class w, so they should be added to your sendmail.cw or RelayTo file, or
-whatever you use.
-
-Now add to sendmail.cf:
-
-R$+ < @ $* . >                          $: <MULTIDROP> $(multidroptable $2
-$: <NO> $) <?> $1 < @ $2 . >
-R<MULTIDROP> <NO> <?> $*                $: $1
-R<MULTIDROP> $+ <?> $+ < @ $* . >       $#drop $@ $2 @ $3 $: $1
-
-These lines should be above the existing lines that read:
-
-# short circuit local delivery so forwarded email works
-R$=L < @ $=w . >        $#local $: @ $1         special local names
-R$+ < @ $=w . >         $#local $: $1                   regular local name
-
-This works as follows (in fact these comments are above my modification in
-our sendmail.cf).
-#
-# MLI. Any drop host gets passed to the drop script
-#
-# The first rule looks up the domain in the multidrop table.
-# The input at this point is always:
-#       user@<dom.ain.>
-#  If found, the resulting line looks like this:
-#       <MULTIDROP> mailbox <?> user@<dom.ain.>
-# if not found, the resulting line will be:
-#       <MULTIDROP> <NO> <?> user@<dom.ain.>
-# The second line restores the "not found" case back to user@<dom.ain.>
-# So if this domain was found in the multidroptable, we still have a line
-starting with <MULTIDROP>
-# as shown above. The third line hands this to the drop script.
-#
-# Note that the user ($:) is the mailbox this message should be stuffed in,
-the host ($@) is the full
-# user@<dom.ain>. This is how the dropscript expects it.
-#
-
-I guess sendmail guru's are now laughing their pants off, and I hope someone
-will show me a better way to achieve this. For now, it works.
-
-Next, we need to define mailer drop (somewhere in the sendmail.cf)
-
-#
-# multidrop pop3 support.
-#
-
-Mdrop,          P=/usr/local/bin/dropmail, F=lFS,
-                T=X-Unix,
-                A=dropmail $u $h
-
-The S flag here is crucial, otherwise the dropmail script won't run as root,
-and under linux (==bash) suid scripts are not permited. I gather most unices
-now disalow suid scripts, so this would be necessary on most unices. There
-probably are other flags that would make this better, but this works, so I
-decided to divert my attention to other tasks at hand (busy, busy, busy....
-;^>).
-
-Now we only need the dropmail script, /usr/local/bin/dropmail, mode 700. It
-looks big, but effectively one pipeline does the real work. The rest is
-configuration, error checking and locking the mailbox.
-
-#!/bin/bash
-
-#
-# Script to force a mail message in a format that fetchmail will recognise.
-# use as a MDA from sendmail. Must be executed with F=S.
-#
-
-#
-# Configuration:
-#
-maildir=/var/spool/mail
-envelope=Delivered-To:
-
-#
-# set PATH to a known value to avoid some security issues
-#
-export PATH=/bin:/usr/bin
-
-#
-#
-#
-to=$2
-user=$1
-mbox=$maildir/$user
-
-#
-# If the mailbox does not exist, create it. Note that we act pretty
-paranoid, this is hopefully
-# resistant to symlink attacks
-#
-if [ ! -f $mbox ]
-then
-        oldumask=`umask`
-        umask 077
-        touch $mbox
-        chmod 660 $mbox || exit 1
-        chown $user $mbox || exit 1
-        chgrp mail $mbox || exit 1
-        umask $oldumask
-fi
-
-# First lock the mailbox, if this doesn't succeed in 64 seconds, give up and
-send
-# mail to postmaster.
-# If this period is to short, increase the retries (-r flag to lockfile)
-#
-# Then run the message through formail to get it into the right mailbox
-format with the
-# right headers added.
-#
-# Delivered-To will make fetchmail propagate this mail to the correct user
-when
-# run with '-E "Delivered-To"'. Set this in the advanced settings of the
-TeamInternet f.i.
-# (if you changed the envelope at the start of this script, adapt this
-accordingly)
-#
-# We also muck up the messageid, so fetchmail will never skip a message on
-the basis of
-# duplicate messageIDs. The -i "Message-ID" will rename the old message ID,
-the -a will
-# add a new one.
-#
-# Lastly, we add a header indicating which host did the rewriting.
-#
-
-if lockfile -r 8 $mbox.lock >/dev/null 2>&1
-then
-        cat - | formail -i "$envelope <$to>" -i "Message-ID:" -a
-"Message-ID:" -i "X-Multidrop-Processing: <`hostname`>" >>$mbox
-        rm -f $mbox.lock
-else
-        (echo "Subject: Cannot lock mailbox for $user" & cat -) |
-/usr/lib/sendmail postmaster
-fi
-
-#
-# EOF
-#
-
-This obviously is very Linux (even RedHat?) dependant, locking mailboxes,
-creating mailboxes with the right permissions, probably even bash dependent.
-I would say that it should be fairly easy to port to other systems, but
-alas, my unix knowledge is lacking for that. I'll also rewrite it someday,
-a.o. that umask handling can be done much better and the location of the
-sendmail binairy should not be fixed.
-
-Now the only thing left to do is to retrieve the mail with fetchmail, using
-'envelope "Delivered-To:"' in the poll line. The above script has added this
-line, so this is all that fetchmail needs.
-
-All parts of this solution need carefull examination. In particular I think
-the new rule lines may not catch all cases, although they worked for
-everything I threw at them and work satisfactorily in production. I'm also
-wondering if there is a more standard way to drop something in a mailbox. I
-yet have to investigate procmail, but all other MDA's mucked with the
-message and effectively undid my carefully added header. I'll experiment
-some more and rethink it all as I learn more.
-
-I'm still wondering, if I can get formail to include another received
-line.... "Received from localhost by dropmail for <user>...." to make it
-work without the envelope flag. Well I'll have to experiment. Do you know if
-there is a header I can add so fetchmail works out-of-the-box?
-
-Regards,
-Martijn Lievaart
-
diff --git a/contrib/poptest b/contrib/poptest
deleted file mode 100644 (file)
index 3f74cff..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/usr/bin/perl
-# Copyright 2000 john Summerfield ,summer@os2.ami.com.au>
-# Your choice of licence: GPL 2 or later, or same licence as Perl.
-#
-# Warranty?                                    None
-# If it breaks?                                The pieces are yours
-# If it breaks something?      You drove it.
-# Bugs?                                                        At least one.
-
-# now we've cleared the air;
-#      This supposed to allow one to talk pop-3 to a mail server. If you're lucky (and know how)
-#              you might also be able to talk a few other Internet protocols with it.
-#      Typically, it's run thus:
-#              pop2test.1 <mailserver> [<mailport>]
-#      mailport's optional; default is 110 (pop-3).
-#      
-#      Having started, you type away much as you would with telnet.
-#      
-#      
-#      
-#      It has this great advantage over telnet: it reads its input from stdin and writes to stdout;
-#              you can prepare the entire sequence in a file, then run it this:
-#                      pop2test.1 <thefileyoujustcreated >theresultsyouwanttoperuse host port
-#      
-#      
-#      uses:
-#              1       Debugging POP3 (and maybe imap does anyone know?) mail problems
-#              2       Deleting the occasional piece of mail that's too big or stuffs fetchmail.
-#              3       Talking to sendmail
-#      
-use Socket;
-sub hx;
-sub getreply;
-$timeout=1;
-$RemoteHost = $ARGV[0];shift;
-$RemotePort = $ARGV[0] || 110;shift;
-($PRname,$PRaliases,$PRport,$PRproto) = getservbyname($RemotePort,'tcp');
-$PRport=$RemotePort unless $PRport;
-$proto=getprotobyname($PRproto);  
-$RemoteIP = inet_aton $RemoteHost or die "Can't resolve $RemoteHost";
-$that = pack 'Sna4x8',AF_INET, $PRport, $RemoteIP;
-socket(REMOTESITE,AF_INET,SOCK_STREAM,$proto)
-        or die "Can't create socket to $RemoteHost: $!\n";;
-connect(REMOTESITE, $that) or die "Can't connect: $!\n";
-select(REMOTESITE);$|=1;select STDOUT;
-$rin = $win = $ein = '';
-vec($rin,fileno(REMOTESITE),1) = 1;
-#vec($win,fileno(REMOTESITE),1) = 1;
-$ein = $rin | $win;
-getreply;
-while ($L=<STDIN>)
-{
-       chomp $L;
-       print REMOTESITE $L . "\r\n";
-       print "send: " . $L . "\n";
-       getreply;
-}
-print REMOTESITE "Quit\r\n";
-getreply;
-#print <REMOTESITE>;
-close REMOTESITE;
-exit;
-# P
-sub hx
-{
-       $N=$_[0];shift;
-       $S=$_[0];shift;
-       return "$N(" . unpack("h", $S) . ") "; 
-}
-sub getreply
-{
-       while ('x')
-       {
-               ($nfound,$timeleft) = select($rout=$rin, undef, $eout=$ein, $timeout);
-               last if $nfound == 0;
-#              print "nf($nfound) tl($timeleft) " . hx("rin",$rin) . hx("rout", $rout) . hx("ein",$ein) . hx("eout",$eout) . "\n";
-               $Reply= <REMOTESITE>;
-               print "recv: " . $Reply;
-               last if $Reply eq '';
-               $Reply =~ s/[\r\n]*//;
-               last if $Reply eq '.';
-       }
-}
-
diff --git a/contrib/preauth-harness b/contrib/preauth-harness
deleted file mode 100755 (executable)
index 0bd0d84..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/perl
-
-BEGIN { $SIG{'__WARN__'} = sub {};};
-
-$hostname = "criens.u-psud.fr";
-$username = "p99dreyf";
-$passwd = "xxxxxxxx";
-$command = "exec ~/bin/imapd";
-
-use Net::Telnet ();
-$host = new Net::Telnet (Timeout => 10,
-                         Port => 23,
-                         Prompt => '/p99dreyf>\s?$/',
-                         Cmd_remove_mode => 1);
-
-$host->option_accept(Dont => &Net::Telnet::TELOPT_ECHO,
-                     Wont => &Net::Telnet::TELOPT_ECHO);
-                     open (FILE,">log");
-$host->dump_log("log2");
-$host->input_log("log3");
-## Issue some commands.
-$host->open($hostname);
-#$host->login($username, $passwd);
-$host->waitfor('/login:\s?$/');
-$host->print("$username");
-$host->waitfor('/Password:\s?$/');
-$host->print("$passwd");
-$host->waitfor('/p99dreyf>\s?$/');
-
-$host->print("$command");
-$strip=1;
-while ($strip) {
-        $greeting=$host->getline();
-   if ($greeting=~/^\* PREAUTH.*$/) { print "$greeting"; $strip=0;};
-}
-    do {
-      do {
-        $cmd=<STDIN>;
-        chop $cmd;
-      } while ($cmd !~/[A-Za-z0-9]/);
-      $host->print("$cmd");
-      print FILE ">>$cmd<<\n";
-      do {
-        $line=$host->getline();
-        chop($line);
-        print "$line\n";
-        print FILE "<<$line<<\n";
-      } while (($line!~/^[A-Za-z0-9]+ (OK|BAD|Expunge).*$/) &&
-                ($line!~/^\* BAD.*$/));
-      print FILE "--next cmd\n";
-    } while ($line!~/^[A-Za-z0-9]+ OK LOGOUT.*$/);
-
-exit;
index a341d4e169ba44d3adb9ba81a7b7e4be4d72f367..bec08b5efa2f2b8d45bf23a19e6578c2f391773e 100644 (file)
@@ -1,16 +1,29 @@
 This patch logs raw socket data, to assist debugging when discriminating
 between server and fetchmail bugs.
 
-Apply it to fetchmail 6.3.20 and set the environment variable
-FETCHMAIL_RAW_LOGFILE to a log file writable by fetchmail. If it's not
-there, it gets created with mode 0600 (which requires directory write
-permission).
+Apply it to socket.c (works as of 6.3.20) and set the environment
+variable FETCHMAIL_RAW_LOGFILE to a log file writable by fetchmail. If
+it's not there, it gets created with mode 0600 (which requires directory
+write permission).
 
 The file gets appended to, so you can log into named pipes, character
 (stream) devices and to the console if you're so inclined.
 
 Note 1: any logging failures cause fetchmail to abort() forcefully.
 
+Note 2: raw control characters persist in the log and are not filtered
+out. In doubt use a pager that filters control characters, or use tools
+such as a binary-capable text edtior, vim's xxd, or hexdump, or od, to
+view the raw log message.
+
+-- Matthias Andree, June 2011
+
+diff --git a/socket.c b/socket.c
+index c8117a5..89847fe 100644
+--- a/socket.c
++++ b/socket.c
+@@ -362,6 +362,49 @@ static    SSL *_ssl_context[FD_SETSIZE];
+=======
 Note 2: non-printable characters are hex-escaped, so it is safe to use
 FETCHMAIL_RAW_LOGFILE=/dev/stderr or similar.
 
@@ -36,6 +49,7 @@ index e338207..dcaf19d 100644
 --- a/socket.c
 +++ b/socket.c
 @@ -381,6 +381,49 @@ static    SSL *_ssl_context[FD_SETSIZE];
+>>>>>>> legacy_63
  static SSL    *SSLGetContext( int );
  #endif /* SSL_ENABLE */
  
@@ -85,29 +99,20 @@ index e338207..dcaf19d 100644
  int SockWrite(int sock, const char *buf, int len)
  {
      int n, wrlen = 0;
-@@ -388,6 +431,12 @@ int SockWrite(int sock, const char *buf, int len)
+@@ -369,6 +412,8 @@ int SockWrite(int sock, const char *buf, int len)
      SSL *ssl;
  #endif
  
-+    if (SockLog()) {
-+      char *tmps = sdump(buf, len);
-+      LogPrintf("[>%d-%s count=%04d] %s\n", sock, SSLGetContext(sock) ? "crypt" : "plain", len, tmps);
-+      free(tmps);
-+    }
++    LogPrintf("[>%d-%s count=%04d] %.*s%s", sock, SSLGetContext(sock) ? "crypt" : "plain", len, len, buf, (len < 1 || buf[len - 1] != '\n') ? "\n" : "");
 +
      while (len)
      {
  #ifdef SSL_ENABLE
-@@ -504,6 +553,13 @@ int SockRead(int sock, char *buf, int len)
+@@ -471,6 +516,8 @@ int SockRead(int sock, char *buf, int len)
            (!newline && len);
      *bp = '\0';
  
-+    if (SockLog())
-+    {
-+      char *tmps = sdump(buf, bp - buf);
-+      LogPrintf("[<%d-%s count=%04d] %s\n", sock, SSLGetContext(sock) ? "crypt" : "plain", bp - buf, tmps);
-+      free(tmps);
-+    }
++    LogPrintf("[<%d-%s count=%04d] %.*s%s", sock, SSLGetContext(sock) ? "crypt" : "plain", bp - buf, bp - buf, buf, newline ? "" : "\n");
 +
      return bp - buf;
  }
diff --git a/contrib/redhat_rc b/contrib/redhat_rc
deleted file mode 100644 (file)
index d94f95c..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/sh
-#
-# fetchmail    This shell script takes care of starting and stopping
-#              fetchmail.
-#
-# chkconfig: 2345 81 45
-# description: The Fetchmail daemons allows to retrieve mail using various
-#             mail protocols and route them to the local MTA just as if
-#             the mail was sent directly to the local MTA. This is
-#             specially useful on intermittent dial-up connections.
-# processname: fetchmail
-# config: /etc/fetchmailrc
-# author[s]:
-#      Andrea Sterbini <a.sterbini@itelcad.it>
-#      ObiTuarY <obituary@freshmeat.net>
-
-. /etc/rc.d/init.d/functions
-
-# Source networking configuration.
-. /etc/sysconfig/network
-
-# Check that networking is up.
-if [ ${NETWORKING} = "no" ]
-then
-       exit 0
-fi 
-    
-# See how we were called.
-case "$1" in
-  start)
-       if [ -s /etc/fetchmailrc ]; then
-               echo -n "Loading fetchmail: "
-               daemon /usr/bin/fetchmail -f /etc/fetchmailrc
-               echo
-               touch /var/lock/subsys/fetchmail
-       else
-               exit 1
-       fi
-       ;;
-  stop)        
-       echo -n "Shutting down fetchmail: "
-       /usr/bin/fetchmail -q >/dev/null 2>&1 && echo fetchmail
-#      killproc fetchmail
-       rm -f /var/lock/subsys/fetchmail
-       ;;
-  status)
-        status fetchmail
-        ;;
-  restart|reload)
-        $0 stop
-        $0 start
-        ;; 
-       *)
-       echo "Usage: fetchmail {start|stop|status|restart|reload}"
-       exit 1
-esac
-
-exit 0
-
-# === End of File ===
diff --git a/contrib/sm-hybrid b/contrib/sm-hybrid
deleted file mode 100644 (file)
index ceecfee..0000000
+++ /dev/null
@@ -1,539 +0,0 @@
-From: Peter 'Rattacresh' Backes <rtc@helen.PLASMA.Xg8.DE>
-Subject: Sendmail-8.11.0+hybrid
-
-Hello,
-
-This is the hybrid patch against sendmail-8.11.0.  To make the binary
-RPMs, type:
-
-cd /usr/src
-tar xzvf /path/to/sendmail+hybrid.tgz
-cd redhat/SOURCES
-wget ftp://your.favourite.mirror/path/to/sendmail.8.11.0.tar.gz
-cd ../SPECS
-rpm -bb sendmail.spec
-
-This patch includes MySQL support so you need the libraries to 
-compile.  If you don't have them you need to change two lines in 
-sendmail.spec before running rpm:
-
-  Change
-Patch8: sendmail-8.11.0-mysqlmap.patch
-  to
-#Patch8: sendmail-8.11.0-mysqlmap.patch
-  and 
-%patch8 -p1 -b .mysqlmap
-  to
-#%patch8 -p1 -b .mysqlmap
-
-----------------------------------------------------------------
-begin 644 sendmail+hybrid.tgz
-M'XL(`$&=TCD``^Q<2W,;5W9NVR,[Z'%2D\K#=L6+:Q()`1MLXD&`,J*A"0(M
-M$1%(8/"0K,@JJH%N$#UL=,/]($3/3%:I2K+/(E5)JF:732K99)-=%EDF55G,
-M#YA]*KLLLL@BW[FW&VB0!"6-1/H1=GF&W?=QSKGGG'M>]T*NH8\T?T.ZRB>;
-MW<QN%8OXRY^S?\7[5K:XE=\JY0MY*9O+EK8V)5:\4JK")_!\S65,<AW'OVR<
-M=^I=!SG7_;A"_KN]>J-V55KP8O+/E3:+N>(FEW^N6,C>R/\ZGE#^[=9^Y\J,
-MP`O*?[-8+.7RI2S)'ZIP(__K>.+R-PNW2U>A!"^S_XNY3<@_G]N\L?_7\L3E
-M;SN:.QB]?@UX0?D7"WGL_WR!Y`]MN)'_=3P+^[_T=>[_>/R7S]W8_^MY0OEW
-MFKUV5;VB$.`E['\I7^3RS^:*-_*_CN>,_#7+U#SC-:\4^5RV!(>^1/ZY0@%]
-MI=)6,8?_2CF)6DJ0?_;UDG'Q\_]<_JOR:F(GM9H.!9^XK>19:M=PCPW+.$VS
-MPD9QX]--&:,8JX@AS+29/S(]-C0M@TU-RV('S2[K&\QX-M%LW=#%"(.-#$TW
-M7#9TG3'-W]=,*\/Z@<\>UAL-FG!B>F8?0)P3#+,-?^JXQQYSQ!2VT3?MC3$F
-M*80_L3U[$ET`G[C.D:N-V8IM3$/B5]@8TB3`;F`S;>@;+I]']*D,\^9DXV\P
-MT34?Q`Z!3[-/V6"DV4=8GN\L(O-&SA3+<9W@:(1.YAFV'E&%9>UJGCE@T`[?
-M&+.0$+:^3@SP#+;?ZW#63%Q\V;XB[U?J#;6]7JNH^\V#<F+B>/Y8\XC2^6LY
-M0<I(P.\9MN%J%L,N-5UCX)N.[7&")YX1Z`[3!@,GL'U/D<&K<D+,TS5C[,R^
-MCK2QX44?IGWDSK]LI^_HI]&76$+TY3N.&[T'P6`2O8.HAX9EK1_;SM2.UJO(
-M8\W6CF:4Z\%X8LRF.WC7?">V+-_5)DPW!HYN$$<'FC\8@:^#P#7]4Z;YOC8X
-M]F0Q((:X9;B>8[/I"$(8.8&ELR/#9]2[YC$2B;Q*'Y@Q1B`KRU_WWOHV/&?L
-M_V!D#(X56,37B>-2^Y\KBO=%^U_*YF[L_W4\;;52VU<5+O>KPL$8@_@9_<T7
-MLO07@N9_Z4&JCP^,R.9+6:0`>1J>0TC`KHJ>FV?^=&<N<>#8OF;"OWC&"7<Z
-M*WN5ZOT5X6\BI\=N*[?)9+O&C^&.F+%.C9[,_;4WT<9CF&AX4YW&P.>=P.?Q
-M4$#K!_"&SI"=.H$+6ST8F39:,588;M>PM%-%EBLV11$6O`GY.G@&F[SG$$Y.
-MAU\HRW=Z[4:9C7Q_4M[8F$ZGBFF#O#%&'RN!;:X?FX:EZ,;&[V^I`VW#(-BA
-M31OY8XMMRS+%#K0PH':-LLP[#[D_'V\F4D2EAE!DBH`$7/!`1#HV)H]!L<_"
-M_-,=3'P.07?L-9\1'!YM4&0Q=ESCHW1L8.%YN&C0YB+P8NR3,VOQDY-"$M"=
-ML1>]DS3H'9@.S4GT9E-$$'WPR;Y#GS+)#4PAXG62S="Q+&?JE>6<EF;S53.B
-MW&.0$N(\4AVA(F/RX@@PTF69^)N*"$C//XFVM+SK^`BDM&.LWF;.A`0-;=/<
-MHV!,ZI(B?>$:"1T"IK3"9:8;0RVP?-[#5\!)M4R/8KB^`4*A/AS3G-*T+.?Z
-M<=+S(>V(_+0^C]0NHCPVGB`,XA`*(00HV]`$Y@@2`F&L*BZ0YX`N`'1^QE<N
-M\'",D%9Z_L&7&_L.999>6"^'0##[<9@LY2!,"K4KP]4R/OR5,:;%AAJ:+@)O
-MQS8H#CME(^V$5'NB(4`W$-"2)"$_VO(D7().MB`F:+DOU`XRS`_B"RB^,HG%
-M*Z!1+J3CLLXL")ZPD4(@F0$ZZY29W.S-,5*TF_(,LHK(?!A,6IJ2'IA6I02!
-MN5!G'Q1!\>-+(=AIV7'/-9(FR1T'])*AB=M/;%W:NW)=$##5R!H[,2T8\Y0,
-MB01?)M_N4-8R:P6^_)Q=?'ZKP1IPZZZ,!YQE"H%AFJXCY:`M`VY.YZG#S%ND
-MA!.9#\S(P$">*!TEDMH$V=[$-9&OA0;G<6@.GI1GAB[Q>,/P!SQAW.B(MB>)
-MR"02N+,#:J(9@\A*7,ZD_.5<6K`8C[E/'9%SLSSG0B.7X:`BDX;11R9<96C&
-MGEP7*V>V*\;-'P?V<>*QWD?Z/6,6M1&7^"[BWA8DBZ&*@,_^J'=P/Y+$3H@^
-MZNNT*OO[:ENNN@9AY2N/,*>0.&(['L-33V8T#D8.XHT0%79;JU-FCR`:B@8T
-M),$G$1@*,%Q`J;>8Y3C'P42$'B-#/D%FJE,RR243;>2[[>9^Q!S6/Y7%?D\]
-M/:RW#AO-YOU>ZW`MDTOKMC7OJAUT'E0:]=JL!Y,GE(J?&!9%+"VB+NYAB(2X
-MOPBW_4H?2:V.K'J%M`N)NS%!SDV[=BY6\B$.!,VG0\6(Z+'"N#Z%H5"T?IT/
-M+L_IK%2K:JM[V&GNJX=K:;D6N4N8DP6.0W*,Q+ONQ"0<DJ/:OFN2?:0R"J?;
-M#T5>IF!A)ME$\WZH6/3&7:3,B:2`AYUH4"]L(C!]80--1X8K(+;W.I%(('>9
-MBC$4<E!Q!:PUAZ>T:0S7!>V\1I":CDS83(SC]I0/%KHB^\8S/\UY/IM"3<KE
-MV[GPHMNY\)W9SNO:#FW2\]LZ%;HG'H[:B,W@"V>@PNW.2V2BB^C/\"W+O`#R
-MQ%0YDAI1))@S0_=1^E*[L:*2R-:K)&7QVH7T5I:9DF7#?V73HC[3QA.+\H#3
-MON&"EV-'&2"762ENY5C'<5WX=O(5F*!GF.V$&8\H4'*9PMD.#&5%'B&R.-WQ
-MIH;A8PO-@>Q1>X;&KKED!\*59=@1=&F*.'[E&V[@\I<%$!1@7;27:E`(R`A;
-MGBL-*0DF1W.%)(AN,D^6,\!>"G-"(IN6:P=C"(1%<1]I(-;#H[)8^*>P`\@_
-M0[7$,^@$K6+'$E6,ATH4Q47I[0PA5`,L,[G:^K02J`@'(:PB94*"Q-3`TL#7
-M*0*SFC%!1DPFV@GWMF=8HD";81-L;F[99_$C19[^R#6BU-.T0<B"2<@(&V9!
-M([P9CX".1ZS*R\;`%<NZ^@PKRCC(EIVU15#/(#HJ"&.V<IB&)N)Q6(,86V_!
-M#,W6<Z[[@%K#$>$*XV/:U-1U>!CWZ:=;Z]G">JY4CJ<Y?%_!M`JK%18B!#&<
-MZ_.D6*[[4!2^I;T8A`(YK]`#>3Z=>&@G0*W1V87)9>R28Y4U.I5`XUAD@SR/
-M,*91^D5Y`Y*;>$Z_Q&%RJC/0(0X"]MYW`U'\ET7*`%;##PI_ZC@@>Z["&6;Z
-MPENQIU'(L5:F1KX//+$12'-I<\AD*G528L)DV-CSSL00YBVR(RGAS2!+.KS@
-M-J:<YJSBF3!5<"8LQ:&G2:-HN##%PED)S8Y\F"PX22E8(/:9RTM`V$`N'0-Q
-MRL-RT(+C8)Y)IGHA$`G]0H(CET,7%36&K958CD?FYEQZ&(569V(02%,WAT/P
-M&**A)?JGX$QHKX2Q&&EVW/.798YQYF\KC4;SH5J+QUG4_^3J7&Z$D;QNX5*[
-M+=+6YP=!8=IY94$0S9F9^Z61D/SZLY>:\KGR2/EC()>K]$HON\KG]*="_Y<:
-M!E8\]&+"^%<S;#=#PJG0@26,[Z\<>A0NRSE%8O_"`KK*,/6J)/3-"4@C51#1
-M)<\?5D*E6&@B]5AHJ"Q^7KG*1#D6]7D4"LVF:V$*108NGN:`WP@A9MYH%N=`
-MBG.9`G+5L0=60%ZJ+,O[<5ZRP-8QQB<C/AV!8]1&1\_XIE??X+$-]XS!<"CW
-MC:$3S:1TDP(8QAVC+GQ8%'A])->9*)8?!3#0MF\8T5F\3R73CZ+=(1)H^Q0D
-M'1T!&_E!\-89DT[CS;!AAP>&^)+A(H@AE@&C;3#24EJ>I04>JW@>N&PG[@RT
-MG8O/#;;E!H5<XFI`F8EXXO9Z;DO^KN9_(X0(&PN'(*__C.GR\S^VF=_,B_._
-MS5)I:[.`IJW-7.'F_.\Z'AV:ZOJI]5R:7_*I.I-3USP:(4D8I$G_2VQA[[#+
-M]@X!0"3JC1S7+_.M2Y$5;`79#<JZYLXNM$BF)RX$"3O0M\BFC6$9"%)WK]YA
-MG>;=[L-*6V5X;[6;#^HU1#>[C]"ILDJON]=LL\I!C56;!]UV?;?7;;8[[.G3
-M2@?CU]:H"X`J!X^8^GFKK78Z#./K^ZU&'5``METYZ-;53H;5#ZJ-7JU^<`^F
-MNM?E]YD:]?UZ%\.ZS0QAHZ6=F\B:=]F^VJ[NX;.R6V_4NX\X.7?KW0/"=I?(
-M8ZU*NUNO]AJ5-FOUVJUFAX#1FFKU3K51J>^K-86!!*!EZ@/UH,LZ>PCDXFO$
-M?PM+W%5!7V6W09`X$BRQ5F^KU2ZM9?Y6!;]`6B/#.BVU6J<7]7,5ZZBT'V5"
-MJ!WU1ST,0B>`U2K[E7M86.HY'($LJKVVND_4@@F=WFZG6^_VNBJ[UVS6.H`$
-MX!VU_:!>53M_R!K-#F=6KZ-F@*-;X<@!!)Q"-]YW>YTZYUG]H*NVV[U6M]X\
-M@$ZR/02T#U106L'D&F=O\X`O&/QIMA\16.(%YWZ&/=Q3T=XF=G*.58@1'7"N
-MV@6PV$#@!"N[L96R`_5>HWY//:BJU-LD.`_K'34-8=4[-*`N$#^L/*(%]OC2
-M24J@3+S&-#;#9<GJ=UFE]J!.I(>#H0"=>J@LS;L`U.E5]T+&TYVR<$=FTS*6
-MW0$7ZK744[JBMWA4G5-R++6P-],LRG^SGZXAR@D!Y=-RHUFM-`[;O8;:4;L=
-MN3.'-"L#59O[),PUI(]#M*6>'H9E^\XAVI[2_U;7TKP^M$IU,'[NSQ;/_5,\
-M-8.+4N"C$.8(D$_7VG>2/_Q)>"3SL^U$<E74:9,[K*AL81G),ELI%G/LH1$:
-M@K#P0@Z*(U)66"(LERV!JKP^L#&H5P%3>46@%(XMBHP+I9W\.)$`H.1V@25S
-M"?[`^CHV9;+MY#HZ=YAS+#H2HIZ%Z-)_C@+4FOM+%("D'F7X\95^?&<G^7&X
-MWO"$#=(!=4N7S:/:L,"+MSY4V="7\/$BZ*\&?`D_5Z-36\/F99Y9.<X-*-V8
-M.3?3"[OYX82!#<S9.CO*T9@2Q6IW?[1WP#Z3Q2+6SU&=4VX3U42T:?/RKH#$
-M:Y[)?")AT[4;B(T:@"8L"".,GQ5JHG(Q<H@)K_!$5:K/R))RQ(^3GSSAJ*$J
-M.7:'[;#D8_88\-D3EGS"MEFR(.1;.^A@[;Y[^IE8'+&1+LBZ3N!]%$&#+/ZD
-M=68EF]%*-K&2P`9ECG7"F11?3K(0'IJ+R'C@V$/S*'!Y845)Q(R@+/TF;0?/
-M6_>"\5AS3Y6))4F_E*3?_3=)NO5WTH?2KWM?!J:^;CE''O4I$_2A_^UMZ;>E
-M[PV0C$CH0]O_2-*;OY#>E[[O!79^;(X-#DEZ[P<86Z'V6#!#[4E)^MX[@/%.
-MY=ZN,M&'U'9;DM[*$MS]P/<ET;:'^;\E_4!Z<S25?'SK^/Y;T/4N!>1#2@'\
-M9V@GNM[[*?K^`KA^S1]8.:5O]B7>]][/0=L74E+ZG6B.;FITO5F9>,K15Y+T
-M!L;\$\;\%W"_/<K[1/H4;?^!MCYP_0;2@`&9"G>P/CF:2`KZP(-;^T27EI,&
-M^/Y??'>)7P;&F/9ZX/J&>2;^SU]%`O"<^+^4AZ+,XO]BB>+_8O8F_K^6Y[GQ
-M?X:"BILDX"8)N$D"OGE)0)Y^K7-A$G![/5M$$M#J=?9J=<#HIDII.8KLJ!!T
-M6%/O@MFUP[;:J#Q:RV1`1/P>,,4/O)YYM@A%U:IYR+]8<$R7`>4YUX!6J13*
-M0]OH?.@,D(7;=!SBN9M&',8\\C$68,SGQ6K\,&U1E7^5A75^;$#Z<Y\38PX-
-MRS-2AY7VO<,PWCU_CD"M?`18.SM`7^`F'9'10;H\Y_;"S9R,?#^,[A>ABT8(
-MK-D2\KHD?UN-'9['&+D1247N4.L\1(S"7WM6(@R#T$^V1=:0S.$CQ4$A,DMO
-M\QC0>&9ZOO<98DX_<&TQ@Y8JYNS0'/&9GV.*(M$70Y7;0=B)IDM1AFH3PSIK
-M(<3C$PJ[F1?TYZM$5LIKLNXITX[0%H7<"OWW213]YN_L(-K=#DE!?T%);FXG
-MBP"*G,#!`L;:44C^=GP-F)C,*<G"=G)37LBE5T,7)J3#?P`F(TO]>"?YP^GV
-M+/_BGG$0^)1BZ(8F<N@.N4;LD<$HL/RO,&N;9W-WDC9%Z"G=^#)P?(.MK+#D
-M'_QD8)F(S/F1]<]8,LVVEZG::I1)\ML(GA],D%2(,KV@ZQ.05;Y#@DB%(^<2
-M$4.:]T/*T^=3S%E^&:&O[JG5^X="6P7Z\(R&BM2.IUD7+Y9GITA&GKO2[4PL
-ME4V+/.5JLJU+DI-E&>/R1#I^^>9L)OV26=QB*OPXU&GZ[^*L3N%:K22+L_2N
-MQ):GO`-$?^&](X].,L+[*X+&2/Y`D/PIT'#VT[V:L3,[[_=I$._FR:$RIXG:
-M:./P7;,ZOR2Y<`JV.'MQ<KA1!8S%@9%5>KDB0$9XNH$OA"Q*(IH^-NUX>6`!
-M4<P6+<5%][CHWLS+(%DEAOMT;.8@^#;I:(E?H&$I_B-6)C8:III?B9L'_5->
-MA_`,GQ72<QK%]LR]O(;&[H"=5=#SR3];*$2<*\Z\GH(`EA9,E%@<=)/_7T?^
-M7_@:\O^M[#S_W\IF\_S\KW3S^[]K>6[R_YO\_R;__[;F_P6E\*W)_Y?=W7_%
-M>L#E<%^\1K`<3/PFV$7]\VMA%_56EO9=6G>X^+K.ZZP_A(C/]C_-X7]+?B"$
-MGK._,[KVBL5%]8HEI0.DKSPUB`H'R;SX?K%ZQ675BI='&*9)"[6*Y26*,,\^
-M4YOX9E<;1+KP^@H.!"RZKLBI?J2YK&L>C\S3Y<`6A'2V@+%8IJ![[#.RD5@<
-M1]H0);I4]J$L-[IP>0J[^`R`PE^`W]GF62R2(>2]3//#&_0ZLO0VIG(*D0TI
-M,R+SE+B&J,2O"/@/!\KB9VN*HO!Y'/>R2H5E&4=(O&;W\+'@S%RY0`-=?O2C
-M9%R`Y'2`"D'#]DT=YSM3Q_DV%6Q6Q3^%4`[M97A#-OX;3W?$0PNZ_[P(=N>R
-M^@ZO&W][JR>KXA\":-^MLEPN7\AXT3_R553H;(>X3F^YVV=5YG476I8M>A:'
-MCI6A]J5T+$GO[TC2K;^F&@:YH;XS[DN^8:+]"TEZ^_>H[A&U*WV-_DTA!7T3
-M]+U'=1->N:`YTOM_*DG?M]%V2]&UT5CB;7\I26_\.:]9Y*41OO\>N'J$2[F[
-MGR]]FBM)'.;[_XKV_T1[['>;G+9?2M);;U$]9/:OM-FFYUF<AO\&[#^C^@DV
-MIG-L2)8D??`NX/P#X"3$KE"\D61Z:/\0]/X-Z'C#EP!9^B`K26^VJ!;DC7.B
-MG"-]0'6?GQ-M@&=.:*J8"S[<^F?"HSD6M:+]`ZS_UC]2FS^8F!.3MV']"8UX
-M0C_3DD3;7TG2NUO4IMO>8=@&'L@?$I\\7S=MB;?]BR2]\^^"GX27M_T"\+Z@
-M-NW_V+OVKK:1+)]_K3.?8,_9/163;AZVC"1;-G%")@9#0C>O!;(S<R8S(&P9
-MU)$EKR1#Z)G,)]X/L??>*CTLRP](8IIIJ3O85KVK[N-WZW'+N_+%N_^#M/^%
-M_30P/;M"KB>>0=A_0+#TGS27%,__"!<VWWZ.8<;\3U57JO'\CUJC^1_T__[M
-M:Y(_Z2??_YU/_>13/T]HZB=T-*96E*RIG[JLJK)6Q?W?,S>`8U8`?TJ%U,[A
-MQ+[A,"S"\PCN5CEZ3^PH#EPZC$Q8ZH<02O$3]T80F/T!QYD`9]<XJETCLV@L
-M2HF';MY6WF1E'P(NZ&\^;75VA#,6\/]2N`M:Y(![A,7!<-H;SK,:]03`S:\I
-MN`Z+V1L'^PD@-M8](^8.6@)H[B12*'&W)2(A0E1&_>S)E_[H_G%Q4OY+A6^$
-M"+N&##%JQ[UA*S;OL'6P,[[!>^X6A@9=,L4H9<3U2^+7L#UTM/_+O=HS0@/;
-MQV=1Y0$&#SS+"58N\'0L*\8T7H0A_]^AY9E^>.H?>CHZ]+^\NBQLXLF+NK=H
-M*P%R#Y@_'`Q`O46GZ(N2]*3Y/X7_'F/_+P"_Q/J?IN3[?Q?XS,)_^=)?CO]R
-M_/<;PW\:W_N;J0#X`4!UG@.`A/^^!VQ8XBZ/FN2?G4.%L<U"\P$+,7,9IPNG
-MZB+(X+C)$IJ,.\I'KYL.SO)T$[4";!+-](G4W#V>*_RWXM0SK7FV#T]Q\GP4
-MLMR.)8ZPRAS`-(E(4QEQ;SN(3<VNN$G@8<,R#:QFC4FXX'%O1#LV+,K8N#P0
-MWD:3L>.=O%!`R.?*A7,U6OOPK:Z9GBQ&DTF+%V#X]KZ!X07HD.0.+Z(P!^CK
-MHVO?B14,-&TH-5E;.'T]#^V(4X^Q13.:Q9)83\)5-_*=P6RS%X2+)FOC:TH"
-MVXY"6X*T4C[_^WN>_WV,_7_56DU/X'_R_Z%K^?SO0IX<_^?X/\?_3PS_5Z>?
-M_9O7`0CA_^\"G]*X++07I(F6P3T-@C$[8*89D('^IX/_L6G*46":!=HSS80(
-MP+(5].1I&EW<YA#GNRIE=TN\&^E>F#R&XG//,T_#WS'\CEQ_?%M8G`U_9X+>
-MFE2>B*A%3:=AXM*],/&_,?Y/X;_:8\S_:FIB_;]*YS_TW/_;8IX<_^7X+\=_
-M3PS_U3C^JTT\^Z%MC.*_Z*Q`#,8(#(*2`21UL?Q/_$-HZF)Y?CQUL2PG$T=I
-M9^$JB`W_$"AE)8X`1Q1Q%(1%:4:3C$*QY<?'O#09^R20W02D[IB?,X$ZSZ<T
-M-UK7I#392:O?SA(8S_N^.'4"`LU`=2%X%/@+<^!QSGD<?N:C@LXL,M.CE^=1
-M5+BZ.!`[J9VGR2;$M198<T:]IP'TT99E===H8W/[[Q&D1`K_ZX^`__5&58OQ
-M?TW,_^HY_E_$D^/_'/_G^/^)X7]]N@-H@?]'SWXOT4U.J'HRK^41%QPAPZ)N
-MX%?R!->>.[RZQJ/40T_LF^7W'=WAS0.FX8W>"B3]S'?83C[3/.%*G.2YYLSS
-MQ+D!,W*&.HP;WZITRB\[NM\):CY:,TXTBR%[$Y]I#M_<]QRU*&Z^@]13BWW0
-M:>JP^+'CU&03+HU>(<-O'0&I[M-8E@E(;^VW#G_VG\?HZ1;!><?M\[NPR="X
-MM7P3J22W,7\/-F;`K;OP1*4X4?&TC,Q1!XWL-57OC3"AL>?H[*\X$S)VS62X
-M=3X^]UM-]VH/3P@L$9^@9S1+P#]0-44AR(I"7DT]C1PR</I$L?LI=5XX%!0A
-M'5)3!B;>C+<<W2X7GSH1#0XI]]_%G)Y/_R?M/[IT[Q'V_^AT_T^UIFGUAMZ@
-M]9^ZJN;VWR*>W/[+[;_<_GM*]I^0TE/V_^NR-J?O+^XM*G?]_4U<?PM':NJ\
-M3K'(YQ75)78>DS2@EO@@Q&W%8[>1GQB.7H6'J$KH(48@+7[O)%XW.2L-^5#)
-M3K\U,_V4Q*WIB3-21M88P:O0VH7^P4.]W!I(.9>!G@%D+8+WCK./;SHNX_?'
-M).YLWSLN1@6@:Y30)D@4P[W7H*?O-R$VF^IF.%4,^7W!K(O2;]O^2^._[[$!
-M?!;^JS<(_^D-//:I-Q#_-93<_^M"GAS_Y?@OQW]/$?]5)^*_.C__^=O!?[GK
-MUT6X?LWQYV/B3^&G,-M)H?8`N#G=[:$F?4/\AVP+/.5_%^]O,_&?IBD-O`6P
-M5E=TM<[]_ZNU'/\MY,G]O^7X+\=_3P+_):3T;.]/";Z.X4+B1F=U?'](&@*&
-MF`Q`WZUIV_(GQ[UU(OPG[8Y<PIP%9F(`DXB9O=4CQW^/A/\B_8]C^ECZ7]5)
-M_^OU:DVI<?VOY^>_%O+D^C_7_[G^?S+Z7TCIK]#_0*]SZO^)4T"3T0!\G0,)
-M0*QL%)#K_\?1_WRUZ3MI_SGT/Y[YX/9_M5:K8_2ZFI__6,B3Z_]<_^?Z_TGH
-M_TA*/U#[1Q/&:NH\A=B>,`<D`)WJ#/N7N/Q#5_5TKB&7Y-D1J&-\5@1`0;@Q
-M?#HH$+$FG`+)]?\B]#_M,?D^$&"F_M>U6/_K=/]+56GD^G\13Z[_<_V?Z_\G
-MH_]#*?T5$"`\??5P%$"5N`\`$"<?9V,`BC@!!N3Z_[OJ?^J6P'V$\S^:VE#"
-M^?]J@^O_>B/W_[N0)]?_N?[/]?^3T?^QE/X*!!"?5IU;V=^:T;5IH-2C>RRF
-M:G01*UN=Y_K_MZ'_'UO_Y$_^Y,_C/;G^?U+Z/[?_<_V?V__Y\\V>W/[/[?]<
-M_S\9_9_;_[G^_Z;ZWS.[()S73X\^G`"GKH>>_>2-BJI4%-FP+0/ZK^V>BLL#
-M'_(HJJ(``'BF\"?]J:I:]9G24.IJHUZOJ_!=;50;C6=,^<:Z+O,9^H'A,?;,
-M<]U@6CS_SE]$=1;]2&?79NS/<:/RLE)E--)-29)E.0J**`,ITJET_N4"3"B<
-M&@'["70\>\E4O5E5FVH59=!+J50J34Q:^)/998?N#:!`B-Q4:DT`AY3J[5LF
-MO]RHE>NLA!_J!GO[5F*%PM#W3,];*1Z;7M_R?<L%5&$ZEMDMKK["<.`&RU_9
-M;>VC>MGY,P@YD*44]$4J%:P>6SD:'"`/;FZR@_;YWN$>Z,0]0`D__@CAB$%/
-M3,/^8'79\TVF9+X]\X!0S"[^BH*?W[I>UW+HP/$*Q?5-#T58F2T'RZNK$.T?
-M\(\JL.]>[0,$LMD;IF)`H>#WSX&F;/=J9?_HW7EK'YBU#'KVO_?:90J'(HH@
-M\CWV0S?T50C]%K@@B"^'EMTE3XS$GV"'#8I1(E%I:'YI5M>5IO1="3L/>A`K
-M?V">N>XJ]O26;3B?=AQHB#LP*^9YSS:N?/;/3;:S>WZP<W9T]$J2'IND\^<>
-MSPSYCSYQ@;H`77RM_*]/E/^*KFBA_->UAH;ROU97<_F_B"<IX\6@KXM!#S\K
-M&Q7QS2GL>A;[:6@S,.,5K4DR?US@3\RG<'8]9`?8W:`OJDVUWM0WF`840)*_
-MII15C97@HTYR?V!X($L#TP/K2&)GZ'2\#PCTTI18Y>Q8D@$K27)[ZX!Q:Q2E
-MH(]1Y3-TOA6YTD(Q*<D.Q%ZIKL(WV[KT#.^N(LF8"[L,/!-RW)+/X#.=%1O/
-MRC%OV9;I?3)MJ$][BSUQ<3>#__V^YU_+P/K7_L,%P'3^5S4*$_A/K^G(__5:
-M->?_13Q9_$^#OGZRTVH?[%3H1^%L:++6P&-:@VE:4ZLW564RWR?3IUA>4S%E
-MQ/+U<H.5\`_RN^4$D!%ZM4<GS?YP,+#-/OHR`<R#G+<-"`E,NAO+=[T[MMV2
-M7Z((J40WO=\,;<?TC$O+MH*[LD3^C452W^T%MP:Z<:>Z53IE=NM9`*H<=GD'
-MEIG582W;1BTG@8202FL,X*+5`YB$X2?P\1ZDPJG(A8.PGFUV`@:Q>J:'M>1,
-MPM8D+JQX22L;JVS@N5<@R=!]^F@3/7-@&QW>1K1/UR\M9]V_1B<\4&DI2HBM
-M`QQ(5I\5((1#/TRBV5`"2"J24[S'N07?-?V.9UV:/A>M];*J@VBE#^QK^D]N
-M@6P#LB\SO)C(P'NFL,Y8_CK@QG60E.9GLP/9?_!Q*@![<HN@)^8]")I2:48.
-M/K1H2G*H1`$=X@B#?HE!4AY#9(>5W(6>@9$9&G;XUL`^:(X7B04D*RZ5'I`6
-MJRR)VR*`SLI\JK*/UH.NJD0?HW7NWXA<1HI.1>I<0PZ8P4@LSBD`W*=D2/4I
-M3<W-)[JAK/C`XI`WB+<:(7.A<\I!8%S2Y$X?^J3K5S@1_`7G9/$>`_3%#W^X
-MD='QT#4Y=4O4%[PTH]N'PBI0)G'8P!T,H5=-J72?C'!J@S=R)(_(-SQ&%^2/
-M:A>8CQQW^A9DU3--&]C',_DU&-2FY*T$$A:+W3L,3"`^SAMQV?##_#RPK8Z%
-MMX'X`[/#&5T0@0_E=*`F'1QQRA:K"8(#FG)M.%><DD=R[(,.`5B"?8PN[M&Z
-MHE;0.&SH90U0#?_@K!=U%-TQ`95%7_#`1?B5+J&`>O@FTAS4K$,42X,EMWJ`
-MAGB/A@R5'I($X9H677S7<0=W(_T)7)N13SPB\V01"M9$7.@JTT<*LR`/VW(^
-M^6&D>)BB(44GJ9*<JCP,UC9V,:<6$F.#R&SU:0B(%'CWQ,V)Z_[`'&B=`EW[
-M7X:]S@6_XSHR#0S:X0@(]WJTA(&+G-3",OWTK]VAW968Z=#M(6$)#(`%>N2*
-M&HTDBZ7P(K!#B`7/7-Y#O(>)%3QV8_"!7U%C!0(UBL;,H`J$JB+=D\EQB6O8
-M3';5I"AC\JW331/9F#CJ)L@G+=)MA\D^SV'8N5P/VQ4U4(BLB+J%+)B#OL,%
-M)KKIT75ZUA7T?DC<Z6PFMGL\AW@Z#.@7AQHS`/@?`$S`*1C_VK1M((93XEX(
-MZPP]0@`1$NGT)$%\GH57";E\R.^P-A8H2]+^`V_8)=P`U3&&V!45(;I554?9
-MS3^XR-@#G>]U3<HKJNE8186HPF:13.*E4AT/D(BD)(8(Y5U<::IS&<F,(Y.H
-M\P0N$;)2C)M,@GI<G56D4AP2JR8B]1;>.@'BU^@#MFN&S=6J9;4&[>6?V&"J
-M;;EPO"F*+H,8W]VT_?;N@3D\AE^GFZI29B>;&OQM;4+=Y`Y[,<0B^%8$3LW(
-MSR2T214U)3G.=ZS:\Q91&LTC;N#<=8R?OX\]U$DP;C"X5R:@60"FP.>F,'R;
-M4<\DNT84FNX(5*Q9W?`JZH8)_9"57RF5)-GL">5#0X@38]*/Z'`N,K1ZP"2@
-M)WXU'4XF-96X@CX(TD`BPX/!=GL\"V!0Y\I'B>D.@\$PB`)"-H%*D^6?9B@.
-M40RR[7F)$9,1K5-E`)K$<P$@*%-B,NS)]<3E2+^F)66B[Y*QH#Z'(((\4T9C
-M-!BM-'08^A4'@=.*6`=;=HT:P\7E=8(C*$D-%MP-++P+AE\B!O@%%8O?E":;
-M>9PY-Q)VWD]#AX&9H"A-76FJ+V?9>2*#<4.OEC#TJALX=O07AV[+L\!^0B.M
-MLL>$VK"MOA7X"=1'N$B01R2TQU1=.:G4T.K#%H?4)KH!8N,L=P"CR<5QY]IU
-MA6#W3:*3#'R<,B%1ZC.<>0>E$L5A%Q?(.LNX.@??K`"_82KX!84L+P.Q[050
-M*1]-QE^@#2@![^+T$=H%!O4,T"\>M]ATO0R&<HE_$+4[@#`N+D*UN;Q,385Z
-M!V#=`)`%J`JV*597DB\N4IVT'B<#\7QQ$??82`BK'!]+[#2CT_RD*`$H97HW
-MD`KTGW&)U^/%VG8<U"7'1\+5"=]UJ)^-;I=$``$CI(23"!0P8.(R?X7D3WQ`
-MKVC28*.L0=?`A\H1]8H_!"E@^"*!Z5'D52E"1R%L258DHJ@*,E\0P39$]J[I
-MBYN>N-*G`:*=;3U!!T!&5`ZW9'U)#L58"J6PE6%D^UY<+#U?7@::=`+C,ZZP
-MA&9G!C:9E@XED6^!&+B#^#[1NR_L'3$W8'B75H"3G!$WX6SGZ7NV?71PO+??
-MPKT5DKP-QHK%#>+$Z$*#;RR0(/"R#Z)+L!!F@&8+ZJ'0LL,.^2BWCUMG[S<_
-MFL6/O3V<`OG8.X8?D@P1C.XOB$*(?\V>,;2#4&)C1$E>$6^)UX$HH>>:1#W1
-M%T",R\NKD@S$OPY=#J5M'[2W]@Y%>=!=B>(Z,?(/BPN1<T)\I`L=I58H#=D`
-MNFIW#R]Z&P/6'^7$(*%YF`"&61;)?`FHQ-.='=;:/SV2DG,[,R5WATMNC43W
-M$="J5L<INMK+ICYE:GXDA[3HWFA6&['H3DTD2&Q]+6E-.P)Q&?PF1"[5"'U"
-M0RVPH=?6);9D]1SH=P:CU]X[D>0EC@!,\:)0**;ZN2B5,N)$O5J$+*%%H)6A
-M,L]%#"J)JA?+THA#$@8^,7!1[A2!3ZZ&-/L&*<E6KV%3Z6_<U''*'6D2DG^B
-M0?@3JYI)R\E6949,M0OCB%:%Q9V?'W_3%8<I\_]J12G1S7+77>\K5O]F[_]H
-MJ/"]H=;J]:K64!HX_P\H+Y__7\2#\]=,'GJ'+#7TZYW>>K\&?Z]-HUOIU]+A
-M$6FD(XY)K(S,:`L(KB."!E<WFK5JLU;G$B<MK*:51+FTAE=,A<35IJ(W:VHL
-MM]!0J"?M!5`D+-PY%6^%.J_2OJMPD]1XI.VCP]V]=XE(=8Q4&HWT?J?5WCDY
-M3<12%;RM)YD=7K:P<\*W:^VA"DY&;V24?+ASEBP]W/25V,:%EPJIJV&)(UE\
-M^+!]?'IP1DYU3EC[:']E;96]9F_1@WT%`]D;\;:`'ZH(U,1KZHE9Q`'ZB_8B
-MSAJQ,-X4T@BCQ)3Q$L>T!D9(8V[*&,DD01@-H+#$HI-"A($?G#"6V/L_VG\\
-M,3LF=&17;H,QV&0O+B5X?0"OH=!`/@`3S+@RY;UND[U^$51>6&]?_/*&1YD0
-M5AHZ([3`1DB%A/H?X-\W>1ZL$V;(_W[7<P=?)?R?S93_2EW74?[KFH[^?W#_
-M1[W6T'/YOXAG,HM'N_9P*J32&>,](HUTK$P.3\7ANP:1Q77<_U>M-?4IPC^S
-MF,(!F"?(X-H&K4?K33W!X*I:)<D/'YS!"_]@1=S2C(QLF\Y5<%TL%PKOSUO;
-M[W>V?X:OAQ_V]PM?RCRF/[Q$0QVC0)R=P^VC-FZU3T?[+!M#P)-.("9$93"_
-M<<<TI'M_OGL$[)1(4<(47=-&>0`B)G!Y!=+1&&6-O[#P@H)_>9C$OKSZ'EM-
-M9O"_AS\:7RD`9O"_IFF$__1&35<;&O&_7LWW_R[DF<S_-/3\;P;W<\(8C93)
-M_",QQ/PBL/X&XC[@6Z4ZF?6SRJ`<3LT!(<=&4P?PV$ABOI>TT8$^^5)"P;=^
-M-<\#UAL`Y[--II3A:Q!]AR^X3]CM]<YQ'K#GFP'^1NN?K?4&KR2Y@-8D6\.S
-M!`-(0\S)UOB,+GP9P+\@CH8+F^=H));%=Z";\"NN(KX"43`EP_BWR+>4SC>.
-M$6:?>D-[AODK;(DHS+OR_PIL^#<\;]7[JZ;4-N"K'7W'F'[@#3M@Z`8@GOU+
-M?&-^!AO:83P+=X#KF8G7%AC.\-)RNJ](<'7-2Y#(T*O8&U%SBH@UBZ\*!;!H
-MV\*6+O+08H6,V\+M-:Z5K:QTL'%79@"9KD!1G3(:Z#=E5FPWSXJKJ[@-&P^S
-M@(C$K<C^K05"B4&J53[V]09)_7J]'.X;+UQZIO&)UZ[`6,?P3;;<7F[25FG<
-MV"QJ^9QW%_OQ1Q9W*G_']VH7$GW-T]"^\[B5<><D"J5:-72J52-1JR&BQ16^
-M=?U+8I-ZF%NBY'MT(V2$G<;DS7A4\,T-*\5OJ$H;&BVD;.ABHR453FE?,^K?
-M1`UA*).DE^B'+&+#^:T5SD5$".P5B\8+*OX.7N/DN#.TY0#7Y9UP:P@N<E$S
-M'EL>_MZ>Z?I?-H,..8"7#XQ/)J[+/:2,6?B_5L7]GP#Z=:6NJ8U\__<"'TDR
-M;+O);BPO0%ZF%;!*]U)<9HS?N)")`OAFQ#@>/R"&7S]*A>0.""D.:H;1I()C
-MWH;?I1\HZ`>I(#:(LVO#O\9K[EZS%Z\QN-.#X$J_`S%NF-S#H!=O*Z[=A1<U
-MB,/>X"M)&@ZZ:+.'T:):]#L5;]#W<9]&XIU4\/H8;0T#H3Z2U+%-PVG&[Z$Q
-M:__Z?1QDF<'_UW>7GM7]OO@?#'\MY/^&WE`0_]=!).3\OX`G"[)WS9O`=6U_
-M_=0*S'7<<UGAVR$J_5J%4P0M&2$,!P-<T9J*VJQI$X'\U`Q'<E*;.ECS+V-`
-MKY050"IBH3>:<\7$!ZWC]LXNSF[*[<.]T^24+`;O'/Z/"'ZQ<G)\<'YT?':^
-MN]]Z=[K*Y/:?VSM;']YM*NE$^WM;-"<KVXYOCP6V(0\>[*?##EJ'1W\ZQ#`D
-MHXS0=R?'4T(/CMH[&`Q,DA&JGIYL8ZB:$::+,#TC;$.$;:3#3K?VP@KA*&4%
-M1S5JZ)CUU%F=KF'V7:?2"4DC/",$!IA2;ZJU9G5C,FF,Y9*F!Z6IZS$]:/H&
-M[0(2GWR5#J$E;K3T3!]A,=D4:%G]:*%]H_P-[1''-GO_S]ZS=K=M([M?I;,_
-M`G'<6(KU]#.5FS2R1,=J9$G5HXEOVD/+$FVSEDB%CSANT_WM=QX`7Z*4M-MD
-M[[D;MB<6@<%@,``&`W!F@#HI[@;M*X$YHBBJN,&*9^4P*\]YX=;$A'Q0ZZ<Y
-MV,S!SHR*P([DF:@$^NT"]6SSLQS2?,;G(_)_?N^^G:'OUN?[_K>SL[M_*.5_
-MM5K=/T#];P>6A*_R_PL\:V<V=ORD1)[>D4E=?0)3LE9=_5DF@2`S\"V>T7OX
-M-:9Z6-L]B'C][>Z2PS?]W:NPL1.==T:_A;>;]1Y(?)S;V__,;C^DV\S%V?G@
-MQS8D8X(UF?E30WQ'([9,_Y9NGF6WH7!V6SP69_<`BXY]XLJW\+QVC&Y"9)$Q
-M"-W?D7P"[]D.VR9A'!PD5K2NYS!0>N,9M.[2<*[%=R:F//]U:LZ-J3DN6;-G
-M5)3^:4V-L?!LCVRS''.Q,*:T8Q8_0,W>S=@2YV-G:ECBNU_OZ<?SRYEO7#MC
-M4+HMPXM@0A^6(.(.VO=8W)8"*.VPE(H;SUO4RN6[N[L2MWIBS[$@%2;?!YJ[
-M!7&)=L:N08:,EH=U>88T0,--.0#BM=]3K`"WY,9[TR6++L3#ALQWMG.+]D6*
-M804LA.9@YA2/M=%R>*X<&L9XWNV8;"9&.+#TAI"GZ\JL+N#]S)P8%ML\&<X<
-MS1W#6EK6I(3F&Y;M$280]`NH-?#\(*LM=-@H!0W'D"SUH3@'N29@:1;]UN`E
-MX.QT5?@>"AR#T5Q>MCK-:'BADNBUM?I`(S3H4D516UJ=P;`_:M!G6PJY$XWY
-MTJL/&Z?B6(-TC<+.U`&P\X+B!B&6,(K/0.LT\3LP!>=A>@:C7@\#T43)>=5J
-MMS'(CZ*)L!R?)XLC'2$!LO$X1<)AC]$`T,W%)+-1O@#<O87QR#>\61,V/`]*
-M\EF?H)&D(Z!.9=P<9RQ`5_@=H(7`!=;UG,F-DUL4MC:V*&2`0$/9W"(O&`;!
-MMK>/@M_I1<)2`3">B-$/Q_!\QQ(+2/X#FV62HYWC&CI3"(//@M$DJ1-X(LL_
-M'Y//1D$$!Z@PAF%NW4U#`+3,+43RIY<8ZX8;B/7PEZ(C?IG8(#6BOW?DBXG6
-M<7SJJ9CGS1?J!3&^>8(J"+^_&\,LCR9,KJ[Q[.O-SOX^I@$YR*'%?4YFH&==
-MGC.@2T],F*C%"8G!#%03,C0`WRH27S&7N$F'>X_I#4\6MT!WQ=[!`!:(H/A4
-M8$OP]3$CW/JYLG4$W,\0PS/,!:X(?JN*)$UTX$?\X/,^_OF=XAV_;V]SE42*
-M:C#E_$(D/94D`0`RD\FF4U$F@>F2!=?72PB2U7)_R3["!*G5F:Z[&$\,XDZ>
-M#WH5UV)0XYGESR64(E0R5='/I\3RY)=*9ZCKN6IH)G'W*%9'1E$6:7"R%'=&
-MAE'"`!C`C,0*>03$6_;GJ$]I?)Q^'JI_N@')8M0"FL[4@`;&8,+Y3G"X?O!%
-MDMP>`.C8PL!(21RM":14J22&W6970B#I..3GBYQ%D58H1LI&'CNBHMKW6!Y+
-M2[&0AV5_-K,G.:GA8VH>YJD<T41)7FR+:IX;)6?@8Y8@G,T-%!BP22S3P*(E
-M206G`AU_K7HEKSZ%`)1ER>HQ[2]73L+QDZIFL9FLG%/_<O5</(T`Q@_:.(6U
-M&5D\?%B[PZ\<H+U\X_YL;11D44'P<AVI2DPPS@@9C2EZ18%";]EM"5M1:\ZE
-M;<_D@@CJHT[+#WY/RY%"BBJE6E/P>Y7+"XAC7(/ZA+Z3O&X")S#S:"GG?30)
-M%Y2I+85<6:IOY(F*7JN@MCI&J$[FO'D^PZM]Y@H4-,N[@JX!I0L&[49`J8[5
-M"O(K`:Y(L0VYQ6<(,@\"^)R=Z,/^>86^@WV0;U7^KB/%[=%1$-$H%"[NQ#1A
-MJ.;QVUD@4I1`46)"35Q@PX.GM$)1MA(W#*"^YSW>WEY0/O<T?[3KR(]V*RC'
-M&'Z*UA2@1T_%OR+M.TJ1=EQ-=U4U(8;J>@SV>D*[%->PO@;!U7H$G>Y)M]UL
-M@'ZZ&L5\/8HS5!:[G?;Y:@SU]1CJO1XHHJN+OUU?_*6F]7X<=8?:8#4*[V-L
-M:&HG6G]U^?%2^?$")R$,KM6%ADN%O-6ERKS1&)#'EO0T8S&D_"114_5*8H2;
-M*K(\1XG(,LI%'U!,ZX&<?0'[&<(%-5(PL0([H^!G$5=Z8<#>B'96<R/4U0.Z
-M)TMTWQKW$WMFS6.T8TN6%?M%?C5#W*V:B#X@DER#XEZ@E8"A;.?C=8/@_<MU
-M@W#.4"TL#);E,Y&'LB36KP\BG\P3'6X9=["HQ,"E$(QA\5:B\=+Q>"L0!9Q7
-MR,3OY$8P]L:XO19RQR*]%27WTOHM6:'*8I9A\87D8CI(=+U4RR4H5SQ$$U0@
-M=[^A.'+PAT/)!4AI1,J?O"B'4Y(V3$2/7#0ICMQ1H+G'.!.,BSAG5@RHM.&4
-M9(G*6L.2&,A:EBS1\5F8DOF$Q=JPIL%2+5$,^R--Z2-2\'07AB7&DOCD\$(U
-M*/0@BR1RAX?G)'W"[U(%J-R1]Y1"=@="RH9J\%#(X69(3]C)C7UK3$LLAQ(*
-M$I:(ZD:HU&#\%%:,Z,Q.G3"$>V:IK,K%52;&K$M48J!5QY.GEV$2UNB@VA1L
-MG'O(W=2Y1W!0-.U486EB%<0CWA0\4LKY(U:4'TTO\[!/R\@QST@?A`JQ&FT4
-M!);J0@*X[Y07DBMJ4G45*R9]^B0CF@/QBG[5.9I>$>'$$,&TBU+4&%OHZHC%
-MHJ-=K![JGS[]RW*41L8?\1QI>L#D@MR/\!N3"GPP(\]O%)^GEP4TUV-#MTH^
-MO1$X\L)&R`GP\P8P=6-MBQ*3]]/Y+^+:]/2RBKO.>O^X-^SKPWPPR$.0A3EE
-M(S?XD<O+C?&58Q@Y;"\ET!OR('QC+H3O.-JB>Y44\="8H8?S&OD@)^\[&R@*
-M)^\$BX6SE^=LNL0*P&.["S4%XBT.FRQ[3DXTJBTG94(^RLC\QP1F6'TH+Z,,
-M(*2@[/;T=K?[<M03Q:*8V?:M\!?`%F"(/\<SY3$#8F,#H5CG<*L<CV>!(2M,
-M:V+/<33!@)!'%WQP+OG[UC?0DSA^[&XX>&K/>AX!+$<;"HZ_^7LX1PU!5^]M
-M%G]<F"N4.N:5Z:!SI7U'I_8P.OVYI;1)I!:[FDN4N#'HKDQA?!QT%`X+<4`:
-M\]JRG4"4)PZ`D<?(,W^1LMGEJ:).3\?O6-(_IA5TD2[LN4_ZVH`/\?V9A_MS
-MF=I]A12&$MTEGJEWET[&SNJO\?X2/#$(CE`!$7[G363)$USYR_+GV/JC],TR
-MQNP-A*\2:E')&AF7P9+2F!E0.=1\A7ZF)-?FQMPUO)S+G,&3KX+ZJDQI>1K4
-M$HK)3H!Q8CX\\>V^@U&$P8'H.(RK8>-E>802(1>G'>8]$Y(7I,@RM$R1$Q3*
-M6GC.(BGE?P$P@NC!I>DAF;$]9U12TG8L+W7E6P-];!W9S(#Z.I[]H(TG#W]F
-M5DHCEM4UZ$:9%Z#,\("`4N_Y3$D2'+"=LA5#52:64_TM`99J*PA922:^9.I4
-M0"U+7#P?7=:AB;RBL\Z:6(Z8W(0`#M8E7&67%0Q9272Y40<.?XB,XNN/A/D.
-MM=3N2ZG'L/%#L,OR8%;KG,@-B/8MIZ<W(FP]G</*POG$P=MRJ_C4MI;0'D+-
-M*04G;_X2S4P_Z(N(6;FBDW:*;!Z+@=;6&D/.W0@Z:@7V<%F10B'@&;SKF)"3
-M[`D9IB#1/IH)2_8-8P16HJ$LRV"T%^$/S+XZ:D2IK6J[,F"'B_5%JF/E$8%2
-M=35F`H.CB34>"L(Z=;^1/EX"\N5,`L1O*K_$#FKCF&%EFDT!!!'_9CBV_(RS
-M$GTF*DN4/.-:"B)>J9J+4G!:N`J'#6'IR6P!_4:-VPACUFD!O$+%MDW4[%""
-M!4=>*P28;!HF.P9&!C5RM-*Q8(Q*6E9!B20<I>L**X;$&5&`E3)05?"_T,A!
-MF3.0!=,_08W!=57T3DDWP<1/<*YC:XV(Q46E4ML]#!RCUUIK*/>\>.%O,090
-M:*ZQ3[YU^$=&7X$59HH1PE4_%-"\GU4'$D+H19!JR"%2[#@R;-:7VZ#!L!$H
-M_!S=/NT4OI#8>1:2RNQ2T95DRJZ`3A&2L-XI*I#01D76XB9*$UI]W23)D2E,
-MBWR1A/QI8TOJS)4&DO^6J>4.7;P0]9>O%';%-OS+9G5KC`G%>F/"I>R$,2&,
-M>3Y`1HXJN\MF"[WG+XKM((X6=1B")X"5X>=%L:G&30H4FW)>%&>$9C(S8:T$
-ML/^TN=7_N6>U_=^3TF&1G>[^3??OC_M_'^S_`_XYW*_"_P=5\O_>.?AJ__<E
-MGH1(@DZ/^UN6Z"_Y6Y\8EQ0A:*^V6Y$7O3Q)RJ"E\LLE]W:X))GS[I(K&OY1
-MKFALS$">:^X;<WL;;0AT#(2C*^.G(U0B9"!I6?.6&\;RF9FN)QT+HS@VBK9A
-M2`<Z96,`TIHB5.&.U7>I4#%9:/I6%@*=&PT6O(*\K<YS[BG^'CMUI]=HRK(M
-MVF2+K=(66M>-.:;CY;U`!65V%?COT6FXQW:"*G2=16&B/!NT:-0CIW^SD]RJ
-M^2\=/^:3OZ&.]?._"BO0?N#_L4O^'_M[E:_Q'[[($[DD#D.4T,&5J0Z3)HX=
-M.YBB\0=CGD*3*M=-CLH5<?Q"/`A>4N&2PS"T)N.Y3P;`=HPH2L*01$MA:7W+
-M"N)OQ\CS;AS;O^9(BO,]0K!P#!DZTW9JF$*I\IGO)2J83\2SU*90J4AH<^;`
-MC8K]&TP8H'`QGMR.KPT57!XM?I5QJF<3'C2!+66EK7+NXOES%&S/GW-4(]#0
-MMF*7_L5BH@(FCG9CNZC(-.O:6;<C[0D&N0O+M@Q([@Z&YSTM=P$"QG^_Q7UZ
-MHM6'HSXD4N@T4(H2$5P!+`")^0$"*'GD%>W(771QB$C1B&-@:L%H?H(PWY\L
-MV,TPM:3OR\RP-A!;%((N3,';$2=W.HZO,)&]&/7I99AT.8->PC4"-FL3<X%Z
-MH1OF$HMU%7,R3)^/Z5!A/#5T-L/1F:1X50M/]RW8]MFS=]A,">.F`+WUQS,Z
-M"-:QDPTG2@+&086,L,I(^=G=^-[5Q]/I4OT64`Z#`"9:-$V7X>OTN3MFII_5
-M!S^.M'Z]J>GU02Z?U5[CC:1-O!BRGT,AJ.X)C"3X5C2JE+QH,)I\C!>>#H.,
-MZ`8`-')"I;>:T+D7._NUG?VM!$Q]-.Q"X>-1JPU`5VAB'P<XJ[_63[NPR8#R
-MB;+#_KF.&S+][+7>;@V&6P7/\1/%F]W.4._UN\>:3M>+GM1AK4L#;,"4`H9H
-MG4'K)RT5D];&:Q7/==[37%S"8+H&T6--$V3A?:%M31^>H@6YKHJE-J[;;NHP
-M;0$ZB"*61EGO7-?Z_6Y_H`^[4#,:CL`0\0PG67/]1-.ABT>I#>CU6S_5&^?L
-M"P=H,(:-#%SC)A`1#AUX->SV`?*`5NMD[S)G1QU-[W='0^1J6O<!([K=U"R*
-MP*/3;7PK"N/M>&WM)ZT--'R;J!YO,XTP):WJ1DMO8)P??=#Z'^RQG:U5`,/6
-MF09M`)C]>0+HI-M_5>\W20^%_,W?RB49;[>T>5>+O":1`TH,\G-6'THZT_ID
-M@#?%ZC"'8'3VD("4=FBM%Z=#@CFM=YIM&%U`!WX6?)*<2\A*_56]A0VI5I(M
-M.6MU]).^ING',,M?#@@FV:DXV\ZT`5X$J+AF6A2PVTA.OBX&J.MHC2$Y*"8K
-M@VP*=5=OIS$5<D^U=G=%%FKZJ2U`4='H4>MNEK/P<F&L<P56S*:6KRE^TNH0
-MP6GY_8&V"O6/(ZIU)ZTMK4%C15:C>W8&';JB.KJ^&?)V*\G)"9D8HZ8+LHKF
-M9DH^S=^^!BL!@NPGQV8<0N_@*&U_`N"H_X*)VODHQDX`>[@*%J959QTNS`]I
-M6P\6U/8DA951;"%=NRD(3T&)&@QA!1T0YY.=QF*Q7<=Z$EE][00E$N55EP0-
-MS"JIM35.8:'K4\]5#Q)@K[K]E[`6-EJ]%I`8BM_=%.D[T'KU?GVHX=K62!4;
-MA*W1K@\&(:;JDR5$!#8D8:6@ODVICYL^Z/:'>K</*Q4N0^@89GKW*6*&H4&(
-M8)U)+J):T#BM]W6>4#[;<1>?7)I>$A+$!RZ@>+?QQ=(X[[`TT.ODF@404A&.
-MKYUM5)5?@C#2Z\UF/TT&8^\PP;"8*:F7NMJ!?@`35F_@Y]1T<<Y+/\AH8&>_
-M>R:7]=3^J;?;W5?Z<??%:""%80H058M"37\!BVPO?9D<=6CA)PC]5;^U:BUN
-M=D?'0-UQ=]1I:,0.D/3K]`GD#+)XH/=`BY/KPNHE886NM:I9QVU@8W"T`VC=
-M\=72*K.DXJ6U'S53#K&*:Q%N*8J6<2>W&C0[H6-A:41E%$]AKD"+OX-MFDL`
-MQ=A#2:?`$>D?>>7#W@\O%*?]A#P`XKW@S=@K$;@B9G!6A_F!0@1:(X_$,?_2
-M]]BL%V^<N31@"VE-[V,ED4@LI[/TT9LMD`,P&W'@EW#?A^=4$=Y@>%?9Y$"?
-MVXXRC_3QM1"LZ@]@Z+5#`#^J9J%H00P*C52!5,CJLMHK18JP"H++$P(&VS@9
-M]R4"&.DS^/-ZJZ!V%--TF'J?"/3]]Z(HBHXH_B:*X\UK4;QNB,V;!PY?J-$4
-MF[_BOQ3D-K?I8R1;1L#;N^#-G:.=BGP)]WPR`4>0V@NIF*VGW__P?3.(XCBT
-M:WC7278YL"\/J;IH2WLC>7\`6?X%QN+R=GIE"L17.:LOZHSACFX2Y*(<5)U/
-M'L18H(F/.15TZ1CZON&0#@Y&;H!UC&$?#V$L6P7@(9.?*]ROA&<3D@ZVM0O.
-M7^!1!*K#%<>?&7@^N4]EQ<)V71-=<`$Y!H3#"]QD2=H#TW4$3$5-^GTIE`9%
-MWW<-0YJ<XN4VU\"'C9H\&ZEM<,&R+/B1<C1)D2D7Y2TN^&&YQC5%Q^+B@RSX
-M/.BTL*3L(>H&U4$\Z;??"OK[/1][;?O\YP=1GTY%=*0(C%EM.-DSBF<:7!\4
-MG4'!33IO![VK&\O_]H>"&#S5K'<GCCW'N5X^G3KJ-UXL!%E#6V7PKT(VDQD^
-M;78&Y?Y)X\G.3OEU<629[S&Y_C2X2J-X#O,&AJXH3F'>_'<$.OKZI#XKSO]+
-MN+3_775\Y/O?;N60XC_M'>Y7#@X.,/X;?@GX>O[_)9Z'#^0]8MF'V8?AI5/T
-MT,<`OBZ#[[D1'GDD37`1P:MPT.R7+B/$J\8\FX(*`);X$PPIJF%R<\M']C6Q
-ML[NW+YY4Q&XE^U#>5[O@VUD#JUA<G<09_AHZ8\M=V+!ZUJ\-RRO(6T?DIPIU
-MS\O/R=K9C\I^AWY4B(8^K=ETH1HMDK@FC"TRCP7ZU%U;:.E3"^\3?2@4R:$R
-M$_U*`.7,*1X\`\"[L5-V_/!^KQ)D90%B0->*!A$71'`+>8F1.I/2M(R3#OXH
-M(#=2T#(\_'B`W(Y=318@@/')&64)&BGLQJV,?;I$$LO"4O@&0]XE,`3POX@C
-MY*^5S2S5$G"'S*`RO+-]>H\Q_F@?];1ZD[TRD0A>B*DG(JV`GO,7I>P;L?E[
-M1QOB!A2V37_@9U/+WH"*'SW"""2>J&2S3.+RU6F_B`\?`J"^-ORIWGY:H6;#
-M*H_7H]T9\#^,U0E]C2EER:EM8[.Z(?".7QZ_^6SFH73BXQ!4;BF;S>#E7:((
-M"LE`C7%5:TUL9#/!VAV&,\3/1U/C71FMBL3.LT?5+'G-FJ@\Q+Z9A)N((*YB
-M-*@B<'QJ9S,R*D;8.S3J-LU(E\3#)L:`OHN],C;HC`SZ%L._U,XTCF[FW@!_
-MN"\WH"^@.V57$#\NIWF88N*C#Z)!YFW22-B(HGC+:<!UV6&;WS.WLQD8"IPF
-MBL9;4>%2GHUW>]&T`N7]MNSZES`&P]&7.3JBGK07LB/M1=B/D6Z\\3WJQBEZ
-MB\?Z\M:<S7#>A_/]$TGC:)$?(PVO>^)AMEDA.N4/2(M5)(%G]A@V/\M$B6)U
-M&9SM%@"<?Z2W@"`?YR4S-D88VC<4;N)W(N4#4O9!TOJ!T?T!S*'95<T:[GB2
-MS=*+9,17I?'_Q[-*_PL$_=]0!^E_!ZOMORH[>PG[K_W]O<I7_>]+/)%U.UBV
-M_],T?7V^W*/F?T]K#,J?J8Y*9:]RB'?\K)K_E8J*_WBP4]F%^5_=W]O]A]C_
-M3/3$GO_R^1_K_U#Z+XR_P_!//NOE_^[!;MC_E<-#[/^]K_$_O]`S\.=SV(?6
-M1%W<F5.,+D1&?FE[;I$[&];SI6PGOCO^R7!<VK7+Z)E]8V;`AJ@F#K,->W'O
-MF-<W7DT<#YK9%X[M+VKJ?F'-@FV1;:'-;KG)&GNVY]CO@`H7T,^]!>OQ6=[$
-M5FKBB@)=PK^EB5NZ-)Q;J.F^9$Q]O%LS=&,)1O$WO[]CVOXH01^7KG^3J*HA
-M]73.)9-W:M%8FD'(S=N2;YG%6].8E:9&^9M#;3(N&VSBC.?A97+,Q`HDFMTP
-MVCTG[$6J"]0JF;=?2WIP+%^Y($$/(J"!=6ZVA[;YE64LT<#M#%3]W_:NK;MM
-M&PD_A[\"C>,3.RLQEGQ-ZV:;B],F;>RLXU[VG.QI*1&654ND2DJU7<?_=G_(
-MSC<#D.!%MI3N0QZ(GL8VB.M@,#<,!L5"&XCN*PKD.(C<@MUJ0?83;.,-D-0M
-MN?EER??;O3`@1;:JC1GHO(S?NP6KD"@]/BK%=JK%G#?JI,QNM8S[CI44VJO"
-MK!CLV&,7<Y`%8]:9CB>/5Z]A&[II(YNP52?Z#_K*2G1FV?*\5<>:Y9VXU[RM
-MH8H-6W_R)<X%=QW]*PK>W8:L@OU,;DC*!1C/=&^M9_##G:7&`S<(\7>B-&-?
-ML9'`ZVGJ)6Q3^^VTKR.=/=1NG_^U[Y"+L<UI25%&XAG+3ZKXU$FKUQ&.C#3?
-ML;\X@Y&&G8(#CJC)/L:Q[WG&@5A3"YGK;:(S*Y83(I:*/<1SZ'AHO>RDZ[F.
-MM!4G75]9/V6N%\9]OD>0!=O-^O!0IL_!`+AJT?^7ZMFV:>"KMAO*]C(:^[+0
-MMCR=7H@"4(L`!M"^I9^%5HK(QMV=S!D6K']3^*.6YE@=AS<?$56&0G)2!YM*
-M(A0?J*8Y=A61+#NC5\_^Q>;A0)WJ"QK)!)?E<4ERJFW/MJRO^+33E,&;\!-A
-M!QPM`?X)[WF>:R=OU[G-:1*?LF<TD6E8[5[?L2XPJ,U99QY)-FIW`?NG^?J=
-M</B%$5Z'IR;FHZ._`*LKKAOU8D(U6^SD8]#4AN_)#;YF`-D&?AA:?/<*;OD%
-MYW$XW8=#A+WIS?#P.!]ZNJ5RU/VW;"3CW##'P?WV;>EA<1+=XRLZ3`G*@Z&E
-M1EAK?1D@+''+?;/=JPS<$+&L>3FZQNF^;-TT'NLPN,J65H#!I%(&PN^ZJHP6
-M<=56$7;U>YI6Q4X9Y$2/)MQ)_9+7HU\5:G5T#$"J3)RQ,-$3;S75T]E$M?\`
-M5H+=J_:DH]H]95Y<,-F=+#OGZ^93-_O$G-SD;F:YS!Y-[E:6:\48R=]&OOE]
-M)^\*S-?D[A;;VS79>WEAPV"]%5S!0HYE\;RD7%JM;+<D7LG%,!54/G[W5FY?
-M&`*FJ#[RX7Q-<.$-03@4Q\KW?=C_?_GE%W5\\-/!,:)P>RL0\"]/U0.\`R*&
-M+KC6Y(*;:K_`!ESIG\$X#-;NXQ_*>WQ&7>!!^=/'\.-^>^!S)<_SP*[;B)#W
-MT5[B^/C!_^!_?*CVU>JU]+)SHYZB*MK)!#9OE?>%MZ(OF;86'B?Y^OZ#PM^J
-M_1(.A3\='+X\.O[UQ2OVOOFZ<]_S^OGE-R\]D^MPR`0`^B(CP(J;UGU,YM=B
-MO*G[-$DL-M1\%*2J^<"3]\9;*IL_0<3\CB>B5LVV\V!+3\P2\36`7X^/CDZ\
-M\7DXI.695#Z@\;F%2^=I^=])_WJCU6EU6YNMK=9V:^?&?,RE\JP-<\"CS&UD
-M_DG["?]?=ZCNWHVRQR=*3@`&_),8)E_4DSO,+B6A$;<][^CY&\*]K^/>[_Z#
-MM1G'R&VGZ_GO"7X/$CQJZ&$YU,N#]R>H49JMPL7JHY\/O_YM2.U&L]_4C^4,
-M<S/;9`RD1"%#GJW):\A#-?GW#UY&%VF+/)"QYP<<G^GX<MS_3`>8[Z7/88!$
-M>?NZ73/,Y/->9"%5HXCVSRG1&U'"[)%H::#9>:VM]IG.2@@I<3#[C:34%#<?
-MX2PZEQKR[*ADOC/[)"T$"0O?/[Q^<7#X_D!]C_$\_Y%XBG`R^L'/7/QZB$"\
-MZ&BA9GF$AAG>6<$R39D6U<[XZ,)5P256"M*9D8Y2X2]VJH]J6ZRGP7/A:,_,
-MB;]GBS-6.UM;12[>KS"J>K^0&AFA;E15F>'NUDF0D./<%;D5VH9[<!LL)%5M
-MJSVH@#5B<4^`@,6RN#480.GV[]_66[EEK[S;<K^!.V"?@Y,@,M[=WJ[4R'CG
-MX_$?N&B/50^#"$\^#%1Z-::?YZF'29Q"&[3>T"SH_*$<-XS)+!G@&'OJ*3A2
-MP!UAF5&CP(/KTQNN'>G;<<5LUSZ-8W__X.C5;<`4KP_''4:K"M*W<XMECO^B
-M!&'F@>LE12W9@("L`,M?I"N)?K6&<#0D37,]>PM6'%FIK-R276&%=L%1L'*:
-M.R^[^C4<H*SZ"!\OHE=&F8,'#F*U7<!&$%QQJ&$8KK*;S!#8\S_X-_&+N7>/
-MG=?SC_=L3J>[ZV_0?YTLQR/0,VJ`\B_I;I-CB7B:S%V_!]?4^@V7[)^-XU#!
-MI7&AXL7736^O@*=']__/@Z`V+3;G5`WU+,W9O+D%;1U)Y>Y).*_![CO->^6.
-MY4/]R&M<S/+:(!VF=J>VMNM'E]4O4W,[LNU;)IY9WSV!].P?%[4$@TG*=29S
-MMC+A[N:.BJ@G(I;'D:N7:[UE)W=S2VVGBU5^XW:>GD6:.FTQWKPOX@@1(50\
-M"BUEF<*D>D%?JPYIH8ZN<I<TQDNJ4/K^$4\#!Q?GZN'S@V]?'UXK#N0&WG40
-MT=C!G-B:W4OCD89YJEC__@WJWU/J6NK!?^_XX,W!BY/[-P_5TZ>J0F1Y')/R
-M,(I_XO%?A->"DR)H!\U7K$V1T*I?A6X-)^87<$#SZU>69-0XZ-EF<C>](D"R
-M`@P4ALI]AHJR8/FP"%QL,Q_NJZ\8/.QW9YMXT/D`$!%MI)\W]VMA=*\`H&Q8
-MU:P,4,IX$3(E85PYBB=B[TVM7136_[",*;E,=#$'5]P2#!GQ(\QQ1BV(-$Y#
-M!C*.6V(.'E5&G(JHXZ*0.[IRAHM&`,FQ,7L2K4S56J0O\2QI#]8DMF!9JRC.
-M*8@!>]>JQI64.O_;W*P&-9D9%!=`J;)F5'$FE5K[E2Q3/QUI/5$=S^"&X3,W
-M56]8KW1*IMKM('2,6&SKG$6".0\01WM#_2<?:K5VJ$=Y;?$T3C3A7S""C-*/
-MQY-@.NP-^95'D1Y7"6\&`YV`ULTBY42^HOF9T^L[1RFZQRH$G.DT66NW8"IL
-M29R,G&3G-H@\+U?[,Z!;,3;/R<77$@6OJ+!N9^6<;+QUV.6T1+*S6XO%V:KP
-M+EG&^K5G(GOM/2IE9].K?LJ@4?>)QU[]D.VQTI?M3,C8+G[H.'/T.^5O/%=D
-M>XXVA<.?=#KLI\9FW`]PKS,D=A<G>C(*^J(EX<R2VLZQ14(!T9ZVP;^(O3*Z
-MX"F3>EUPE;$%XIJ#,,I6J]?PS->U;#3K;NL5DG5[\<R87QH(/M)`!BQCUTER
-MM@:)7H4:I!?=JZIMR%:.<I3_;>40V5<U@M8<$`V,]#\G!)$SPGK@NO"8TX:W
-M>-]"?S^Q4\-Z%^_-(?.?V*73PA+].BSE$_MUF=*GU,=AFXC?!8RI40Z*!>KE
-M?Z':,!?=0KC+QB);"QKN+=4*%C(:S%D0#?0H'G@>W@'(`J[R&\+O-%YY>T[*
-M,K6[GTS[WPS&EWZHGWIM$KQQ%CJ%,T@0QA.(-"`Z$N<JQN,!TV36G^)\M8WK
-MI=H\VP"F+0XK;75(%8SN;A7UBCM17IA$67YB@.A@%`9)J'XY/#A1X[X2P-/P
-M9YJ'W^G>/7P9D5S!!A^>:GG3!<><`UH/#$EZIH81%/+9;+`07,Q49Z/I$&>-
-M*IU-^.!,3@O9(H1(V@+^1^H]R91HV@0MOK7I5\-+=BX83K,+;K&Q5U"?0T2N
-M#\V=#-QLH]9_I@QN?>?NU@,>N`PS:Y>IMKD,+!?_A^:JEX`;C6\L`!6[RD9L
-M,1-_0V*->9A[T=H;?I=K4\VWP17>]UZN=H<RPB&_Q1RR^"^;)EOJG]FO*5&=
-M;6GX.7CG8<RW<<Z"L=J/Y/=OQ!,5KU>CC]DD9$^&6'K9H"R6[G0FV;%@EPMJ
-M(N*9/8>`HQ8.+Q+P^"!2WP:G4QKU_H!_EOKC!\AXPYQA)Z`U(X2+6,S/9N#>
-M'+^?'<!]"U9)*K6VLM?M;J[7=?U<)Q$W=QP3A3A/_AO]14#=[^DD+G5/F,BH
-M,34[UR&?:NTYX<3*SL;F]KI=9PZHNAQ`3PG7Q0H<Q1'[KRE615),H+.[MVX7
-MB]LV&_[5B'0;`MT/`4VA3\#9-SG^#P%GE#H1XH>73\8I?*?FW2MDU0T2!188
-M?`';A?<'5I=OW4.%BMJ38*"S57VI^VJ#H\<^67!5(;MG&Y#:_1-^3%CDE_%[
-MN)U%5B'C6ZQ&0C)P`.%3'>GMC3X]56_BLRA%5[_W?B_U8^U+-&3%0VZQ>#A@
-M!Z5X-IW,I@3FS=VMG74?R$WZ,N($H,S#E8?0\L9;F#H'L.6"3[@@QI^'(!PB
-MS`+CQ+I]/CW34JPOC5B+X6.2BCEX;65KQ[3&W?:Z(KGV.KY+<S87G"E&E%E@
-M,8JR=,.DCA\5XN!57XHU!6YC-.XQ)@=DJ^U[04PN*X$$/58=!>9&N:-^GNQU
-MUUUF0S1[F6Y`F0U7&,^B@6$`KY(A4=G1DGAXRHQF>C6):=,-,&*[V":TA+67
-M^X;[TOB[>QUG_),$'&V9+N-+"2MR<6Z86Q;'`B"RCA>$.!%3F47B6+J6?7X;
-MZ5RK43#!I48)4I(2]9Q,KGS+47C8>\L,F]O$($TVP:.'9ZQ2/0G8MRTU%ZG!
-M97PBAN"??QFAAOWEB#S"F=;C>!]BU"=IT-FD><M$QBM18--8VICH&-L)_IXZ
-M2(?LV8HPMFCW3`^+/FT%#[W4=U=M8WMY1"F:?*R\QJ!AK4K>L2*Q/G95+=,I
-MF&WWR6*[V;#47-V%C&OB3^LP,M/S+0'FII>:C_'@I`4<(P!V&D2Z2C$L2CFA
-MA@VULMR7'?1HH8E$_Q6(6(MW3[)@+(;>\FIGDA<A#1Z?;G'D)=8G9J,ZO=.%
-M6W<QN/7C)-&7_6GUB-)G`H43/FO"X^VL+_'`<]1G^S(;V_U<ZJ)^.PL#56%^
-M,_8?%%.BV=30%21#Y]ZF:LWZYHJ``NK%PMB"^#$<8P$)EGO^$W\S6R#@Q]LA
-M8>/;_G<Z(M5D?SRF24??C(=1Y$=Z^M22=^YL9QF,R85+ZM$V`\XO.+VWJ#S'
-MH,`:[+#P.#.^A*3DX94^XA&GI[*,_>GHRN(`ZVH=Z>?MD*098B_?^PZ$Y)=Q
-MJ;-G++H(2O(M2BS*7-F'/>#Q;MW%&6RU[/..]9SE%]-1W]S2Q\N9[*\+5VD3
-MG\*\ZTF5V>B"\-FS49",KGQ7Z20I=-F)S-6Q!76,RL:MWDU:(,H!]]G,UN?+
-M`=@BA$V]810D\C32MM]]G!)I[^<8<V5HYIYZE\2XB4;:K_6DWB?VF99ZFL)/
-M?22D5XCTT/@(A[I%R-JB$E9PYM:[RR"2)@F>]FWHR`-IOI6HM<XRK5G*)'IR
-M04DZ(G(B.+Y+XFD4#36I7PEN6NR'O_?*[22#LR^446#A`&W5?2`WG(5&@B,T
-MY;.`W8U[VG0.P!#-ZM&.(N7-S(0[WUJT<V['ZN$,:.H5V^?=L^,7%@71I&S]
-MA9O,)3O3..A!D`QCQ#8@1!!:RB>9LTF:Z1LA!.T9<XG#+,"(=;17:TRNS%_K
-MOB*BFQ!>D!9'.PY:"FTC4HEL;!+,C'$M%<9!FQ278X"]CUBL?L075(C:_=-=
-MN8V]!6<Z)LV_?!09]@@EV`J7\>109-I<GA&7<6;7MLX:5Y'EMJ)/%%^LP[9S
-M='+P)2G1@X1-%T*RZQS^62C<\O=:^,?OM.3!"8GL!EEGRW^BUB`U'=,0OJ,.
-M>GI*8A/]>Z$U:G:YQK:_L4[D=$8TMQ^`UAIYGT0T!,_WX`5QE;F^AS$$`L/;
-M+:GD4<E5$<>=AS81J<S91'`T)E,!`;5SH$Y^+$X5XX)'.:*3JO2,!]:#U!CI
-M3#KC93,(>I`,S]5)$M/^W=<7T[HU<WP;[&(Y)K+NYH+K+Q(>+ZX52'/;DRRE
-MVQ7><>:IR8TKTJR+W*JSO5R_."ZP_1K%E$T;9B-5#/H8%>GI!;[26:K+.MNJ
-MXJN$+OPV%J5\8A@*Q3*TY^_F]`A4D%C)&%1B*J(XBVKC'B)*RO=QP0BJTZPV
-M>ZX?PRIB28]C!MC87`Q+F'HX>J,5"J%HC(?,M^-S;/%99'`\1W$V+@%_:USA
-M!/9LW.LN,A((/[2N`RAM4R'V+34+K3F3!4*"7WM'K:7GP\D$?HK;7ZQG.CG4
-MELXB'8EMMDWL%X@*^O)L-#D+B.9F3(8-+Z($'+Y^GP7`2M=]5_!>#,+2782H
-M9+)(?A.KXF\F>___^-W;SR'^0W>WT^'X#[O=)OY#DYK4I"8UJ4E-:E*3FM2D
-M)C6I24UJ4I.:U*0F-:E)36I2DYK4I"8UJ4E-:E*3FM2D)C6I2?/2_P"5Y0%=
-$`.`!````
-`
-end
diff --git a/contrib/start_dynamic_ppp b/contrib/start_dynamic_ppp
deleted file mode 100644 (file)
index 7ceeddb..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/sh
-# setup hostname in /etc/hosts.  use IP if no name available.
-echo cyberhq > /tmp/local_name
-echo $4 > /tmp/ip
-host $4 | fgrep Name | cut -c7- > /tmp/ip_name
-if [ ! -s /tmp/ip_name ]; then
-    echo $4 > /tmp/ip_name
-fi
-cat /tmp/ip_name > /etc/sendmail.cw
-paste /tmp/ip /tmp/ip_name /tmp/local_name > /tmp/host_bottom
-cat /etc/hosts.top /tmp/host_bottom > /etc/hosts
-rm /tmp/ip /tmp/ip_name /tmp/host_bottom /tmp/local_name
-# Restart sendmail with new name.
-kill -HUP `head -1 /var/run/sendmail.pid`
-# Start fetchmail as root to fetch our mail.
-fetchmail
diff --git a/contrib/toprocmail b/contrib/toprocmail
deleted file mode 100644 (file)
index 159c0b3..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/usr/bin/perl
-
-# fetchmail -> procmail pretti-fier proxy thingamajig
-# ver. 2000-04-01
-#
-# John Lim Eng Hooi <jleh@mail.com>
-#
-
-# Where's procmail located?
-$proc_path = '/usr/bin/procmail';
-
-# Define your ANSI color codes here, I've only bothered to define
-# those I use :)
-$ANSI_green = "\e[0;32m";
-$ANSI_b_white = "\e[1;37m";
-$ANSI_normal = "\e[0;39m";
-
-# Open up procmail
-open (PROCPIPE, "|$proc_path") || die "Can't open procmail pipe!";
-
-# Analyze the message line by line
-while (<STDIN>) {
-
-   # Suck up the lines we want, in this case I just want From: and Subject:
-   if (/^From:/) {
-     $from = $_;
-   }
-
-   if (/^Subject:/) {
-     $subj = $_;
-   }
-
-   # Stuff it out to the pipe too
-   print PROCPIPE;
-}
-
-# Print it out
-print "\n";
-print $ANSI_green, "  ", $from;
-print $ANSI_b_white, "  ", $subj, $ANSI_normal;
-
-# fetchmail's status is appended after this
-print "  -->";
-
-# We're done
-close (PROCPIPE);
diff --git a/contrib/zsh-completion b/contrib/zsh-completion
deleted file mode 100644 (file)
index c5e653f..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-# Set up command completion for zsh
-#
-fetchmailauthtypes=(password kerberos kerberos_v5)
-fetchmailprotocols=(auto pop2 pop3 apop rpop kpop sdps imap imap-k4 imap-gss etrn)
-function fetchmailformattedinterfaces ()
-{ reply=(`ifconfig|perl -e '$/="";while(<>){s/[\r\n]//g;if(/^(\w+\d*).*inet addr:([\d\.]+)/){print "$1/$2\n";}}'`) }
-function fetchmailcompctl ()
-{ reply=(`awk '{ print $2 }' < ~/.fetchmailrc` `fetchmail --help 2>&1| cut -c 7-19 | sed "s/,//g"`) }
-compctl -K fetchmailcompctl \
-       -x "C[-1,-L|--logfile]" -f \
-       -  "C[-1,-f|--fetchmailrc]" -f \
-       -  "C[-1,-i|--idfile]" -f \
-       -  "C[-1,-I|--interface]" -K fetchmailformattedinterfaces \
-       -  "C[-1,-M|--monitor]" -K fetchmailformattedinterfaces \
-       -  "C[-1,-p|--protocol]" -k fetchmailprotocols \
-       -  "C[-1,-A|--auth]" -k fetchmailauthtypes \
-       -  "c[-1,--plugin]" -m \
-       -  "c[-1,--plugout]" -m \
-       -- fetchmail
-
diff --git a/cram.c b/cram.c
index cf33393ebb9662e6a69ae8eb4352d35ee6c3570e..f7559e6d9668792ef42c30ebd6dc1327c1e5a5cb 100644 (file)
--- a/cram.c
+++ b/cram.c
@@ -8,13 +8,11 @@
 #include  <stdio.h>
 #include  <string.h>
 #include  <ctype.h>
-#if defined(STDC_HEADERS)
 #include  <stdlib.h>
-#endif
 #include  "fetchmail.h"
 #include  "socket.h"
 
-#include  "i18n.h"
+#include  "gettext.h"
 #include "fm_md5.h"
 
 void hmac_md5 (const unsigned char *password,  size_t pass_len,
index 5ae73ed69565c6bd0d299b85e503494d0d448100..8f39e86cfe48f18b1c9ed0e86a0039e26258f00f 100644 (file)
--- a/daemon.c
+++ b/daemon.c
 #include <signal.h>
 #include <string.h>
 #include <sys/types.h>
-#ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
-#endif
-#ifdef HAVE_FCNTL_H
 #include <fcntl.h>
-#else /* !HAVE_FCNTL_H */
-#ifdef HAVE_SYS_FCNTL_H
-#include <sys/fcntl.h>
-#endif /* HAVE_SYS_FCNTL_H */
-#endif /* !HAVE_FCNTL_H */
 #include <sys/stat.h>  /* get umask(2) prototyped */
 
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
 
-#if defined(STDC_HEADERS)
 #include <stdlib.h>
-#endif
-
-#if defined(QNX)
-#include <unix.h>
-#endif
-
-#if !defined(HAVE_SETSID) && defined(SIGTSTP)
-#if defined(HAVE_TERMIOS_H)
-#  include <termios.h>         /* for TIOCNOTTY under Linux */
-#endif
 
-#if !defined(TIOCNOTTY) && defined(HAVE_SGTTY_H)
-#  include <sgtty.h>           /* for TIOCNOTTY under NEXTSTEP */
-#endif
-#endif /* !defined(HAVE_SETSID) && defined(SIGTSTP) */
+#include <termios.h>           /* for TIOCNOTTY under Linux */
 
 /* BSD portability hack */
 #if !defined(SIGCHLD) && defined(SIGCLD)
 #include "fetchmail.h"
 #include "tunable.h"
 
-static RETSIGTYPE
+static void
 sigchld_handler (int sig)
 /* process SIGCHLD to obtain the exit code of the terminating process */
 {
-#if    defined(HAVE_WAITPID)                           /* the POSIX way */
     int status;
 
     while (waitpid(-1, &status, WNOHANG) > 0)
        continue; /* swallow 'em up. */
-#elif  defined(HAVE_WAIT3)                             /* the BSD way */
-    pid_t pid;
-#if defined(HAVE_UNION_WAIT) && !defined(__FreeBSD__)
-    union wait status;
-#else
-    int status;
-#endif
-
-    while ((pid = wait3(&status, WNOHANG, 0)) > 0)
-       continue; /* swallow 'em up. */
-#else  /* Zooks! Nothing to do but wait(), and hope we don't block... */
-    int status;
-
-    wait(&status);
-#endif
     lastsig = SIGCHLD;
     (void)sig;
 }
 
-RETSIGTYPE null_signal_handler(int sig) { (void)sig; }
+void null_signal_handler(int sig) { (void)sig; }
 
 SIGHANDLERTYPE set_signal_handler(int sig, SIGHANDLERTYPE handler)
 /* 
@@ -92,37 +52,23 @@ SIGHANDLERTYPE set_signal_handler(int sig, SIGHANDLERTYPE handler)
  */
 {
   SIGHANDLERTYPE rethandler;
-#ifdef HAVE_SIGACTION
   struct sigaction sa_new, sa_old;
 
   memset (&sa_new, 0, sizeof sa_new);
   sigemptyset (&sa_new.sa_mask);
   sa_new.sa_handler = handler;
   sa_new.sa_flags = 0;
-#ifdef SA_RESTART      /* SunOS 4.1 portability hack */
   /* system call should restart on all signals except SIGALRM */
   if (sig != SIGALRM)
       sa_new.sa_flags |= SA_RESTART;
-#endif
-#ifdef SA_NOCLDSTOP    /* SunOS 4.1 portability hack */
   if (sig == SIGCHLD)
       sa_new.sa_flags |= SA_NOCLDSTOP;
-#endif
   sigaction(sig, &sa_new, &sa_old);
   rethandler = sa_old.sa_handler;
 #if defined(SIGPWR)
   if (sig == SIGCHLD)
      sigaction(SIGPWR, &sa_new, NULL);
 #endif
-#else /* HAVE_SIGACTION */
-  rethandler = signal(sig, handler);
-#if defined(SIGPWR)
-  if (sig == SIGCHLD)
-      signal(SIGPWR, handler);
-#endif
-  /* system call should restart on all signals except SIGALRM */
-  siginterrupt(sig, sig == SIGALRM);
-#endif /* HAVE_SIGACTION */
   return rethandler;
 }
 
@@ -170,38 +116,11 @@ daemonize (const char *logfile)
   /* Make ourselves the leader of a new process group with no
      controlling terminal */
 
-#if    defined(HAVE_SETSID)            /* POSIX */
   /* POSIX makes this soooo easy to do */
   if (setsid() < 0) {
     report(stderr, "setsid (%s)\n", strerror(errno));
     return(PS_IOERR);
   }
-#elif  defined(SIGTSTP)                /* BSD */
-  /* change process group */
-#ifndef __EMX__
-  setpgrp(0, getpid());
-#endif
-  /* lose controlling tty */
-  if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
-    ioctl(fd, TIOCNOTTY, (char *) 0);
-    close(fd); /* not checking should be safe, there were no writes */
-  }
-#else                                  /* SVR3 and older */
-  /* change process group */
-#ifndef __EMX__
-  setpgrp();
-#endif
-  
-  /* lose controlling tty */
-  set_signal_handler(SIGHUP, SIG_IGN);
-  if ((childpid = fork()) < 0) {
-    report(stderr, "fork (%s)\n", strerror(errno));
-    return(PS_IOERR);
-  }
-  else if (childpid > 0) {
-    exit(0);   /* parent */
-  }
-#endif
 
 nottyDetach:
 
index ef2cc07af7068c35ed121b882f87b7032e665acd..94aa50b63a9ceba7b46c154dad7e2558fc3938a8 100644 (file)
@@ -6,7 +6,7 @@
 <title>Updated design notes on fetchmail</title>
 <link rev="made" href="mailto:matthias.andree@gmx.de" />
 <meta name="description" content="Updated design notes on fetchmail." />
-<meta name="keywords" content="fetchmail, POP, POP2, POP3, IMAP, ETRN, ODMR, remote mail" />
+<meta name="keywords" content="fetchmail, POP3, IMAP, ETRN, ODMR, remote mail" />
 <style type="text/css">
 /*<![CDATA[*/
  h1.c1 {text-align: center}
index c2917268cedfce70fa9d70f085bad27b7f4f201b..a6a18754efd550628d292c444ffa767bcb5a5752 100644 (file)
--- a/driver.c
+++ b/driver.c
 #include  <setjmp.h>
 #include  <errno.h>
 #include  <string.h>
-#ifdef HAVE_MEMORY_H
-#include  <memory.h>
-#endif /* HAVE_MEMORY_H */
-#if defined(STDC_HEADERS)
 #include  <stdlib.h>
 #include  <limits.h>
-#endif
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
-#if defined(HAVE_SYS_ITIMER_H)
-#include <sys/itimer.h>
-#endif
 #include  <signal.h>
-#ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
-#endif
+#include <sys/time.h>
 
-#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
-#endif
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
 #include <netdb.h>
 #ifdef HAVE_PKG_hesiod
 #ifdef __cplusplus
@@ -48,11 +32,8 @@ extern "C" {
 #include <langinfo.h>
 
 #include "kerberos.h"
-#ifdef KERBEROS_V4
-#include <netinet/in.h>
-#endif /* KERBEROS_V4 */
 
-#include "i18n.h"
+#include "gettext.h"
 #include "socket.h"
 
 #include "fetchmail.h"
@@ -98,7 +79,6 @@ void resetidletimeout(void)
 void set_timeout(int timeleft)
 /* reset the nonresponse-timeout */
 {
-#if !defined(__EMX__) && !defined(__BEOS__)
     struct itimerval ntimeout;
 
     if (timeleft == 0)
@@ -108,10 +88,9 @@ void set_timeout(int timeleft)
     ntimeout.it_value.tv_sec  = timeleft;
     ntimeout.it_value.tv_usec = 0;
     setitimer(ITIMER_REAL, &ntimeout, (struct itimerval *)NULL);
-#endif
 }
 
-static RETSIGTYPE timeout_handler (int signal)
+static void timeout_handler (int signal)
 /* handle SIGALRM signal indicating a server timeout */
 {
     (void)signal;
@@ -140,74 +119,9 @@ static int cleanupSockClose (int fd)
     return (scerror);
 }
 
-#ifdef KERBEROS_V4
-static int kerberos_auth(socket, canonical, principal) 
-/* authenticate to the server host using Kerberos V4 */
-int socket;            /* socket to server host */
-char *canonical;       /* server name */
-char *principal;
-{
-    KTEXT ticket;
-    MSG_DAT msg_data;
-    CREDENTIALS cred;
-    Key_schedule schedule;
-    int rem;
-    char * prin_copy = (char *) NULL;
-    char * prin = (char *) NULL;
-    char * inst = (char *) NULL;
-    char * realm = (char *) NULL;
-
-    if (principal != (char *)NULL && *principal)
-    {
-        char *cp;
-        prin = prin_copy = xstrdup(principal);
-       for (cp = prin_copy; *cp && *cp != '.'; ++cp)
-           ;
-       if (*cp)
-       {
-           *cp++ = '\0';
-           inst = cp;
-           while (*cp && *cp != '@')
-               ++cp;
-           if (*cp)
-           {
-               *cp++ = '\0';
-               realm = cp;
-           }
-       }
-    }
-  
-    ticket = xmalloc(sizeof (KTEXT_ST));
-    rem = (krb_sendauth (0L, socket, ticket,
-                        prin ? prin : "pop",
-                        inst ? inst : canonical,
-                        realm ? realm : ((char *) (krb_realmofhost (canonical))),
-                        ((unsigned long) 0),
-                        (&msg_data),
-                        (&cred),
-                        (schedule),
-                        ((struct sockaddr_in *) 0),
-                        ((struct sockaddr_in *) 0),
-                        "KPOPV0.1"));
-    free(ticket);
-    if (prin_copy)
-    {
-        free(prin_copy);
-    }
-    if (rem != KSUCCESS)
-    {
-       report(stderr, GT_("kerberos error %s\n"), (krb_get_err_text (rem)));
-       return (PS_AUTHFAIL);
-    }
-    return (0);
-}
-#endif /* KERBEROS_V4 */
-
 #ifdef KERBEROS_V5
-static int kerberos5_auth(socket, canonical)
-/* authenticate to the server host using Kerberos V5 */
-int socket;             /* socket to server host */
-const char *canonical;  /* server name */
+/** authenticate to the server host using Kerberos V5 */
+static int kerberos5_auth(int socket /** socket to server host */, const char *canonical /** server name */)
 {
     krb5_error_code retval;
     krb5_context context;
@@ -455,7 +369,7 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
         * could be "auto". */
        switch (ctl->server.protocol)
        {
-           case P_POP3: case P_APOP: case P_RPOP:
+           case P_POP3:
            fetchsizelimit = 1;
        }
 
@@ -465,7 +379,7 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
     }
 
     /*
-     * What forces this code is that in POP2 and
+     * What forces this code is that in
      * IMAP2bis you can't fetch a message without
      * having it marked `seen'.  In POP3 and IMAP4, on the
      * other hand, you can (peek_capable is set by 
@@ -690,8 +604,44 @@ static int fetch_messages(int mailserver_socket, struct query *ctl,
                if (separatefetchbody)
                {
                    len = -1;
-                   if ((err=(ctl->server.base_protocol->fetch_body)(mailserver_socket,ctl,num,&len)))
+                   if ((err=(ctl->server.base_protocol->fetch_body)(mailserver_socket,ctl,num,&len))) {
+                       if (err == PS_ERROR && ctl->server.retrieveerror) {
+                           /*
+                            * Mark a message with a protocol error as seen.
+                            * This can be used to see which messages we've attempted
+                            * to download, but failed.
+                            */
+                           if (ctl->server.retrieveerror == RE_MARKSEEN) {
+                               if ((ctl->server.base_protocol->mark_seen)(mailserver_socket,ctl,num)) {
+                                   return(err);
+                               }
+                           }
+
+                           if (ctl->server.retrieveerror != RE_ABORT) {
+                               /*
+                                * Do not abort download session.  Continue with the next message.
+                                *
+                                * Prevents a malformed message from blocking all other messages
+                                * behind it in the mailbox from being downloaded.
+                                *
+                                * Reconnect to SMTP to force this incomplete message to be dropped.
+                                * Required because we've already begun the DATA portion of the
+                                * interaction with the SMTP server (commands are ignored/
+                                * considered part of the message data).
+                                */
+                               abort_message_sink(ctl);
+
+                               // Ensure we don't delete the failed message from the server.
+                               suppress_delete = TRUE;
+
+                               // Bookkeeping required before next message can be downloaded.
+                               goto flagthemail;
+                           }
+                       }
+
                        return(err);
+                   }
+
                    /*
                     * Work around a bug in Novell's
                     * broken GroupWise IMAP server;
@@ -1082,7 +1032,6 @@ static int do_session(
                             ctl->server.base_protocol->name, ctl->server.pollname);
                    strlcpy(errbuf, strerror(err_no), sizeof(errbuf));
                report_complete(stderr, ": %s\n", errbuf);
-
            }
            err = PS_SOCKET;
            set_timeout(0);
@@ -1123,17 +1072,6 @@ static int do_session(
         */
        set_timeout(0);
        phase = oldphase;
-#ifdef KERBEROS_V4
-       if (ctl->server.authenticate == A_KERBEROS_V4 && (strcasecmp(proto->name,"IMAP") != 0))
-       {
-           set_timeout(mytimeout);
-           err = kerberos_auth(mailserver_socket, ctl->server.truename,
-                              ctl->server.principal);
-           set_timeout(0);
-           if (err != 0)
-               goto cleanUp;
-       }
-#endif /* KERBEROS_V4 */
 
 #ifdef KERBEROS_V5
        if (ctl->server.authenticate == A_KERBEROS_V5)
@@ -1548,7 +1486,7 @@ is restored."));
        msg = GT_("socket");
        break;
     case PS_SYNTAX:
-       msg = GT_("missing or bad RFC822 header");
+       msg = GT_("missing or bad RFC822 header or command line option");
        break;
     case PS_IOERR:
        msg = GT_("MDA");
@@ -1609,14 +1547,6 @@ int do_protocol(struct query *ctl /** parsed options with merged-in defaults */,
 {
     int        err;
 
-#ifndef KERBEROS_V4
-    if (ctl->server.authenticate == A_KERBEROS_V4)
-    {
-       report(stderr, GT_("Kerberos V4 support not linked.\n"));
-       return(PS_ERROR);
-    }
-#endif /* KERBEROS_V4 */
-
 #ifndef KERBEROS_V5
     if (ctl->server.authenticate == A_KERBEROS_V5)
     {
diff --git a/env.c b/env.c
index edf998983a88be540d639946ed9c8b669711f07f..7d03ae170a463502476d59b13bfae242fbd49a54 100644 (file)
--- a/env.c
+++ b/env.c
@@ -8,32 +8,21 @@
 #include "config.h"
 #include <stdio.h>
 #include <ctype.h>
-#if defined(STDC_HEADERS)
 #include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
 #include <pwd.h>
 #include <string.h>
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
 #include <netdb.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include "fetchmail.h"
 #include "getaddrinfo.h"
 
-#include "i18n.h"
-#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS) && defined(HAVE_STRFTIME)
+#include "gettext.h"
+#if defined(ENABLE_NLS)
 #include <locale.h>
 #endif
 
-#ifndef HAVE_DECL_GETENV
-extern char *getenv(const char *);     /* needed on sysV68 R3V7.1. */
-#endif
-
 void envquery(int argc, char **argv)
 /* set up basic stuff from the environment (including the rc file name) */
 {
@@ -226,7 +215,6 @@ char *rfc822timestamp(void)
     static char buf[50];
 
     time(&now);
-#ifdef HAVE_STRFTIME
     /*
      * Conform to RFC822.  We generate a 4-digit year here, avoiding
      * Y2K hassles.  Max length of this timestamp in an English locale
@@ -235,25 +223,15 @@ char *rfc822timestamp(void)
      * weird multibyte i18n characters (such as kanji) from showing up
      * in your Received headers.
      */
-#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS)
+#if defined(ENABLE_NLS)
     setlocale (LC_TIME, "C");
 #endif
     strftime(buf, sizeof(buf)-1, 
             "%a, %d %b %Y %H:%M:%S XXXXX (%Z)", localtime(&now));
-#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS)
+#if defined(ENABLE_NLS)
     setlocale (LC_TIME, "");
 #endif
     strncpy(strstr(buf, "XXXXX"), tzoffset(&now), 5);
-#else
-    /*
-     * This is really just a portability fallback, as the
-     * date format ctime(3) emits is not RFC822
-     * conformant.
-     */
-    strlcpy(buf, ctime(&now), sizeof(buf));
-    buf[strlen(buf)-1] = '\0'; /* remove trailing \n */
-#endif /* HAVE_STRFTIME */
-
     return(buf);
 }
 
@@ -263,13 +241,8 @@ const char *showproto(int proto)
     switch (proto)
     {
     case P_AUTO: return("auto");
-#ifdef POP2_ENABLE
-    case P_POP2: return("POP2");
-#endif /* POP2_ENABLE */
 #ifdef POP3_ENABLE
     case P_POP3: return("POP3");
-    case P_APOP: return("APOP");
-    case P_RPOP: return("RPOP");
 #endif /* POP3_ENABLE */
 #ifdef IMAP_ENABLE
     case P_IMAP: return("IMAP");
index 7667c9c2fa5f2952aaa68dd1298112c24de2b1dc..52e09059062397063b7f636d3acf0541aff82d4a 100644 (file)
@@ -6,7 +6,7 @@
     <title>Eric S. Raymond's former Design notes on fetchmail</title>
 <link rev="made" href="mailto:esr@snark.thyrsus.com" />
 <meta name="description" content="Design notes on fetchmail." />
-<meta name="keywords" content="fetchmail, POP, POP2, POP3, IMAP, remote mail" />
+<meta name="keywords" content="fetchmail, POP3, IMAP, remote mail" />
 <style type="text/css">
 /*<![CDATA[*/
  h1.c1 {text-align: center}
diff --git a/etrn.c b/etrn.c
index ac416c86c3bed7eeb7246c268f7f259c12d04f67..24c532d306607967af0c7dd47ea1128ac1b09988 100644 (file)
--- a/etrn.c
+++ b/etrn.c
@@ -9,13 +9,10 @@
 #include  <stdio.h>
 #include  <stdlib.h>
 #include  <assert.h>
-#ifdef HAVE_NET_SOCKET_H /* BeOS needs this */
-#include <net/socket.h>
-#endif
 #include  <netdb.h>
 #include  <errno.h>
 #include  <unistd.h>
-#include  "i18n.h"
+#include  "gettext.h"
 #include  "fetchmail.h"
 #include  "smtp.h"
 #include  "socket.h"
index c57438fc2f58ffb079e61712488d0e6f209ea0d8..0e4e0054d5146d760e321700474b0f27109ab857 100644 (file)
@@ -17,7 +17,7 @@ a much better one.
 <title>The Fetchmail FAQ</title>
 <meta name="description"
 content="Frequently asked questions about fetchmail."/>
-<meta name="keywords" content="fetchmail, POP, POP2, POP3, IMAP, remote mail"/>
+<meta name="keywords" content="fetchmail, POP3, IMAP, remote mail"/>
 </head>
 <body>
 <table width="100%" cellpadding="0" summary="Canned page footer">
@@ -528,11 +528,11 @@ paper on the Web with a search for that title.</p>
 <h2><a id="G8" name="G8">G8. What is the best server to use with
 fetchmail?</a></h2>
 
-<p>Fetchmail will work with any POP, IMAP, ETRN, or ODMR server
+<p>Fetchmail will work with any POP3, IMAP, ETRN, or ODMR server
 that conforms to the relevant standards/RFCs (and even some outright
 broken ones like <a href="#S2">Microsoft Exchange</a> and <a
     href="#S6">Novell GroupWise</a>). This doesn't mean it works equally
-well with all, however. POP2 servers, and POP3 servers without UIDL,
+well with all, however. POP3 servers without UIDL
 limit fetchmail's capabilities in various ways described on the manual
 page.</p>
 
@@ -1595,11 +1595,20 @@ so broken that it's unusable. One symptom is that messages without
 a terminating newline get the POP3 message termination dot emitted
 -- you guessed it -- right after the last character of the message,
 with no terminating newline added. This will hang fetchmail or any
-other RFC-compliant server. IMAP is alleged to work OK, though.</p>
-
-<p>Older versions of Exchange are semi-usable.  They randomly drop
-attachments on the floor, though.  Microsoft acknowledges this
-as a known bug and apparently has no plans to fix it.</p>
+other RFC-compliant client. IMAP is alleged to work OK, though.</p>
+
+<p>Exchange 2003 SP2 has been observed to alter MIME boundary
+lines in multipart messages between one IMAP FETCH command and the next
+under some circumstances -- for instance, when the top-level
+Content-Transfer-Encoding is "binary" (which is commonplace with Perl's
+MIME::Lite module).  This causes MUAs to not detect attachments, but
+render the whole message body as one lump of hardly legible to
+unintelligible text, rather than nicely presenting text part and
+attachments or images separately.  The cause is that Exchange uses its
+own message store and needs to convert back to MIME message format
+on-the-fly, and apparently this is sometimes subject to such
+inconsistencies.
+</p>
 
 <p>Fetchmail using IMAP usually supports the proprietary NTLM mode used
 with Microsoft Exchange servers. "Usually" here means that it fails on some
@@ -1719,9 +1728,6 @@ explicitly to your mailbox name.</li>
 </ul>
 </blockquote>
 
-<p>But, the best option involves finding a server that runs better
-software.</p>
-
 <h2><a id="S3" name="S3">S3. How can I use fetchmail with HP
 OpenMail?</a></h2>
 
@@ -3548,7 +3554,7 @@ oversized mails or both when a user specifies both
 first message in your mailbox. This usually stems from a message like
 the one shown below, which is automatically created on your server. This
 message shows up if the University of Washington IMAP or PINE software
-is used on the server together with a POP2 or POP3 daemon that is not
+is used on the server together with a POP3 daemon that is not
 aware of these messages, such as some versions of Qualcomm Popper
 (QPOP):</p>
 
index 227ed111e1e058340c786aa36636b2a491860ceb..e52984ba4018d6b4c7bf3b2803459393736898cd 100644 (file)
 <hr />
 <h1 class="c1">Fetchmail Feature List</h1>
 
+<h2>Version 7.0:</h2>
+<ul>
+<li>Removes support for obsolete POP2, POP3/RPOP, POP3 LAST, Kerberos IV.</li>
+</ul>
+
 <h2>Since 5.0:</h2>
 
 <ul>
@@ -199,7 +204,7 @@ syslog.</li>
 only when a point-to-point link to a particular IP address is
 up.</li>
 
-<li>RPOP support (restored; had been removed in 1.8).</li>
+<li>RPOP support (restored; had been removed in 1.8, later removed again).</li>
 </ul>
 
 <h2>2.0 and earlier versions:</h2>
index 4327c6e4bce21c3da471e2a174a5195a1fe48d02..021a1af00a409c43e06c85c87fbdf9daea136bd3 100644 (file)
@@ -6,18 +6,12 @@
 #include "config.h"
 
 #include <stdio.h>
-#if defined(STDC_HEADERS)
 #include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
 #include <fcntl.h>
 #include <string.h>
 #include <signal.h>
-#if defined(HAVE_SYSLOG)
 #include <syslog.h>
-#endif
 #include <pwd.h>
 #ifdef __FreeBSD__
 #include <grp.h>
 #include <errno.h>
 #include <sys/types.h>
 #include <sys/stat.h>
-#ifdef HAVE_SETRLIMIT
 #include <sys/resource.h>
-#endif /* HAVE_SETRLIMIT */
 
 #ifdef HAVE_SOCKS
 #include <socks.h> /* SOCKSinit() */
 #endif /* HAVE_SOCKS */
 
-#ifdef HAVE_LANGINFO_H
 #include <langinfo.h>
-#endif
 
 #include "fetchmail.h"
 #include "socket.h"
 #include "tunable.h"
 #include "smtp.h"
 #include "netrc.h"
-#include "i18n.h"
+#include "gettext.h"
 #include "lock.h"
 
 /* need these (and sys/types.h) for res_init() */
@@ -84,8 +74,14 @@ static int activecount;              /* count number of active entries */
 static struct runctl cmd_run;  /* global options set from command line */
 static time_t parsetime;       /* time of last parse */
 
-static RETSIGTYPE terminate_run(int);
-static RETSIGTYPE terminate_poll(int);
+static void terminate_run(int);
+static void terminate_poll(int);
+
+#ifdef HAVE_LIBPWMD
+static pwm_t *pwm;             /* the handle */
+static const char *pwmd_socket;        /* current socket */
+static const char *pwmd_file;  /* current file */
+#endif
 
 #if defined(__FreeBSD__) && defined(__FreeBSD_USE_KVM)
 /* drop SGID kmem privileage until we need it */
@@ -108,8 +104,8 @@ static void dropprivs(void)
 }
 #endif
 
-#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS) && defined(HAVE_STRFTIME)
 #include <locale.h>
+#if defined(ENABLE_NLS)
 /** returns timestamp in current locale,
  * and resets LC_TIME locale to POSIX. */
 static char *timestamp (void)
@@ -127,7 +123,7 @@ static char *timestamp (void)
 #define timestamp rfc822timestamp
 #endif
 
-static RETSIGTYPE donothing(int sig) 
+static void donothing(int sig) 
 {
     set_signal_handler(sig, donothing);
     lastsig = sig;
@@ -151,10 +147,288 @@ static void printcopyright(FILE *fp) {
 
 const char *iana_charset;
 
+#ifdef HAVE_LIBPWMD
+static void exit_with_pwmd_error(gpg_error_t error)
+{
+    gpg_err_code_t code = gpg_err_code(error);
+
+    report(stderr, GT_("pwmd: error %i: %s\n"), code, pwmd_strerror(error));
+
+    if (pwm) {
+       pwmd_close(pwm);
+       pwm = NULL;
+    }
+
+    /* Don't exit if daemonized. There may be other active accounts. */
+    if (isatty(1))
+       exit(PS_UNDEFINED);
+}
+
+static int do_pwmd_connect(const char *socketname, const char *filename)
+{
+    static int init;
+    gpg_error_t rc;
+    pwmd_socket_t s;
+
+    if (!init) {
+       pwmd_init();
+       init = 1;
+    }
+
+    if (!pwm || (pwm && socketname && !pwmd_socket) ||
+           (pwm && !socketname && pwmd_socket) ||
+           (pwm && socketname && pwmd_socket && strcmp(socketname, pwmd_socket))) {
+       if (pwm)
+           pwmd_close(pwm);
+
+       pwm = pwmd_new("Fetchmail");
+       rc = pwmd_connect_url(pwm, socketname);
+
+       if (rc) {
+           exit_with_pwmd_error(rc);
+           return 1;
+       }
+    }
+
+    if (run.pinentry_timeout > 0) {
+       rc = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY_TIMEOUT,
+               run.pinentry_timeout);
+
+       if (rc) {
+           exit_with_pwmd_error(rc);
+           return 1;
+       }
+    }
+
+    rc = pwmd_socket_type(pwm, &s);
+
+    if (rc) {
+       exit_with_pwmd_error(rc);
+       return 1;
+    }
+
+    if (!pwmd_file || strcmp(filename, pwmd_file)) {
+       if (s == PWMD_SOCKET_SSH)
+           /* use a local pinentry since X11 forwarding is broken. */
+           rc = pwmd_open2(pwm, filename);
+       else
+           rc = pwmd_open(pwm, filename);
+
+       if (rc) {
+           exit_with_pwmd_error(rc);
+           return 1;
+       }
+    }
+
+    /* May be null to use the default of ~/.pwmd/socket. */
+    pwmd_socket = socketname;
+    pwmd_file = filename;
+    return 0;
+}
+
+static int get_pwmd_details(const char *pwmd_account, int protocol,
+       struct query *ctl)
+{
+    const char *prot = showproto(protocol);
+    gpg_error_t error;
+    char *result;
+    char *tmp = xstrdup(pwmd_account);
+    int i;
+
+    for (i = 0; tmp[i]; i++) {
+       if (i && tmp[i] == '^')
+           tmp[i] = '\t';
+    }
+
+    /*
+     * Get the hostname for this protocol. Element path must be
+     * account->[protocol]->hostname.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\t%s\thostname", tmp, prot);
+
+    if (error) {
+       if (gpg_err_code(error) == GPG_ERR_NOT_FOUND) {
+           report(stderr, GT_("pwmd: %s->%s->hostname: %s\n"), pwmd_account, prot, pwmd_strerror(error));
+           pwmd_close(pwm);
+           pwm = NULL;
+
+           if (isatty(1))
+               exit(PS_SYNTAX);
+
+           return 1;
+       }
+       else {
+           exit_with_pwmd_error(error);
+           return 1;
+       }
+    }
+
+    if (ctl->server.pollname != ctl->server.via)
+       xfree(ctl->server.via);
+
+    ctl->server.via = xstrdup(result);
+
+    if (ctl->server.queryname)
+       xfree(ctl->server.queryname);
+
+    ctl->server.queryname = xstrdup(ctl->server.via);
+
+    if (ctl->server.truename)
+       xfree(ctl->server.truename);
+
+    ctl->server.truename = xstrdup(ctl->server.queryname);
+    pwmd_free(result);
+
+    /*
+     * Server port. Fetchmail tries standard ports for known services so it
+     * should be alright if this element isn't found. ctl->server.protocol is
+     * already set. This sets ctl->server.service.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\t%s\tport", tmp, prot);
+
+    if (error) {
+       if (gpg_err_code(error) == GPG_ERR_NOT_FOUND)
+           report(stderr, GT_("pwmd: %s->%s->port: %s\n"), pwmd_account, prot, pwmd_strerror(error));
+       else {
+           exit_with_pwmd_error(error);
+           return 1;
+       }
+    }
+    else {
+       if (ctl->server.service)
+           xfree(ctl->server.service);
+
+       ctl->server.service = xstrdup(result);
+       pwmd_free(result);
+    }
+
+    /*
+     * Get the remote username. Element must be account->username.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\tusername", tmp);
+
+    if (error) {
+       if (gpg_err_code(error) == GPG_ERR_NOT_FOUND) {
+           report(stderr, GT_("pwmd: %s->username: %s\n"), pwmd_account, pwmd_strerror(error));
+
+           if (!isatty(1)) {
+               pwmd_close(pwm);
+               pwm = NULL;
+               return 1;
+           }
+       }
+       else {
+           exit_with_pwmd_error(error);
+           return 1;
+       }
+    }
+    else {
+       if (ctl->remotename)
+           xfree(ctl->remotename);
+
+       if (ctl->server.esmtp_name)
+           xfree(ctl->server.esmtp_name);
+
+       ctl->remotename = xstrdup(result);
+       ctl->server.esmtp_name = xstrdup(result);
+       pwmd_free(result);
+    }
+
+    /*
+     * Get the remote password. Element must be account->password.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\tpassword", tmp);
+
+    if (error) {
+       if (gpg_err_code(error) == GPG_ERR_NOT_FOUND) {
+           report(stderr, GT_("pwmd: %s->password: %s\n"), pwmd_account, pwmd_strerror(error));
+
+           if (!isatty(1)) {
+               pwmd_close(pwm);
+               pwm = NULL;
+               return 1;
+           }
+       }
+       else {
+           exit_with_pwmd_error(error);
+           return 1;
+       }
+    }
+    else {
+       if (ctl->password)
+           xfree(ctl->password);
+
+       ctl->password= xstrdup(result);
+       pwmd_free(result);
+    }
+
+#ifdef SSL_ENABLE
+    /*
+     * If there is a ssl element and set to 1, enable ssl for this account.
+     * Element path must be account->[protocol]->ssl.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\t%s\tssl", tmp, prot);
+
+    if (error) {
+       if (gpg_err_code(error) == GPG_ERR_NOT_FOUND) {
+           report(stderr, GT_("pwmd: %s->%s->ssl: %s\n"), pwmd_account, prot, pwmd_strerror(error));
+
+           if (!isatty(1)) {
+               pwmd_close(pwm);
+               pwm = NULL;
+               return 1;
+           }
+       }
+       else {
+           exit_with_pwmd_error(error);
+           return 1;
+       }
+    }
+    else {
+       ctl->use_ssl = atoi(result) >= 1 ? FLAG_TRUE : FLAG_FALSE;
+       pwmd_free(result);
+    }
+
+    /*
+     * account->[protocol]->sslfingerprint.
+     */
+    error = pwmd_command(pwm, &result, "GET %s\t%s\tsslfingerprint", tmp, prot);
+
+    if (error) {
+       if (gpg_err_code(error) == GPG_ERR_NOT_FOUND) {
+           report(stderr, GT_("pwmd: %s->%s->sslfingerprint: %s\n"), pwmd_account, prot, pwmd_strerror(error));
+
+           if (!isatty(1)) {
+               pwmd_close(pwm);
+               pwm = NULL;
+               return 1;
+           }
+       }
+       else {
+           exit_with_pwmd_error(error);
+           return 1;
+       }
+    }
+    else {
+       if (ctl->sslfingerprint)
+           xfree(ctl->sslfingerprint);
+
+       ctl->sslfingerprint = xstrdup(result);
+       pwmd_free(result);
+    }
+#endif
+
+    xfree(tmp);
+    return 0;
+}
+#endif
+
 int main(int argc, char **argv)
 {
     int bkgd = FALSE;
     int implicitmode = FALSE;
+    flag safewithbg = FALSE; /** if parsed options are compatible with a
+                             fetchmail copy running in the background */
     struct query *ctl;
     netrc_entry *netrc_list;
     char *netrc_file, *tmpbuf;
@@ -198,7 +472,7 @@ int main(int argc, char **argv)
 
 #define IDFILE_NAME    ".fetchids"
     run.idfile = prependdir (IDFILE_NAME, fmhome);
-  
+
     outlevel = O_NORMAL;
 
     /*
@@ -222,7 +496,7 @@ int main(int argc, char **argv)
     {
        int i;
 
-       i = parsecmdline(argc, argv, &cmd_run, &cmd_opts);
+       i = parsecmdline(argc, argv, &cmd_run, &cmd_opts, &safewithbg);
        if (i < 0)
            exit(PS_SYNTAX);
 
@@ -233,9 +507,6 @@ int main(int argc, char **argv)
     if (versioninfo)
     {
        const char *features = 
-#ifdef POP2_ENABLE
-       "+POP2"
-#endif /* POP2_ENABLE */
 #ifndef POP3_ENABLE
        "-POP3"
 #endif /* POP3_ENABLE */
@@ -275,15 +546,12 @@ int main(int argc, char **argv)
 #ifdef ENABLE_NLS
        "+NLS"
 #endif /* ENABLE_NLS */
-#ifdef KERBEROS_V4
-       "+KRB4"
-#endif /* KERBEROS_V4 */
 #ifdef KERBEROS_V5
        "+KRB5"
 #endif /* KERBEROS_V5 */
-#ifndef HAVE_RES_SEARCH
-       "-DNS"
-#endif
+#ifdef HAVE_LIBPWMD
+       "+PWMD"
+#endif /* HAVE_LIBPWMD */
        ".\n";
        printf(GT_("This is fetchmail release %s"), VERSION);
        fputs(features, stdout);
@@ -312,20 +580,13 @@ int main(int argc, char **argv)
        run.use_syslog = 0;
     }
 
-#if defined(HAVE_SYSLOG)
     /* logging should be set up early in case we were restarted from exec */
     if (run.use_syslog)
     {
-#if defined(LOG_MAIL)
        openlog(program_name, LOG_PID, LOG_MAIL);
-#else
-       /* Assume BSD4.2 openlog with two arguments */
-       openlog(program_name, LOG_PID);
-#endif
        report_init(-1);
     }
     else
-#endif
        report_init((run.poll_interval == 0 || nodetach) && !run.logfile);
 
 #ifdef POP3_ENABLE
@@ -343,7 +604,6 @@ int main(int argc, char **argv)
     /* construct the lockfile */
     fm_lock_setup(&run);
 
-#ifdef HAVE_SETRLIMIT
     /*
      * Before getting passwords, disable core dumps unless -v -d0 mode is on.
      * Core dumps could otherwise contain passwords to be scavenged by a
@@ -356,7 +616,6 @@ int main(int argc, char **argv)
        corelimit.rlim_max = 0;
        setrlimit(RLIMIT_CORE, &corelimit);
     }
-#endif /* HAVE_SETRLIMIT */
 
 #define        NETRC_FILE      ".netrc"
     /* parse the ~/.netrc file (if present) for future password lookups. */
@@ -502,17 +761,23 @@ int main(int argc, char **argv)
        else if (getpid() == pid)
            /* this test enables re-execing on a changed rcfile */
            fm_lock_assert();
-       else if (argc > 1)
+       else if (argc > 1 && !safewithbg)
        {
            fprintf(stderr,
                    GT_("fetchmail: can't accept options while a background fetchmail is running.\n"));
+           {
+               int i;
+               fprintf(stderr, "argc = %d, arg list:\n", argc);
+               for (i = 1; i < argc; i++) fprintf(stderr, "arg %d = \"%s\"\n", i, argv[i]);
+           }
            return(PS_EXCLUDE);
        }
        else if (kill(pid, SIGUSR1) == 0)
        {
-           fprintf(stderr,
-                   GT_("fetchmail: background fetchmail at %ld awakened.\n"),
-                   (long)pid);
+           if (outlevel > O_SILENT)
+               fprintf(stderr,
+                       GT_("fetchmail: background fetchmail at %ld awakened.\n"),
+                       (long)pid);
            return(0);
        }
        else
@@ -643,6 +908,11 @@ int main(int argc, char **argv)
         * leaks...
         */
        struct stat     rcstat;
+#ifdef HAVE_LIBPWMD
+       time_t now;
+
+       time(&now);
+#endif
 
        if (strcmp(rcfile, "-") == 0) {
            /* do nothing */
@@ -652,7 +922,15 @@ int main(int argc, char **argv)
                       GT_("couldn't time-check %s (error %d)\n"),
                       rcfile, errno);
        }
+#ifdef HAVE_LIBPWMD
+       /*
+        * isatty() to make sure this is a background process since the
+        * lockfile is removed after each invokation.
+        */
+       else if (!isatty(1) && rcstat.st_mtime > parsetime)
+#else
        else if (rcstat.st_mtime > parsetime)
+#endif
        {
            report(stdout, GT_("restarting fetchmail (%s changed)\n"), rcfile);
 
@@ -745,6 +1023,19 @@ int main(int argc, char **argv)
 
                    dofastuidl = 0; /* this is reset in the driver if required */
 
+#ifdef HAVE_LIBPWMD
+                   /*
+                    * At each poll interval, check the pwmd server for
+                    * changes in host and auth settings.
+                    */
+                   if (ctl->pwmd_file) {
+                       if (do_pwmd_connect(ctl->pwmd_socket, ctl->pwmd_file))
+                           continue;
+
+                       if (get_pwmd_details(ctl->server.pollname, ctl->server.protocol, ctl))
+                           continue;
+                   }
+#endif
                    querystatus = query_host(ctl);
 
                    if (NUM_NONZERO(ctl->fastuidl))
@@ -813,6 +1104,13 @@ int main(int argc, char **argv)
                }
            }
 
+#ifdef HAVE_LIBPWMD
+       if (pwm) {
+           pwmd_close(pwm);
+           pwm = NULL;
+       }
+#endif
+
        /* close connections cleanly */
        terminate_poll(0);
 
@@ -936,7 +1234,6 @@ static void optmerge(struct query *h2, struct query *h1, int force)
     FLAG_MERGE(server.skip);
     FLAG_MERGE(server.dns);
     FLAG_MERGE(server.checkalias);
-    FLAG_MERGE(server.uidl);
     FLAG_MERGE(server.principal);
 
 #ifdef CAN_MONITOR
@@ -949,6 +1246,7 @@ static void optmerge(struct query *h2, struct query *h1, int force)
     FLAG_MERGE(server.plugout);
     FLAG_MERGE(server.tracepolls);
     FLAG_MERGE(server.badheader);
+    FLAG_MERGE(server.retrieveerror);
 
     FLAG_MERGE(wildcard);
     FLAG_MERGE(remotename);
@@ -1058,8 +1356,36 @@ static int load_params(int argc, char **argv, int optind)
 
     if ((implicitmode = (optind >= argc)))
     {
+#ifdef HAVE_LIBPWMD
+       for (ctl = querylist; ctl; ctl = ctl->next) {
+           ctl->active = !ctl->server.skip;
+
+           if (ctl->pwmd_file) {
+               /*
+                * Cannot get an element path without a service.
+                */
+               if (ctl->server.protocol <= 1) {
+                   report(stderr, GT_("fetchmail: %s configuration invalid, pwmd_file requires a protocol specification\n"),
+                           ctl->server.pollname);
+                   pwmd_close(pwm);
+                   exit(PS_SYNTAX);
+               }
+
+               if (do_pwmd_connect(ctl->pwmd_socket, ctl->pwmd_file))
+                   continue;
+
+               if (get_pwmd_details(ctl->server.pollname, ctl->server.protocol,
+                           ctl))
+                   continue;
+
+               time(&rcstat.st_mtime);
+           }
+       }
+
+#else
        for (ctl = querylist; ctl; ctl = ctl->next)
            ctl->active = !ctl->server.skip;
+#endif
     }
     else
        for (; optind < argc; optind++) 
@@ -1080,6 +1406,27 @@ static int load_params(int argc, char **argv, int optind)
                        fprintf(stderr,GT_("Warning: multiple mentions of host %s in config file\n"),argv[optind]);
                    ctl->active = TRUE;
                    predeclared = TRUE;
+
+#ifdef HAVE_LIBPWMD
+                   if (ctl->pwmd_file) {
+                       /*
+                        * Cannot get an element path without a service.
+                        */
+                       if (ctl->server.protocol <= 1) {
+                           report(stderr, GT_("%s configuration invalid, pwmd_file requires a protocol specification\n"),
+                                  ctl->server.pollname);
+                           exit(PS_SYNTAX);
+                       }
+
+                       fprintf(stderr, "%s(%i): %s\n", __FILE__, __LINE__, __FUNCTION__);
+                       if (do_pwmd_connect(ctl->pwmd_socket, ctl->pwmd_file))
+                           continue;
+
+                       if (get_pwmd_details(ctl->server.pollname,
+                                   ctl->server.protocol, ctl))
+                           continue;
+                   }
+#endif
                }
 
            if (!predeclared)
@@ -1090,8 +1437,32 @@ static int load_params(int argc, char **argv, int optind)
                 * call later on.
                 */
                ctl = hostalloc((struct query *)NULL);
+
+#ifdef HAVE_LIBPWMD
+               if (cmd_opts.pwmd_file) {
+                   /*
+                    * Cannot get an element path without a service.
+                    */
+                   if (cmd_opts.server.protocol == 0 || cmd_opts.server.protocol == 1) {
+                       report(stderr, GT_("Option --pwmd-file needs a service (-p) parameter.\n"));
+                       exit(PS_SYNTAX);
+                   }
+
+                       fprintf(stderr, "%s(%i): %s\n", __FILE__, __LINE__, __FUNCTION__);
+                   if (do_pwmd_connect(cmd_opts.pwmd_socket, cmd_opts.pwmd_file))
+                       continue;
+
+                   if (get_pwmd_details(argv[optind], cmd_opts.server.protocol,
+                           ctl))
+                       continue;
+               }
+               else
+                   ctl->server.via =
+                       ctl->server.pollname = xstrdup(argv[optind]);
+#else
                ctl->server.via =
                    ctl->server.pollname = xstrdup(argv[optind]);
+#endif
                ctl->active = TRUE;
                ctl->server.lead_server = (struct hostdata *)NULL;
            }
@@ -1167,7 +1538,6 @@ static int load_params(int argc, char **argv, int optind)
     for (ctl = querylist; ctl; ctl = ctl->next)
        if (ctl->active && 
                (ctl->server.protocol==P_ETRN || ctl->server.protocol==P_ODMR
-                || ctl->server.authenticate == A_KERBEROS_V4
                 || ctl->server.authenticate == A_KERBEROS_V5))
        {
            fetchmailhost = host_fqdn(1);
@@ -1227,7 +1597,6 @@ static int load_params(int argc, char **argv, int optind)
            DEFAULT(ctl->mimedecode, FALSE);
            DEFAULT(ctl->idle, FALSE);
            DEFAULT(ctl->server.dns, TRUE);
-           DEFAULT(ctl->server.uidl, FALSE);
            DEFAULT(ctl->use_ssl, FALSE);
            DEFAULT(ctl->sslcertck, FALSE);
            DEFAULT(ctl->server.checkalias, FALSE);
@@ -1243,12 +1612,6 @@ static int load_params(int argc, char **argv, int optind)
            }
 #endif /* SSL_ENABLE */
 #undef DEFAULT
-#ifndef KERBEROS_V4
-           if (ctl->server.authenticate == A_KERBEROS_V4) {
-               report(stderr, GT_("KERBEROS v4 support is configured, but not compiled in.\n"));
-               exit(PS_SYNTAX);
-           }
-#endif
 #ifndef KERBEROS_V5
            if (ctl->server.authenticate == A_KERBEROS_V5) {
                report(stderr, GT_("KERBEROS v5 support is configured, but not compiled in.\n"));
@@ -1282,15 +1645,6 @@ static int load_params(int argc, char **argv, int optind)
            if (!ctl->localnames)       /* for local delivery via SMTP */
                save_str_pair(&ctl->localnames, user, NULL);
 
-#ifndef HAVE_RES_SEARCH
-           /* can't handle multidrop mailboxes unless we can do DNS lookups */
-           if (MULTIDROP(ctl) && ctl->server.dns)
-           {
-               ctl->server.dns = FALSE;
-               report(stderr, GT_("fetchmail: warning: no DNS available to check multidrop fetches from %s\n"), ctl->server.pollname);
-           }
-#endif /* !HAVE_RES_SEARCH */
-
            /*
             * can't handle multidrop mailboxes without "envelope"
             * option, this causes truckloads full of support complaints
@@ -1320,13 +1674,6 @@ static int load_params(int argc, char **argv, int optind)
                                   ctl->server.pollname);
                    exit(PS_SYNTAX);
                }
-               if (ctl->server.protocol == P_RPOP && port >= 1024)
-               {
-                   (void) fprintf(stderr,
-                                  GT_("fetchmail: %s configuration invalid, RPOP requires a privileged port\n"),
-                                  ctl->server.pollname);
-                   exit(PS_SYNTAX);
-               }
            }
            if (ctl->listener == LMTP_MODE)
            {
@@ -1375,7 +1722,7 @@ static int load_params(int argc, char **argv, int optind)
     return(implicitmode);
 }
 
-static RETSIGTYPE terminate_poll(int sig)
+static void terminate_poll(int sig)
 /* to be executed at the end of a poll cycle */
 {
 
@@ -1393,7 +1740,7 @@ static RETSIGTYPE terminate_poll(int sig)
 #endif /* POP3_ENABLE */
 }
 
-static RETSIGTYPE terminate_run(int sig)
+static void terminate_run(int sig)
 /* to be executed on normal or signal-induced termination */
 {
     struct query       *ctl;
@@ -1415,10 +1762,6 @@ static RETSIGTYPE terminate_run(int sig)
        if (ctl->password)
          memset(ctl->password, '\0', strlen(ctl->password));
 
-#if !defined(HAVE_ATEXIT)
-    fm_lock_release();
-#endif
-
     if (activecount == 0)
        exit(PS_NOMAIL);
     else
@@ -1436,9 +1779,6 @@ static const int autoprobe[] =
 #ifdef POP3_ENABLE
     P_POP3,
 #endif /* POP3_ENABLE */
-#ifdef POP2_ENABLE
-    P_POP2
-#endif /* POP2_ENABLE */
 };
 
 static int query_host(struct query *ctl)
@@ -1474,17 +1814,7 @@ static int query_host(struct query *ctl)
        }
        ctl->server.protocol = P_AUTO;
        break;
-    case P_POP2:
-#ifdef POP2_ENABLE
-       st = doPOP2(ctl);
-#else
-       report(stderr, GT_("POP2 support is not configured.\n"));
-       st = PS_PROTOCOL;
-#endif /* POP2_ENABLE */
-       break;
     case P_POP3:
-    case P_APOP:
-    case P_RPOP:
 #ifdef POP3_ENABLE
        do {
            st = doPOP3(ctl);
@@ -1541,6 +1871,14 @@ static int query_host(struct query *ctl)
     return(st);
 }
 
+static int print_id_of(struct uid_db_record *rec, void *unused)
+{
+    (void)unused;
+
+    printf("\t%s\n", rec->id);
+    return 0;
+}
+
 static void dump_params (struct runctl *runp,
                         struct query *querylist, flag implicit)
 /* display query parameters in English */
@@ -1553,10 +1891,8 @@ static void dump_params (struct runctl *runp,
        printf(GT_("Logfile is %s\n"), runp->logfile);
     if (strcmp(runp->idfile, IDFILE_NAME))
        printf(GT_("Idfile is %s\n"), runp->idfile);
-#if defined(HAVE_SYSLOG)
     if (runp->use_syslog)
        printf(GT_("Progress messages will be logged via syslog\n"));
-#endif
     if (runp->invisible)
        printf(GT_("Fetchmail will masquerade and will not generate Received\n"));
     if (runp->showdots)
@@ -1602,22 +1938,14 @@ static void dump_params (struct runctl *runp,
                printf(GT_("  Password will be prompted for.\n"));
            else if (outlevel >= O_VERBOSE)
            {
-               if (ctl->server.protocol == P_APOP)
-                   printf(GT_("  APOP secret = \"%s\".\n"),
-                          visbuf(ctl->password));
-               else if (ctl->server.protocol == P_RPOP)
-                   printf(GT_("  RPOP id = \"%s\".\n"),
-                          visbuf(ctl->password));
-               else
-                   printf(GT_("  Password = \"%s\".\n"),
-                                                       visbuf(ctl->password));
+               printf(GT_("  Password = \"%s\".\n"),
+                                   visbuf(ctl->password));
            }
        }
 
        if (ctl->server.protocol == P_POP3 
            && ctl->server.service && !strcmp(ctl->server.service, KPOP_PORT)
-           && (ctl->server.authenticate == A_KERBEROS_V4 ||
-               ctl->server.authenticate == A_KERBEROS_V5))
+           && (ctl->server.authenticate == A_KERBEROS_V5))
            printf(GT_("  Protocol is KPOP with Kerberos %s authentication"),
                   ctl->server.authenticate == A_KERBEROS_V5 ? "V" : "IV");
        else
@@ -1626,8 +1954,6 @@ static void dump_params (struct runctl *runp,
            printf(GT_(" (using service %s)"), ctl->server.service);
        else if (outlevel >= O_VERBOSE)
            printf(GT_(" (using default port)"));
-       if (ctl->server.uidl && MAILBOX_PROTOCOL(ctl))
-           printf(GT_(" (forcing UIDL use)"));
        putchar('.');
        putchar('\n');
        switch (ctl->server.authenticate)
@@ -1653,15 +1979,17 @@ static void dump_params (struct runctl *runp,
        case A_GSSAPI:
            printf(GT_("  GSSAPI authentication will be forced.\n"));
            break;
-       case A_KERBEROS_V4:
-           printf(GT_("  Kerberos V4 authentication will be forced.\n"));
-           break;
        case A_KERBEROS_V5:
            printf(GT_("  Kerberos V5 authentication will be forced.\n"));
            break;
        case A_SSH:
            printf(GT_("  End-to-end encryption assumed.\n"));
            break;
+       case A_APOP:
+           printf(GT_("  APOP authentication will be forced.\n"));
+           break;
+       default:
+           abort();
        }
        if (ctl->server.principal != (char *) NULL)
            printf(GT_("  Mail service principal is: %s\n"), ctl->server.principal);
@@ -1940,22 +2268,16 @@ static void dump_params (struct runctl *runp,
        else if (outlevel >= O_VERBOSE)
            printf(GT_("  No plugout command specified.\n"));
 
-       if (ctl->server.protocol > P_POP2 && MAILBOX_PROTOCOL(ctl))
+       if (MAILBOX_PROTOCOL(ctl))
        {
-           if (!ctl->oldsaved)
+           int count;
+
+           if (!(count = uid_db_n_records(&ctl->oldsaved)))
                printf(GT_("  No UIDs saved from this host.\n"));
            else
            {
-               struct idlist *idp;
-               int count = 0;
-
-               for (idp = ctl->oldsaved; idp; idp = idp->next)
-                   ++count;
-
                printf(GT_("  %d UIDs saved.\n"), count);
-               if (outlevel >= O_VERBOSE)
-                   for (idp = ctl->oldsaved; idp; idp = idp->next)
-                       printf("\t%s\n", idp->id);
+               traverse_uid_db(&ctl->oldsaved, print_id_of, NULL);
            }
        }
 
@@ -1974,6 +2296,19 @@ static void dump_params (struct runctl *runp,
                break;
        }
 
+       switch (ctl->server.retrieveerror) {
+           case RE_ABORT:
+               if (outlevel >= O_VERBOSE)
+                   printf(GT_("  Messages with fetch body errors will cause the session to abort.\n"));
+               break;
+           case RE_CONTINUE:
+               printf(GT_("  Messages with fetch body errors will be skipped, the session will continue.\n"));
+               break;
+           case RE_MARKSEEN:
+               printf(GT_("  Messages with fetch body errors will be marked seen, the session will continue.\n"));
+               break;
+       }
+
        if (ctl->properties)
            printf(GT_("  Pass-through properties \"%s\".\n"),
                   visbuf(ctl->properties));
index d759d391e6bbd7d4de651e67d2669b2a08e81922..4560c6834c92b1fe582574750731edb1d8852e0b 100644 (file)
@@ -5,56 +5,40 @@
  * For license terms, see the file COPYING in this directory.
  */
 
-/* We need this for HAVE_STDARG_H, etc */
 #include "config.h"
 
+#ifdef __NetBSD__
+#define _NETBSD_SOURCE 1
+#endif
+
 struct addrinfo;
 
 /* We need this for size_t */
 #include <sys/types.h>
 
-/* We need this for time_t */
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
-#endif
+#include <sys/time.h>
+#include <time.h>
 
-#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
-#endif
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
 #include <netdb.h>
 #include <stdio.h>
 
-/* Import Trio if needed */
-#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
-#  include "trio/trio.h"
-#endif
+#include "fm_strl.h"
 
-/* We need this for strstr */
-#if !defined(HAVE_STRSTR) && !defined(strstr)
-char *strstr(const char *, const char *);
-#endif
+#include "uid_db.h"
 
-#include "fm_strl.h"
+#ifdef HAVE_LIBPWMD
+#include <libpwmd.h>
+#endif
 
-/* constants designating the various supported protocols */
-#define                P_AUTO          1
-#define                P_POP2          2
-#define                P_POP3          3
-#define                P_APOP          4
-#define                P_RPOP          5
-#define                P_IMAP          6
-#define                P_ETRN          7
-#define                P_ODMR          8
+/** constants designating the various supported protocols -- ordered */
+enum protocols {
+    P_AUTO = 1 /**< probe IMAP and POP3 - deprecated */,
+    P_POP3     /**  POP3, including APOP and KPOP, RFC 1939 et al. */,
+    P_IMAP     /**  IMAP4, RFC 3501 */,
+    P_ETRN     /**  ETRN - SMTP Service Extension for Remote Message Queue Starting, "extended TURN", RFC 1985 */,
+    P_ODMR     /**  ODMR/ATRN - On-Demand Mail Relay SMTP with dynamic addresses/Authenticated TURN, RFC 2645 */
+};
 
 #define                SMTP_PORT       "smtp"
 #define                SMTP_PORT_NUM   25
@@ -72,24 +56,25 @@ char *strstr(const char *, const char *);
  */
 #define MAILBOX_PROTOCOL(ctl)  ((ctl)->server.protocol < P_ETRN)
 
-/* authentication types */
-#define                A_ANY           0       /* use the first method that works */
-#define                A_PASSWORD      1       /* password authentication */
-#define                A_NTLM          2       /* Microsoft NTLM protocol */
-#define                A_CRAM_MD5      3       /* CRAM-MD5 shrouding (RFC2195) */
-#define                A_OTP           4       /* One-time password (RFC1508) */
-#define                A_KERBEROS_V4   5       /* authenticate w/ Kerberos V4 */
-#define                A_KERBEROS_V5   6       /* authenticate w/ Kerberos V5 */
-#define        A_GSSAPI        7       /* authenticate with GSSAPI */
-#define                A_SSH           8       /* authentication at session level */
-#define                A_MSN           9       /* same as NTLM with keyword MSN */
-#define                A_EXTERNAL      10      /* external authentication (client cert) */
+/** authentication types */
+enum authenticators {
+       A_ANY = 0       /**< use the first method that works */,
+       A_PASSWORD      /** password authentication */,
+       A_NTLM          /** Microsoft NTLM protocol */,
+       A_CRAM_MD5      /** CRAM-MD5 shrouding (RFC2195) */,
+       A_OTP           /** One-time password (RFC1508) */,
+       A_APOP          /** POP3 APOP */,
+       A_KERBEROS_V5   /** authenticate w/ Kerberos V5 */,
+       A_GSSAPI        /** authenticate with GSSAPI */,
+       A_SSH           /** authentication at session level */,
+       A_MSN           /** same as NTLM with keyword MSN */,
+       A_EXTERNAL      /** external authentication (client cert) */
+};
 
 /* some protocols or authentication types (KERBEROS, GSSAPI, SSH) don't
  * require a password */
 #define NO_PASSWORD(ctl) \
     ((ctl)->server.authenticate == A_OTP \
-     || (ctl)->server.authenticate == A_KERBEROS_V4 \
      || (ctl)->server.authenticate == A_KERBEROS_V5 \
      || (ctl)->server.authenticate == A_GSSAPI \
      || (ctl)->server.authenticate == A_SSH \
@@ -180,6 +165,9 @@ struct runctl
     char       *pidfile;       /** where to record the PID of daemon mode processes */
     const char *postmaster;
     char       *properties;
+#ifdef HAVE_LIBPWMD
+    int                pinentry_timeout;
+#endif
     int                poll_interval;  /** poll interval in seconds (daemon mode, 0 == off) */
     flag       bouncemail;
     flag       spambounce;
@@ -258,6 +246,9 @@ struct method               /* describe methods for protocol state machine */
 
 enum badheader { BHREJECT = 0, BHACCEPT };
 
+/* Message retrieval error mode */
+enum retrieveerror { RE_ABORT = 0, RE_CONTINUE, RE_MARKSEEN };
+
 struct hostdata                /* shared among all user connections to given server */
 {
     /* rc file data */
@@ -266,7 +257,7 @@ struct hostdata             /* shared among all user connections to given server */
     struct idlist *akalist;            /* server name first, then akas */
     struct idlist *localdomains;       /* list of pass-through domains */
     int protocol;                      /* protocol type */
-    const char *service;               /* service name */
+    char *service;                     /* service name */
     int interval;                      /* # cycles to skip between polls */
     int authenticate;                  /* authentication mode to try */
     int timeout;                       /* inactivity timout in seconds */
@@ -275,7 +266,6 @@ struct hostdata             /* shared among all user connections to given server */
     char *qvirtual;                    /* prefix removed from local user id */
     flag skip;                         /* suppress poll in implicit mode? */
     flag dns;                          /* do DNS lookup on multidrop? */
-    flag uidl;                         /* use RFC1725 UIDLs? */
 #ifdef SDPS_ENABLE
     flag sdps;                         /* use Demon Internet SDPS *ENV */
 #endif /* SDPS_ENABLE */
@@ -284,6 +274,7 @@ struct hostdata             /* shared among all user connections to given server */
     char *principal;                   /* Kerberos principal for mail service */
     char *esmtp_name, *esmtp_password; /* ESMTP AUTH information */
     enum badheader badheader;          /* bad-header {pass|reject} */
+    enum retrieveerror retrieveerror;  /* retrieve-error (abort|continue|markseen) */
 
 #if defined(linux) || defined(__FreeBSD__)
 #define CAN_MONITOR
@@ -329,6 +320,11 @@ struct query
     char *password;            /* remote password to use */
     struct idlist *mailboxes;  /* list of mailboxes to check */
 
+#ifdef HAVE_LIBPWMD
+    char *pwmd_socket;         /* socket to connect to */
+    char *pwmd_file;           /* file to open on the server */
+#endif
+
     /* per-forwarding-target data */
     struct idlist *smtphunt;   /* list of SMTP hosts to try forwarding to */
     struct idlist *domainlist; /* domainlist to fetch from */
@@ -389,8 +385,7 @@ struct query
     int smtp_socket;           /* socket descriptor for SMTP connection */
     unsigned int uid;          /* UID of user to deliver to */
     struct idlist *skipped;    /* messages skipped on the mail server */
-    struct idlist *oldsaved, *newsaved;
-    struct idlist **oldsavedend;
+    struct uid_db oldsaved, newsaved;
     char lastdigest[DIGESTLEN];        /* last MD5 hash seen on this connection */
     char *folder;              /* folder currently being polled */
 
@@ -482,12 +477,11 @@ extern const char *iana_charset;  /* IANA assigned charset name */
 /* prototypes for globally callable functions */
 
 /* from /usr/include/sys/cdefs.h */
-#if !defined __GNUC__ || __GNUC__ < 2
+#if !defined __GNUC__
 # define __attribute__(xyz)    /* Ignore. */
 #endif
 
 /* error.c: Error reporting */
-#if defined(HAVE_STDARG_H)
 void report_init(int foreground);
  /** Flush partial message, suppress program name tag for next report printout. */
 void report_flush(FILE *fp);
@@ -503,12 +497,6 @@ void report_complete (FILE *fp, const char *format, ...)
 void report_at_line (FILE *fp, int, const char *, unsigned int, const char *, ...)
     __attribute__ ((format (printf, 5, 6)))
     ;
-#else
-void report ();
-void report_build ();
-void report_complete ();
-void report_at_line ();
-#endif
 
 /* driver.c -- main driver loop */
 void set_timeout(int);
@@ -535,7 +523,6 @@ int readheaders(int sock,
                       int num,
                       flag *suppress_readbody);
 int readbody(int sock, struct query *ctl, flag forward, int len);
-#if defined(HAVE_STDARG_H)
 void gen_send(int sock, const char *, ... )
     __attribute__ ((format (printf, 2, 3)))
     ;
@@ -545,13 +532,6 @@ int gen_recv_split(int sock, char *buf, int size, struct RecvSplit *rs);
 int gen_transact(int sock, const char *, ... )
     __attribute__ ((format (printf, 2, 3)))
     ;
-#else
-void gen_send();
-int gen_recv();
-void gen_recv_split_init();
-int gen_recv_split();
-int gen_transact();
-#endif
 extern struct msgblk msgblk;
 
 /* use these to track what was happening when the nonresponse timer fired */
@@ -592,14 +572,11 @@ int open_sink(struct query*, struct msgblk *, int*, int*);
 void release_sink(struct query *);
 int close_sink(struct query *, struct msgblk *, flag);
 int open_warning_by_mail(struct query *);
-#if defined(HAVE_STDARG_H)
 void stuff_warning(const char *, struct query *, const char *, ... )
     __attribute__ ((format (printf, 3, 4)))
     ;
-#else
-void stuff_warning();
-#endif
 void close_warning_by_mail(struct query *, struct msgblk *);
+void abort_message_sink(struct query *ctl);
 
 /* rfc822.c: RFC822 header parsing */
 char *reply_hack(char *, const char *, size_t *);
@@ -657,7 +634,6 @@ int interface_approve(struct hostdata *, flag domonitor);
 #include "xmalloc.h"
 
 /* protocol driver and methods */
-int doPOP2 (struct query *); 
 int doPOP3 (struct query *);
 int doIMAP (struct query *);
 int doETRN (struct query *);
@@ -665,7 +641,6 @@ int doODMR (struct query *);
 
 /* authentication functions */
 int do_cram_md5(int sock, const char *command, struct query *ctl, const char *strip);
-int do_rfc1731(int sock, const char *command, const char *truename);
 int check_gss_creds(const char *service, const char *hostname);
 int do_gssauth(int sock, const char *command, const char *service, const char *hostname, const char *username);
 int do_otp(int sock, const char *command, struct query *ctl);
@@ -676,14 +651,14 @@ int do_otp(int sock, const char *command, struct query *ctl);
 extern char currentwd[1024], rcfiledir[1024];
 
 struct query *hostalloc(struct query *); 
-int parsecmdline (int, char **, struct runctl *, struct query *);
+int parsecmdline (int, char **, struct runctl *, struct query *, flag *);
 char *prependdir (const char *, const char *);
 char *MD5Digest (unsigned const char *);
 void hmac_md5 (const unsigned char *, size_t, const unsigned char *, size_t, unsigned char *, size_t);
 int POP3_auth_rpa(char *, char *, int socket);
-typedef RETSIGTYPE (*SIGHANDLERTYPE) (int);
+typedef void (*SIGHANDLERTYPE) (int);
 void deal_with_sigchld(void);
-RETSIGTYPE null_signal_handler(int sig);
+void null_signal_handler(int sig);
 SIGHANDLERTYPE set_signal_handler(int sig, SIGHANDLERTYPE handler);
 int daemonize(const char *);
 char *fm_getpassword(char *);
@@ -711,34 +686,9 @@ char *rfc2047e(const char*, const char *);
 void yyerror(const char *);
 int yylex(void);
 
-#ifdef __EMX__
-void itimerthread(void*);
-/* Have to include these first to avoid errors from redefining getcwd
-   and chdir.  They're re-include protected in EMX, so it's okay, I
-   guess.  */
-#include <stdlib.h>
-#include <unistd.h>
-/* Redefine getcwd and chdir to get drive-letter support so we can
-   find all of our lock files and stuff. */
-#define getcwd _getcwd2
-#define chdir _chdir2
-#endif /* _EMX_ */
-
-#ifdef HAVE_STRERROR
-#  if !defined(strerror) && !defined(HAVE_DECL_STRERROR)       /* On some systems, strerror is a macro */
-char *strerror (int);
-#  endif
-#endif /* HAVE_STRERROR */
-
 #define STRING_DISABLED        (char *)-1
 #define STRING_DUMMY   ""
 
-#ifdef NeXT
-#ifndef S_IXGRP
-#define S_IXGRP 0000010
-#endif
-#endif
-
 #ifndef HAVE_STPCPY
 char *stpcpy(char *, const char*);
 #endif
index 56026d0bea96acb40d896a9c351a9565036c215b..babc57ab7c4a5899865c27b5dc2c464ccee94e99 100644 (file)
@@ -10,7 +10,7 @@
 .\" Load www macros to process .URL requests, this requires groff:
 .mso www.tmac
 .\"
-.TH fetchmail 1 "fetchmail 6.3.22" "fetchmail" "fetchmail reference manual"
+.TH fetchmail 1 "fetchmail 7.0.0-alpha3" "fetchmail" "fetchmail reference manual"
 
 .SH NAME
 fetchmail \- fetch mail from a POP, IMAP, ETRN, or ODMR-capable server
@@ -29,10 +29,9 @@ normal mail user agents such as \fBmutt\fP(1), \fBelm\fP(1) or
 to repeatedly poll one or more systems at a specified interval.
 .PP
 The \fBfetchmail\fP program can gather mail from servers supporting any
-of the common mail-retrieval protocols: POP2 (legacy, to be removed from
-future release), POP3, IMAP2bis, IMAP4, and IMAP4rev1.  It can also use
-the ESMTP ETRN extension and ODMR.  (The RFCs describing all these
-protocols are listed at the end of this manual page.)
+of the common mail-retrieval protocols: POP3, IMAP2bis, IMAP4, and IMAP4rev1.
+It can also use the ESMTP ETRN extension and ODMR.  (The RFCs describing all
+these protocols are listed at the end of this manual page.)
 .PP
 While \fBfetchmail\fP is primarily intended to be used over on-demand
 TCP/IP links (such as SLIP or PPP connections), it may also be useful as
@@ -180,7 +179,7 @@ doesn't play well with queries to multiple sites, and doesn't work
 with ETRN or ODMR.  It will return a false positive if you leave read but
 undeleted mail in your server mailbox and your fetch protocol can't
 tell kept messages from new ones.  This means it will work with IMAP,
-not work with POP2, and may occasionally flake out under POP3.
+and may occasionally flake out under POP3.
 .TP
 .B \-s | \-\-silent
 Silent mode.  Suppresses all progress/status messages that are
@@ -214,11 +213,9 @@ mode in the next fetchmail release.
 Retrieve both old (seen) and new messages from the mailserver.  The
 default is to fetch only messages the server has not marked seen.
 Under POP3, this option also forces the use of RETR rather than TOP.
-Note that POP2 retrieval behaves as though \-\-all is always on (see
-RETRIEVAL FAILURE MODES below) and this option does not work with ETRN
-or ODMR.  While the \-a and \-\-all command-line and fetchall rcfile
-options have been supported for a long time, the \-\-fetchall
-command-line option was added in v6.3.3.
+While the \-a and \-\-all command-line and fetchall rcfile options have been
+supported for a long time, the \-\-fetchall command-line option was added in
+v6.3.3.
 .TP
 .B \-k | \-\-keep
 (Keyword: keep)
@@ -227,8 +224,7 @@ Keep retrieved messages on the remote mailserver.  Normally, messages
 are deleted from the folder on the mailserver after they have been retrieved.
 Specifying the \fBkeep\fP option causes retrieved messages to remain in
 your folder on the mailserver.  This option does not work with ETRN or
-ODMR. If used with POP3, it is recommended to also specify the \-\-uidl
-option or uidl keyword.
+ODMR.
 .TP
 .B \-K | \-\-nokeep
 (Keyword: nokeep)
@@ -248,8 +244,7 @@ you check your mail with other clients than fetchmail, and cause
 fetchmail to delete a message it had never fetched before.  It can also
 cause mail loss if the mail server marks the message seen after
 retrieval (IMAP2 servers). You should probably not use this option in your
-configuration file. If you use it with POP3, you must use the 'uidl'
-option. What you probably want is the default setting: if you don't
+configuration file. What you probably want is the default setting: if you don't
 specify '\-k', then fetchmail will automatically delete messages after
 successful delivery.
 .TP
@@ -268,19 +263,12 @@ mailserver.  If no protocol is specified, the default is AUTO.
 \fBproto\fP may be one of the following:
 .RS
 .IP AUTO
-Tries IMAP, POP3, and POP2 (skipping any of these for which support
+Tries IMAP and POP3 (skipping any of these for which support
 has not been compiled in).
-.IP POP2
-Post Office Protocol 2 (legacy, to be removed from future release)
 .IP POP3
 Post Office Protocol 3
-.IP APOP
-Use POP3 with old-fashioned MD5-challenge authentication.
-Considered not resistant to man-in-the-middle attacks.
-.IP RPOP
-Use POP3 with RPOP authentication.
 .IP KPOP
-Use POP3 with Kerberos V4 authentication on port 1109.
+Use POP3 with Kerberos V5 authentication on port 1109.
 .IP SDPS
 Use POP3 with Demon Internet's SDPS extensions.
 .IP IMAP
@@ -302,19 +290,6 @@ ODMR mode requires an ODMR-capable server and works similarly to
 ETRN, except that it does not require the client machine to have
 a static DNS.
 .TP
-.B \-U | \-\-uidl
-(Keyword: uidl)
-.br
-Force UIDL use (effective only with POP3).  Force client-side tracking
-of 'newness' of messages (UIDL stands for "unique ID listing" and is
-described in RFC1939).  Use with 'keep' to use a mailbox as a baby
-news drop for a group of users. The fact that seen messages are skipped
-is logged, unless error logging is done through syslog while running in
-daemon mode.  Note that fetchmail may automatically enable this option
-depending on upstream server capabilities.  Note also that this option
-may be removed and forced enabled in a future fetchmail version. See
-also: \-\-idfile.
-.TP
 .B \-\-idle (since 6.3.3)
 (Keyword: idle, since before 6.0.0)
 .br
@@ -742,6 +717,17 @@ Specify how fetchmail is supposed to treat messages with bad headers,
 i. e. headers with bad syntax. Traditionally, fetchmail has rejected such
 messages, but some distributors modified fetchmail to accept them. You can now
 configure fetchmail's behaviour per server.
+.TP
+.B \-\-retrieve\-error {abort|continue|markseen}
+(Keyword: retrieve\-error; since v7.0)
+.br
+Specify how fetchmail is supposed to treat messages which fail to be
+retrieved due to server errors, i. e. fetching the message body fails with
+a server error. Traditionally, fetchmail has aborted the session leaving
+both the message with the error and any subsequent messages on the server.
+Both the continue and markseen options will allow the session to continue
+enabling subsequent messages on the server to be retrieved.  You can now
+configure fetchmail's behaviour per server.
 
 .SS Resource Limit Control Options
 .TP
@@ -829,7 +815,7 @@ This option works with POP3 only.
 (Keyword: expunge)
 .br
 Arrange for deletions to be made final after a given number of
-messages.  Under POP2 or POP3, fetchmail cannot make deletions final
+messages.  Under POP3, fetchmail cannot make deletions final
 without sending QUIT and ending the session -- with this option on,
 fetchmail will break a long mail retrieval session into multiple
 sub-sessions, sending QUIT after each sub-session. This is a good
@@ -914,12 +900,11 @@ Note that this option may be removed from a future fetchmail version.
 .br
 This option permits you to specify an authentication type (see USER
 AUTHENTICATION below for details).  The possible values are \fBany\fP,
-\&\fBpassword\fP, \fBkerberos_v5\fP, \fBkerberos\fP (or, for
-excruciating exactness, \fBkerberos_v4\fP), \fBgssapi\fP,
+\&\fBpassword\fP, \fBkerberos_v5\fP, \fBgssapi\fP,
 \fBcram\-md5\fP, \fBotp\fP, \fBntlm\fP, \fBmsn\fP (only for POP3),
 \fBexternal\fP (only IMAP) and \fBssh\fP.
 When \fBany\fP (the default) is specified, fetchmail tries
-first methods that don't require a password (EXTERNAL, GSSAPI, KERBEROS\ IV,
+first methods that don't require a password (EXTERNAL, GSSAPI,
 KERBEROS\ 5); then it looks for methods that mask your password
 (CRAM-MD5, NTLM, X\-OTP - note that MSN is only supported for POP3, but not
 autoprobed); and only if the server doesn't
@@ -931,11 +916,10 @@ Any value other than \fBpassword\fP, \fBcram\-md5\fP, \fBntlm\fP,
 \&\fBmsn\fP or \fBotp\fP suppresses fetchmail's normal inquiry for a
 password.  Specify \fBssh\fP when you are using an end-to-end secure
 connection such as an ssh tunnel; specify \fBexternal\fP when you use
-TLS with client authentication and specify \fBgssapi\fP or
-\&\fBkerberos_v4\fP if you are using a protocol variant that employs
-GSSAPI or K4.  Choosing KPOP protocol automatically selects Kerberos
-authentication.  This option does not work with ETRN.  GSSAPI service names are
-in line with RFC-2743 and IANA registrations, see
+TLS with client authentication and specify \fBgssapi\fP if you are using a
+protocol variant that employs GSSAPI.  Choosing KPOP protocol automatically
+selects Kerberos authentication.  This option does not work with ETRN.
+GSSAPI service names are in line with RFC-2743 and IANA registrations, see
 .URL http://www.iana.org/assignments/gssapi-service-names/ "Generic Security Service Application Program Interface (GSSAPI)/Kerberos/Simple Authentication and Security Layer (SASL) Service Names" . 
 .SS Miscellaneous Options
 .TP
@@ -1107,17 +1091,6 @@ a mailbox on the server.  Contact your server administrator if you don't know
 the correct user-id and password for your mailbox account.
 .SH POP3 VARIANTS
 .PP
-Early versions of POP3 (RFC1081, RFC1225) supported a crude form of
-independent authentication using the \fI.rhosts\fP file on the
-mailserver side.  Under this RPOP variant, a fixed per-user ID
-equivalent to a password was sent in clear over a link to a reserved
-port, with the command RPOP rather than PASS to alert the server that it
-should do special checking.  RPOP is supported by \fBfetchmail\fP
-(you can specify 'protocol RPOP' to have the program send 'RPOP'
-rather than 'PASS') but its use is strongly discouraged, and support
-will be removed from a future fetchmail version.  This
-facility was vulnerable to spoofing and was withdrawn in RFC1460.
-.PP
 RFC1460 introduced APOP authentication.  In this variant of POP3,
 you register an APOP password on your server host (on some servers, the
 program to do this is called \fBpopauth\fP(8)).  You put the same
@@ -1127,7 +1100,8 @@ time to the server, which can verify it by checking its authorization
 database.
 
 \fBNote that APOP is no longer considered resistant against
-man-in-the-middle attacks.\fP
+man-in-the-middle attacks, and should not be used without a verified
+SSL/TLS connection.\fP
 .SS RETR or TOP
 \fBfetchmail\fP makes some efforts to make the server believe messages
 had not been retrieved, by using the TOP command with a large number of
@@ -1140,14 +1114,10 @@ retrieves the full message with header and body, sets the "seen" flag
 that.
 .PP
 \fBfetchmail\fP will always use the RETR command if "fetchall" is set.
-\fBfetchmail\fP will also use the RETR command if "keep" is set and
-"uidl" is unset.  Finally, \fBfetchmail\fP will use the RETR command on
+As a workaround, \fBfetchmail\fP will use the RETR command on
 Maillennium POP3/PROXY servers (used by Comcast) to avoid a deliberate
 TOP misinterpretation in this server that causes message corruption.
 .PP
-In all other cases, \fBfetchmail\fP will use the TOP command. This
-implies that in "keep" setups, "uidl" must be set if "TOP" is desired.
-.PP
 \fBNote\fP that this description is true for the current version of
 fetchmail, but the behavior may change in future versions. In
 particular, fetchmail may prefer the RETR command because the TOP
@@ -1156,7 +1126,7 @@ command causes much grief on some servers and is only optional.
 .PP
 If your \fBfetchmail\fP was built with Kerberos support and you specify
 Kerberos authentication (either with \-\-auth or the \fI.fetchmailrc\fP
-option \fBauthenticate kerberos_v4\fP) it will try to get a Kerberos
+option \fBauthenticate kerberos_v5\fP) it will try to get a Kerberos
 ticket from the mailserver at the start of each query.  Note: if
 either the pollname or via name is 'hesiod', fetchmail will try to use
 Hesiod to look up the mailserver.
@@ -1380,7 +1350,7 @@ or Gerrit Pape's
 Note that this also causes the logfile option to be ignored (though
 perhaps it shouldn't).
 .PP
-Note that while running in daemon mode polling a POP2 or IMAP2bis server,
+Note that while running in daemon mode polling a IMAP2bis server,
 transient errors (such as DNS failures or sendmail delivery refusals)
 may force the fetchall option on for the duration of the next polling
 cycle.  This is a robustness feature.  It means that if a message is
@@ -1483,11 +1453,6 @@ read directly on the server (or fetched with a previous \fIfetchmail
 server are being fetched (and deleted) even when you don't specify
 \-\-all.  There are several reasons this can happen.
 .PP
-One could be that you're using POP2.  The POP2 protocol includes no
-representation of 'new' or 'old' state in messages, so \fBfetchmail\fP
-must treat all messages as new all the time.  But POP2 is obsolete, so
-this is unlikely.
-.PP
 A potential POP3 problem might be servers that insert messages
 in the middle of mailboxes (some VMS implementations of mail are
 rumored to do this).  The \fBfetchmail\fP code assumes that new
@@ -1730,7 +1695,7 @@ Specify DNS name of mailserver, overriding poll name
 T}
 proto[col]     \-p     \&      T{
 Specify protocol (case insensitive):
-POP2, POP3, IMAP, APOP, KPOP
+POP3, IMAP, KPOP
 T}
 local[domains] \&      m       T{
 Specify domain(s) to be regarded as local
@@ -1784,12 +1749,6 @@ T}
 no checkalias  \&      m       T{
 Do comparison by name for multidrop (default)
 T}
-uidl           \-U     \&      T{
-Force POP3 to use client-side UIDLs (recommended)
-T}
-no uidl        \&      \&      T{
-Turn off POP3 use of client-side UIDLs (default)
-T}
 interval       \&      \&      T{
 Only check this site every N poll cycles; N is a numeric argument.
 T}
@@ -1808,6 +1767,10 @@ T}
 bad-header     \&      \&      T{
 How to treat messages with a bad header. Can be reject (default) or accept.
 T}
+retrieve-error \&      \&      T{
+How to behave when messages that cannot be retrieved due to a server error
+are encountered. Can be abort (default), continue or markseen.
+T}
 .TE
 
 Here are the legal user descriptions and options:
@@ -1881,7 +1844,7 @@ postconnect       \&      \&      T{
 Command to be executed after each connection
 T}
 keep           \-k     \&      T{
-Don't delete seen messages from server (for POP3, uidl is recommended)
+Don't delete seen messages from server
 T}
 flush          \-F     \&      T{
 Flush all seen messages before querying (DANGEROUS)
@@ -2200,27 +2163,26 @@ Legal protocol identifiers for use with the 'protocol' keyword are:
 .sp
 .nf
     auto (or AUTO) (legacy, to be removed from future release)
-    pop2 (or POP2) (legacy, to be removed from future release)
+
     pop3 (or POP3)
-    sdps (or SDPS)
+      sdps (or SDPS) (a POP3 variant specific to Demon)
+      kpop (or KPOP) (a Kerberos-based variant)
+
     imap (or IMAP)
-    apop (or APOP)
-    kpop (or KPOP)
 .fi
 .sp
 .PP
-Legal authentication types are 'any', 'password', 'kerberos',
-\&'kerberos_v4', 'kerberos_v5' and 'gssapi', 'cram\-md5', 'otp', 'msn'
-(only for POP3), 'ntlm', 'ssh', 'external' (only IMAP).
+Legal authentication types are 'any', 'password', 'apop' (only for
+POP3), \&'kerberos_v5' and 'gssapi', 'cram\-md5', 'otp', 'msn'
+(only for POP3), 'ntlm', 'ssh', 'external' (only for IMAP).
 The 'password' type specifies
-authentication by normal transmission of a password (the password may be
-plain text or subject to protocol-specific encryption as in CRAM-MD5);
-\&'kerberos' tells \fBfetchmail\fP to try to get a Kerberos ticket at the
+authentication by normal transmission of a password;
+\&'kerberos_v5' tells \fBfetchmail\fP to try to get a Kerberos ticket at the
 start of each query instead, and send an arbitrary string as the
 password; and 'gssapi' tells fetchmail to use GSSAPI authentication.
 See the description of the 'auth' keyword for more.
 .PP
-Specifying 'kpop' sets POP3 protocol over port 1109 with Kerberos V4
+Specifying 'kpop' sets POP3 protocol over port 1109 with Kerberos V5
 authentication.  These defaults may be overridden by later options.
 .PP
 There are some global option statements: 'set logfile'
@@ -2375,7 +2337,7 @@ Multiple servers may be listed:
 .IP
 .nf
 poll pop.provider.net proto pop3 user "jsmith" pass "secret1"
-poll other.provider.net proto pop2 user "John.Smith" pass "My^Hat"
+poll other.provider.net proto imap user "John.Smith" pass "My^Hat"
 .fi
 
 .PP
@@ -2385,7 +2347,7 @@ Here's the same version with more whitespace and some noise words:
 .nf
 poll pop.provider.net proto pop3
      user "jsmith", with password secret1, is "jsmith" here;
-poll other.provider.net proto pop2:
+poll other.provider.net proto imap:
      user "John.Smith", with password "My^Hat", is "John.Smith" here;
 .fi
 
@@ -2895,7 +2857,7 @@ buggy terminal ioctl code in the kernel.
 The \-f\~\- option (reading a configuration from stdin) is incompatible
 with the plugin option.
 .PP
-The 'principal' option only handles Kerberos IV, not V.
+The 'principal' option does not work for Kerberos V.
 .PP
 Interactively entered passwords are truncated after 63 characters. If
 you really need to use a longer password, you will have to use a
@@ -2968,8 +2930,6 @@ RFC 2554.
 mail:
 RFC 822, RFC 2822, RFC 1123, RFC 1892, RFC 1894.
 .TP 5
-POP2:
-RFC 937
 .TP 5
 POP3:
 RFC 1081, RFC 1225, RFC 1460, RFC 1725, RFC 1734, RFC 1939, RFC 1957,
@@ -2978,9 +2938,6 @@ RFC 2195, RFC 2449.
 APOP:
 RFC 1939.
 .TP 5
-RPOP:
-RFC 1081, RFC 1225.
-.TP 5
 IMAP2/IMAP2BIS:
 RFC 1176, RFC 1732.
 .TP 5
index 2dc02d875995b088dd49e2e84a89ae434e085074..b4b0a1ae7facd4431a39b776e39cefb071b9ab5e 100755 (executable)
@@ -5,7 +5,7 @@
 # Matthias Andree <matthias.andree@gmx.de>
 # Requires Python with Tkinter, and the following OS-dependent services:
 #      posix, posixpath, socket
-version = "1.57"
+version = "1.58"
 
 from Tkinter import *
 from Dialog import *
@@ -88,7 +88,6 @@ class Server:
        self.interval = 0               # Skip interval
        self.protocol = 'auto'          # Default to auto protocol
        self.service = None             # Service name to use
-       self.uidl = FALSE               # Don't use RFC1725 UIDLs by default
        self.auth = 'any'               # Default to password authentication
        self.timeout = 300              # 5-minute timeout
        self.envelope = 'Received'      # Envelope-address header
@@ -106,6 +105,7 @@ class Server:
        self.esmtppassword = None       # ESMTP 2554 password
        self.tracepolls = FALSE         # Add trace-poll info to headers
        self.badheader = FALSE          # Pass messages with bad headers on?
+       self.retrieveerror = 'abort'    # Policy when message retrieval errors encountered
        self.users = []                 # List of user entries for site
        Server.typemap = (
            ('pollname',  'String'),
@@ -114,7 +114,6 @@ class Server:
            ('interval',  'Int'),
            ('protocol',  'String'),
            ('service',   'String'),
-           ('uidl',      'Boolean'),
            ('auth',      'String'),
            ('timeout',   'Int'),
            ('envelope',  'String'),
@@ -131,7 +130,8 @@ class Server:
            ('esmtppassword', 'String'),
            ('principal', 'String'),
            ('tracepolls','Boolean'),
-           ('badheader', 'Boolean'))
+           ('badheader', 'Boolean'),
+           ('retrieveerror', 'String'))
 
     def dump(self, folded):
        res = ""
@@ -157,12 +157,9 @@ class Server:
            res = res + (" qvirtual " + str(self.qvirtual) + "\n");
        if self.auth != ServerDefaults.auth:
            res = res + " auth " + self.auth
-       if self.dns != ServerDefaults.dns or self.uidl != ServerDefaults.uidl:
-           res = res + " and options"
        if self.dns != ServerDefaults.dns:
+           res = res + " and options"
            res = res + flag2str(self.dns, 'dns')
-       if self.uidl != ServerDefaults.uidl:
-           res = res + flag2str(self.uidl, 'uidl')
        if folded:      res = res + "\n    "
        else:        res = res + " "
 
@@ -200,9 +197,17 @@ class Server:
            res = res + " esmtppassword " + `self.esmtppassword`
        if self.interface or self.monitor or self.principal or self.plugin or self.plugout:
            if folded:
-               res = res + "\n"
+               res = res + "\n    "
+
        if self.badheader:
                res = res + "bad-header accept "
+       if self.retrieveerror == 'continue':
+               res = res + "retrieve-error continue "
+       if self.retrieveerror == 'markseen':
+               res = res + "retrieve-error markseen "
+       if self.badheader or self.retrieveerror != ServerDefaults.retrieveerror:
+           if folded:
+               res = res + "\n"
 
        if res[-1] == " ": res = res[0:-1]
 
@@ -432,8 +437,7 @@ class User:
 #
 
 # IANA port assignments and bogus 1109 entry
-ianaservices = {"pop2":109,
-               "pop3":110,
+ianaservices = {"pop3":110,
                "1109":1109,
                "imap":143,
                "smtp":25,
@@ -441,16 +445,14 @@ ianaservices = {"pop2":109,
 
 # fetchmail protocol to IANA service name
 defaultports = {"auto":None,
-               "POP2":"pop2",
                "POP3":"pop3",
-               "APOP":"pop3",
                "KPOP":"1109",
                "IMAP":"imap",
                "ETRN":"smtp",
                "ODMR":"odmr"}
 
 authlist = ("any", "password", "gssapi", "kerberos", "ssh", "otp",
-           "msn", "ntlm")
+           "msn", "ntlm", "apop", "cram-md5")
 
 listboxhelp = {
     'title' : 'List Selection Help',
@@ -960,6 +962,13 @@ the normal operation of fetchmail when it is run with no arguments.
 If it is off, fetchmail will only query this host when it is given as
 a command-line argument.
 
+The `Retrieve Error Policy' specifies how server errors during
+message retrieval are handled.  The default behaviour is to abort the
+current session.  Both the continue and markseen options will skip
+the message with the error, but continue the session allowing for 
+downloading of subsequent messages.  Additionally, the markseen
+option will mark the skipped message as seen.
 The `True name of server' box should specify the actual DNS name
 to query. By default this is the same as the poll name.
 
@@ -1115,7 +1124,6 @@ class ServerEdit(Frame, MyWidget):
        # a custom port number you should be in expert mode and playing
        # close enough attention to notice this...
        self.service.set(defaultports[proto])
-       if not proto in ("POP3", "APOP", "KPOP"): self.uidl.state = DISABLED
 
     def user_edit(self, username, mode):
        self.subwidgets[username] = UserEdit(username, self).edit(mode, Toplevel())
@@ -1137,6 +1145,9 @@ class ServerEdit(Frame, MyWidget):
            Checkbutton(ctlwin, text='Poll ' + host + ' normally?', variable=self.active).pack(side=TOP)
            Checkbutton(ctlwin, text='Pass messages with bad headers?',
                    variable=self.badheader).pack(side=TOP)
+            retrieveerrorlist = ['abort', 'continue', 'markseen']
+            Label(ctlwin, text="Retrieve Error Policy").pack(side=TOP)
+            ButtonBar(ctlwin, '', self.retrieveerror, retrieveerrorlist, 1, None)
            LabeledEntry(ctlwin, 'True name of ' + host + ':',
                      self.via, leftwidth).pack(side=TOP, fill=X)
            LabeledEntry(ctlwin, 'Cycles to skip between polls:',
@@ -1149,10 +1160,8 @@ class ServerEdit(Frame, MyWidget):
 
        # Compute the available protocols from the compile-time options
        protolist = ['auto']
-       if 'pop2' in feature_options:
-           protolist.append("POP2")
        if 'pop3' in feature_options:
-           protolist = protolist + ["POP3", "APOP", "KPOP"]
+           protolist = protolist + ["POP3", "KPOP"]
        if 'sdps' in feature_options:
            protolist.append("SDPS")
        if 'imap' in feature_options:
@@ -1171,9 +1180,6 @@ class ServerEdit(Frame, MyWidget):
            LabeledEntry(protwin, 'On server TCP/IP service:',
                      self.service, leftwidth).pack(side=TOP, fill=X)
            self.defaultPort()
-           Checkbutton(protwin,
-               text="POP3: track `seen' with client-side UIDLs?",
-               variable=self.uidl).pack(side=TOP)
        Button(protwin, text='Probe for supported protocols', fg='blue',
               command=self.autoprobe).pack(side=LEFT)
        Button(protwin, text='Help', fg='blue',
@@ -1247,7 +1253,7 @@ class ServerEdit(Frame, MyWidget):
        else:
            realhost = self.server.pollname
        greetline = None
-       for protocol in ("IMAP","POP3","POP2"):
+       for protocol in ("IMAP","POP3"):
            service = defaultports[protocol]
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            try:
@@ -1272,18 +1278,6 @@ out before getting a response.
            warnings = ''
            # OK, now try to recognize potential problems
 
-           if protocol == "POP2":
-               warnings = warnings + """
-It appears you have somehow found a mailserver running only POP2.
-Congratulations.  Have you considered a career in archaeology?
-
-Unfortunately, stock fetchmail binaries don't include POP2 support anymore.
-Unless the first line of your fetchmail -V output includes the string "POP2",
-you'll have to build it from sources yourself with the configure
-switch --enable-POP2.
-
-"""
-
 ### POP3 servers start here
 
            if string.find(greetline, "1.003") > 0 or string.find(greetline, "1.004") > 0:
@@ -1498,7 +1492,7 @@ recommend you upgrade to a non-broken IMAP server.
            if string.find(greetline, "Domino IMAP4") > 0:
                warnings = warnings + """
 Your IMAP server appears to be Lotus Domino.  This server, at least up
-to version 4.6.2a, has a bug in its generation of MIME boundaries (see
+to version 5.0.2, has a bug in its generation of MIME boundaries (see
 the details in the fetchmail FAQ).  As a result, even MIME aware MUAs
 will see attachments as part of the message text.  If your Domino server's
 POP3 facility is enabled, we recommend you fall back on it.
@@ -1514,20 +1508,6 @@ It looks like you could use APOP on this server and avoid sending it your
 password in clear.  You should talk to the mailserver administrator about
 this.
 
-"""
-           if string.find(greetline, "IMAP2bis") > 0:
-               warnings = warnings + """
-IMAP2bis servers have a minor problem; they can't peek at messages without
-marking them seen.  If you take a line hit during the retrieval, the
-interrupted message may get left on the server, marked seen.
-
-To work around this, it is recommended that you set the `fetchall'
-option on all user entries associated with this server, so any stuck
-mail will be retrieved next time around.
-
-To fix this bug, upgrade to an IMAP4 server.  The fetchmail FAQ includes
-a pointer to an open-source implementation.
-
 """
            if string.find(greetline, "IMAP4rev1") > 0:
                warnings = warnings + """
index 97cec65c9862b3136f2e81645494e26675080c47..63f000fe8e3cc8946df5b8fef349fd633d6963e7 100644 (file)
@@ -1,6 +1,6 @@
 #include "config.h"
 #include "fetchmail.h"
-#include "i18n.h"
+#include "gettext.h"
 
 #include <signal.h>
 #include <errno.h>
index f55909a403d9e8b5a5991550e923900633cdbe61..ea61c8231cf9fcd0405a16f246f4f312e8910148 100644 (file)
--- a/fm_md5.h
+++ b/fm_md5.h
@@ -3,19 +3,13 @@
 
 #include "config.h"
 
-#include <sys/types.h>
+#include <stdint.h>
 
 #include "fetchmail.h"
 
-#if SIZEOF_INT == 4
-typedef unsigned int uint32;
-#else
-typedef unsigned long int uint32;
-#endif
-
 struct MD5Context {
-       uint32 buf[4];
-       uint32 bits[2];
+       uint32_t buf[4];
+       uint32_t bits[2];
        union {
            unsigned char in[64];
            uint32        in32[16];
@@ -25,7 +19,7 @@ struct MD5Context {
 void MD5Init(struct MD5Context *context);
 void MD5Update(struct MD5Context *context, const void *buf, unsigned len);
 void MD5Final(void *digest, struct MD5Context *context);
-void MD5Transform(uint32 buf[4], uint32 const in[16]);
+void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
 
 /*
  * This is needed to make RSAREF happy on some MS-DOS compilers.
index 5283428797b856b73462b19c0e6799d3e77e80ec..a72d110dde6ca05e0a80e6d45dbd99a11ed31396 100644 (file)
@@ -21,7 +21,6 @@ Description:  Fetchmail is a free, full-featured, robust, and well-documented
 Keywords:      mail, client, POP3, APOP, KPOP, IMAP, ETRN, ODMR, SMTP, ESMTP, GSSAPI, RPA, NTLM, CRAM-MD5, SASL
 Author:                matthias.andree@gmx.de (Matthias Andree)
                shetye@bombay.retortsoft.com (Sunil Shetye)
-               rfunk@funknet.net (Rob Funk)
 Maintained-by: fetchmail-devel@lists.berlios.de
 Primary-site:  http://developer.berlios.de/projects/fetchmail
                `ls -sk @PACKAGE@-@VERSION@.tar.bz2 | \
index 3c19ba7c832fb9f3825c3b98c6d29e7cd5024351..c1624299eb43d75a494420ce7694c83aa0f93903 100644 (file)
--- a/getpass.c
+++ b/getpass.c
 #include <signal.h>
 #include <fcntl.h>
 #include <stdlib.h>
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
 #include "fetchmail.h"
-#include "i18n.h"
+#include "gettext.h"
 
 #define INPUT_BUF_SIZE PASSWORDLEN
 
-#if defined(HAVE_TERMIOS_H) && defined(HAVE_TCSETATTR)
-#  include <termios.h>
-#else
-#if defined(HAVE_TERMIO_H)
-#  include <sys/ioctl.h>
-#  include <termio.h>
-#else
-#if defined(HAVE_SGTTY_H)
-#  include <sgtty.h>
-#endif
-#endif
-#endif
+#include <termios.h>
 
 static int ttyfd;
 
-#if defined(HAVE_TCSETATTR)
-  static struct termios termb;
-  static tcflag_t flags;
-#else
-#if defined(HAVE_TERMIO_H)
-  static struct termio termb;
-  static unsigned short flags;
-#else
-#if defined(HAVE_STTY)
-  static struct sgttyb ttyb;
-  static int flags;
-#endif
-#endif
-#endif
+static struct termios termb;
+static tcflag_t flags;
 
 static void save_tty_state(void);
 static void disable_tty_echo(void);
 static void restore_tty_state(void);
-static RETSIGTYPE sigint_handler(int);
+static void sigint_handler(int);
 
 char *fm_getpassword(char *prompt)
 {
-#if !(defined(HAVE_TCSETATTR) || defined(HAVE_TERMIO_H) || defined(HAVE_STTY))
-#if defined(HAVE_GETPASS) 
-    char *getpass();
-    return getpass(prompt);
-#else
-    fputs(GT_("ERROR: no support for getpassword() routine\n"),stderr);
-    exit(1);
-#endif
-#else
     register char *p;
     register int c;
     FILE *fi;
@@ -133,60 +99,29 @@ char *fm_getpassword(char *prompt)
        fclose(fi);     /* not checking should be safe, file mode was "r" */
 
     return(pbuf);
-#endif /* !(defined(HAVE_TCSETATTR) || ... */
 }
 
 static void save_tty_state (void)
 {
-#if defined(HAVE_TCSETATTR)
     tcgetattr(ttyfd, &termb);
     flags = termb.c_lflag;
-#else
-#if defined(HAVE_TERMIO_H)
-    ioctl(ttyfd, TCGETA, (char *) &termb);
-    flags = termb.c_lflag;
-#else  /* we HAVE_STTY */
-    gtty(ttyfd, &ttyb);
-    flags = ttyb.sg_flags;
-#endif
-#endif
 }
 
 static void disable_tty_echo(void) 
 {
     /* turn off echo on the tty */
-#if defined(HAVE_TCSETATTR)
     termb.c_lflag &= ~ECHO;
     tcsetattr(ttyfd, TCSAFLUSH, &termb);
-#else
-#if defined(HAVE_TERMIO_H)
-    termb.c_lflag &= ~ECHO;
-    ioctl(ttyfd, TCSETA, (char *) &termb);
-#else  /* we HAVE_STTY */
-    ttyb.sg_flags &= ~ECHO;
-    stty(ttyfd, &ttyb);
-#endif
-#endif
 }
 
 static void restore_tty_state(void)
 {
     /* restore previous tty echo state */
-#if defined(HAVE_TCSETATTR)
     termb.c_lflag = flags;
     tcsetattr(ttyfd, TCSAFLUSH, &termb);
-#else
-#if defined(HAVE_TERMIO_H)
-    termb.c_lflag = flags;
-    ioctl(ttyfd, TCSETA, (char *) &termb);
-#else  /* we HAVE_STTY */
-    ttyb.sg_flags = flags;
-    stty(ttyfd, &ttyb);
-#endif
-#endif
 }
 
-static RETSIGTYPE sigint_handler(int signum)
+static void sigint_handler(int signum)
 {
     (void)signum;
     restore_tty_state();
diff --git a/gettext.h b/gettext.h
new file mode 100644 (file)
index 0000000..e27bb7e
--- /dev/null
+++ b/gettext.h
@@ -0,0 +1,274 @@
+/* Convenience header for conditional use of GNU <libintl.h>.
+   Copyright (C) 1995-1998, 2000-2002, 2004-2006 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published
+   by the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+   USA.  */
+
+#ifndef _LIBGETTEXT_H
+#define _LIBGETTEXT_H 1
+
+/* NLS can be disabled through the configure --disable-nls option.  */
+#if ENABLE_NLS
+
+/* Get declarations of GNU message catalog functions.  */
+# include <libintl.h>
+
+/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
+   the gettext() and ngettext() macros.  This is an alternative to calling
+   textdomain(), and is useful for libraries.  */
+# ifdef DEFAULT_TEXT_DOMAIN
+#  undef gettext
+#  define gettext(Msgid) \
+     dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
+#  undef ngettext
+#  define ngettext(Msgid1, Msgid2, N) \
+     dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
+# endif
+
+#else
+
+/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
+   chokes if dcgettext is defined as a macro.  So include it now, to make
+   later inclusions of <locale.h> a NOP.  We don't include <libintl.h>
+   as well because people using "gettext.h" will not include <libintl.h>,
+   and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
+   is OK.  */
+#if defined(__sun)
+# include <locale.h>
+#endif
+
+/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
+   <libintl.h>, which chokes if dcgettext is defined as a macro.  So include
+   it now, to make later inclusions of <libintl.h> a NOP.  */
+#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
+# include <cstdlib>
+# if (__GLIBC__ >= 2) || _GLIBCXX_HAVE_LIBINTL_H
+#  include <libintl.h>
+# endif
+#endif
+
+/* Disabled NLS.
+   The casts to 'const char *' serve the purpose of producing warnings
+   for invalid uses of the value returned from these functions.
+   On pre-ANSI systems without 'const', the config.h file is supposed to
+   contain "#define const".  */
+# define gettext(Msgid) ((const char *) (Msgid))
+# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
+# define dcgettext(Domainname, Msgid, Category) \
+    ((void) (Category), dgettext (Domainname, Msgid))
+# define ngettext(Msgid1, Msgid2, N) \
+    ((N) == 1 \
+     ? ((void) (Msgid2), (const char *) (Msgid1)) \
+     : ((void) (Msgid1), (const char *) (Msgid2)))
+# define dngettext(Domainname, Msgid1, Msgid2, N) \
+    ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
+# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
+    ((void) (Category), dngettext(Domainname, Msgid1, Msgid2, N))
+# define textdomain(Domainname) ((const char *) (Domainname))
+# define bindtextdomain(Domainname, Dirname) \
+    ((void) (Domainname), (const char *) (Dirname))
+# define bind_textdomain_codeset(Domainname, Codeset) \
+    ((void) (Domainname), (const char *) (Codeset))
+
+#endif
+
+/* A pseudo function call that serves as a marker for the automated
+   extraction of messages, but does not call gettext().  The run-time
+   translation is done at a different place in the code.
+   The argument, String, should be a literal string.  Concatenated strings
+   and other string expressions won't work.
+   The macro's expansion is not parenthesized, so that it is suitable as
+   initializer for static 'char[]' or 'const char[]' variables.  */
+#define gettext_noop(String) String
+
+/* The separator between msgctxt and msgid in a .mo file.  */
+#define GETTEXT_CONTEXT_GLUE "\004"
+
+/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
+   MSGID.  MSGCTXT and MSGID must be string literals.  MSGCTXT should be
+   short and rarely need to change.
+   The letter 'p' stands for 'particular' or 'special'.  */
+#ifdef DEFAULT_TEXT_DOMAIN
+# define pgettext(Msgctxt, Msgid) \
+   pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#else
+# define pgettext(Msgctxt, Msgid) \
+   pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#endif
+#define dpgettext(Domainname, Msgctxt, Msgid) \
+  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
+  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
+#ifdef DEFAULT_TEXT_DOMAIN
+# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
+   npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#else
+# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
+   npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#endif
+#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
+  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
+  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+pgettext_aux (const char *domain,
+             const char *msg_ctxt_id, const char *msgid,
+             int category)
+{
+  const char *translation = dcgettext (domain, msg_ctxt_id, category);
+  if (translation == msg_ctxt_id)
+    return msgid;
+  else
+    return translation;
+}
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+npgettext_aux (const char *domain,
+              const char *msg_ctxt_id, const char *msgid,
+              const char *msgid_plural, unsigned long int n,
+              int category)
+{
+  const char *translation =
+    dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
+  if (translation == msg_ctxt_id || translation == msgid_plural)
+    return (n == 1 ? msgid : msgid_plural);
+  else
+    return translation;
+}
+
+/* The same thing extended for non-constant arguments.  Here MSGCTXT and MSGID
+   can be arbitrary expressions.  But for string literals these macros are
+   less efficient than those above.  */
+
+#include <string.h>
+
+#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
+  (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
+   /* || __STDC_VERSION__ >= 199901L */ )
+
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+#include <stdlib.h>
+#endif
+
+#define pgettext_expr(Msgctxt, Msgid) \
+  dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
+#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
+  dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+dcpgettext_expr (const char *domain,
+                const char *msgctxt, const char *msgid,
+                int category)
+{
+  size_t msgctxt_len = strlen (msgctxt) + 1;
+  size_t msgid_len = strlen (msgid) + 1;
+  const char *translation;
+#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+  char msg_ctxt_id[msgctxt_len + msgid_len];
+#else
+  char buf[1024];
+  char *msg_ctxt_id =
+    (msgctxt_len + msgid_len <= sizeof (buf)
+     ? buf
+     : (char *) malloc (msgctxt_len + msgid_len));
+  if (msg_ctxt_id != NULL)
+#endif
+    {
+      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+      msg_ctxt_id[msgctxt_len - 1] = '\004';
+      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+      translation = dcgettext (domain, msg_ctxt_id, category);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+      if (msg_ctxt_id != buf)
+       free (msg_ctxt_id);
+#endif
+      if (translation != msg_ctxt_id)
+       return translation;
+    }
+  return msgid;
+}
+
+#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
+  dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
+#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
+  dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+dcnpgettext_expr (const char *domain,
+                 const char *msgctxt, const char *msgid,
+                 const char *msgid_plural, unsigned long int n,
+                 int category)
+{
+  size_t msgctxt_len = strlen (msgctxt) + 1;
+  size_t msgid_len = strlen (msgid) + 1;
+  const char *translation;
+#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+  char msg_ctxt_id[msgctxt_len + msgid_len];
+#else
+  char buf[1024];
+  char *msg_ctxt_id =
+    (msgctxt_len + msgid_len <= sizeof (buf)
+     ? buf
+     : (char *) malloc (msgctxt_len + msgid_len));
+  if (msg_ctxt_id != NULL)
+#endif
+    {
+      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+      msg_ctxt_id[msgctxt_len - 1] = '\004';
+      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+      translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+      if (msg_ctxt_id != buf)
+       free (msg_ctxt_id);
+#endif
+      if (!(translation == msg_ctxt_id || translation == msgid_plural))
+       return translation;
+    }
+  return (n == 1 ? msgid : msgid_plural);
+}
+
+#define GT_(s) gettext(s)
+#define  N_(s)        (s)
+
+#endif /* _LIBGETTEXT_H */
index c2c7d94ff46aef0502a587bf47db9c868d18d47e..95d631b87c2e6e4db3e2f9ec774554daac89e4f6 100644 (file)
--- a/gssapi.c
+++ b/gssapi.c
@@ -8,13 +8,11 @@
 #include  <stdio.h>
 #include  <string.h>
 #include  <ctype.h>
-#if defined(STDC_HEADERS)
 #include  <stdlib.h>
-#endif
 #include  "fetchmail.h"
 #include  "socket.h"
 
-#include  "i18n.h"
+#include  "gettext.h"
 #include "fm_md5.h"
 
 #include <sys/types.h>
diff --git a/i18n.h b/i18n.h
deleted file mode 100644 (file)
index 5659fc4..0000000
--- a/i18n.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Convenience header for conditional use of GNU <libintl.h>.
-   Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
-
-   This program 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, or (at your option)
-   any later version.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-   USA.  */
-
-#ifndef _LIBGETTEXT_H
-#define _LIBGETTEXT_H 1
-
-/* NLS can be disabled through the configure --disable-nls option.  */
-#ifdef ENABLE_NLS
-
-/* Get declarations of GNU message catalog functions.  */
-# include <libintl.h>
-
-#else
-
-/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
-   chokes if dcgettext is defined as a macro.  So include it now, to make
-   later inclusions of <locale.h> a NOP.  We don't include <libintl.h>
-   as well because people using "gettext.h" will not include <libintl.h>,
-   and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
-   is OK.  */
-#if defined(__sun)
-# include <locale.h>
-#endif
-
-/* Disabled NLS.
-   The casts to 'const char *' serve the purpose of producing warnings
-   for invalid uses of the value returned from these functions.
-   On pre-ANSI systems without 'const', the config.h file is supposed to
-   contain "#define const".  */
-# define gettext(Msgid) ((const char *) (Msgid))
-# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
-# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
-# define ngettext(Msgid1, Msgid2, N) \
-    ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
-# define dngettext(Domainname, Msgid1, Msgid2, N) \
-    ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
-# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
-    ((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
-# define textdomain(Domainname) ((const char *) (Domainname))
-# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
-# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
-
-#endif
-
-/* A pseudo function call that serves as a marker for the automated
-   extraction of messages, but does not call gettext().  The run-time
-   translation is done at a different place in the code.
-   The argument, String, should be a literal string.  Concatenated strings
-   and other string expressions won't work.
-   The macro's expansion is not parenthesized, so that it is suitable as
-   initializer for static 'char[]' or 'const char[]' variables.  */
-#define gettext_noop(String) String
-
-#define GT_(String) gettext(String)
-#define N_(String) gettext_noop(String)
-
-#endif /* _LIBGETTEXT_H */
diff --git a/idle.c b/idle.c
index 4ea21a3c4b4bfc74d712166b4fa900a2b4e3bf9c..04c191847870798f96634cf793f273724ce3c701 100644 (file)
--- a/idle.c
+++ b/idle.c
@@ -42,7 +42,7 @@ volatile int lastsig;         /* last signal received */
  */
 static sig_atomic_t    alarm_latch = FALSE;
 
-RETSIGTYPE gotsigalrm(int sig)
+void gotsigalrm(int sig)
 {
     set_signal_handler(sig, gotsigalrm);
     lastsig = sig;
@@ -50,29 +50,11 @@ RETSIGTYPE gotsigalrm(int sig)
 }
 #endif /* SLEEP_WITH_ALARM */
 
-#ifdef __EMX__
-/* Various EMX-specific definitions */
-static int itimerflag;
-
-void itimerthread(void* dummy)
-{
-    if (outlevel >= O_VERBOSE)
-       report(stderr, 
-              GT_("fetchmail: thread sleeping for %d sec.\n"), poll_interval);
-    while(1)
-    {
-       _sleep2(poll_interval*1000);
-       kill((getpid()), SIGALRM);
-    }
-}
-#endif
-
 int interruptible_idle(int seconds)
 /* time for a pause in the action; return TRUE if awakened by signal */
 {
     int awoken = FALSE;
 
-#ifndef __EMX__
 #ifdef SLEEP_WITH_ALARM                /* not normally on */
     /*
      * We can't use sleep(3) here because we need an alarm(3)
@@ -144,15 +126,6 @@ int interruptible_idle(int seconds)
     } while (lastsig == SIGCHLD);
     }
 #endif
-#else /* EMX */
-    alarm_latch = FALSE;
-    set_signal_handler(SIGALRM, gotsigalrm);
-    _beginthread(itimerthread, NULL, 32768, NULL);
-    /* see similar code above */
-    if (!alarm_latch)
-       pause();
-    set_signal_handler(SIGALRM, SIG_IGN);
-#endif /* ! EMX */
     if (lastsig == SIGUSR1 || ((seconds && getuid() == ROOT_UID)
        && lastsig == SIGHUP))
        awoken = TRUE;
index d886de6b0756227fbb6954839f8ed2bd7adeef0c..a2dfe3a65984a9514b7936e34e45389414ef17be 100644 (file)
--- a/idlist.c
+++ b/idlist.c
@@ -82,21 +82,6 @@ void save_str_pair(struct idlist **idl, const char *str1, const char *str2)
     (*end)->next = (struct idlist *)NULL;
 }
 
-#ifdef __UNUSED__
-void free_str_pair_list(struct idlist **idl)
-/* free the given ID pair list */
-{
-    if (*idl == (struct idlist *)NULL)
-       return;
-
-    free_idpair_list(&(*idl)->next);
-    free ((*idl)->id);
-    free ((*idl)->val.id2);
-    free(*idl);
-    *idl = (struct idlist *)NULL;
-}
-#endif
-
 /** Check if ID \a str is in idlist \a idl. \return idlist entry if found,
  * NULL if not found. */
 struct idlist *str_in_list(struct idlist **idl, const char *str,
diff --git a/imap.c b/imap.c
index cb87eda5378f258f20955c3524f2f84c6d29cd0e..65d225381b7c1b926c5d38d1e8312dbaf67c6ee2 100644 (file)
--- a/imap.c
+++ b/imap.c
 #include  <string.h>
 #include  <strings.h>
 #include  <ctype.h>
-#if defined(STDC_HEADERS)
 #include  <stdlib.h>
 #include  <limits.h>
 #include  <errno.h>
-#endif
 #include  "fetchmail.h"
 #include  "socket.h"
 
-#include  "i18n.h"
+#include  "gettext.h"
 
 /* imap_version values */
-#define IMAP2          -1      /* IMAP2 or IMAP2BIS, RFC1176 */
 #define IMAP4          0       /* IMAP4 rev 0, RFC1730 */
 #define IMAP4rev1      1       /* IMAP4 rev 1, RFC2060 */
 
@@ -354,12 +351,6 @@ static int capa_probe(int sock, struct query *ctl)
                report(stdout, GT_("Protocol identified as IMAP4 rev 0\n"));
        }
     }
-    else if (ok == PS_ERROR)
-    {
-       imap_version = IMAP2;
-       if (outlevel >= O_DEBUG)
-           report(stdout, GT_("Protocol identified as IMAP2 or IMAP2BIS\n"));
-    }
     else
        return ok;
 
@@ -378,7 +369,7 @@ static int capa_probe(int sock, struct query *ctl)
            report(stdout, GT_("will idle after poll\n"));
     }
 
-    peek_capable = (imap_version >= IMAP4);
+    peek_capable = TRUE;
 
     return PS_SUCCESS;
 }
@@ -542,24 +533,6 @@ static int imap_getauth(int sock, struct query *ctl, char *greeting)
     }
 #endif /* GSSAPI */
 
-#ifdef KERBEROS_V4
-    if ((ctl->server.authenticate == A_ANY 
-        || ctl->server.authenticate == A_KERBEROS_V4
-        || ctl->server.authenticate == A_KERBEROS_V5) 
-       && strstr(capabilities, "AUTH=KERBEROS_V4"))
-    {
-       if ((ok = do_rfc1731(sock, "AUTHENTICATE", ctl->server.truename)))
-       {
-           /* SASL cancellation of authentication */
-           gen_send(sock, "*");
-           if(ctl->server.authenticate != A_ANY)
-                return ok;
-       }
-       else
-           return ok;
-    }
-#endif /* KERBEROS_V4 */
-
     /*
      * No such luck.  OK, now try the variants that mask your password
      * in a challenge-response.
@@ -619,15 +592,6 @@ static int imap_getauth(int sock, struct query *ctl, char *greeting)
     }
 #endif /* NTLM_ENABLE */
 
-#ifdef __UNUSED__      /* The Cyrus IMAP4rev1 server chokes on this */
-    /* this handles either AUTH=LOGIN or AUTH-LOGIN */
-    if ((imap_version >= IMAP4rev1) && (!strstr(capabilities, "LOGIN")))
-    {
-       report(stderr, 
-              GT_("Required LOGIN capability not supported by server\n"));
-    }
-#endif /* __UNUSED__ */
-
     /* 
      * We're stuck with sending the password en clair.
      * The reason for this odd-looking logic is that some
@@ -776,7 +740,7 @@ static int imap_search(int sock, struct query *ctl, int count)
      * higher and only when keeping mails. This flag will have an
      * effect only when user has marked some unread mails for deletion
      * using another e-mail client. */
-    flag skipdeleted = (imap_version >= IMAP4) && ctl->keep;
+    flag skipdeleted = ctl->keep;
     const char *undeleted;
 
     /* structure to keep the end portion of the incomplete response */
@@ -1208,28 +1172,23 @@ static int imap_fetch_body(int sock, struct query *ctl, int number, int *lenp)
      * equivalent".  However, we know of at least one server that
      * treats them differently in the presence of MIME attachments;
      * the latter form downloads the attachment, the former does not.
-     * The server is InterChange, and the fool who implemented this
-     * misfeature ought to be strung up by his thumbs.  
+     * The server is InterChange.
      *
      * When I tried working around this by disabling use of the 4rev1 form,
      * I found that doing this breaks operation with M$ Exchange.
      * Annoyingly enough, Exchange's refusal to cope is technically legal
-     * under RFC2062.  Trust Microsoft, the Great Enemy of interoperability
-     * standards, to find a way to make standards compliance irritating....
+     * under RFC2062.
      */
     switch (imap_version)
     {
     case IMAP4rev1:    /* RFC 2060 */
+    default:
        gen_send(sock, "FETCH %d BODY.PEEK[TEXT]", number);
        break;
 
     case IMAP4:                /* RFC 1730 */
        gen_send(sock, "FETCH %d RFC822.TEXT.PEEK", number);
        break;
-
-    default:           /* RFC 1176 */
-       gen_send(sock, "FETCH %d RFC822.TEXT", number);
-       break;
     }
 
     /* looking for FETCH response */
@@ -1311,21 +1270,13 @@ static int imap_delete(int sock, struct query *ctl, int number)
     number -= expunged;
 
     /*
-     * Use SILENT if possible as a minor throughput optimization.
-     * Note: this has been dropped from IMAP4rev1.
-     *
-     * We set \Seen because there are some IMAP servers (notably HP
-     * OpenMail and MS Exchange) do message-receipt DSNs,
-     * but only when the seen bit gets set.
-     * This is the appropriate time -- we get here right
+     * We set Seen because there are some IMAP servers (notably HP
+     * OpenMail) that do message-receipt DSNs, but only when the seen
+     * bit is set.  This is the appropriate time -- we get here right
      * after the local SMTP response that says delivery was
      * successful.
      */
-    if ((ok = gen_transact(sock,
-                       imap_version == IMAP4 
-                               ? "STORE %d +FLAGS.SILENT (%s)"
-                               : "STORE %d +FLAGS (%s)",
-                       number, delflags)))
+    if ((ok = gen_transact(sock, "STORE %d +FLAGS.SILENT (\\Seen \\Deleted)", number)))
        return(ok);
     else
        deletions++;
@@ -1353,11 +1304,7 @@ static int imap_mark_seen(int sock, struct query *ctl, int number)
     /* expunges change the message numbers */
     number -= expunged;
 
-    return(gen_transact(sock,
-       imap_version == IMAP4
-       ? "STORE %d +FLAGS.SILENT (\\Seen)"
-       : "STORE %d +FLAGS (\\Seen)",
-       number));
+    return(gen_transact(sock,"STORE %d +FLAGS.SILENT (\\Seen)", number));
 }
 
 static int imap_end_mailbox_poll(int sock, struct query *ctl)
index b63e1121c75d8794fb578bd6368f123ab2e98d02..f9445cb8aba1a01948dc50beb25aed0445146ae3 100644 (file)
 
 #include <stdio.h>
 #include <string.h>
-#if defined(STDC_HEADERS)
 #include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
 #include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <net/if.h>
 #if defined(__FreeBSD__)
 #if defined __FreeBSD_USE_KVM
-#if __FreeBSD_version >= 300001
 #include <net/if_var.h>
-#endif
 #include <kvm.h>
 #include <nlist.h>
 #include <sys/fcntl.h>
-#else
+#else /* !defined __FreeBSD_USE_KVM */
 #include <sys/sysctl.h>
 #include <net/route.h>
 #include <net/if_dl.h>
-#endif
-#endif
+#endif /* defined __FreeBSD_USE_KVM */
+#endif /* defined __FreeBSD__ */
 #include "socket.h"
-#include "i18n.h"
+#include "gettext.h"
 #include "tunable.h"
 
 typedef struct {
@@ -231,14 +225,11 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo)
        char                    iname[16];
        struct ifnet            ifnet;
        unsigned long           ifnet_addr = ifnet_savedaddr;
-#if __FreeBSD_version >= 300001
        struct ifnethead        ifnethead;
        struct ifaddrhead       ifaddrhead;
-#endif
        struct ifaddr           ifaddr;
        unsigned long           ifaddr_addr;
        struct sockaddr         sa;
-       unsigned long           sa_addr;
        uint                    i;
        
        if (if_egid)
@@ -260,12 +251,8 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo)
                }
        }
 
-#if __FreeBSD_version >= 300001
        kvm_read(kvmfd, ifnet_savedaddr, (char *) &ifnethead, sizeof ifnethead);
        ifnet_addr = (u_long) ifnethead.tqh_first;
-#else
-       ifnet_addr = ifnet_savedaddr;
-#endif
 
        while (ifnet_addr)
        {
@@ -285,11 +272,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo)
                        ifinfo->rx_packets = ifnet.if_ipackets;
                        ifinfo->tx_packets = ifnet.if_opackets;
 
-#if __FreeBSD_version >= 300001
                        ifaddr_addr = (u_long) ifnet.if_addrhead.tqh_first;
-#else
-                       ifaddr_addr = (u_long) ifnet.if_addrlist;
-#endif
                        
                        while(ifaddr_addr)
                        {
@@ -298,11 +281,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo)
                                
                                if (sa.sa_family != AF_INET)
                                {
-#if __FreeBSD_version >= 300001
                                        ifaddr_addr = (u_long) ifaddr.ifa_link.tqe_next;
-#else
-                                       ifaddr_addr = (u_long) ifaddr.ifa_next;
-#endif
                                        continue;
                                }
                        
@@ -324,11 +303,7 @@ get_ifinfo(const char *ifname, ifinfo_t *ifinfo)
                        return 0;
                }
 
-#if __FreeBSD_version >= 300001
                ifnet_addr = (u_long) ifnet.if_link.tqe_next;
-#else
-               ifnet_addr = (unsigned long) ifnet.if_next;
-#endif
        }
 
        if (if_egid)
diff --git a/kerberos.c b/kerberos.c
deleted file mode 100644 (file)
index 141c9e3..0000000
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * kerberos.c -- Kerberos authentication (see RFC 1731).
- *
- * For license terms, see the file COPYING in this directory.
- */
-#include  "config.h"
-
-#ifdef KERBEROS_V4
-
-#include  <stdio.h>
-#include  <string.h>
-#include  <ctype.h>
-#if defined(STDC_HEADERS)
-#include  <stdlib.h>
-#endif
-#include  "fetchmail.h"
-#include  "socket.h"
-#include  "kerberos.h"
-
-#include <sys/types.h>
-#include <netinet/in.h>  /* for htonl/ntohl */
-
-#include  "i18n.h"
-
-#if SIZEOF_INT == 4
-typedef        int     int32;
-#elif SIZEOF_SHORT == 4
-typedef        short   int32;
-#elif SIZEOF_LONG == 4
-typedef        long    int32;
-#else
-#error Cannot deduce a 32-bit-type
-#endif
-
-int do_rfc1731(int sock, const char *command, const char *truename)
-/* authenticate as per RFC1731 -- note 32-bit integer requirement here */
-{
-    int result = 0, len;
-    char buf1[4096], buf2[4096];
-    union {
-      int32 cint;
-      char cstr[4];
-    } challenge1, challenge2;
-    char srvinst[INST_SZ];
-    char *p;
-    char srvrealm[REALM_SZ];
-    KTEXT_ST authenticator;
-    CREDENTIALS credentials;
-    char tktuser[MAX_K_NAME_SZ+1+INST_SZ+1+REALM_SZ+1];
-    char tktinst[INST_SZ];
-    char tktrealm[REALM_SZ];
-    des_cblock session;
-    des_key_schedule schedule;
-
-    gen_send(sock, "%s KERBEROS_V4", command);
-
-    /* The data encoded in the first ready response contains a random
-     * 32-bit number in network byte order.  The client should respond
-     * with a Kerberos ticket and an authenticator for the principal
-     * "imap.hostname@realm", where "hostname" is the first component
-     * of the host name of the server with all letters in lower case
-     * and where "realm" is the Kerberos realm of the server.  The
-     * encrypted checksum field included within the Kerberos
-     * authenticator should contain the server provided 32-bit number
-     * in network byte order.
-     */
-
-    if ((result = gen_recv(sock, buf1, sizeof buf1)) != 0) {
-       return result;
-    }
-
-    len = from64tobits(challenge1.cstr, buf1, sizeof(challenge1.cstr));
-    if (len < 0) {
-       report(stderr, GT_("could not decode initial BASE64 challenge\n"));
-       return PS_AUTHFAIL;
-    }
-
-    /* this patch by Dan Root <dar@thekeep.org> solves an endianess
-     * problem. */
-    {
-       char tmp[4];
-
-       *(int *)tmp = ntohl(*(int *) challenge1.cstr);
-       memcpy(challenge1.cstr, tmp, sizeof(tmp));
-    }
-
-    /* Client responds with a Kerberos ticket and an authenticator for
-     * the principal "imap.hostname@realm" where "hostname" is the
-     * first component of the host name of the server with all letters
-     * in lower case and where "realm" is the Kerberos realm of the
-     * server.  The encrypted checksum field included within the
-     * Kerberos authenticator should contain the server-provided
-     * 32-bit number in network byte order.
-     */
-
-    strncpy(srvinst, truename, (sizeof srvinst)-1);
-    srvinst[(sizeof srvinst)-1] = '\0';
-    for (p = srvinst; *p; p++) {
-      if (isupper((unsigned char)*p)) {
-       *p = tolower((unsigned char)*p);
-      }
-    }
-
-    strncpy(srvrealm, (char *)krb_realmofhost(srvinst), (sizeof srvrealm)-1);
-    srvrealm[(sizeof srvrealm)-1] = '\0';
-    if ((p = strchr(srvinst, '.')) != NULL) {
-      *p = '\0';
-    }
-
-    result = krb_mk_req(&authenticator, "imap", srvinst, srvrealm, 0);
-    if (result) {
-       report(stderr, "krb_mq_req: %s\n", krb_get_err_text(result));
-       return PS_AUTHFAIL;
-    }
-
-    result = krb_get_cred("imap", srvinst, srvrealm, &credentials);
-    if (result) {
-       report(stderr, "krb_get_cred: %s\n", krb_get_err_text(result));
-       return PS_AUTHFAIL;
-    }
-
-    memcpy(session, credentials.session, sizeof session);
-    memset(&credentials, 0, sizeof credentials);
-    des_key_sched(&session, schedule);
-
-    result = krb_get_tf_fullname(TKT_FILE, tktuser, tktinst, tktrealm);
-    if (result) {
-       report(stderr, "krb_get_tf_fullname: %s\n", krb_get_err_text(result));
-       return PS_AUTHFAIL;
-    }
-
-#ifdef __UNUSED__
-    /*
-     * Andrew H. Chatham <andrew.chatham@duke.edu> alleges that this check
-     * is not necessary and has consistently been messing him up.
-     */
-    if (strcmp(tktuser, user) != 0) {
-       report(stderr, 
-              GT_("principal %s in ticket does not match -u %s\n"), tktuser,
-               user);
-       return PS_AUTHFAIL;
-    }
-#endif /* __UNUSED__ */
-
-    if (tktinst[0]) {
-       report(stderr, 
-              GT_("non-null instance (%s) might cause strange behavior\n"),
-               tktinst);
-       strlcat(tktuser, ".", sizeof(tktuser));
-       strlcat(tktuser, tktinst, sizeof(tktuser));
-    }
-
-    if (strcmp(tktrealm, srvrealm) != 0) {
-       strlcat(tktuser, "@", sizeof(tktuser));
-       strlcat(tktuser, tktrealm, sizeof(tktuser));
-    }
-
-    result = krb_mk_req(&authenticator, "imap", srvinst, srvrealm,
-           challenge1.cint);
-    if (result) {
-       report(stderr, "krb_mq_req: %s\n", krb_get_err_text(result));
-       return PS_AUTHFAIL;
-    }
-
-    to64frombits(buf1, authenticator.dat, authenticator.length);
-    if (outlevel >= O_MONITOR) {
-       report(stdout, "IMAP> %s\n", buf1);
-    }
-    strcat(buf1, "\r\n");
-    SockWrite(sock, buf1, strlen(buf1));
-
-    /* Upon decrypting and verifying the ticket and authenticator, the
-     * server should verify that the contained checksum field equals
-     * the original server provided random 32-bit number.  Should the
-     * verification be successful, the server must add one to the
-     * checksum and construct 8 octets of data, with the first four
-     * octets containing the incremented checksum in network byte
-     * order, the fifth octet containing a bit-mask specifying the
-     * protection mechanisms supported by the server, and the sixth
-     * through eighth octets containing, in network byte order, the
-     * maximum cipher-text buffer size the server is able to receive.
-     * The server must encrypt the 8 octets of data in the session key
-     * and issue that encrypted data in a second ready response.  The
-     * client should consider the server authenticated if the first
-     * four octets the un-encrypted data is equal to one plus the
-     * checksum it previously sent.
-     */
-    
-    if ((result = gen_recv(sock, buf1, sizeof buf1)) != 0)
-       return result;
-
-    /* The client must construct data with the first four octets
-     * containing the original server-issued checksum in network byte
-     * order, the fifth octet containing the bit-mask specifying the
-     * selected protection mechanism, the sixth through eighth octets
-     * containing in network byte order the maximum cipher-text buffer
-     * size the client is able to receive, and the following octets
-     * containing a user name string.  The client must then append
-     * from one to eight octets so that the length of the data is a
-     * multiple of eight octets. The client must then PCBC encrypt the
-     * data with the session key and respond to the second ready
-     * response with the encrypted data.  The server decrypts the data
-     * and verifies the contained checksum.  The username field
-     * identifies the user for whom subsequent IMAP operations are to
-     * be performed; the server must verify that the principal
-     * identified in the Kerberos ticket is authorized to connect as
-     * that user.  After these verifications, the authentication
-     * process is complete.
-     */
-
-    len = from64tobits(buf2, buf1, sizeof(buf2));
-    if (len < 0) {
-       report(stderr, GT_("could not decode BASE64 ready response\n"));
-       return PS_AUTHFAIL;
-    }
-
-    des_ecb_encrypt((des_cblock *)buf2, (des_cblock *)buf2, schedule, 0);
-    memcpy(challenge2.cstr, buf2, 4);
-    if ((int32)ntohl(challenge2.cint) != challenge1.cint + 1) {
-       report(stderr, GT_("challenge mismatch\n"));
-       return PS_AUTHFAIL;
-    }      
-
-    memset(authenticator.dat, 0, sizeof authenticator.dat);
-
-    result = htonl(challenge1.cint);
-    memcpy(authenticator.dat, &result, sizeof result);
-
-    /* The protection mechanisms and their corresponding bit-masks are as
-     * follows:
-     *
-     * 1 No protection mechanism
-     * 2 Integrity (krb_mk_safe) protection
-     * 4 Privacy (krb_mk_priv) protection
-     */
-    authenticator.dat[4] = 1;
-
-    len = strlen(tktuser);
-    strncpy((char *)authenticator.dat+8, tktuser, len);
-    authenticator.length = len + 8 + 1;
-    while (authenticator.length & 7) {
-       authenticator.length++;
-    }
-    des_pcbc_encrypt((const unsigned char *)authenticator.dat,
-           (unsigned char *)authenticator.dat, authenticator.length, schedule,
-           &session, 1);
-
-    to64frombits(buf1, authenticator.dat, authenticator.length);
-
-    /* ship down the response, accept the server's error/ok indication */
-    suppress_tags = TRUE;
-    result = gen_transact(sock, "%s", buf1);
-    suppress_tags = FALSE;
-    if (result)
-       return(result);
-    else
-       return(PS_SUCCESS);
-}
-#endif /* KERBEROS_V4 */
-
-/* kerberos.c ends here */
-
index fc0689dadf50abb5be664559e103d719dc7186b6..ae3d3db59e6c4863717dfa9202d25c12cbbad916 100644 (file)
@@ -6,33 +6,12 @@
 
 #ifndef H_KERBEROS__
 #define H_KERBEROS__
+
 #include  "config.h"
-#if defined(KERBEROS_V4) || defined(KERBEROS_V5)
 
 #ifdef KERBEROS_V5
 #include <krb5.h>
 /* #include <com_err.h> */
-#endif
-
-#ifdef KERBEROS_V4
-#  ifdef KERBEROS_V4_V5
-#    include <kerberosIV/krb.h>
-#    include <kerberosIV/des.h>
-#  else
-#    if defined (__bsdi__) 
-#      include <des.h> /* order of includes matters */
-#      define krb_get_err_text(e) (krb_err_txt[e])
-#    endif
-#    include <krb.h>
-#    if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__linux__)
-#      define krb_get_err_text(e) (krb_err_txt[e])
-#      include <des.h>
-#    endif
-#  endif
-#endif
-
-/* des.h might define _ for no good reason.  */
-#undef _
+#endif /* KERBEROS_V5 */
 
-#endif /* KERBEROS_V4 || KERBEROS_V5 */
 #endif /* H_KERBEROS__ */
index cd74ec0aaf489273c90d12ced63c40aa9de6134e..af5da953a92a0805c055c1aa1827884c3f03b1b5 100644 (file)
 
 #include "gethostbyname.h"
 
-#if HAVE_GETIPNODEBYNAME
-
-void
-free_ghbnctx (struct ghbnctx *ctx)
-{
-  assert (ctx != NULL);
-
-  if (ctx->hostent != NULL)
-    freehostent (ctx->hostent);
-}
-
-struct hostent *
-gethostbyname_ctx (const char *host, struct ghbnctx *ctx)
-{
-  assert (ctx != NULL);
-
-  memset (ctx, 0, sizeof (struct ghbnctx));
-  ctx->hostent = getipnodebyname (host, AF_UNSPEC, AI_ADDRCONFIG, &ctx->h_err);
-  return ctx->hostent;
-}
-
-int
-h_error_ctx (struct ghbnctx *ctx)
-{
-  assert (ctx != NULL);
-
-  return ctx->h_err;
-}
-
-#elif HAVE_GETHOSTBYNAME_R == 6
+#if HAVE_GETHOSTBYNAME_R == 6
 
 void
 free_ghbnctx (struct ghbnctx *ctx)
index 2b963997c6017dde0b5271753aa6dda40f6c7b45..474c030b0d2fa1556ef6c772768c6c7d2596d5b7 100644 (file)
 #ifndef _gethostbyname_h
 #define _gethostbyname_h
 
-#if HAVE_GETIPNODEBYNAME
-
-struct ghbnctx
-  {
-    int h_err;
-    struct hostent *hostent;
-  };
-
-#elif HAVE_GETHOSTBYNAME_R == 6
+#if HAVE_GETHOSTBYNAME_R == 6
 
 struct ghbnctx
   {
diff --git a/lock.c b/lock.c
index 213969f1f012f323c470ceb3a1e6b1c1aec43ffa..2d656df65289fcf3ae829ac3d5306cb192fd3d03 100644 (file)
--- a/lock.c
+++ b/lock.c
@@ -6,21 +6,15 @@
 #include "config.h"
 
 #include <stdio.h>
-#ifdef HAVE_STRING_H
 #include <string.h> /* strcat() */
-#endif
-#if defined(STDC_HEADERS)
 #include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
 
 #include "fetchmail.h"
-#include "i18n.h"
+#include "gettext.h"
 #include "lock.h"
 
 static char *lockfile;         /** name of lockfile */
@@ -66,9 +60,7 @@ static void unlockit(void)
 void fm_lock_dispose(void)
 /* arrange for a lock to be removed on process exit */
 {
-#ifdef HAVE_ATEXIT
     atexit(unlockit);
-#endif
 }
 
 int fm_lock_state(void)
diff --git a/lock.h b/lock.h
index 27f63cf0599396f64a59b9778cb3cf268975d024..07d3ec34be536dd81b2e06274f6cc8bc2e1d982d 100644 (file)
--- a/lock.h
+++ b/lock.h
@@ -30,8 +30,7 @@ void fm_lock_release(void);
  */
 int  fm_lock_state(void);
 
-/** If atexit(3) is available on the system this software is compiled on,
- * register an exit handler to dipose of the lock on process exit. */
+/** Register an atexit() exit handler to dipose of the lock on process exit. */
 void fm_lock_dispose(void);
 
 #endif
diff --git a/md5c.c b/md5c.c
index 11a61516e2e335d201dfb4291dde1d2e88b2ab09..dcf25d5f42433ea483efb5cfc15dacb362907535 100644 (file)
--- a/md5c.c
+++ b/md5c.c
 
 #include "config.h"
 #include "fm_md5.h"
-#ifdef HAVE_STRING_H
 #include <string.h>   /* memmove */
-#endif
-
 #include <inttypes.h>
 
 /*
index 5affe31651981b4f26e938f9cffbc664673b1da1..41dd2e7ae35457cdea5ee3f1e8441937d40bb3fa 100644 (file)
--- a/md5ify.c
+++ b/md5ify.c
 
 #include <stdio.h>
 #include <string.h>
-
-#if defined(STDC_HEADERS)
 #include <string.h>
-#endif
 
+#include "fetchmail.h"
 #include "fm_md5.h"
 
 char *
diff --git a/memmove.c b/memmove.c
deleted file mode 100644 (file)
index 2ffab60..0000000
--- a/memmove.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Scratch implementation of memmove() in case your C library lacks one.
- *
- * For license terms, see the file COPYING in this directory.
- */
-char *memmove(char *dst, register char *src, register int n)
-{
-    register char *svdst;
-
-    if ((dst > src) && (dst < src + n)) 
-    {
-        src += n;
-        for (svdst = dst + n; n-- > 0; )
-            *--svdst = *--src;
-    }
-    else
-    {
-        for (svdst = dst; n-- > 0; )
-            *svdst++ = *src++;
-    }
-    return dst;
-}
diff --git a/mx.h b/mx.h
deleted file mode 100644 (file)
index 3bb1e34..0000000
--- a/mx.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* mx.h -- name-to-preference association for MX records.
- * For license terms, see the file COPYING in this directory.
- */
-
-#include "config.h"
-
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-
-struct mxentry
-{
-    char       *name;
-    int                pref;
-};
-
-extern struct mxentry * getmxrecords(const char *);
-
-#if !HAVE_DECL_H_ERRNO
-extern int h_errno;
-#endif
-
-/* mx.h ends here */
diff --git a/mxget.c b/mxget.c
deleted file mode 100644 (file)
index 4529c22..0000000
--- a/mxget.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * mxget.c -- fetch MX records for given DNS name
- *
- * Copyright (C) 1996, 1997, 1998, 2000, 2002 by Eric S. Raymond
- * Copyright (C) 2005, 2006, 2007 by Matthias Andree
- * For license terms, see the file COPYING in this directory.
- */
-
-#include "config.h"
-#include "fetchmail.h"
-#include <stdio.h>
-#include <string.h>
-#ifdef HAVE_RES_SEARCH
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
-#include <netdb.h>
-#include <sys/types.h>
-#include <netinet/in.h>
-
-#ifdef __BEOS__
-#include "beos/beos_nameser.h"
-#endif
-
-#ifdef HAVE_ARPA_NAMESER_H
-#include <arpa/nameser.h>
-#endif
-#ifdef HAVE_RESOLV_H
-#include <resolv.h>
-#endif
-
-#include "mx.h"
-
-/*
- * This ought to be in the bind library.  It's adapted from sendmail.
- */
-
-/*
- * These are defined in RFC833. Some bind interface headers don't declare them.
- * Ghod help us if they're ever actually incompatible with what's in 
- * the arpa/nameser.h header.
- */
-#ifndef PACKETSZ
-#define PACKETSZ       512             /* maximum packet size */
-#endif
-#ifndef HFIXEDSZ
-#define        HFIXEDSZ        12              /* #/bytes of fixed data in header */
-#endif
-#ifndef INT32SZ
-#define        INT32SZ         4               /* for systems without 32-bit ints */
-#endif
-#ifndef INT16SZ
-#define        INT16SZ         2               /* for systems without 16-bit ints */
-#endif
-
-/* minimum possible size of MX record in packet */
-#define MIN_MX_SIZE    8       /* corresp to "a.com 0" w/ terminating space */
-
-struct mxentry *getmxrecords(const char *name)
-/* get MX records for given host */
-{
-    char answer[PACKETSZ], *eom, *cp, *bp;
-    int n, ancount, qdcount, buflen, type, pref, ind;
-    static struct mxentry pmx[(PACKETSZ - HFIXEDSZ) / MIN_MX_SIZE];
-    static char MXHostBuf[PACKETSZ - HFIXEDSZ]; 
-    HEADER *hp;
-
-    pmx->name = (char *)NULL;
-    pmx->pref = -1;
-    n = res_search(name, C_IN,T_MX, (unsigned char *)&answer, sizeof(answer));
-    if (n == -1)
-       return((struct mxentry *)NULL);
-    if ((size_t)n > sizeof(answer))
-       n = sizeof(answer);     
-
-    hp = (HEADER *)&answer;
-    cp = answer + HFIXEDSZ;
-    eom = answer + n;
-    h_errno = 0;
-    for (qdcount = ntohs(hp->qdcount); qdcount--; cp += n + QFIXEDSZ)
-      if ((n = dn_skipname((unsigned char *)cp, (unsigned char *)eom)) < 0)
-           return((struct mxentry *)NULL);
-    buflen = sizeof(MXHostBuf) - 1;
-    bp = MXHostBuf;
-    ind = 0;
-    ancount = ntohs(hp->ancount);
-    while (--ancount >= 0 && cp < eom)
-    {
-       if ((n = dn_expand((unsigned char *)answer, (unsigned char *)eom,
-                          (unsigned char *)cp, bp, buflen)) < 0)
-           break;
-       cp += n;
-       GETSHORT(type, cp);
-       cp += INT16SZ + INT32SZ;
-       GETSHORT(n, cp);
-       if (type != T_MX)
-       {
-           cp += n;
-           continue;
-       }
-       GETSHORT(pref, cp);
-       if ((n = dn_expand((unsigned char *)answer, (unsigned char *)eom,
-                          (unsigned char *)cp, bp, buflen)) < 0)
-           break;
-       cp += n;
-
-       pmx[ind].name = bp;
-       pmx[ind].pref = pref;
-       ++ind;
-
-       n = strlen((const char *)bp);
-       bp += n;
-       *bp++ = '\0';
-
-       buflen -= n + 1;
-    }
-
-    pmx[ind].name = (char *)NULL;
-    pmx[ind].pref = -1;
-    return(pmx);
-}
-#endif /* HAVE_RES_SEARCH */
-
-#ifdef STANDALONE
-#include <stdlib.h>
-
-int main(int argc, char *argv[])
-{
-#ifdef HAVE_RES_SEARCH
-    struct mxentry *responses;
-#endif
-
-    if (argc != 2 || 0 == strcmp(argv[1], "-h")) {
-       fprintf(stderr, "Usage: %s domain\n", argv[0]);
-       exit(1);
-    }
-
-#ifdef HAVE_RES_SEARCH
-    responses = getmxrecords(argv[1]);
-    if (responses == (struct mxentry *)NULL) {
-       puts("No MX records found");
-    } else {
-       do {
-           printf("%s %d\n", responses->name, responses->pref);
-       } while ((++responses)->name);
-    }
-#else
-    puts("This program was compiled without HAS_RES_SEARCH and does nothing.");
-#endif
-
-    return 0;
-}
-#endif /* TESTMAIN */
-
-/* mxget.c ends here */
diff --git a/netrc.c b/netrc.c
index a585e1a0be37c236336713b949f15e7f9b3926e6..5af542735349214d901c9f0f0f0ad5f366ede832 100644 (file)
--- a/netrc.c
+++ b/netrc.c
@@ -10,6 +10,8 @@
    (Makefile.am should have a rule so you can just type "make netrc")
 */
 
+#define _XOPEN_SOURCE 600
+
 #include "config.h"
 
 #include <stdio.h>
@@ -19,7 +21,7 @@
 
 #include "fetchmail.h"
 #include "netrc.h"
-#include "i18n.h"
+#include "gettext.h"
 
 #ifdef STANDALONE
 /* Normally defined in xstrdup.c. */
diff --git a/netrc.h b/netrc.h
index c69316a89b6c40e3801e058e07181cfe3a01a1d4..0758db232d78fae558810af9dd96aa00d9329ad8 100644 (file)
--- a/netrc.h
+++ b/netrc.h
 # define __END_DECLS /* empty */
 #endif
 
-#undef __P
-#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) || defined(__cplusplus)
-# define __P(protos) protos
-#else
-# define __P(protos) ()
-#endif
-
 /* The structure used to return account information from the .netrc. */
 typedef struct _netrc_entry {
   /* The exact host name given in the .netrc, NULL if default. */
@@ -41,14 +34,14 @@ __BEGIN_DECLS
 /* Parse FILE as a .netrc file (as described in ftp(1)), and return a
    list of entries.  NULL is returned if the file could not be
    parsed. */
-netrc_entry *parse_netrc __P((char *file));
+netrc_entry *parse_netrc (char *file);
 
 /* Return the netrc entry from LIST corresponding to HOST.  NULL is
    returned if no such entry exists. */
-netrc_entry *search_netrc __P((netrc_entry *list, char *host, char *account));
+netrc_entry *search_netrc (netrc_entry *list, char *host, char *account);
 
 /* Free the netrc list structure */
-void free_netrc __P((netrc_entry *list));
+void free_netrc (netrc_entry *list);
 __END_DECLS
 
 #endif /* _NETRC_H_ */
index 057c1b9147c5a338468ac1dd56356b9bcf52fa3c..941d0a070bba39aa64fbf7a237bffad994ca551e 100644 (file)
@@ -2,7 +2,7 @@
 
 #ifdef NTLM_ENABLE
 #include "fetchmail.h"
-#include "i18n.h"
+#include "gettext.h"
 #include "ntlm.h"
 #include "socket.h"
 
diff --git a/odmr.c b/odmr.c
index d495e9cd0223713270710c20acb0a601c75f4178..64e70bcebb3e1af0311fec11474b48d24dc328ea 100644 (file)
--- a/odmr.c
+++ b/odmr.c
@@ -9,23 +9,13 @@
 #include  <stdio.h>
 #include  <stdlib.h>
 #include  <assert.h>
-#ifdef HAVE_STRING_H /* strcat() */
 #include <string.h>
-#endif
-#ifdef HAVE_NET_SOCKET_H /* BeOS needs this */
-#include <net/socket.h>
-#endif
 #include  <sys/types.h>
-#ifdef HAVE_NET_SELECT_H /* AIX needs this */
-#include <net/select.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H /* AIX 4.1, at least, needs this */
 #include  <sys/select.h>
-#endif
 #include  <netdb.h>
 #include  <errno.h>
 #include  <unistd.h>
-#include  "i18n.h"
+#include  "gettext.h"
 #include  "fetchmail.h"
 #include  "sdump.h"
 #include  "smtp.h"
diff --git a/opie.c b/opie.c
index 26f3c93cc561e610120b2eb21538b066fb9dfbec..4b8ad4f3ead2ce5fc158f31c518ff218432f3abc 100644 (file)
--- a/opie.c
+++ b/opie.c
@@ -8,13 +8,11 @@
 #include  <stdio.h>
 #include  <string.h>
 #include  <ctype.h>
-#if defined(STDC_HEADERS)
 #include  <stdlib.h>
-#endif
 #include  "fetchmail.h"
 #include  "socket.h"
 
-#include  "i18n.h"
+#include  "gettext.h"
 #include "fm_md5.h"
 
 #ifdef OPIE_ENABLE
index d53044fc72c4215ee3e975092acde6fb7819a142..cee5fae453ec77fc73a4edded2a9580b8777131c 100644 (file)
--- a/options.c
+++ b/options.c
 #include <pwd.h>
 #include <string.h>
 #include <errno.h>
-#if defined(STDC_HEADERS)
 #include  <stdlib.h>
 #include  <limits.h>
-#else
-#include  <ctype.h>
-#endif
 
 #include "getopt.h"
 #include "fetchmail.h"
-#include "i18n.h"
+#include "gettext.h"
 
 enum {
     LA_INVISIBLE = 256,
@@ -55,15 +51,24 @@ enum {
     LA_IDLE,
     LA_NOSOFTBOUNCE,
     LA_SOFTBOUNCE,
-    LA_BADHEADER
+    LA_BADHEADER,
+    LA_RETRIEVEERROR
 };
 
-/* options still left: CgGhHjJoORTWxXYz */
-static const char *shortoptions = 
+static const char *shortoptions =
+/* options still left: ghHjJoRTWxXYz */
+#ifdef HAVE_LIBPWMD
+       "O:C:G:"
+#endif
        "?Vcsvd:NqL:f:i:p:UP:A:t:E:Q:u:akKFnl:r:S:Z:b:B:e:m:I:M:yw:D:";
 
 static const struct option longoptions[] = {
 /* this can be const because all flag fields are 0 and will never get set */
+#ifdef HAVE_LIBPWMD
+  {"pwmd-socket",      required_argument,  (int *) 0, 'C' },
+  {"pwmd-file",                required_argument,  (int *) 0, 'G' },
+  {"pinentry-timeout", required_argument,  (int *) 0, 'O' },
+#endif
   {"help",     no_argument,       (int *) 0, '?' },
   {"version",  no_argument,       (int *) 0, 'V' },
   {"check",    no_argument,       (int *) 0, 'c' },
@@ -109,6 +114,7 @@ static const struct option longoptions[] = {
   {"norewrite",        no_argument,       (int *) 0, 'n' },
   {"limit",    required_argument, (int *) 0, 'l' },
   {"warnings", required_argument, (int *) 0, 'w' },
+  {"retrieve-error",   required_argument, (int *) 0, LA_RETRIEVEERROR },
 
   {"folder",   required_argument, (int *) 0, 'r' },
   {"smtphost", required_argument, (int *) 0, 'S' },
@@ -159,7 +165,6 @@ static const struct option longoptions[] = {
 static int xatoi(char *s, int *errflagptr)
 /* do safe conversion from string to number */
 {
-#if defined (STDC_HEADERS) && defined (LONG_MAX) && defined (INT_MAX)
     /* parse and convert numbers, but also check for invalid characters in
      * numbers
      */
@@ -190,48 +195,16 @@ static int xatoi(char *s, int *errflagptr)
     }
 
     return (int) value;  /* shut up, I know what I'm doing */
-#else
-    int        i;
-    char *dp;
-# if defined (STDC_HEADERS)
-    size_t     len;
-# else
-    int                len;
-# endif
-
-    /* We do only base 10 conversions here (atoi)! */
-
-    len = strlen(s);
-    /* check for leading white spaces */
-    for (i = 0; (i < len) && isspace((unsigned char)s[i]); i++)
-       ;
-
-    dp = &s[i];
-
-    /* check for +/- */
-    if (i < len && (s[i] == '+' || s[i] == '-'))       i++;
-
-    /* skip over digits */
-    for ( /* no init */ ; (i < len) && isdigit((unsigned char)s[i]); i++)
-       ;
-
-    /* check for trailing garbage */
-    if (i != len) {
-       (void) fprintf(stderr, GT_("String '%s' is not a valid number string.\n"), s);
-       (*errflagptr)++;
-       return 0;
-    }
-
-    /* atoi should be safe by now, except for number range over/underflow */
-    return atoi(dp);
-#endif
 }
 
 /** parse and validate the command line options */
 int parsecmdline (int argc /** argument count */,
                  char **argv /** argument strings */,
                  struct runctl *rctl /** global run controls to modify */,
-                 struct query *ctl /** option record to initialize */)
+                 struct query *ctl /** option record to initialize */,
+                 flag *safewithbg /** set to whether options are
+                                    compatible with another copy
+                                    running in the background */)
 {
     /*
      * return value: if positive, argv index of last parsed option + 1
@@ -246,9 +219,12 @@ int parsecmdline (int argc /** argument count */,
     int errflag = 0;   /* TRUE when a syntax error is detected */
     int helpflag = 0;  /* TRUE when option help was explicitly requested */
     int option_index;
+    int option_safe;   /* to track if option currently parsed is safe
+                          with a background copy */
     char *buf, *cp;
 
     rctl->poll_interval = -1;
+    *safewithbg = TRUE;
 
     memset(ctl, '\0', sizeof(struct query));    /* start clean */
     ctl->smtp_socket = -1;
@@ -257,21 +233,37 @@ int parsecmdline (int argc /** argument count */,
           (c = getopt_long(argc,argv,shortoptions,
                            longoptions, &option_index)) != -1)
     {
+       option_safe = FALSE;
+
        switch (c) {
+#ifdef HAVE_LIBPWMD
+       case 'C':
+           ctl->pwmd_socket = prependdir(optarg, currentwd);
+           break;
+       case 'G':
+           ctl->pwmd_file = xstrdup(optarg);
+           break;
+       case 'O':
+           rctl->pinentry_timeout = atoi(optarg);
+           break;
+#endif
        case 'V':
            versioninfo = TRUE;
+           option_safe = TRUE;
            break;
        case 'c':
            check_only = TRUE;
            break;
        case 's':
            outlevel = O_SILENT;
+           option_safe = 1;
            break;
        case 'v':
            if (outlevel >= O_VERBOSE)
                outlevel = O_DEBUG;
            else
                outlevel = O_VERBOSE;
+           option_safe = TRUE;
            break;
        case 'd':
            rctl->poll_interval = xatoi(optarg, &errflag);
@@ -329,8 +321,6 @@ int parsecmdline (int argc /** argument count */,
            /* XXX -- should probably use a table lookup here */
            if (strcasecmp(optarg,"auto") == 0)
                ctl->server.protocol = P_AUTO;
-           else if (strcasecmp(optarg,"pop2") == 0)
-               ctl->server.protocol = P_POP2;
 #ifdef SDPS_ENABLE
            else if (strcasecmp(optarg,"sdps") == 0)
            {
@@ -340,18 +330,12 @@ int parsecmdline (int argc /** argument count */,
 #endif /* SDPS_ENABLE */
            else if (strcasecmp(optarg,"pop3") == 0)
                ctl->server.protocol = P_POP3;
-           else if (strcasecmp(optarg,"apop") == 0)
-               ctl->server.protocol = P_APOP;
-           else if (strcasecmp(optarg,"rpop") == 0)
-               ctl->server.protocol = P_RPOP;
            else if (strcasecmp(optarg,"kpop") == 0)
            {
                ctl->server.protocol = P_POP3;
                ctl->server.service = xstrdup(KPOP_PORT);
 #ifdef KERBEROS_V5
                ctl->server.authenticate =  A_KERBEROS_V5;
-#else
-               ctl->server.authenticate =  A_KERBEROS_V4;
 #endif /* KERBEROS_V5 */
            }
            else if (strcasecmp(optarg,"imap") == 0)
@@ -366,7 +350,7 @@ int parsecmdline (int argc /** argument count */,
            }
            break;
        case 'U':
-           ctl->server.uidl = FLAG_TRUE;
+           /* EMPTY - removed in 7.0.0 */
            break;
        case LA_IDLE:
            ctl->idle = FLAG_TRUE;
@@ -377,16 +361,12 @@ int parsecmdline (int argc /** argument count */,
        case LA_AUTH:
            if (strcmp(optarg, "password") == 0)
                ctl->server.authenticate = A_PASSWORD;
-           else if (strcmp(optarg, "kerberos") == 0)
 #ifdef KERBEROS_V5
+           else if (strcmp(optarg, "kerberos") == 0)
                ctl->server.authenticate = A_KERBEROS_V5;
-#else
-               ctl->server.authenticate = A_KERBEROS_V4;
-#endif /* KERBEROS_V5 */
            else if (strcmp(optarg, "kerberos_v5") == 0)
                ctl->server.authenticate = A_KERBEROS_V5;
-           else if (strcmp(optarg, "kerberos_v4") == 0)
-               ctl->server.authenticate = A_KERBEROS_V4;
+#endif /* KERBEROS_V5 */
            else if (strcmp(optarg, "ssh") == 0)
                ctl->server.authenticate = A_SSH;
            else if (strcasecmp(optarg, "external") == 0)
@@ -407,6 +387,8 @@ int parsecmdline (int argc /** argument count */,
                ctl->server.authenticate = A_ANY;
            else if (strcmp(optarg, "msn") == 0)
                ctl->server.authenticate = A_MSN;
+           else if (strcmp(optarg, "apop") == 0)
+               ctl->server.authenticate = A_APOP;
            else {
                fprintf(stderr,GT_("Invalid authentication `%s' specified.\n"), optarg);
                errflag++;
@@ -594,6 +576,7 @@ int parsecmdline (int argc /** argument count */,
 
        case LA_CONFIGDUMP:
            configdump = TRUE;
+           option_safe = TRUE;
            break;
 
        case LA_SYSLOG:
@@ -608,10 +591,25 @@ int parsecmdline (int argc /** argument count */,
            ctl->server.tracepolls = FLAG_TRUE;
            break;
 
+       case LA_RETRIEVEERROR:
+           if (strcasecmp(optarg,"abort") == 0) {
+               ctl->server.retrieveerror = RE_ABORT;
+           } else if (strcasecmp(optarg,"continue") == 0) {
+               ctl->server.retrieveerror = RE_CONTINUE;
+           } else if (strcasecmp(optarg,"markseen") == 0) {
+               ctl->server.retrieveerror = RE_MARKSEEN;
+           } else {
+               fprintf(stderr,GT_("Invalid retrieve-error policy `%s' specified.\n"), optarg);
+               errflag++;
+           }
+           break;
+
        case '?':
+           helpflag = 1;
        default:
-           helpflag++;
+           break;
        }
+       *safewithbg &= option_safe;
     }
 
     if (errflag || ocount > 1 || helpflag) {
@@ -657,9 +655,16 @@ int parsecmdline (int argc /** argument count */,
        P(GT_("      --plugout     specify external command to open smtp connection\n"));
        P(GT_("      --bad-header {reject|accept}\n"
              "                    specify policy for handling messages with bad headers\n"));
+       P(GT_("      --retrieve-error {abort|continue|markseen}\n"
+              "                        specify policy for processing messages with retrieve errors\n"));
 
        P(GT_("  -p, --protocol    specify retrieval protocol (see man page)\n"));
-       P(GT_("  -U, --uidl        force the use of UIDLs (pop3 only)\n"));
+#ifdef HAVE_LIBPWMD
+        P(GT_("  -C, --pwmd-socket pwmd socket path (~/.pwmd/socket)\n"));
+        P(GT_("  -G, --pwmd-file   filename to use on the pwmd server\n"));
+        P(GT_("  -O, --pinentry-timeout   seconds until pinentry is canceled\n"));
+#endif
+
        P(GT_("      --port        TCP port to connect to (obsolete, use --service)\n"));
        P(GT_("  -P, --service     TCP service to connect to (can be numeric TCP port)\n"));
        P(GT_("      --auth        authentication type (password/kerberos/ssh/otp)\n"));
index 39e43347052eb58be6d726c309b02d382567f174..32835c57bcaf7f4feced2b27a4ee56a12d696c8c 100644 (file)
@@ -10,7 +10,6 @@ gssapi.c
 idle.c
 imap.c
 interface.c
-kerberos.c
 lock.c
 netrc.c
 odmr.c
diff --git a/pop2.c b/pop2.c
deleted file mode 100644 (file)
index 03d58a1..0000000
--- a/pop2.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * pop2.c -- POP2 protocol methods
- *
- * Copyright 1997 by Eric S. Raymond
- * For license terms, see the file COPYING in this directory.
- */
-
-#include  "config.h"
-
-#ifdef POP2_ENABLE
-#include  <stdio.h>
-#if defined(STDC_HEADERS)
-#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-#include  "fetchmail.h"
-#include  "socket.h"
-#include  "i18n.h"
-
-static int pound_arg, equal_arg;
-
-static int pop2_ok (int sock, char *argbuf)
-/* parse POP2 command response */
-{
-    int ok;
-    char buf [POPBUFSIZE+1];
-
-    pound_arg = equal_arg = -1;
-
-    if ((ok = gen_recv(sock, buf, sizeof(buf))) == 0)
-    {
-       if (buf[0] == '+')
-           ok = 0;
-       else if (buf[0] == '#')
-       {
-           pound_arg = atoi(buf+1);
-           ok = 0;
-       }
-       else if (buf[0] == '=')
-       {
-           equal_arg = atoi(buf+1);
-           ok = 0;
-       }
-       else if (buf[0] == '-')
-           ok = PS_ERROR;
-       else
-           ok = PS_PROTOCOL;
-
-       if (argbuf != NULL)
-           strcpy(argbuf,buf);
-    }
-
-    return(ok);
-}
-
-static int pop2_getauth(int sock, struct query *ctl, char *buf)
-/* apply for connection authorization */
-{
-    int status;
-
-    (void)buf;
-
-    if (ctl->sslproto && !strcasecmp(ctl->sslproto, "tls1") && !ctl->use_ssl)
-    {
-       report(stderr, GT_("POP2 does not support STLS. Giving up.\n"));
-       return PS_SOCKET;
-    }
-
-    if (ctl->server.authenticate != A_ANY && ctl->server.authenticate != A_PASSWORD)
-    {
-       report(stderr, GT_("POP2 only supports password authentication. Giving up.\n"));
-       return PS_AUTHFAIL;
-    }
-
-    strlcpy(shroud, ctl->password, sizeof(shroud));
-    status = gen_transact(sock,
-                 "HELO %s %s",
-                 ctl->remotename, ctl->password);
-    memset(shroud, 0x55, sizeof(shroud));
-    shroud[0] = '\0';
-    return status;
-}
-
-static int pop2_getrange(int sock, struct query *ctl, const char *folder, 
-                        int *countp, int *newp, int *bytes)
-/* get range of messages to be fetched */
-{
-    (void)ctl;
-
-    /* maybe the user wanted a non-default folder */
-    if (folder)
-    {
-       int     ok = gen_transact(sock, "FOLD %s", folder);
-
-       if (ok != 0)
-           return(ok);
-       if (pound_arg == -1)
-           return(PS_ERROR);
-    }
-    else
-       /*
-        * We should have picked up a count of messages in the user's
-        * default inbox from the pop2_getauth() response. 
-        *
-        * Note: this logic only works because there is no way to select
-        * both the unnamed folder and named folders within a single
-        * fetchmail run.  If that assumption ever becomes invalid, the
-        * pop2_getauth code will have to stash the pound response away
-        * explicitly in case it gets stepped on.
-        */
-       if (pound_arg == -1)
-           return(PS_ERROR);
-
-    *countp = pound_arg;
-    *bytes = *newp = -1;
-
-    return(0);
-}
-
-static int pop2_fetch(int sock, struct query *ctl, int number, int *lenp)
-/* request nth message */
-{
-    int        ok;
-
-    (void)ctl;
-    *lenp = 0;
-    ok = gen_transact(sock, "READ %d", number);
-    if (ok)
-       return(0);
-    *lenp = equal_arg;
-
-    gen_send(sock, "RETR");
-
-    return(ok);
-}
-
-static int pop2_trail(int sock, struct query *ctl, const char *tag)
-/* send acknowledgement for message data */
-{
-    (void)ctl;
-    (void)tag;
-    return(gen_transact(sock, ctl->keep ? "ACKS" : "ACKD"));
-}
-
-static int pop2_logout(int sock, struct query *ctl)
-/* send logout command */
-{
-    (void)ctl;
-    return(gen_transact(sock, "QUIT"));
-}
-
-static const struct method pop2 =
-{
-    "POP2",                            /* Post Office Protocol v2 */
-    "pop2",                            /* standard POP2 port */
-    "pop2",                            /* ssl POP2 port - not */
-    FALSE,                             /* this is not a tagged protocol */
-    FALSE,                             /* does not use message delimiter */
-    pop2_ok,                           /* parse command response */
-    pop2_getauth,                      /* get authorization */
-    pop2_getrange,                     /* query range of messages */
-    NULL,                              /* no way to get sizes */
-    NULL,                              /* no way to get sizes of subsets */
-    NULL,                              /* messages are always new */
-    pop2_fetch,                                /* request given message */
-    NULL,                              /* no way to fetch body alone */
-    pop2_trail,                                /* eat message trailer */
-    NULL,                              /* no POP2 delete method */
-    NULL,                              /* how to mark a message as seen */
-    NULL,                              /* how to end mailbox processing */
-    pop2_logout,                       /* log out, we're done */
-    FALSE                              /* no, we can't re-poll */
-};
-
-int doPOP2 (struct query *ctl)
-/* retrieve messages using POP2 */
-{
-    peek_capable = FALSE;
-    return(do_protocol(ctl, &pop2));
-}
-#endif /* POP2_ENABLE */
-
-/* pop2.c ends here */
diff --git a/pop3.c b/pop3.c
index 9cf8494416073967342ae4a5ad0cd1181d0f51b0..a84bbcc3aadb8740af1754eea454ea14abd6a394 100644 (file)
--- a/pop3.c
+++ b/pop3.c
 #include  <stdio.h>
 #include  <string.h>
 #include  <ctype.h>
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
-#if defined(STDC_HEADERS)
 #include  <stdlib.h>
-#endif
 #include  <errno.h>
 
 #include  "fetchmail.h"
 #include  "socket.h"
-#include  "i18n.h"
+#include  "gettext.h"
+#include  "uid_db.h"
 
 #ifdef OPIE_ENABLE
 #ifdef __cplusplus
@@ -45,9 +42,9 @@ flag done_capa = FALSE;
 #if defined(GSSAPI)
 flag has_gssapi = FALSE;
 #endif /* defined(GSSAPI) */
-#if defined(KERBEROS_V4) || defined(KERBEROS_V5)
+#if defined(KERBEROS_V5)
 flag has_kerberos = FALSE;
-#endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
+#endif /* defined(KERBEROS_V5) */
 static flag has_cram = FALSE;
 #ifdef OPIE_ENABLE
 flag has_otp = FALSE;
@@ -205,9 +202,9 @@ static int capa_probe(int sock)
 #if defined(GSSAPI)
     has_gssapi = FALSE;
 #endif /* defined(GSSAPI) */
-#if defined(KERBEROS_V4) || defined(KERBEROS_V5)
+#if defined(KERBEROS_V5)
     has_kerberos = FALSE;
-#endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
+#endif /* defined(KERBEROS_V5) */
     has_cram = FALSE;
 #ifdef OPIE_ENABLE
     has_otp = FALSE;
@@ -237,11 +234,6 @@ static int capa_probe(int sock)
                has_gssapi = TRUE;
 #endif /* defined(GSSAPI) */
 
-#if defined(KERBEROS_V4)
-           if (strstr(buffer, "KERBEROS_V4"))
-               has_kerberos = TRUE;
-#endif /* defined(KERBEROS_V4)  */
-
 #ifdef OPIE_ENABLE
            if (strstr(buffer, "X-OTP"))
                has_otp = TRUE;
@@ -267,15 +259,61 @@ static void set_peek_capable(struct query *ctl)
      * we have a means of reliably tracking which mail we need to
      * refetch should the connection abort in the middle.
      * fetchall forces RETR, as does keep without UIDL */
-    peek_capable = !ctl->fetchall && (!ctl->keep || ctl->server.uidl);
+    peek_capable = !ctl->fetchall;
+}
+
+static int do_apop(int sock, struct query *ctl, char *greeting)
+{
+    char *start, *end;
+
+    /* build MD5 digest from greeting timestamp + password */
+    /* find start of timestamp */
+    start = strchr(greeting, '<');
+    if (!start) {
+       report(stderr,
+               GT_("Required APOP timestamp not found in greeting\n"));
+       return PS_AUTHFAIL;
+    }
+
+    /* find end of timestamp */
+    end = strchr(start + 1, '>');
+
+    if (!end || end == start + 1) {
+       report(stderr,
+               GT_("Timestamp syntax error in greeting\n"));
+       return(PS_AUTHFAIL);
+    } else {
+       *++end = '\0';
+    }
+
+    /* SECURITY: 2007-03-17
+     * Strictly validating the presented challenge for RFC-822
+     * conformity (it must be a msg-id in terms of that standard) is
+     * supposed to make attacks against the MD5 implementation
+     * harder[1]
+     *
+     * [1] "Security vulnerability in APOP authentication",
+     *     Gaëtan Leurent, fetchmail-devel, 2007-03-17 */
+    if (!rfc822_valid_msgid((unsigned char *)start)) {
+       report(stderr,
+               GT_("Invalid APOP timestamp.\n"));
+       return PS_AUTHFAIL;
+    }
+
+    /* copy timestamp and password into digestion buffer */
+    char *msg = (char *)xmalloc((end-start+1) + strlen(ctl->password) + 1);
+    strcpy(msg,start);
+    strcat(msg,ctl->password);
+    strcpy((char *)ctl->digest, MD5Digest((unsigned char *)msg));
+    free(msg);
+
+    return gen_transact(sock, "APOP %s %s", ctl->remotename, (char *)ctl->digest);
 }
 
 static int pop3_getauth(int sock, struct query *ctl, char *greeting)
 /* apply for connection authorization */
 {
     int ok;
-    char *start,*end;
-    char *msg;
 #ifdef OPIE_ENABLE
     char *challenge;
 #endif /* OPIE_ENABLE */
@@ -287,9 +325,9 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
 #if defined(GSSAPI)
     has_gssapi = FALSE;
 #endif /* defined(GSSAPI) */
-#if defined(KERBEROS_V4) || defined(KERBEROS_V5)
+#if defined(KERBEROS_V5)
     has_kerberos = FALSE;
-#endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
+#endif /* defined(KERBEROS_V5) */
     has_cram = FALSE;
 #ifdef OPIE_ENABLE
     has_otp = FALSE;
@@ -343,8 +381,12 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
         ctl->server.sdps = TRUE;
 #endif /* SDPS_ENABLE */
 
+    /* this is a leftover from the times 6.3.X and older when APOP was a
+     * "protocol" (P_APOP) rather than an authenticator (A_APOP),
+     * however, the switch is still useful because we can break; after
+     * an authenticator failed. */
    switch (ctl->server.protocol) {
-    case P_POP3:
+   case P_POP3:
 #ifdef RPA_ENABLE
        /* XXX FIXME: AUTH probing (RFC1734) should become global */
        /* CompuServe POP3 Servers as of 990730 want AUTH first for RPA */
@@ -389,7 +431,6 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
         */
        if ((ctl->server.authenticate == A_ANY) ||
                (ctl->server.authenticate == A_GSSAPI) ||
-               (ctl->server.authenticate == A_KERBEROS_V4) ||
                (ctl->server.authenticate == A_KERBEROS_V5) ||
                (ctl->server.authenticate == A_OTP) ||
                (ctl->server.authenticate == A_CRAM_MD5) ||
@@ -501,22 +542,6 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
        /*
         * OK, we have an authentication type now.
         */
-#if defined(KERBEROS_V4)
-       /* 
-        * Servers doing KPOP have to go through a dummy login sequence
-        * rather than doing SASL.
-        */
-       if (has_kerberos &&
-           ctl->server.service && (strcmp(ctl->server.service, KPOP_PORT)!=0)
-           && (ctl->server.authenticate == A_KERBEROS_V4
-            || ctl->server.authenticate == A_KERBEROS_V5
-            || ctl->server.authenticate == A_ANY))
-       {
-           ok = do_rfc1731(sock, "AUTH", ctl->server.truename);
-           if (ok == PS_SUCCESS || ctl->server.authenticate != A_ANY)
-               break;
-       }
-#endif /* defined(KERBEROS_V4) || defined(KERBEROS_V5) */
 
 #if defined(GSSAPI)
        if (has_gssapi &&
@@ -542,31 +567,39 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
 #endif /* OPIE_ENABLE */
 
 #ifdef NTLM_ENABLE
-    /* MSN servers require the use of NTLM (MSN) authentication */
-    if (!strcasecmp(ctl->server.pollname, "pop3.email.msn.com") ||
-           ctl->server.authenticate == A_MSN)
-       return (do_pop3_ntlm(sock, ctl, 1) == 0) ? PS_SUCCESS : PS_AUTHFAIL;
-    if (ctl->server.authenticate == A_NTLM || (has_ntlm && ctl->server.authenticate == A_ANY)) {
-       ok = do_pop3_ntlm(sock, ctl, 0);
-        if (ok == 0 || ctl->server.authenticate != A_ANY)
-           break;
-    }
+       /* MSN servers require the use of NTLM (MSN) authentication */
+       if (!strcasecmp(ctl->server.pollname, "pop3.email.msn.com") ||
+               ctl->server.authenticate == A_MSN)
+           return (do_pop3_ntlm(sock, ctl, 1) == 0) ? PS_SUCCESS : PS_AUTHFAIL;
+       if (ctl->server.authenticate == A_NTLM || (has_ntlm && ctl->server.authenticate == A_ANY)) {
+           ok = do_pop3_ntlm(sock, ctl, 0);
+           if (ok == 0 || ctl->server.authenticate != A_ANY)
+               break;
+       }
 #else
-    if (ctl->server.authenticate == A_NTLM || ctl->server.authenticate == A_MSN)
-    {
-       report(stderr,
-          GT_("Required NTLM capability not compiled into fetchmail\n"));
-    }
+       if (ctl->server.authenticate == A_NTLM || ctl->server.authenticate == A_MSN)
+       {
+           report(stderr,
+                   GT_("Required NTLM capability not compiled into fetchmail\n"));
+       }
 #endif
 
-       if (ctl->server.authenticate == A_CRAM_MD5 || 
-           (has_cram && ctl->server.authenticate == A_ANY))
+       if (ctl->server.authenticate == A_CRAM_MD5 ||
+               (has_cram && ctl->server.authenticate == A_ANY))
        {
            ok = do_cram_md5(sock, "AUTH", ctl, NULL);
            if (ok == PS_SUCCESS || ctl->server.authenticate != A_ANY)
                break;
        }
 
+       if (ctl->server.authenticate == A_APOP
+                   || ctl->server.authenticate == A_ANY)
+       {
+           ok = do_apop(sock, ctl, greeting);
+           if (ok == PS_SUCCESS || ctl->server.authenticate != A_ANY)
+               break;
+       }
+
        /* ordinary validation, no one-time password or RPA */ 
        if ((ok = gen_transact(sock, "USER %s", ctl->remotename)))
            break;
@@ -603,7 +636,6 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
         * users switching *to* KPOP accidentally revealing their
         * password */
        if ((ctl->server.authenticate == A_ANY
-                   || ctl->server.authenticate == A_KERBEROS_V4
                    || ctl->server.authenticate == A_KERBEROS_V5)
                && (ctl->server.service != NULL
                    && strcmp(ctl->server.service, KPOP_PORT) == 0))
@@ -625,61 +657,6 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
        shroud[0] = '\0';
        break;
 
-    case P_APOP:
-       /* build MD5 digest from greeting timestamp + password */
-       /* find start of timestamp */
-       for (start = greeting;  *start != 0 && *start != '<';  start++)
-           continue;
-       if (*start == 0) {
-           report(stderr,
-                  GT_("Required APOP timestamp not found in greeting\n"));
-           return(PS_AUTHFAIL);
-       }
-
-       /* find end of timestamp */
-       for (end = start;  *end != 0  && *end != '>';  end++)
-           continue;
-       if (*end == 0 || end == start + 1) {
-           report(stderr, 
-                  GT_("Timestamp syntax error in greeting\n"));
-           return(PS_AUTHFAIL);
-       }
-       else
-           *++end = '\0';
-
-       /* SECURITY: 2007-03-17
-        * Strictly validating the presented challenge for RFC-822
-        * conformity (it must be a msg-id in terms of that standard) is
-        * supposed to make attacks against the MD5 implementation
-        * harder[1]
-        *
-        * [1] "Security vulnerability in APOP authentication",
-        *     Gaëtan Leurent, fetchmail-devel, 2007-03-17 */
-       if (!rfc822_valid_msgid((unsigned char *)start)) {
-           report(stderr,
-                   GT_("Invalid APOP timestamp.\n"));
-           return PS_AUTHFAIL;
-       }
-
-       /* copy timestamp and password into digestion buffer */
-       msg = (char *)xmalloc((end-start+1) + strlen(ctl->password) + 1);
-       strcpy(msg,start);
-       strcat(msg,ctl->password);
-       strcpy((char *)ctl->digest, MD5Digest((unsigned char *)msg));
-       free(msg);
-
-       ok = gen_transact(sock, "APOP %s %s", ctl->remotename, (char *)ctl->digest);
-       break;
-
-    case P_RPOP:
-       if ((ok = gen_transact(sock,"USER %s", ctl->remotename)) == 0) {
-           strlcpy(shroud, ctl->password, sizeof(shroud));
-           ok = gen_transact(sock, "RPOP %s", ctl->password);
-           memset(shroud, 0x55, sizeof(shroud));
-           shroud[0] = '\0';
-       }
-       break;
-
     default:
        report(stderr, GT_("Undefined protocol request in POP3_auth\n"));
        ok = PS_ERROR;
@@ -707,22 +684,6 @@ static int pop3_getauth(int sock, struct query *ctl, char *greeting)
        return(ok);
     }
 
-/* Disable the sleep. Based on patch by Brian Candler 2004-04-19/2004-11-08,
- * accepted by Matthias Andree.
- *
- * Rationale: the server must have locked the spool before returning +OK;
- * this sleep just wastes time and hence, for modem and GSM CSD users, money. */
-#ifdef WANT_BOGUS
-    /*
-     * Empirical experience shows some server/OS combinations
-     * may need a brief pause even after any lockfiles on the
-     * server are released, to give the server time to finish
-     * copying back very large mailfolders from the temp-file...
-     * this is only ever an issue with extremely large mailboxes.
-     */
-    sleep(3); /* to be _really_ safe, probably need sleep(5)! */
-#endif
-
     /* we're approved */
     return(PS_SUCCESS);
 }
@@ -733,39 +694,6 @@ static void trim(char *s) {
     s[0] = '\0';
 }
 
-/* XXX FIXME: using the Message-ID is unsafe, some messages (spam,
- * broken messages) do not have Message-ID headers, and messages without
- * those appear to break this code and cause fetchmail (at least version
- * 6.2.3) to not delete such messages properly after retrieval.
- * See Sourceforge Bug #780933.
- *
- * The other problem is that the TOP command itself is optional, too... */
-static int pop3_gettopid(int sock, int num , char *id, size_t idsize)
-{
-    int ok;
-    int got_it;
-    char buf [POPBUFSIZE+1];
-    snprintf(buf, sizeof(buf), "TOP %d 1", num);
-    if ((ok = gen_transact(sock, "%s", buf)) != 0)
-       return ok;
-    got_it = 0;
-    while (gen_recv(sock, buf, sizeof(buf)) == 0)
-    {
-       if (DOTLINE(buf))
-           break;
-       if (!got_it && 0 == strncasecmp("Message-Id:", buf, 11)) {
-           char *p = buf + 11;
-           got_it = 1;
-           p += strspn(p, POSIX_space);
-           strlcpy(id, p, idsize);
-           trim(id);
-       }
-    }
-    /* XXX FIXME: do not return success here if no Message-ID header was
-     * found. */
-    return 0;
-}
-
 /** Parse the UID response (leading +OK must have been
  * stripped off) in buf, store the number in gotnum, and store the ID
  * into the caller-provided buffer "id" of size "idsize".
@@ -815,26 +743,25 @@ static int pop3_fastuidl( int sock,  struct query *ctl, unsigned int count, int
     int ok;
     unsigned int first_nr, last_nr, try_nr;
     char id [IDLEN+1];
-    struct idlist *savep = NULL; /** pointer to cache save_str result, speeds up saves */
 
     first_nr = 0;
     last_nr = count + 1;
     while (first_nr < last_nr - 1)
     {
-       struct idlist   *newl;
+       struct uid_db_record *rec;
 
        try_nr = (first_nr + last_nr) / 2;
        if ((ok = pop3_getuidl(sock, try_nr, id, sizeof(id))) != 0)
            return ok;
-       if ((newl = str_in_list(&ctl->oldsaved, id, FALSE)))
+       if ((rec = find_uid_by_id(&ctl->oldsaved, id)))
        {
-           flag mark = newl->val.status.mark;
+           flag mark = rec->status;
            if (mark == UID_DELETED || mark == UID_EXPUNGED)
            {
                if (outlevel >= O_VERBOSE)
                    report(stderr, GT_("id=%s (num=%u) was deleted, but is still present!\n"), id, try_nr);
                /* just mark it as seen now! */
-               newl->val.status.mark = mark = UID_SEEN;
+               rec->status = mark = UID_SEEN;
            }
 
            /* narrow the search region! */
@@ -848,7 +775,7 @@ static int pop3_fastuidl( int sock,  struct query *ctl, unsigned int count, int
                first_nr = try_nr;
 
            /* save the number */
-           newl->val.status.num = try_nr;
+           set_uid_db_num(&ctl->oldsaved, rec, try_nr);
        }
        else
        {
@@ -857,8 +784,8 @@ static int pop3_fastuidl( int sock,  struct query *ctl, unsigned int count, int
            last_nr = try_nr;
 
            /* save it */
-           savep = save_str(savep ? &savep : &ctl->oldsaved, id, UID_UNSEEN);
-           savep->val.status.num = try_nr;
+           rec = uid_db_insert(&ctl->oldsaved, id, UID_UNSEEN);
+           set_uid_db_num(&ctl->oldsaved, rec, try_nr);
        }
     }
     if (outlevel >= O_DEBUG && last_nr <= count)
@@ -870,98 +797,6 @@ static int pop3_fastuidl( int sock,  struct query *ctl, unsigned int count, int
     return 0;
 }
 
-static int pop3_slowuidl( int sock,  struct query *ctl, int *countp, int *newp)
-{
-    /* XXX FIXME: this code is severely broken. A Cc:d mailing list
-     * message will arrive twice with the same Message-ID, so this
-     * slowuidl code will break. Same goes for messages without
-     * Message-ID headers at all. This code would best be removed. */
-    /* This approach tries to get the message headers from the
-     * remote hosts and compares the message-id to the already known
-     * ones:
-     *  + if the first message containes a new id, all messages on
-     *    the server will be new
-     *  + if the first is known, try to estimate the last known message
-     *    on the server and check. If this works you know the total number
-     *    of messages to get.
-     *  + Otherwise run a binary search to determine the last known message
-     */
-    int ok, nolinear = 0;
-    int first_nr, list_len, try_id, try_nr, add_id;
-    int num;
-    char id [IDLEN+1];
-
-    if ((ok = pop3_gettopid(sock, 1, id, sizeof(id))) != 0)
-       return ok;
-
-    if( ( first_nr = str_nr_in_list(&ctl->oldsaved, id) ) == -1 ) {
-       /* the first message is unknown -> all messages are new */
-       *newp = *countp;        
-       return 0;
-    }
-
-    /* check where we expect the latest known message */
-    list_len = count_list( &ctl->oldsaved );
-    try_id = list_len  - first_nr; /* -1 + 1 */
-    if( try_id > 1 ) {
-       if( try_id <= *countp ) {
-           if ((ok = pop3_gettopid(sock, try_id, id, sizeof(id))) != 0)
-               return ok;
-    
-           try_nr = str_nr_last_in_list(&ctl->oldsaved, id);
-       } else {
-           try_id = *countp+1;
-           try_nr = -1;
-       }
-       if( try_nr != list_len -1 ) {
-           /* some messages inbetween have been deleted... */
-           if( try_nr == -1 ) {
-               nolinear = 1;
-
-               for( add_id = 1<<30; add_id > try_id-1; add_id >>= 1 )
-                   ;
-               for( ; add_id; add_id >>= 1 ) {
-                   if( try_nr == -1 ) {
-                       if( try_id - add_id <= 1 ) {
-                           continue;
-                       }
-                       try_id -= add_id;
-                   } else 
-                       try_id += add_id;
-                   
-                   if ((ok = pop3_gettopid(sock, try_id, id, sizeof(id))) != 0)
-                       return ok;
-                   try_nr = str_nr_in_list(&ctl->oldsaved, id);
-               }
-               if( try_nr == -1 ) {
-                   try_id--;
-               }
-           } else {
-               report(stderr, 
-                      GT_("Messages inserted into list on server. Cannot handle this.\n"));
-               return -1;
-           }
-       } 
-    }
-    /* the first try_id messages are known -> copy them to the newsaved list */
-    for( num = first_nr; num < list_len; num++ )
-    {
-       struct idlist   *newl = save_str(&ctl->newsaved, 
-                               str_from_nr_list(&ctl->oldsaved, num),
-                               UID_UNSEEN);
-       newl->val.status.num = num - first_nr + 1;
-    }
-
-    if( nolinear ) {
-       free_str_list(&ctl->oldsaved);
-       ctl->oldsaved = 0;
-       last = try_id;
-    }
-
-    *newp = *countp - try_id;
-    return 0;
-}
-
 static int pop3_getrange(int sock, 
                         struct query *ctl,
                         const char *folder,
@@ -973,7 +808,7 @@ static int pop3_getrange(int sock,
 
     (void)folder;
     /* Ensure that the new list is properly empty */
-    ctl->newsaved = (struct idlist *)NULL;
+    clear_uid_db(&ctl->newsaved);
 
 #ifdef MBOX
     /* Alain Knaff suggests this, but it's not RFC standard */
@@ -994,20 +829,17 @@ static int pop3_getrange(int sock,
     } else
        return(ok);
 
-    /*
-     * Newer, RFC-1725/1939-conformant POP servers may not have the LAST
-     * command.  We work as hard as possible to hide this, but it makes
-     * counting new messages intrinsically quadratic in the worst case.
-     */
+    /* unless fetching all mail, get UID list (UIDL) */
     last = 0;
     *newp = -1;
-    /* if there are messages, and UIDL is desired, use UIDL
-     * also use UIDL if fetchall is unset */
-    if (*countp > 0 && (!ctl->fetchall || ctl->server.uidl))
+    if (*countp > 0)
     {
        int fastuidl;
        char id [IDLEN+1];
 
+       set_uid_db_num_pos_0(&ctl->oldsaved, *countp);
+       set_uid_db_num_pos_0(&ctl->newsaved, *countp);
+
        /* should we do fast uidl this time? */
        fastuidl = ctl->fastuidl;
        if (*countp > 7 &&              /* linear search is better if there are few mails! */
@@ -1023,23 +855,6 @@ static int pop3_getrange(int sock,
        else
            dofastuidl = 0;
 
-       if (!ctl->server.uidl) {
-           gen_send(sock, "LAST");
-           ok = pop3_ok(sock, buf);
-       } else
-           ok = 1;
-
-       if (ok == 0)
-       {
-           /* scan LAST reply */
-           if (sscanf(buf, "%d", &last) == 0)
-           {
-               report(stderr, GT_("protocol error\n"));
-               return(PS_ERROR);
-           }
-           *newp = (*countp - last);
-       }
-       else
        {
            /* do UIDL */
            if (dofastuidl)
@@ -1047,9 +862,7 @@ static int pop3_getrange(int sock,
            /* grab the mailbox's UID list */
            if (gen_transact(sock, "UIDL") != 0)
            {
-               /* don't worry, yet! do it the slow way */
-               if (pop3_slowuidl(sock, ctl, countp, newp))
-               {
+               if (!ctl->fetchall) {
                    report(stderr, GT_("protocol error while fetching UIDLs\n"));
                    return(PS_ERROR);
                }
@@ -1058,7 +871,6 @@ static int pop3_getrange(int sock,
            {
                /* UIDL worked - parse reply */
                unsigned long unum;
-               struct idlist *newl = NULL;
 
                *newp = 0;
                while (gen_recv(sock, buf, sizeof(buf)) == PS_SUCCESS)
@@ -1068,14 +880,13 @@ static int pop3_getrange(int sock,
 
                    if (parseuid(buf, &unum, id, sizeof(id)) == PS_SUCCESS)
                    {
-                       struct idlist   *old;
+                       struct uid_db_record    *old_rec, *new_rec;
 
-                       newl = save_str(newl ? &newl : &ctl->newsaved, id, UID_UNSEEN);
-                       newl->val.status.num = unum;
+                       new_rec = uid_db_insert(&ctl->newsaved, id, UID_UNSEEN);
 
-                       if ((old = str_in_list(&ctl->oldsaved, id, FALSE)))
+                       if ((old_rec = find_uid_by_id(&ctl->oldsaved, id)))
                        {
-                           flag mark = old->val.status.mark;
+                           flag mark = old_rec->status;
                            if (mark == UID_DELETED || mark == UID_EXPUNGED)
                            {
                                /* XXX FIXME: switch 3 occurrences from
@@ -1085,9 +896,9 @@ static int pop3_getrange(int sock,
                                if (outlevel >= O_VERBOSE)
                                    report(stderr, GT_("id=%s (num=%d) was deleted, but is still present!\n"), id, (int)unum);
                                /* just mark it as seen now! */
-                               old->val.status.mark = mark = UID_SEEN;
+                               old_rec->status = mark = UID_SEEN;
                            }
-                           newl->val.status.mark = mark;
+                           new_rec->status = mark;
                            if (mark == UID_UNSEEN)
                            {
                                (*newp)++;
@@ -1104,10 +915,17 @@ static int pop3_getrange(int sock,
                             * swap the lists (say, due to socket error),
                             * the same mail will not be downloaded again.
                             */
-                           old = save_str(&ctl->oldsaved, id, UID_UNSEEN);
+                           old_rec = uid_db_insert(&ctl->oldsaved, id, UID_UNSEEN);
+
+                       }
+                       /*
+                        * save the number if it will be needed later on
+                        * (messsage will either be fetched or deleted)
+                        */
+                       if (new_rec->status == UID_UNSEEN || ctl->flush) {
+                           set_uid_db_num(&ctl->oldsaved, old_rec, unum);
+                           set_uid_db_num(&ctl->newsaved, new_rec, unum);
                        }
-                       /* save the number */
-                       old->val.status.num = unum;
                    } else
                        return PS_ERROR;
                } /* multi-line loop for UIDL reply */
@@ -1176,8 +994,9 @@ static int pop3_getsizes(int sock, int count, int *sizes)
 static int pop3_is_old(int sock, struct query *ctl, int num)
 /* is the given message old? */
 {
-    struct idlist *newl;
-    if (!ctl->oldsaved)
+    struct uid_db_record *rec;
+
+    if (!uid_db_n_records(&ctl->oldsaved))
        return (num <= last);
     else if (dofastuidl)
     {
@@ -1187,56 +1006,33 @@ static int pop3_is_old(int sock, struct query *ctl, int num)
            return(TRUE);
 
        /* in fast uidl, we manipulate the old list only! */
-
-       if ((newl = id_find(&ctl->oldsaved, num)))
+       if ((rec = find_uid_by_num(&ctl->oldsaved, num)))
        {
            /* we already have the id! */
-           return(newl->val.status.mark != UID_UNSEEN);
+           return(rec->status != UID_UNSEEN);
        }
 
        /* get the uidl first! */
        if (pop3_getuidl(sock, num, id, sizeof(id)) != PS_SUCCESS)
            return(TRUE);
 
-       if ((newl = str_in_list(&ctl->oldsaved, id, FALSE))) {
+       if ((rec = find_uid_by_id(&ctl->oldsaved, id))) {
            /* we already have the id! */
-           newl->val.status.num = num;
-           return(newl->val.status.mark != UID_UNSEEN);
+           set_uid_db_num(&ctl->oldsaved, rec, num);
+           return(rec->status != UID_UNSEEN);
        }
 
        /* save it */
-       newl = save_str(&ctl->oldsaved, id, UID_UNSEEN);
-       newl->val.status.num = num;
+       rec = uid_db_insert(&ctl->oldsaved, id, UID_UNSEEN);
+       set_uid_db_num(&ctl->oldsaved, rec, num);
+
        return(FALSE);
+    } else {
+       rec = find_uid_by_num(&ctl->newsaved, num);
+       return !rec || rec->status != UID_UNSEEN;
     }
-    else
-        return ((newl = id_find(&ctl->newsaved, num)) != NULL &&
-           newl->val.status.mark != UID_UNSEEN);
 }
 
-#ifdef UNUSED
-/*
- * We could use this to fetch headers only as we do for IMAP.  The trouble 
- * is that there's no way to fetch the body only.  So the following RETR 
- * would have to re-fetch the header.  Enough messages have longer headers
- * than bodies to make this a net loss.
- */
-static int pop_fetch_headers(int sock, struct query *ctl,int number,int *lenp)
-/* request headers of nth message */
-{
-    int ok;
-    char buf[POPBUFSIZE+1];
-
-    gen_send(sock, "TOP %d 0", number);
-    if ((ok = pop3_ok(sock, buf)) != 0)
-       return(ok);
-
-    *lenp = -1;                /* we got sizes from the LIST response */
-
-    return(PS_SUCCESS);
-}
-#endif /* UNUSED */
-
 static int pop3_fetch(int sock, struct query *ctl, int number, int *lenp)
 /* request nth message */
 {
@@ -1330,28 +1126,31 @@ static int pop3_fetch(int sock, struct query *ctl, int number, int *lenp)
 static void mark_uid_seen(struct query *ctl, int number)
 /* Tell the UID code we've seen this. */
 {
-    struct idlist      *sdp;
+    struct uid_db_record *rec;
 
-    if ((sdp = id_find(&ctl->newsaved, number)))
-       sdp->val.status.mark = UID_SEEN;
+    if ((rec = find_uid_by_num(&ctl->newsaved, number)))
+       rec->status = UID_SEEN;
     /* mark it as seen in oldsaved also! In case, we do not swap the lists
      * (say, due to socket error), the same mail will not be downloaded
      * again.
      */
-    if ((sdp = id_find(&ctl->oldsaved, number)))
-       sdp->val.status.mark = UID_SEEN;
+    if ((rec = find_uid_by_num(&ctl->oldsaved, number)))
+       rec->status = UID_SEEN;
 }
 
 static int pop3_delete(int sock, struct query *ctl, int number)
 /* delete a given message */
 {
+    struct uid_db_record *rec;
     int ok;
     mark_uid_seen(ctl, number);
     /* actually, mark for deletion -- doesn't happen until QUIT time */
     ok = gen_transact(sock, "DELE %d", number);
     if (ok != PS_SUCCESS)
        return(ok);
-    delete_str(dofastuidl ? &ctl->oldsaved : &ctl->newsaved, number);
+
+    rec = find_uid_by_num(dofastuidl ? &ctl->oldsaved : &ctl->newsaved, number);
+    rec->status = UID_DELETED;
     return(PS_SUCCESS);
 }
 
@@ -1368,24 +1167,6 @@ static int pop3_logout(int sock, struct query *ctl)
 {
     int ok;
 
-#ifdef __UNUSED__
-    /*
-     * We used to do this in case the server marks messages deleted when seen.
-     * (Yes, this has been reported, in the MercuryP/NLM server.
-     * It's even legal under RFC 1939 (section 8) as a site policy.)
-     * It interacted badly with UIDL, though.  Thomas Zajic wrote:
-     * "Running 'fetchmail -F -v' and checking the logs, I found out
-     * that fetchmail did in fact flush my mailbox properly, but sent
-     * a RSET just before sending QUIT to log off.  This caused the
-     * POP3 server to undo/forget about the previous DELEs, resetting
-     * my mailbox to its original (ie.  unflushed) state. The
-     * ~/.fetchids file did get flushed though, so the next time
-     * fetchmail was run it saw all the old messages as new ones ..."
-     */
-     if (ctl->keep)
-       gen_transact(sock, "RSET");
-#endif /* __UNUSED__ */
-
     ok = gen_transact(sock, "QUIT");
     if (!ok)
        expunge_uids(ctl);
index c7e49fea6999c97e6a17982940f19a8255838937..7cbf12ed3c9beaedceb93cd161a85e192204b9f2 100644 (file)
@@ -5,13 +5,14 @@
  *
  * For license terms, see the file COPYING in this directory.
  */
-#include <string.h>
 
 #include "config.h"
 #include "fetchmail.h"
 #include "xmalloc.h"
 #include "rcfile_y.h"
 
+#include <string.h>
+
 int prc_lineno = 1;
 
 #ifdef LEXDEBUG
@@ -79,9 +80,8 @@ preauth(enticate)?    { SETSTATE(AUTH); return AUTHENTICATE; }
 auth(enticate)?        { SETSTATE(AUTH); return AUTHENTICATE; }
 any            { SETSTATE(0); yylval.proto = A_ANY; return AUTHTYPE;}
 gssapi         { SETSTATE(0); yylval.proto = A_GSSAPI; return AUTHTYPE;}
-kerberos(_v)?4 { SETSTATE(0); yylval.proto = A_KERBEROS_V4; return AUTHTYPE;}
 kerberos(_v)?5 { SETSTATE(0); yylval.proto = A_KERBEROS_V5; return AUTHTYPE;}
-kerberos       { SETSTATE(0); yylval.proto = A_KERBEROS_V4; return AUTHTYPE;}
+kerberos       { SETSTATE(0); yylval.proto = A_KERBEROS_V5; return AUTHTYPE;}
 ssh            { SETSTATE(0); yylval.proto = A_SSH; return AUTHTYPE;}
 external       { SETSTATE(0); yylval.proto = A_EXTERNAL; return AUTHTYPE;}
 (otp|opie)     { SETSTATE(0); yylval.proto = A_OTP; return AUTHTYPE;}
@@ -89,6 +89,7 @@ cram(-md5)?   { SETSTATE(0); yylval.proto = A_CRAM_MD5; return AUTHTYPE;}
 msn            { SETSTATE(0); yylval.proto = A_MSN; return AUTHTYPE;}
 ntlm           { SETSTATE(0); yylval.proto = A_NTLM; return AUTHTYPE;}
 <AUTH>password { SETSTATE(0); yylval.proto = A_PASSWORD; return AUTHTYPE;}
+apop           { SETSTATE(0); yylval.proto = A_APOP; return AUTHTYPE;}
 timeout                { return TIMEOUT;}
 envelope       { return ENVELOPE; }
 qvirtual       { return QVIRTUAL; }
@@ -98,8 +99,15 @@ esmtppassword        { return ESMTPPASSWORD; }
 bad-header     { return BADHEADER; }
 accept         { return ACCEPT; }
 reject         { return REJECT_; }
+retrieve-error { return RETRIEVEERROR; }
+abort          { return ABORT; }
+continue       { return CONTINUE; }
+markseen       { return MARKSEEN; }
 
 user(name)?    {SETSTATE(NAME); return USERNAME; }
+pwmd_socket    { return PWMD_SOCKET; }
+pwmd_file      { return PWMD_FILE; }
+pinentry_timeout       { return PINENTRY_TIMEOUT; }
 <INITIAL,NAME>pass(word)?      {SETSTATE(NAME); return PASSWORD; }
 folder(s)?     { return FOLDER; }
 smtp(host)?    { return SMTPHOST; }
@@ -188,14 +196,11 @@ options           {/* EMPTY */}
 [;:,]          {/* EMPTY */}
 
 (auto)|(AUTO)  { yylval.proto = P_AUTO;  return PROTO; }
-(pop2)|(POP2)  { yylval.proto = P_POP2;  return PROTO; }
-(sdps)|(SDPS)   { return SDPS; }
+(sdps)|(SDPS)  { return SDPS; }
 (pop3)|(POP3)  { yylval.proto = P_POP3;  return PROTO; }
 (imap)|(IMAP)  { yylval.proto = P_IMAP;  return PROTO; }
-(apop)|(APOP)   { yylval.proto = P_APOP;  return PROTO; }
-(rpop)|(RPOP)   { yylval.proto = P_RPOP;  return PROTO; }
-(etrn)|(ETRN)   { yylval.proto = P_ETRN;  return PROTO; }
-(odmr)|(ODMR)   { yylval.proto = P_ODMR;  return PROTO; }
+(etrn)|(ETRN)  { yylval.proto = P_ETRN;  return PROTO; }
+(odmr)|(ODMR)  { yylval.proto = P_ODMR;  return PROTO; }
 (kpop)|(KPOP)  { return KPOP; }
 
 (#.*)?\\?\n    { prc_lineno++; }   /* newline is ignored */
index 91de6146178f10fd7c6ea66cc6789fe3b8056cbc..39bb7a99c217e83adde71af8e09cf1d277df1240 100644 (file)
@@ -9,17 +9,11 @@
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/file.h>
-#if defined(HAVE_SYS_WAIT_H)
 #include <sys/wait.h>
-#endif
 #include <sys/stat.h>
 #include <errno.h>
-#if defined(STDC_HEADERS)
 #include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
 #include <string.h>
 
 #if defined(__CYGWIN__)
@@ -27,7 +21,7 @@
 #endif /* __CYGWIN__ */
 
 #include "fetchmail.h"
-#include "i18n.h"
+#include "gettext.h"
   
 /* parser reads these */
 char *rcfile;                  /* path name of rc file */
@@ -63,6 +57,7 @@ extern char * yytext;
 
 %token DEFAULTS POLL SKIP VIA AKA LOCALDOMAINS PROTOCOL
 %token AUTHENTICATE TIMEOUT KPOP SDPS ENVELOPE QVIRTUAL
+%token PINENTRY_TIMEOUT PWMD_SOCKET PWMD_FILE
 %token USERNAME PASSWORD FOLDER SMTPHOST FETCHDOMAINS MDA BSMTP LMTP
 %token SMTPADDRESS SMTPNAME SPAMRESPONSE PRECONNECT POSTCONNECT LIMIT WARNINGS
 %token INTERFACE MONITOR PLUGIN PLUGOUT
@@ -71,6 +66,7 @@ extern char * yytext;
 %token SET LOGFILE DAEMON SYSLOG IDFILE PIDFILE INVISIBLE POSTMASTER BOUNCEMAIL
 %token SPAMBOUNCE SOFTBOUNCE SHOWDOTS
 %token BADHEADER ACCEPT REJECT_
+%token RETRIEVEERROR ABORT CONTINUE MARKSEEN
 %token <proto> PROTO AUTHTYPE
 %token <sval>  STRING
 %token <number> NUMBER
@@ -116,6 +112,13 @@ statement  : SET LOGFILE optmap STRING     {run.logfile = prependdir ($4, rcfiledir);
                | SET NO INVISIBLE              {run.invisible = FALSE;}
                | SET SHOWDOTS                  {run.showdots = FLAG_TRUE;}
                | SET NO SHOWDOTS               {run.showdots = FLAG_FALSE;}
+               | SET PINENTRY_TIMEOUT optmap NUMBER {
+#ifdef HAVE_LIBPWMD
+                   run.pinentry_timeout = $4;
+#else
+                   yyerror(GT_("pwmd not enabled"));
+#endif
+                   }
 
 /* 
  * The way the next two productions are written depends on the fact that
@@ -154,14 +157,13 @@ serv_option       : AKA alias_list
                | PROTOCOL PROTO        {current.server.protocol = $2;}
                | PROTOCOL KPOP         {
                                            current.server.protocol = P_POP3;
-
-                                           if (current.server.authenticate == A_PASSWORD)
 #ifdef KERBEROS_V5
+                                           if (current.server.authenticate == A_PASSWORD)
                                                current.server.authenticate = A_KERBEROS_V5;
-#else
-                                               current.server.authenticate = A_KERBEROS_V4;
-#endif /* KERBEROS_V5 */
                                            current.server.service = KPOP_PORT;
+#else
+                                           yyerror(GT_("Kerberos not enabled."));
+#endif
                                        }
                | PRINCIPAL STRING      {current.server.principal = $2;}
                | ESMTPNAME STRING      {current.server.esmtp_name = $2;}
@@ -174,8 +176,8 @@ serv_option : AKA alias_list
                                            yyerror(GT_("SDPS not enabled."));
 #endif /* SDPS_ENABLE */
                                        }
-               | UIDL                  {current.server.uidl = FLAG_TRUE;}
-               | NO UIDL               {current.server.uidl  = FLAG_FALSE;}
+               | UIDL                  {/* EMPTY - removed in 7.0.0 */}
+               | NO UIDL               {/* EMPTY - removed in 7.0.0 */}
                | CHECKALIAS            {current.server.checkalias = FLAG_TRUE;}
                | NO CHECKALIAS         {current.server.checkalias  = FLAG_FALSE;}
                | SERVICE STRING        {
@@ -236,6 +238,9 @@ serv_option : AKA alias_list
                | NO TRACEPOLLS         {current.server.tracepolls = FLAG_FALSE;}
                | BADHEADER ACCEPT      {current.server.badheader = BHACCEPT;}
                | BADHEADER REJECT_     {current.server.badheader = BHREJECT;}
+               | RETRIEVEERROR ABORT   {current.server.retrieveerror = RE_ABORT;}
+               | RETRIEVEERROR CONTINUE {current.server.retrieveerror = RE_CONTINUE;}
+               | RETRIEVEERROR MARKSEEN {current.server.retrieveerror = RE_MARKSEEN;}
                ;
 
 userspecs      : user1opts             {record_current(); user_reset();}
@@ -373,6 +378,22 @@ user_option        : TO mapping_list HERE
                | EXPUNGE NUMBER        {current.expunge     = NUM_VALUE_IN($2);}
 
                | PROPERTIES STRING     {current.properties  = $2;}
+
+               | PWMD_SOCKET STRING    {
+#ifdef HAVE_LIBPWMD
+                   current.pwmd_socket = xstrdup($2);
+#else
+                   yyerror(GT_("pwmd not enabled"));
+#endif
+                                       }
+
+               | PWMD_FILE STRING      {
+#ifdef HAVE_LIBPWMD
+                   current.pwmd_file = xstrdup($2);
+#else
+                   yyerror(GT_("pwmd not enabled"));
+#endif
+                                       }
                ;
 %%
 
@@ -396,7 +417,6 @@ void yyerror (const char *s)
 int prc_filecheck(const char *pathname,
                  const flag securecheck /** shortcuts permission, filetype and uid tests if false */)
 {
-#ifndef __EMX__
     struct stat statbuf;
 
     errno = 0;
@@ -430,7 +450,6 @@ int prc_filecheck(const char *pathname,
        return(PS_IOERR);
     }
 
-#ifndef __BEOS__
 #ifdef __CYGWIN__
     if (cygwin_internal(CW_CHECK_NTSEC, pathname))
 #endif /* __CYGWIN__ */
@@ -440,18 +459,12 @@ int prc_filecheck(const char *pathname,
                pathname);
        return(PS_IOERR);
     }
-#endif /* __BEOS__ */
 
-#ifdef HAVE_GETEUID
     if (statbuf.st_uid != geteuid())
-#else
-    if (statbuf.st_uid != getuid())
-#endif /* HAVE_GETEUID */
     {
        fprintf(stderr, GT_("File %s must be owned by you.\n"), pathname);
        return(PS_IOERR);
     }
-#endif
     return(PS_SUCCESS);
 }
 
index 5d9abb73a8332bb48d0fc13dc4afd54494869016..b6101e406d7550c1b0be70c87a303344aea8e7cb 100644 (file)
--- a/report.c
+++ b/report.c
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
-#if defined(HAVE_SYSLOG)
 #include <syslog.h>
-#endif
-#include "i18n.h"
+#include "gettext.h"
 #include "fetchmail.h"
 
-#if defined(HAVE_VPRINTF) || defined(HAVE_DOPRNT) || defined(_LIBC) || defined(HAVE_STDARG_H)
-# if HAVE_STDARG_H
-#  include <stdarg.h>
-#  define VA_START(args, lastarg) va_start(args, lastarg)
-# else
-#  include <varargs.h>
-#  define VA_START(args, lastarg) va_start(args)
-# endif
-#else
-# define va_alist a1, a2, a3, a4, a5, a6, a7, a8
-# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
-#endif
+#include <stdarg.h>
 
 #define MALLOC(n)      xmalloc(n)      
 #define REALLOC(n,s)   xrealloc(n,s)   
@@ -48,42 +35,11 @@ static int partial_suppress_tag = 0;
 static unsigned unbuffered;
 static unsigned int use_syslog;
 
-#ifdef _LIBC
-/* In the GNU C library, there is a predefined variable for this.  */
-
-# define program_name program_invocation_name
-# include <errno.h>
-
-#else
-
-# if !HAVE_STRERROR && !defined(strerror)
-char *strerror (int errnum)
-{
-    extern char *sys_errlist[];
-    extern int sys_nerr;
-
-    if (errnum > 0 && errnum <= sys_nerr)
-       return sys_errlist[errnum];
-    return GT_("Unknown system error");
-}
-# endif        /* HAVE_STRERROR */
-#endif /* _LIBC */
-
 /* Print the program name and error message MESSAGE, which is a printf-style
    format string with optional args. */
-/* VARARGS */
-void
-#ifdef HAVE_STDARG_H
-report (FILE *errfp, const char *message, ...)
-#else
-report (FILE *errfp, message, va_alist)
-     const char *message;
-     va_dcl
-#endif
+void report(FILE *errfp, const char *message, ...)
 {
-#ifdef VA_START
     va_list args;
-#endif
 
     /* If a partially built message exists, print it now so it's not lost.  */
     if (partial_message_size_used != 0)
@@ -92,14 +48,11 @@ report (FILE *errfp, message, va_alist)
        report (errfp, GT_("%s (log message incomplete)\n"), partial_message);
     }
 
-#if defined(HAVE_SYSLOG)
     if (use_syslog)
     {
        int priority;
 
-#ifdef VA_START
-       VA_START (args, message);
-#endif
+       va_start (args, message);
        priority = (errfp == stderr) ? LOG_ERR : LOG_INFO;
 
 #ifdef HAVE_VSYSLOG
@@ -118,12 +71,9 @@ report (FILE *errfp, message, va_alist)
        }
 #endif
 
-#ifdef VA_START
        va_end(args);
-#endif
     }
     else /* i. e. not using syslog */
-#endif
     {
        if ( *message == '\n' )
        {
@@ -134,17 +84,9 @@ report (FILE *errfp, message, va_alist)
                fprintf (errfp, "%s: ", program_name);
        partial_suppress_tag = 0;
 
-#ifdef VA_START
-       VA_START (args, message);
-# if defined(HAVE_VPRINTF) || defined(_LIBC)
+       va_start (args, message);
        vfprintf (errfp, message, args);
-# else
-       _doprnt (message, args, errfp);
-# endif
        va_end (args);
-#else
-       fprintf (errfp, message, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
        fflush (errfp);
     }
 }
@@ -168,12 +110,10 @@ void report_init(int mode /** 0: regular output, 1: unbuffered output, -1: syslo
        use_syslog = FALSE;
        break;
 
-#ifdef HAVE_SYSLOG
     case -1:                   /* syslogd */
        unbuffered = FALSE;
        use_syslog = TRUE;
        break;
-#endif /* HAVE_SYSLOG */
     }
 }
 
@@ -203,7 +143,6 @@ static void rep_ensuresize(void) {
        }
 }
 
-#ifdef HAVE_STDARG_H
 static void report_vbuild(const char *message, va_list args)
 {
     int n;
@@ -232,50 +171,16 @@ static void report_vbuild(const char *message, va_list args)
        partial_message = (char *)REALLOC (partial_message, partial_message_size);
     }
 }
-#endif
 
-void
-#ifdef HAVE_STDARG_H
-report_build (FILE *errfp, const char *message, ...)
-#else
-report_build (FILE *errfp, message, va_alist)
-     const char *message;
-     va_dcl
-#endif
+void report_build (FILE *errfp, const char *message, ...)
 {
-#ifdef VA_START
     va_list args;
-#else
-    int n;
-#endif
 
     rep_ensuresize();
 
-#if defined(VA_START)
-    VA_START(args, message);
+    va_start(args, message);
     report_vbuild(message, args);
     va_end(args);
-#else
-    for ( ; ; )
-    {
-       n = snprintf (partial_message + partial_message_size_used,
-                     partial_message_size - partial_message_size_used,
-                     message, a1, a2, a3, a4, a5, a6, a7, a8);
-
-       /* output error, f. i. EILSEQ */
-       if (n < 0) break;
-
-       if (n >= 0
-           && (unsigned)n < partial_message_size - partial_message_size_used)
-        {
-           partial_message_size_used += n;
-           break;
-       }
-
-       partial_message_size += 2048;
-       partial_message = REALLOC (partial_message, partial_message_size);
-    }
-#endif
 
     if (unbuffered && partial_message_size_used != 0)
     {
@@ -299,28 +204,15 @@ void report_flush(FILE *errfp)
    be empty.)  The completed report message is then printed (and reset to
    empty.) */
 /* VARARGS */
-void
-#ifdef HAVE_STDARG_H
-report_complete (FILE *errfp, const char *message, ...)
-#else
-report_complete (FILE *errfp, message, va_alist)
-     const char *message;
-     va_dcl
-#endif
+void report_complete (FILE *errfp, const char *message, ...)
 {
-#ifdef VA_START
     va_list args;
-#endif
 
     rep_ensuresize();
 
-#if defined(VA_START)
-    VA_START(args, message);
+    va_start(args, message);
     report_vbuild(message, args);
     va_end(args);
-#else
-    report_build(errfp, message, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
 
     /* Finally... print it.  */
     partial_message_size_used = 0;
@@ -339,22 +231,10 @@ report_complete (FILE *errfp, message, va_alist)
 static int error_one_per_line;
 
 /* If errnum is nonzero, print its corresponding system error message. */
-void
-#ifdef HAVE_STDARG_H
-report_at_line (FILE *errfp, int errnum, const char *file_name,
+void report_at_line (FILE *errfp, int errnum, const char *file_name,
               unsigned int line_number, const char *message, ...)
-#else
-report_at_line (FILE *errfp, errnum, file_name, line_number, message, va_alist)
-     int errnum;
-     const char *file_name;
-     unsigned int line_number;
-     const char *message;
-     va_dcl
-#endif
 {
-#ifdef VA_START
     va_list args;
-#endif
 
     if (error_one_per_line)
     {
@@ -381,17 +261,9 @@ report_at_line (FILE *errfp, errnum, file_name, line_number, message, va_alist)
     if (file_name != NULL)
        fprintf (errfp, "%s:%u: ", file_name, line_number);
 
-#ifdef VA_START
-    VA_START (args, message);
-# if defined(HAVE_VPRINTF) || defined(_LIBC)
+    va_start (args, message);
     vfprintf (errfp, message, args);
-# else
-    _doprnt (message, args, errfp);
-# endif
     va_end (args);
-#else
-    fprintf (errfp, message, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
 
     if (errnum)
        fprintf (errfp, ": %s", strerror (errnum));
index 15b88f05ef476312af280de1d2ec7183ed4768db..4efba8349eb6a79c494cae0d95aa54e9b72fb7dc 100644 (file)
--- a/rfc822.c
+++ b/rfc822.c
@@ -20,7 +20,11 @@ MIT license.  Compile with -DMAIN to build the demonstrator.
 
 ******************************************************************************/
 
+#define _XOPEN_SOURCE 600
+#define __BSD_VISIBLE 1
+
 #include "config.h"
+#include "fetchmail.h"
 
 #include  <stdio.h>
 #include  <ctype.h>
@@ -28,11 +32,10 @@ MIT license.  Compile with -DMAIN to build the demonstrator.
 #include  <strings.h>
 #include  <stdlib.h>
 
-#include "fetchmail.h"
 #include "sdump.h"
 
 #ifndef MAIN
-#include "i18n.h"
+#include "gettext.h"
 #else
 #include  <unistd.h>
 static int verbose;
diff --git a/rpa.c b/rpa.c
index c365f0ded8b2338ed9a1b2792557c4d0da07b209..3f236ce945c40f56154aa9e75fc033b62e2519ef 100644 (file)
--- a/rpa.c
+++ b/rpa.c
@@ -26,7 +26,7 @@
 #include  "socket.h"
 #include  "fetchmail.h"
 #include  "fm_md5.h"
-#include  "i18n.h"
+#include  "gettext.h"
 
 #ifdef TESTMODE
 extern unsigned char line1[];
@@ -36,23 +36,21 @@ extern unsigned char line3[];
 extern int linecount;
 #endif
 
-#ifndef NO_PROTO
-  /* prototypes for internal functions */
-  static int  POP3_rpa_resp(char* argbuf, int socket );
-  static void LenAppend(char** pptr, int len);
-  static int  LenSkip(char** pptr, int rxlen);
-  static int  DecBase64(char* bufp);
-  static void EncBase64(char* bufp, int len);
-  static void ToUnicode(char** pptr, char delim, unsigned char* buf, int* plen,
+/* prototypes for internal functions */
+static int  POP3_rpa_resp(char* argbuf, int socket );
+static void LenAppend(char** pptr, int len);
+static int  LenSkip(char** pptr, int rxlen);
+static int  DecBase64(char* bufp);
+static void EncBase64(char* bufp, int len);
+static void ToUnicode(char** pptr, char delim, unsigned char* buf, int* plen,
                        int conv);
-  static int  SetRealmService(char* bufp);
-  static void GenChallenge(unsigned char* buf, int len);
-  static int  DigestPassphrase(char* passphrase,
+static int  SetRealmService(char* bufp);
+static void GenChallenge(unsigned char* buf, int len);
+static int  DigestPassphrase(char* passphrase,
                               unsigned char* rbuf, int unicodeit);
-  static void CompUserResp(void);
-  static int  CheckUserAuth(void);
-  static void md5(const void* in, int len, unsigned char* out);
-#endif
+static void CompUserResp(void);
+static int  CheckUserAuth(void);
+static void md5(const void* in, int len, unsigned char* out);
 
 /* RPA protocol definitions */
 
index 0a12c640446b35dfa42e8e1405367db85784be84..a775c9c93f2562070be1d4a5da2bb07145b25c28 100644 (file)
@@ -7,19 +7,15 @@
  */
 #include "fetchmail.h"
 #include "getaddrinfo.h"
-#include "i18n.h"
+#include "gettext.h"
 
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
 #include <netdb.h>
-#if defined(HAVE_NETINET_IN_H)
 #include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
 #include <arpa/inet.h>
-#endif
 #include <sys/socket.h>
 
 int servport(const char *service) {
diff --git a/sink.c b/sink.c
index 5d92556f01d5435ef1d9e1d847521a4b50d6b350..5e9bef9864eb80f6ae3bac880a33b582be8a1e55 100644 (file)
--- a/sink.c
+++ b/sink.c
 #include  <errno.h>
 #include  <string.h>
 #include  <signal.h>
-#ifdef HAVE_MEMORY_H
-#include  <memory.h>
-#endif /* HAVE_MEMORY_H */
-#if defined(STDC_HEADERS)
 #include  <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
 #include  <unistd.h>
-#endif
-#if defined(HAVE_STDARG_H)
 #include  <stdarg.h>
-#else
-#include  <varargs.h>
-#endif
 #include  <ctype.h>
 #include  <langinfo.h>
 
@@ -42,7 +31,7 @@
 
 #include  "socket.h"
 #include  "smtp.h"
-#include  "i18n.h"
+#include  "gettext.h"
 
 /* BSD portability hack...I know, this is an ugly place to put it */
 #if !defined(SIGCHLD) && defined(SIGCLD)
@@ -444,18 +433,6 @@ static int handle_smtp_report(struct query *ctl, struct msgblk *msg)
 
     responses[0] = xstrdup(smtp_response);
 
-#ifdef __UNUSED__
-    /*
-     * Don't do this!  It can really mess you up if, for example, you're
-     * reporting an error with a single RCPT TO address among several;
-     * RSET discards the message body and it doesn't get sent to the
-     * valid recipients.
-     */
-    smtp_rset(ctl);    /* stay on the safe side */
-    if (outlevel >= O_DEBUG)
-       report(stdout, GT_("Saved error is still %d\n"), smtperr);
-#endif /* __UNUSED */
-
     /*
      * Note: send_bouncemail message strings are not made subject
      * to gettext translation because (a) they're going to be 
@@ -532,12 +509,6 @@ static int handle_smtp_report(struct query *ctl, struct msgblk *msg)
         * (b) we wouldn't want spammers to get confirmation that
         * this address is live, anyway.
         */
-#ifdef __DONT_FEED_THE_SPAMMERS__
-       if (run.bouncemail)
-           send_bouncemail(ctl, msg, XMIT_ACCEPT,
-                       "Invalid address in MAIL FROM (SMTP error 553).\r\n", 
-                       1, responses);
-#endif /* __DONT_FEED_THE_SPAMMERS__ */
        free(responses[0]);
        return(PS_REFUSED);
 
@@ -616,10 +587,7 @@ static int handle_smtp_report_without_bounce(struct query *ctl, struct msgblk *m
        return(PS_REFUSED);
 
     case 553: /* invalid sending domain */
-#ifdef __DONT_FEED_THE_SPAMMERS__
-       if (run.bouncemail)
-           return(PS_SUCCESS);
-#endif /* __DONT_FEED_THE_SPAMMERS__ */
+       /* do not send bounce mail - it would feed spammers */
        return(PS_REFUSED);
 
     default:
@@ -1096,9 +1064,7 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg,
              int *good_addresses, int *bad_addresses)
 /* open a stream to a local MDA */
 {
-#ifdef HAVE_SETEUID
     uid_t orig_uid;
-#endif /* HAVE_SETEUID */
     struct     idlist *idp;
     int        length = 0, fromlen = 0, nameslen = 0;
     char       *names = NULL, *before, *after, *from = NULL;
@@ -1184,6 +1150,16 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg,
        for (dp = after, sp = before; (*dp = *sp); dp++, sp++) {
            if (sp[0] != '%')   continue;
 
+           if (sp > before && sp[-1] == '\'') {
+               report(stderr, GT_("MDA option contains single-quoted %%%c expansion.\n"), sp[1]);
+               report(stderr, GT_("Refusing to deliver. Check the manual and fix your mda option.\n"));
+               free(before);
+               free(after);
+               if (from) free(from);
+               if (names) free(names);
+               return PS_SYNTAX;
+           }
+
            /* need to expand? BTW, no here overflow, because in
            ** the worst case (end of string) sp[1] == '\0' */
            if (sp[1] == 's' || sp[1] == 'T') {
@@ -1221,7 +1197,6 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg,
     if (outlevel >= O_DEBUG)
        report(stdout, GT_("about to deliver with: %s\n"), before);
 
-#ifdef HAVE_SETEUID
     /*
      * Arrange to run with user's permissions if we're root.
      * This will initialize the ownership of any files the
@@ -1233,19 +1208,16 @@ static int open_mda_sink(struct query *ctl, struct msgblk *msg,
        report(stderr, GT_("Cannot switch effective user id to %ld: %s\n"), (long)ctl->uid, strerror(errno));
        return PS_IOERR;
     }
-#endif /* HAVE_SETEUID */
 
     sinkfp = popen(before, "w");
     free(before);
     before = NULL;
 
-#ifdef HAVE_SETEUID
     /* this will fail quietly if we didn't start as root */
     if (seteuid(orig_uid)) {
        report(stderr, GT_("Cannot switch effective user id back to original %ld: %s\n"), (long)orig_uid, strerror(errno));
        return PS_IOERR;
     }
-#endif /* HAVE_SETEUID */
 
     if (!sinkfp)
     {
@@ -1576,15 +1548,7 @@ int open_warning_by_mail(struct query *ctl)
 /* if rfc2047charset is non-NULL, encode the line (that is assumed to be
  * a header line) as per RFC-2047 using rfc2047charset as the character
  * set field */
-#if defined(HAVE_STDARG_H)
 void stuff_warning(const char *rfc2047charset, struct query *ctl, const char *fmt, ... )
-#else
-void stuff_warning(rfc2047charset, ctl, fmt, va_alist)
-const char *charset;
-struct query *ctl;
-const char *fmt;       /* printf-style format */
-va_dcl
-#endif
 {
     /* make huge -- i18n can bulk up error messages a lot */
     char       buf[2*MSGBUFSIZE+4];
@@ -1596,11 +1560,7 @@ va_dcl
      * case it was a string constant.  We make a virtue of that necessity
      * here by supporting stdargs/varargs.
      */
-#if defined(HAVE_STDARG_H)
     va_start(ap, fmt) ;
-#else
-    va_start(ap);
-#endif
     vsnprintf(buf, sizeof(buf) - 2, fmt, ap);
     va_end(ap);
 
@@ -1621,4 +1581,18 @@ void close_warning_by_mail(struct query *ctl, struct msgblk *msg)
     close_sink(ctl, msg, TRUE);
 }
 
+void abort_message_sink(struct query *ctl)
+/*
+ * Forcibly close the SMTP connection and re-open.
+ *
+ * Used to abort message delivery once the DATA command has been issued.
+ * Required because all text after the DATA command is considered to be
+ * part of the message body (it is impossible to issue an SMTP command
+ * to abort message delivery once the DATA command has been issued).
+ */
+{
+  smtp_close(ctl, 0);
+  smtp_setup(ctl);
+}
+
 /* sink.c ends here */
index ad14707ff7bd4cc30384eec5e5507f86cff95f8a..2714064cbf0bf4239b1659f87dc4334cf6a17755 100644 (file)
@@ -26,6 +26,7 @@ extern int DEBUGLEVEL;
 
 #include <unistd.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <string.h>
 #include <ctype.h>
 #include "smbbyteorder.h"
@@ -33,10 +34,6 @@ extern int DEBUGLEVEL;
 #include "smbencrypt.h"
 #include "smbmd4.h"
 
-#ifndef _AIX
-typedef unsigned char uchar;
-typedef signed short int16;
-#endif
 typedef int BOOL;
 #define False 0
 #define True  1
@@ -65,12 +62,6 @@ static size_t skip_multibyte_char(char c)
     return 0;
 }
 
-
-/*******************************************************************
-safe string copy into a known length string. maxlength does not
-include the terminating zero.
-********************************************************************/
-
 static void strupper(char *s)
 {
 while (*s)
@@ -89,7 +80,7 @@ while (*s)
   }
 }
 
-extern void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
+extern void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8, unsigned char p24[24]);
 
 /*
  This implements the X/Open SMB password encryption
@@ -97,9 +88,9 @@ extern void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]);
  encrypted password into p24 
  */
 
-void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
+void SMBencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
   {
-  uchar p14[15], p21[21];
+  unsigned char p14[15], p21[21];
   
   memset(p21,'\0',21);
   memset(p14,'\0',14);
@@ -119,7 +110,7 @@ void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
   }
 
 /* Routines for Windows NT MD4 Hash functions. */
-static int _my_wcslen(int16 *str)
+static int _my_wcslen(int16_t *str)
 {
        int len = 0;
        while(*str++ != 0)
@@ -134,10 +125,10 @@ static int _my_wcslen(int16 *str)
  * format.
  */
  
-static int _my_mbstowcs(int16 *dst, uchar *src, int len)
+static int _my_mbstowcs(int16_t *dst, unsigned char *src, int len)
 {
        int i;
-       int16 val;
+       int16_t val;
  
        for(i = 0; i < len; i++) {
                val = *src;
@@ -154,10 +145,10 @@ static int _my_mbstowcs(int16 *dst, uchar *src, int len)
  * Creates the MD4 Hash of the users password in NT UNICODE.
  */
  
-static void E_md4hash(uchar *passwd, uchar *p16)
+static void E_md4hash(unsigned char *passwd, unsigned char *p16)
 {
        int len;
-       int16 wpwd[129];
+       int16_t wpwd[129];
        
        /* Password cannot be longer than 128 characters */
        len = strlen((char *)passwd);
@@ -167,15 +158,15 @@ static void E_md4hash(uchar *passwd, uchar *p16)
        _my_mbstowcs(wpwd, passwd, len);
        wpwd[len] = 0; /* Ensure string is null terminated */
        /* Calculate length in bytes */
-       len = _my_wcslen(wpwd) * sizeof(int16);
+       len = _my_wcslen(wpwd) * sizeof(int16_t);
 
        mdfour(p16, (unsigned char *)wpwd, len);
 }
 
 /* Does the des encryption from the NT or LM MD4 hash. */
-void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24])
+void SMBOWFencrypt(unsigned char passwd[16], unsigned char *c8, unsigned char p24[24])
 {
-       uchar p21[21];
+       unsigned char p21[21];
  
        memset(p21,'\0',21);
  
@@ -184,10 +175,9 @@ void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24])
 }
 
 /* Does the NT MD4 hash then des encryption. */
-void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
+void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
 {
-       uchar p21[21];
+       unsigned char p21[21];
  
        memset(p21,'\0',21);
  
@@ -201,43 +191,3 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
        dump_data(100, (char *)p24, 24);
 #endif
 }
-
-#if 0
-
-BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode)
-{
-       int new_pw_len = strlen(passwd) * (unicode ? 2 : 1);
-
-       if (new_pw_len > 512)
-       {
-               DEBUG(0,("make_oem_passwd_hash: new password is too long.\n"));
-               return False;
-       }
-
-       /*
-        * Now setup the data area.
-        * We need to generate a random fill
-        * for this area to make it harder to
-        * decrypt. JRA.
-        */
-       generate_random_buffer((unsigned char *)data, 516, False);
-       if (unicode)
-       {
-               struni2( &data[512 - new_pw_len], passwd);
-       }
-       else
-       {
-               fstrcpy( &data[512 - new_pw_len], passwd);
-       }
-       SIVAL(data, 512, new_pw_len);
-
-#ifdef DEBUG_PASSWORD
-       DEBUG(100,("make_oem_passwd_hash\n"));
-       dump_data(100, data, 516);
-#endif
-       SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True);
-
-       return True;
-}
-
-#endif
diff --git a/smtp.c b/smtp.c
index 1c99c69675917cbbda7c2e1f6ebf9e91faf8946c..d831249243192b401831e4ce1ed7f93a0ce0f560 100644 (file)
--- a/smtp.c
+++ b/smtp.c
@@ -18,7 +18,7 @@
 #include <signal.h>
 #include "socket.h"
 #include "smtp.h"
-#include "i18n.h"
+#include "gettext.h"
 
 struct opt
 {
index 634b4760b87d0ffa106620e62a436967a50d1ea8..daa291d37f97badb24917d5f4136eb21b8811cd7 100644 (file)
--- a/socket.c
+++ b/socket.c
 #include <errno.h>
 #include <string.h>
 #include <ctype.h> /* isspace() */
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif /* HAVE_MEMORY_H */
 #include <sys/types.h>
 #include <sys/stat.h>
-#ifndef HAVE_NET_SOCKET_H
 #include <sys/socket.h>
-#else
-#include <net/socket.h>
-#endif
 #include <sys/un.h>
 #include <netinet/in.h>
-#ifdef HAVE_ARPA_INET_H
 #include <arpa/inet.h>
-#endif
 #include <netdb.h>
-#if defined(STDC_HEADERS)
 #include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
-#if defined(HAVE_STDARG_H)
 #include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-#  include <sys/time.h>
-# else
-#  include <time.h>
-# endif
-#endif
+#include <sys/time.h>
+#include <time.h>
 
 #include "socket.h"
 #include "fetchmail.h"
 #include "getaddrinfo.h"
-#include "i18n.h"
+#include "gettext.h"
 #include "sdump.h"
 
-/* Defines to allow BeOS and Cygwin to play nice... */
-#ifdef __BEOS__
-static char peeked;
-#define fm_close(a)  closesocket(a)
-#define fm_write(a,b,c)  send(a,b,c,0)
-#define fm_peek(a,b,c)   recv(a,b,c,0)
-#define fm_read(a,b,c)   recv(a,b,c,0)
-#else
-#define fm_close(a)  close(a)
+/* Defines to allow Cygwin to play nice... */
+#define fm_close(a)     close(a)
 #define fm_write(a,b,c)  write(a,b,c)
 #define fm_peek(a,b,c)   recv(a,b,c, MSG_PEEK)
+
 #ifdef __CYGWIN__
 #define fm_read(a,b,c)   cygwin_read(a,b,c)
 static ssize_t cygwin_read(int sock, void *buf, size_t count);
 #else /* ! __CYGWIN__ */
 #define fm_read(a,b,c)   read(a,b,c)
 #endif /* __CYGWIN__ */
-#endif
 
 /* We need to define h_errno only if it is not already */
 #ifndef h_errno
@@ -80,7 +48,6 @@ extern int h_errno;
 # endif
 #endif /* ndef h_errno */
 
-#ifdef HAVE_SOCKETPAIR
 static char *const *parse_plugin(const char *plugin, const char *host, const char *service)
 {
        char **argvec;
@@ -134,6 +101,7 @@ static char *const *parse_plugin(const char *plugin, const char *host, const cha
        if (!argvec)
        {
                report(stderr, GT_("fetchmail: malloc failed\n"));
+               free(plugin_copy);
                return NULL;
        }
        memset(argvec, 0, s);
@@ -198,7 +166,6 @@ static int handle_plugin(const char *host,
     (void) close(fds[0]);
     return fds[1];
 }
-#endif /* HAVE_SOCKETPAIR */
 
 /** Set socket to SO_KEEPALIVE. \return 0 for success. */
 int SockKeepalive(int sock) {
@@ -221,7 +188,7 @@ int UnixOpen(const char *path)
        return -1;
     }
 
-    /* Socket opened saved. Usefull if connect timeout 
+    /* Socket opened saved. Useful if connect timeout
      * because it can be closed.
      */
     mailserver_socket_temp = sock;
@@ -249,10 +216,8 @@ int SockOpen(const char *host, const char *service,
     int ord;
     char errbuf[8192] = "";
 
-#ifdef HAVE_SOCKETPAIR
     if (plugin)
        return handle_plugin(host,service,plugin);
-#endif /* HAVE_SOCKETPAIR */
 
     memset(&req, 0, sizeof(struct addrinfo));
     req.ai_socktype = SOCK_STREAM;
@@ -343,32 +308,19 @@ int SockOpen(const char *host, const char *service,
     return i;
 }
 
-
-#if defined(HAVE_STDARG_H)
 int SockPrintf(int sock, const char* format, ...)
 {
-#else
-int SockPrintf(sock,format,va_alist)
-int sock;
-char *format;
-va_dcl {
-#endif
-
     va_list ap;
     char buf[8192];
 
-#if defined(HAVE_STDARG_H)
     va_start(ap, format) ;
-#else
-    va_start(ap);
-#endif
     vsnprintf(buf, sizeof(buf), format, ap);
     va_end(ap);
     return SockWrite(sock, buf, strlen(buf));
-
 }
 
 #ifdef SSL_ENABLE
+#define OPENSSL_NO_SSL_INTERN 1
 #include <openssl/ssl.h>
 #include <openssl/err.h>
 #include <openssl/pem.h>
@@ -415,14 +367,6 @@ int SockRead(int sock, char *buf, int len)
 
     if (--len < 1)
        return(-1);
-#ifdef __BEOS__
-    if (peeked != 0){
-        (*bp) = peeked;
-        bp++;
-        len--;
-        peeked = 0;
-    }
-#endif        
     do {
        /* 
         * The reason for these gymnastics is that we want two things:
@@ -485,18 +429,12 @@ int SockRead(int sock, char *buf, int len)
 #endif /* SSL_ENABLE */
        {
 
-#ifdef __BEOS__
-           if ((n = fm_read(sock, bp, 1)) <= 0)
-#else
            if ((n = fm_peek(sock, bp, len)) <= 0)
-#endif
                return (-1);
            if ((newline = (char *)memchr(bp, '\n', n)) != NULL)
                n = newline - bp + 1;
-#ifndef __BEOS__
            if ((n = fm_read(sock, bp, n)) == -1)
                return(-1);
-#endif /* __BEOS__ */
        }
        bp += n;
        len -= n;
@@ -551,9 +489,6 @@ int SockPeek(int sock)
        if (n == -1)
                return -1;
 
-#ifdef __BEOS__
-    peeked = ch;
-#endif
     return(ch);
 }
 
@@ -900,13 +835,7 @@ int SSLOpen(int sock, char *mycert, char *mykey, const char *myproto, int certck
                return(-1);
        }
 
-       {
-           char *tmp = getenv("FETCHMAIL_DISABLE_CBC_IV_COUNTERMEASURE");
-           if (tmp == NULL || *tmp == '\0' || strspn(tmp, " \t") == strlen(tmp))
-               sslopts &= ~ SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
-       }
-
-       SSL_CTX_set_options(_ctx[sock], sslopts);
+       SSL_CTX_set_options(_ctx[sock], (SSL_OP_ALL | SSL_OP_NO_SSLv2) & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS);
 
        if (certck) {
                SSL_CTX_set_verify(_ctx[sock], SSL_VERIFY_PEER, SSL_ck_verify_callback);
index 0c4ac001d219505555857c736eafdb9e93e0095a..9d9406d958c4eae21dfe3d901807dce816bcf4bf 100644 (file)
--- a/socket.h
+++ b/socket.h
 struct addrinfo;
 
 #include <config.h>
-#ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
-#elif HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
 #include <netdb.h>
 
 /** Create a new client socket; returns -1 on error */
 int SockOpen(const char *host, const char *service, const char *plugin, struct addrinfo **);
 
-
 /** 
 Get a string terminated by an '\n' (matches interface of fgets).
 Pass it a valid socket, a buffer for the string, and
@@ -41,7 +36,7 @@ Returns number of bytes successfully written.
 int SockWrite(int sock, const char *buf, int size);
 
 /* from /usr/include/sys/cdefs.h */
-#if !defined __GNUC__ || __GNUC__ < 2
+#if !defined __GNUC__
 # define __attribute__(xyz)    /* Ignore. */
 #endif
 
@@ -49,13 +44,9 @@ int SockWrite(int sock, const char *buf, int size);
 Send formatted output to the socket (matches interface of fprintf).
 Returns number of bytes successfully written.
 */
-#if defined(HAVE_STDARG_H)
 int SockPrintf(int sock, const char *format, ...)
     __attribute__ ((format (printf, 2, 3)))
     ;
-#else
-int SockPrintf();
-#endif
  
 /**
 Close a socket previously opened by SockOpen.  This allows for some
index 7aa0fa80430515369575cbd4eb657d08ce10653c..85a5fd2f623fd317236ab281d38bc4afee971205 100755 (executable)
@@ -57,9 +57,9 @@ Summary(da):  Alsidig POP/IMAP post-afhentnings dæmon
 Summary(de):   Program zum Abholen von E-Mail via POP/IMAP
 Summary(es):   Recolector de correo via POP/IMAP
 Summary(fr):   Daemon de récupération de courrier électronique POP/IMAP complet
-Summary(pl):   Zdalny demon pocztowy do protokołów POP2, POP3, APOP, IMAP
+Summary(pl):   Zdalny demon pocztowy do protokołów POP3, APOP, IMAP
 Summary(pt):   Busca mensagens de um servidor usando POP ou IMAP
-Summary(tr):   POP2, POP3, APOP, IMAP protokolleri ile uzaktan mektup alma yazılımı
+Summary(tr):   POP3, APOP, IMAP protokolleri ile uzaktan mektup alma yazılımı
 Summary(vi):   trình nền lấy thư POP/IMAP có tính năng đầy đủ
 BuildRoot: %{_tmppath}/%{name}-root
 #Keywords: mail, client, POP3, APOP, KPOP, IMAP, ETRN, ODMR, SMTP, ESMTP, GSSAPI, RPA, NTLM, CRAM-MD5, SASL
diff --git a/strcasecmp.c b/strcasecmp.c
deleted file mode 100644 (file)
index 76ab9be..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/* 
- * scratch implementation of strcasecmp(), 
- * in case your C library doesn't have it 
- *
- * For license terms, see the file COPYING in this directory.
- */
-#include <ctype.h>
-
-int strcasecmp(char *s1, char *s2)
-{
-    while (toupper((unsigned char)*s1) == toupper((unsigned char)*s2++))
-       if (*s1++ == '\0')
-           return 0;
-    return(toupper((unsigned char)*s1) - toupper((unsigned char)*--s2));
-}
-
-int strncasecmp(char *s1, char *s2, register int n)
-{
-    while (--n >= 0 && toupper((unsigned char)*s1) == toupper((unsigned char)*s2++))
-       if (*s1++ == '\0')
-           return 0;
-    return(n < 0 ? 0 : toupper((unsigned char)*s1) - toupper((unsigned char)*--s2));
-}
index 22428d6829a893886a5dec60a785afcf105aa7e8..0af16670e01eb25b2b399bc373de131b3736951f 100644 (file)
--- a/strlcat.c
+++ b/strlcat.c
@@ -17,6 +17,9 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include "config.h"
+#include "fetchmail.h"
+
 #include <sys/types.h>
 #include <assert.h>
 #include <string.h>
index 5963dfe323f998a059f8a81d04c1a8414ff6ee12..c9f0ef2b27b09021cc701866bc85f7770d1d1594 100644 (file)
--- a/strlcpy.c
+++ b/strlcpy.c
@@ -17,6 +17,9 @@
  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include "config.h"
+#include "fetchmail.h"
+
 #include <sys/types.h>
 #include <assert.h>
 #include <string.h>
diff --git a/strstr.c b/strstr.c
deleted file mode 100644 (file)
index b2deeae..0000000
--- a/strstr.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * strstr -- locate first occurence of a substring 
- *
- * Locates the first occurrence in the string pointed to by S1 of the string
- * pointed to by S2.  Returns a pointer to the substring found, or a NULL
- * pointer if not found.  If S2 points to a string with zero length, the
- * function returns S1. 
- *
- * For license terms, see the file COPYING in this directory.
- */
-
-char *strstr(register char *buf, register char *sub)
-{
-    register char *bp;
-
-    if (!*sub)
-       return buf;
-    for (;;)
-    {
-       if (!*buf)
-           break;
-       bp = buf;
-       for (;;)
-       {
-           if (!*sub)
-               return buf;
-           if (*bp++ != *sub++)
-               break;
-       }
-       sub -= (unsigned long) bp;
-       sub += (unsigned long) buf;
-       buf += 1;
-    }
-    return 0;
-}
-
diff --git a/tls.c b/tls.c
index c66a4f55fd395e8607e8a42c62a5b6d16bf5f50e..62539f91f24ff4f452e2674e3b778da22df1867f 100644 (file)
--- a/tls.c
+++ b/tls.c
@@ -5,9 +5,7 @@
 
 #include "fetchmail.h"
 
-#ifdef HAVE_STRINGS_H
 #include <strings.h>
-#endif
 
 /** return true if user allowed TLS */
 int maybe_tls(struct query *ctl) {
index ec8013a516f03d1f66f83bf4af37a65e25ce0708..2b8d04f8ec15e8b5256d90f2aa5545954340d722 100644 (file)
@@ -9,31 +9,17 @@
 #include  <stdio.h>
 #include  <string.h>
 #include  <ctype.h>
-#ifdef HAVE_MEMORY_H
-#include  <memory.h>
-#endif /* HAVE_MEMORY_H */
-#if defined(STDC_HEADERS)
 #include  <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
 #include <unistd.h>
-#endif
-#if defined(HAVE_STDARG_H)
 #include  <stdarg.h>
-#else
-#include  <varargs.h>
-#endif
 #include <limits.h>
 #include <assert.h>
 
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
 #include <sys/socket.h>
 #include <netdb.h>
 #include "fm_md5.h"
 
-#include "i18n.h"
+#include "gettext.h"
 #include "socket.h"
 #include "fetchmail.h"
 
@@ -688,15 +674,6 @@ eoh:
         * We will just check if the first message in the mailbox has an
         * X-IMAP: header.
         */
-#ifdef POP2_ENABLE
-       /*
-        * We disable this check under POP2 because there's no way to
-        * prevent deletion of the message.  So at least we ought to
-        * forward it to the user so he or she will have some clue
-        * that things have gone awry.
-        */
-       if (servport("pop2") != servport(protocol->service))
-#endif /* POP2_ENABLE */
            if (num == 1 && !strncasecmp(line, "X-IMAP:", 7)) {
                free(line);
                retain_mail = 1;
@@ -889,24 +866,6 @@ eoh:
        else if (!strncasecmp("Resent-Sender:", line, 14) && (strchr(line, '@') || strchr(line, '!')))
            resent_sender_offs = (line - msgblk.headers);
 
-#ifdef __UNUSED__
-       else if (!strncasecmp("Message-Id:", line, 11))
-       {
-           if (ctl->server.uidl)
-           {
-               char id[IDLEN+1];
-
-               line[IDLEN+12] = 0;             /* prevent stack overflow */
-               sscanf(line+12, "%s", id);
-               if (!str_find( &ctl->newsaved, num))
-               {
-                   struct idlist *newl = save_str(&ctl->newsaved,id,UID_SEEN);
-                   newl->val.status.num = num;
-               }
-           }
-       }
-#endif /* __UNUSED__ */
-
        /* if multidrop is on, gather addressee headers */
        if (MULTIDROP(ctl))
        {
@@ -1383,6 +1342,28 @@ process_headers:
        return PS_SOCKET;
 }
 
+/** Convenience function factored out from readbody(): 
+ * send buffer \a buf via stuffline() and handle errors and progress.
+ * Store return value in \a *n, and return PS_IOERR for failure or
+ * PS_SUCCESS otherwise. */
+static int rb_send(struct query *ctl, char *buf, int *n)
+{
+    *n = stuffline(ctl, buf);
+
+    if (*n < 0)
+    {
+       report(stdout, GT_("error writing message text\n"));
+       release_sink(ctl);
+       return(PS_IOERR);
+    }
+    else if (want_progress())
+    {
+       fputc('*', stdout);
+       fflush(stdout);
+    }
+    return PS_SUCCESS;
+}
+
 int readbody(int sock, struct query *ctl, flag forward, int len)
 /** read and dispose of a message body presented on \a sock */
 /** \param ctl         query control record */
@@ -1478,7 +1459,7 @@ int readbody(int sock, struct query *ctl, flag forward, int len)
        /* ship out the text line */
        if (forward && (!issoftline))
        {
-           int n;
+           int n, err;
            inbufp = buf;
 
            /* guard against very long lines */
@@ -1486,22 +1467,31 @@ int readbody(int sock, struct query *ctl, flag forward, int len)
            buf[MSGBUFSIZE+2] = '\n';
            buf[MSGBUFSIZE+3] = '\0';
 
-           n = stuffline(ctl, buf);
-
-           if (n < 0)
-           {
-               report(stdout, GT_("error writing message text\n"));
-               release_sink(ctl);
-               return(PS_IOERR);
-           }
-           else if (want_progress())
-           {
-               fputc('*', stdout);
-               fflush(stdout);
-           }
+           err = rb_send(ctl, buf, &n);
+           if (err != PS_SUCCESS)
+               return err;
        }
     }
 
+    /* Flush buffer -- bug introduced by ESR on 1998-03-20 before
+     * release 4.4.1 when ESR did not sufficiently audit Henrik
+     * Storner's patch.
+     * Trouble reported in June 2011 by Lars Hecking, with
+     * text/html quoted-printable messages generated by
+     * Outlook/Exchange that got mutilated by fetchmail.
+     */
+    if (forward && issoftline)
+    {
+       int n;
+
+       /* force proper line termination */
+       inbufp[0] = '\r';
+       inbufp[1] = '\n';
+       inbufp[2] = '\0';
+
+       return rb_send(ctl, buf, &n);
+    }
+
     return(PS_SUCCESS);
 }
 
@@ -1532,15 +1522,10 @@ static void enshroud(char *buf)
     }
 }
 
-#if defined(HAVE_STDARG_H)
 /** assemble command in printf(3) style and send to the server */
-void gen_send(int sock, const char *fmt, ... )
-#else
-void gen_send(sock, fmt, va_alist)
-int sock;              /** socket to which server is connected */
-const char *fmt;       /** printf-style format */
-va_dcl
-#endif
+void gen_send(int sock/** socket to which server is connected */,
+             const char *fmt /** printf-style format */,
+             ...)
 {
     char buf [MSGBUFSIZE+1];
     va_list ap;
@@ -1550,11 +1535,7 @@ va_dcl
     else
        buf[0] = '\0';
 
-#if defined(HAVE_STDARG_H)
     va_start(ap, fmt);
-#else
-    va_start(ap);
-#endif
     vsnprintf(buf + strlen(buf), sizeof(buf)-2-strlen(buf), fmt, ap);
     va_end(ap);
 
@@ -1732,15 +1713,10 @@ int gen_recv_split(int sock  /** socket to which server is connected */,
 }
 /** @} */
 
-#if defined(HAVE_STDARG_H)
-int gen_transact(int sock, const char *fmt, ... )
-#else
-int gen_transact(int sock, fmt, va_alist)
-int sock;              /** socket to which server is connected */
-const char *fmt;       /** printf-style format */
-va_dcl
-#endif
 /** assemble command in printf(3) style, send to server, fetch a response */
+int gen_transact(int sock       /** socket to which server is connected */,
+                const char *fmt /** printf-style format */,
+                ...)
 {
     int ok;
     char buf [MSGBUFSIZE+1];
@@ -1754,11 +1730,7 @@ va_dcl
     else
        buf[0] = '\0';
 
-#if defined(HAVE_STDARG_H)
     va_start(ap, fmt) ;
-#else
-    va_start(ap);
-#endif
     vsnprintf(buf + strlen(buf), sizeof(buf)-2-strlen(buf), fmt, ap);
     va_end(ap);
 
diff --git a/trio/CHANGES b/trio/CHANGES
deleted file mode 100644 (file)
index fec2926..0000000
+++ /dev/null
@@ -1,785 +0,0 @@
-CHANGES -- trio
-
-
-The changes listed without a name attributed to them were most likely done by
-Bjorn Reese and/or Daniel Stenberg.
-
-Version 1.14 - 2010/01/26
--------------------------
-* David Byron
-  Added trio_xstring_append_max.
-
-* Fixed compilation problem on Cygwin due to lack of long double math
-  (reported by Matthias Andree).
-
-* David Boyce
-  Added #undef of standard stdio function names before assigning trio functions
-  to them.
-
-* Matthias Andree
-  Upgraded configure.in to use new macros instead of obsoleted macros.
-
-* Matthias Andree
-  Added VPATH to Makefile.in
-
-* Tom Honermann
-  Fixed problem with subnormal numbers which caused an infinite loop outputting
-  leading spaces.
-
-* Adam McLaurin
-  Improved parsing performance by avoiding memset() and memcpy() on character
-  arrays.
-
-* Gideon Smeding
-  Fixed %u scanning of signed numbers.
-
-* Gideon Smeding
-  Fixed group scanning for non-matching input.
-
-* Fixed missing undo of look-ahead reading for scanf functions. This does only
-  work for the scanf* and fscanf* functions, not dscanf* and cscanf* functions
-  (reported by Gideon Smeding).
-
-* If the format string is empty, scanf does not attempt to read any input.
-
-* Ralf Junker
-  Fixed Borland compilation for user-defined specifiers.
-
-
-Version 1.13 - 2008/11/09
--------------------------
-* Ives Aerts
-  Added the $<format|skip> format for user-defined specifiers, which is
-  compatible with compiler warnings about mismatches between specifiers and
-  arguments.
-
-* Added TRIO_DEPRECATED flag (reported by David Boyce)
-
-* Fixed rounding adjustment for long double (reported as bug item #2136686).
-
-* Added Makefile dependency for test target (reported as bug item #2136636).
-
-* David Boyce
-  Fixed long long support for MSVC.
-
-* Fixed potential problem with read after buffer end for non-zero terminated
-  strings (reported as bug item #1828465).
-
-* Andreas Stricker
-  Added WinCE support.
-
-* Fixed number of significant digits for %g.
-
-
-Version 1.12 - 2006/10/22
--------------------------
-* Fixed scanning of floats (reported by Bernd Ahlers).
-
-* Fixed configure.in for GCC on Tru64 and MIPSpro on IRIX (reported by Andreas
-  Maus).
-
-* Olli Savia
-  Added support for LynxOS.
-
-
-Version 1.11 - 2006/04/08
--------------------------
-* Mark Pickelmann
-  Fixed trio_unregister. If the first element was removed, the remaining
-  list would be removed as well.
-
-* Fixed unintended formatting of %e that would result in non-zero numbers
-  starting with zero (reported by Mark Pickelmann and Gisli Ottarsson).
-
-* Fixed compilation with Sun Workshop 6 (reported by Matthias Andree).
-
-* Fixed accuracy for denormalized numbers (bug item #758327).
-
-* Glen Davidson
-  Fixed scanning of floating-point numbers without a decimal-point (bug item
-  #1370427).
-
-* David Byron
-  Fixed more compiler warnings.
-
-* Fixed compilation of trio_to_long_double and TRIO_FEATURE_FLOAT (reported by
-  David Byron).
-
-* Fixed precision of large floating-point numbers (bug item #1314524).
-
-* Karl Bochert
-  Fixed trio_fpclassify_and_signbit to only restore the floating-point
-  precision.
-
-* Fixed detection of need for ieee option on FreeBSD/Alpha.
-
-* Added TRIO_SNPRINTF_ONLY compilation.
-
-* Fixed trio_to_double by not using strtod() on Tru64/DECC because it does not
-  support hex-floats.
-
-* Fixed crash on 64 bits machines related to a previous workaround in version
-  1.9 for uninitialized va_list (reported by Nicolai Tufar, suggestion by
-  Douglas Gwyn).
-
-* Patrick Jessee
-  Fixed width calculation for %g.
-
-* Added macros for internal features.
-
-* Jon Foster
-  Added macros for conditional compilation of many features. Documented all
-  the features.
-
-* Karl Bochert
-  Fixed problem with Borland C++, which changes the floating-point precision
-  for certain math functions (log10() and _fpclass()).
-
-* Karl Bochert
-  Fixed compilation warnings on Borland C++.
-
-* Removed any occurrence of #elif because Borland C++ reports wrong line
-  numbers when they are present (reported by Karl Bochert).
-
-* David Byron
-  Added trio_asprintfv.
-
-* Brian Chapman
-  Fixed Mac OS X compilation.
-
-* David Byron
-  Fixed several compiler warnings.
-
-* Fixed printing of out-of-range arguments for %hhd and %hd. These arguments
-  can be out of range because of default integer promotion.
-
-* Bob Friesenhahn
-  Fixed installation of header files.
-
-* Joe Orton
-  Added SHELL to Makefile.in to avoid problems with CShells.
-
-* Shaun Tancheff
-  Fixed regresion tests for MSVC.
-
-* Craig Berry
-  Fixed the VMS C99 workaround.
-
-
-Version 1.10 - 2003/03/06
--------------------------
-* Rearranged some include files to accommodate large file support (reported by
-  Albert Chin-A-Young).
-
-* Added support for SunOS 4.1.x lack of strerror, tolower, and toupper
-  (reported by Peter McCluskey).
-
-* Fixed pedantic compilation with TRIO_MINIMAL.
-
-* Jose Kahan
-  Moved <limits.h> to avoid redefinition problems.
-
-* Fixed hex-float exponents (reported by Matthias Clasen).
-
-* Fixed handling of negative width and precision via paramters (reported by
-  Jacob Navia).
-
-* Nigel Hall
-  Fixed TRIO_VA_START for VMS.
-
-* Rune Enggaard Lausen
-  Fixed compilation for Borland C++ Builder.
-
-* Fixed precision of hex-float numbers (reported by James Antill).
-
-* Fixed plus sign only to be added for signed numbers.
-
-* Fixed printing of integers with value and precision of zero (reported by
-  James Antill).
-
-* Fixed %#.o to only print one zero if the value is zero (reported by James
-  Antill).
-
-* Rewrote check for IEEE compilation option to remove dependency on additional
-  scripts.
-
-* Mehdi Lavasani
-  Makefile install target fixed to work with older install programs.
-
-* Collapsed the DECC, MSVC, HP-UX, and AIX code for trio_fpclassify_and_sign()
-  with further preprocessing.
-
-
-Version 1.9 - 2002/10/13
-------------------------
-* Fixed trio_fpclassify_and_signbit on AIX 3.2
-
-* Added configure check for -ieee/-mieee compilation option for Alpha machines.
-
-* Craig Berry
-  Fixed compilation on VMS.
-
-* Albert Chin-A-Young
-  Fixed incorrect conditional expression in trio_isinf.
-
-* Fixed the warnings about uninitialized va_list in the printfv and scanfv
-  family without the use of compiler specific pragmas (suggested by Ian
-  Pilcher).
-
-* Fixed space flag for floating-point numbers (reported by Ian Main).
-
-
-Version 1.8 - 2002/07/10
-------------------------
-* Fixed infinite loop in multibyte handling (reported by Gisli Ottarsson).
-
-* Added the customizable cprintf/cscanf family which enables to user to specify
-  input and output stream functions (suggested by Florian Schulze).
-
-* Fixed trio_isinf by removing the HP-UX workaround, and instead making sure
-  that the C99 macro will adhere to the trio return values (reported by Luke
-  Dunstan).
-
-* Alexander Lukyanov
-  Fixed boundary case for scanning and EOF.
-
-* Jacob Navia
-  Enabled the L modifier for formatting.
-
-* Added TRIO_MINIMAL to build trio without the string functions.
-
-* Added the R modifier to print rounded floating-point numbers.
-
-* Added trio_to_long_double and long double scanning (the L modifier).
-
-* Added trio_locale_decimal_point, trio_locale_thousand_separator,
-  trio_locale_grouping to overwrite locale settings.
-
-* Rewrote TrioWriteDouble to avoid temporary buffers and thus the danger of
-  buffer overflows (for instance %.5000f).
-
-* Improved floating-point formatting accuracy.
-
-* Fixed formatting of non-decimal exponents.
-
-* Fixed thousand separator checking.
-
-* Fixed %f scanning to get a float and %lf to get a double.
-
-* Fixed WIN32 compilation (reported by Emmanuel Mogenet)
-
-* Fixed regression test cases to exclude disabled features.
-
-
-Version 1.7 - 2002/05/07
-------------------------
-* Fixed trio_to_double to handle hex-floats properly.
-
-* Fixed printing of %a-format to be like %e, not like %g.
-
-* Fixed floating-point printing of values beyond the machine accuracy.
-
-* Fixed %f for printing with large precision.
-
-* Fixed the usage of C99 nan(), which caused a crash on OSF/1 (reported by
-  Georg Bolz)
-
-* Joe Orton
-  Fixed %p on 64-bit platforms.
-
-* Made trio compile with K&R compilers.
-
-* Emmanuel Mogenet
-  Fixed bug in trio_asprintf.
-
-* Emmanuel Mogenet
-  Various WIN32 fixes.
-
-* Joe Orton
-  Fixed trio_isinf() on HP-UX, and added test cases.
-
-* Joe Orton
-  Fixed non-portable use of $^ in Makefile.
-
-* Joe Orton
-  Added autoconf.
-
-* Alexander Lukyanov
-  Fixed a number of bugs in the scanning of EOF and the count specifier.
-
-* Richard Jinks
-  Added trio_nzero
-
-* Fixed incorrect handling of return code from TrioReadChar (reported by
-  Henrik Löf)
-
-* Fixed parsing of character class expressions.
-
-* Fixed trio_to_double which did not work with long fractions.
-
-* Fixed %f for printing of large numbers.
-
-* Fixed %#s to handle whitespaces as non-printable characters.
-
-* Added trio_isfinite, trio_signbit, and trio_fpclassify.
-
-* Added new test cases.
-
-
-Version 1.6 - 2002/01/13
-------------------------
-* Added dynamic string functions.
-
-* Rewrote and extended documentation in JavaDoc (using Doxygen).
-
-* Moved and renamed strio functions to triostr.
-
-* Robert Collins
-  Added definition for Cygwin.
-
-* Markus Henke
-  Added long double workaround for the HP C/iX compiler.
-
-* Marc Verwerft
-  Improved error handling for dynamically allocated strings.
-
-* John Fotheringham
-  Made trionan compile on OpenVMS.
-
-* Added 'd' and 'D' as exponent letters when using TRIO_MICROSOFT.
-
-* Fixed uninitial memory read for the parameter modifiers.
-
-
-Version 1.5 - 2001/09/08
-------------------------
-* Merged with libxml changes.
-
-* Moved NaN and Inf handling to separate file to enable reuse in other
-  projects.
-
-* Igor Zlatkovic
-  Fixed TrioGenerateNan for MSVC.
-
-* Fixed lots of preprocessor macros and internal data structure names.
-
-
-Version 1.4 - 2001/06/03
-------------------------
-* Added hex-float (%a and %A) for scanning.
-
-* Added wide character arguments (%ls, %ws, %S, %lc, %wc, and %C) for both
-  printf and scanf.
-
-* Added mutex callbacks for user-specified specifiers to enable applications to
-  add thread-safety. These are registered with trio_register, where the
-  namespace is set to either ":enter" to lock a mutex, or ":leave" to unlock a
-  mutex.
-
-* Added equivalence class expressions for scanning. For example, %[[=a=]] scans
-  for all letters in the same equivalence class as the letter 'a' as defined
-  by the locale.
-
-* Changed character class expressions for scanning. The expressions must now
-  be embedded withing an extra set of brackets, e.g. %[[:alpha:]]. This was
-  done to adhere to the syntax of UNIX98 regular expressions.
-
-* Added the possibility to specify standard support (TRIO_C99 etc.) as compiler
-  options.
-
-* Fixed conversion of hex-float in StrToDouble.
-
-* Fixed formatting of hex-float numbers.
-
-* Stan Boehm
-  Fixed crash on QNX, which happend because some buffers on the stack were too
-  big.
-
-* Fixed default precision for %f and %g (reported by Jose Ortiz)
-
-* Howard Kapustein
-  Added the I8, I16, I32, and I64 modifiers.
-
-* Jose Ortiz
-  Fixed rounding problem for %e.
-
-* Jose Ortiz
-  Fixed various problems with the xlC and Sun C++ compilers.
-
-
-Version 1.3 - 2001/05/16
-------------------------
-* trio's treatment of the field width when the %e code was used was not
-  correct (reported by Gisli Ottarsson). It turns out the fraction part should
-  be zero-padded by default and the exponent part should be zero-prefixed if
-  it is only one digit. At least that's how the GNU and Sun libc's work. The
-  trio floating point output looks identical to them now.
-
-* Fixed group scanning with modifiers.
-
-* Fixed compilation for 64-bit Digital Unix.
-
-* Igor Zlatkovic
-  Fixed compilation of dprintf, which uses read/write, for MSVC.
-
-* Fixed various compilation problems on Digital Unix (mainly associated with
-  va_list).
-
-
-Version 1.2 - 2001/04/11
-------------------------
-* Added autoconf integration. If compiled with HAVE_CONFIG_H the following
-  happens. Firstly, <config.h> is included. Secondly, trio will only be
-  compiled if WITH_TRIO is defined herein. Thirdly, if TRIO_REPLACE_STDIO is
-  defined, only stdio functions that have not been detected by autoconf, i.e.
-  those not defined by HAVE_PRINTF or similar, will be replaced by trio
-  functions (suggested by Daniel Veillard).
-
-* Fixed '%m.nf' output. Previously trio did not treat the width properly
-  in all cases (reported by Gisli Ottarsson).
-
-* Added explicit promotion for the scanfv family.
-
-* Fixed more C++ compilation warnings.
-
-
-Version 1.1 - 2001/02/25
-------------------------
-* Added explicit promotion for the printfv familiy. A float must be specified
-  by %hf.
-
-* Fixed positionals for printfv (reported by Gisli Ottarsson).
-
-* Fixed an integer to pointer conversion problem on the SGI MIPS C compiler
-  (reported by Gisli Ottarsson).
-
-* Fixed ANSI C++ warnings (type casting, and namespace is a reserved keyword).
-
-* Added \n to all examples in the documentation to prevent confusion.
-
-* Fixed StrSubstringMax
-
-
-Version 1.0 - 2000/12/10
-------------------------
-* Bumped Version number.
-
-
-Version 0.25 - 2000/12/09
--------------------------
-* Wrote more documentation.
-
-* Improved NaN support and added NaN to regression test.
-
-* Fixed C99 support.
-
-* Added missing getter/setter functions.
-
-
-Version 0.24 - 2000/12/02
--------------------------
-* Added callback functionality for the user-defined specifier (<>). All
-  the necessary functions are defined in triop.h header file. See the
-  documentation for trio_register for further detail.
-
-* Wrote initial documentation on the callback functionality.
-
-* Added the printfv and scanfv family of functions, which takes a pointer
-  array rather than variadic arguments. Each pointer in the array must point
-  to the associated data (requested by Bruce Korb).
-
-* As indicated in version 0.21 the extension modifiers (<>) have now been
-  completely removed.
-
-* Added skipping of thousand-separators in floating-point number scanning.
-
-
-Version 0.23 - 2000/10/21
--------------------------
-* Added width to scanning of floating-point numbers.
-
-* Wrote more documentation on trio_printf.
-
-* Fixed problem with trailing zeroes after decimal-point.
-
-
-Version 0.22 - 2000/08/06
--------------------------
-* Added LC_CTYPE locale dependent character class expressions to scan lists.
-  Included are [:alnum:], [:alpha:], [:cntrl:], [:digit:], [:graph:],
-  [:lower:], [:print:], [:punct:], [:space:], [:upper:], [:xdigit:]
-
-* Added C escapes to alternative string formatting and scanning.
-
-* Added StrSubstringMax.
-
-* Wrote a little more documentation.
-
-* Fixed scanf return values.
-
-* Fixed a sign error for non-ascii characters.
-
-
-Version 0.21 - 2000/07/19
--------------------------
-* Converted the documentation to TeX. With latex2man the documentation can
-  automatically be converted into man pages.
-
-* Added trio_scanf, trio_vscanf, trio_fscanf, and trio_vfscanf.
-
-* Added trio_dprintf, trio_vdprintf, trio_dscanf, and trio_vdscanf. These
-  functions can be used to write and read directly to pipes and sockets (the
-  assume blocking sockets). Stdio buffering is surpassed, so the functions are
-  async-safe. However, reading from stdin (STDIN_FILENO) or writing to stdout
-  (STDOUT_FILENO) reintroduces the buffering.
-
-* Paul Janzen
-  Added trio_asprintf and trio_vasprintf, which are compatible with the GNU
-  and BSD interfaces.
-
-* Added scanlist ranges for group scanning (%[]).
-
-* Added width for scanning (missing for floating-point numbers though).
-
-* Added variable size modifier (&) to handle system defined types of unknown
-  size. This modifier makes certain assumptions about the integer sizes, which
-  may not be valid on any machine. Consequently, the modifier will remain
-  undocumented, as it may be removed later.
-
-* Added \777 and \xFF to alternative string scanning (%#s)
-
-* Added the TRIO_REPLACE_STDIO check in the header.
-
-* Improved performance of the multibyte character parsing.
-
-* Fixed positionals (%n$) which had stopped working.
-
-* Fixed hh and ll modifiers to allow exactly two letters and no more.
-
-* Fixed ANSI C++ warnings. Also fixed the compiler warning about casting
-  between integer and pointer (this has been annoying me for ages). 
-
-* Fixed snprintf and vsnprintf with zero buffer size.
-
-* Fixed NAN problems (reported by Keith Briggs).
-
-* Fixed parsing of multibyte characters. The format string was not correctly
-  advanced in case of a multibyte character.
-
-* Renamed many of the internal functions to have more consistant names.
-
-* Removed the <quote=c> and <fill=c> modifiers. They are not really worth
-  including. The other <> modifiers may disappear as well.
-
-
-Version 0.20 - 2000/06/05
--------------------------
-* Added intmax_t and ptrdiff_t support.
-
-* Added support for LC_NUMERIC grouping.
-
-* Added double-dot notation for the conversion base. The style is now
-  %width.precision.base, where any argument can be a number, an asterix
-  indicating a parameter, or be omitted entirely. For example, %*..2i is
-  to specify binary numbers without precision, and with width as a parameter
-  on the va_list.
-
-* Added sticky modifier (!), which makes subsequent specifiers of the same
-  type reuse the current modifiers. Inspired by a suggestion from Gary Porter.
-
-* Added group scanning (%[]). Scanlist ranges and multibyte sequences are not
-  supported yet.
-
-* Added count scanning (%n).
-
-* Changed the number scanning to accept thousand separators and any base.
-
-* Fixed positional for parameters. It is possible to write something like
-  %3$*1$.*2$d (which happens to be the same as %*.*d).
-
-* Fixed precision of integers.
-
-* Fixed parameter flags. Before trio could only handle one parameter flag per
-  specifier, although two (three with double-dot base) were possible.
-
-* Fixed isinf() for those platforms where it is unimplemented.
-
-
-Version 0.18 - 2000/05/27
--------------------------
-* Rewrote the entire floating-point formatting function (Danny Dulai had
-  reported several errors and even supplied some patches, which unfortunately
-  were lost due to the refactoring).
-
-* Removed the use of strlen() in the declaration of a stack array. This
-  caused problems on some compilers (besides it isn't really ANSI C compliant
-  anyways). Using some arbitrarily chosen maximum value; should examine if
-  some standard defines an upper limit on the length of decimal-point and
-  thousands-separator (sizeof(wchar_t) perhaps?)
-
-* Changed the parsing of the format string to be multibyte aware.
-
-
-Version 0.17 - 2000/05/19
--------------------------
-* Added INF, -INF, and NAN for floating-point numbers.
-
-* Fixed %#.9g -- alternative with precision.
-
-* Ken Gibson
-  Fixed printing of negative hex numbers
-
-* Joerg (last name unknown)
-  Fixed convertion of non-ASCII characters
-
-
-Version 0.16 - 1999/08/06
--------------------------
-* Changed the constness of the second argument of StrFloat and StrDouble. The
-  lack of parameter overloading in C is the reason for the strange use of
-  constness in strtof and strtod.
-
-* Cleaned up constness.
-
-
-Version 0.15 - 1999/07/23
--------------------------
-* Fixed the internal representation of numbers from signed to unsigned. Signed
-  numbers posed a problem for large unsigned numbers (reported by Tero)
-
-* Fixed a tiny bug in trio_vsprintfcat
-
-* Changed the meaning of the max argument of StrAppendMax to be consistant
-  with StrFormatAppendMax. Now it is the maximal size of the entire target
-  buffer, not just the appended size. This makes it easier to avoid buffer
-  overflows (requested by Tero)
-
-
-Version 0.14 - 1999/05/16
--------------------------
-* Added size_t support (just waiting for a C99 compliant compiler to add
-  ptrdiff_t and intmax_t)
-
-* Rewrote TrioOutStreamDouble so it does not use the libc sprintf to emulate
-  floating-point anylonger.
-
-* Fixed width, precision, and adjustment for numbers and doubles.
-
-
-Version 0.13 - 1999/05/06
--------------------------
-* Fixed zero padding for %d. Now %d will only zero pad if explicitly requested
-  to do so with the 0 flag (reported by Tero).
-
-* Fixed an incorrect while() condition in TrioGetString (reported by Tero).
-
-
-Version 0.12 - 1999/04/19
--------------------------
-* Fixed incorrect zero padding of pointers
-
-* Added StrHash with STRIO_HASH_PLAIN
-
-* Added StrFormatDateMax
-
-
-Version 0.11 - 1999/03/25
--------------------------
-* Made it compile under cygwin
-
-* Fixed a bug were TrioPreprocess would return an error if no formatting chars
-  were found (reported by Tero).
-
-
-Version - 1999/03/19
---------------------
-* Added trio_strerror and TRIO_ERROR_NAME.
-
-* Changed the error codes to be positive (as errno)
-
-* Fixed two reads of uninitialized memory reported by Purify
-
-* Added binary specifiers 'b' and 'B' (like SCO.) ThousandSeparator can be
-  used to separate nibbles (4 bit)
-
-* Renamed all Internal* functions to Trio*, which seems like a better
-  namespace (even though it is of no practical interest because these
-  functions are not visible beyond the scope of this file.)
-
-
-Version - 1999/03/12
---------------------
-* Added hex-float format for StrToDouble
-
-* Double references and gaps in the arguments are not allowed (for the %n$
-  format) and in both cases an error code is returned.
-
-* Added StrToDouble (and StrToFloat)
-
-
-Version - 1999/03/08
---------------------
-* Added InStream and OutStream to the trio_T structure.
-
-* Started work on TrioScan.
-
-* Return values for errors changed. Two macros to unpack the error code has
-  been added to the header.
-
-* Shortshort (hh) flag added.
-
-* %#s also quotes the quote-char now.
-
-* Removed the 'errorInFormat' boolean, which isn't used anymore after the
-  functions bail out with an error instead.
-
-
-Version - 1999/03/04
---------------------
-* More than MAX_PARAMETERS parametes will now cause the TrioPreprocess()
-  function to return error.
-
-* Unknown flags and/or specifiers cause errors too.
-
-* Added trio_snprintfcat and trio_vsnprintfcat and the defined name
-  StrFormatAppendMax. They append a formatted string to the end of a string.
-
-* Define MAX_PARAMETERS to 128 at all times instead of using NL_ARGMAX when
-  that exists.
-
-* Added platform fixes for Amiga as suggested by Tero Jänkä <tesaja@utu.fi>
-
-
-Version - 1999/01/31
---------------------
-* vaprintf did add a zero byte even when it had failed.
-
-* Cleaned up the code for locale handling and thousand separator
-
-* Added trio_aprintf() and trio_vaprintf(). They return an allocated string.
-
-* Added thousands separator for numbers
-
-* Added floating point support for *printf
-
-
-Version - 1998/10/20
---------------------
-* StrMatchCase() called StrMatch() instead of itself recursively
-
-* Rewrote the implementation of *printf and *scanf and put all the code in
-  this file. Extended qualifiers and qualifiers from other standards were
-  added.
-
-* Added StrSpanFunction, StrToLong, and StrToUnsignedLong
-
-
-Version - 1998/05/23
---------------------
-* Made the StrEqual* functions resistant to NULL pointers
-
-* Turns out strdup() is no standard at all, and some platforms (I seem to
-  recall HP-UX) has problems with it. Made our own StrDuplicate() instead.
-
-* Added StrFormat() and StrFormatMax() to serve as sprintf() and snprintf()
-  respectively.
diff --git a/trio/FILES b/trio/FILES
deleted file mode 100644 (file)
index 22a5ea1..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-FILES
-README
-CHANGES
-Makefile.in
-maketgz
-strio.h
-trio.c
-trio.h
-triodef.h
-trionan.c
-trionan.h
-triop.h
-triostr.c
-triostr.h
-compare.c
-example.c
-regression.c
-configure
-configure.in
-install-sh
-autogen.sh
-doc/doc.h
-doc/doc_dynamic.h
-doc/doc_printf.h
-doc/doc_register.h
-doc/doc_scanf.h
-doc/doc_static.h
-doc/footer.html
-doc/header.html
-doc/trio.cfg
-doc/trio.css
-html/trio.css
-html/*.html
diff --git a/trio/Makefile.in b/trio/Makefile.in
deleted file mode 100644 (file)
index 4f3b969..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-SHELL = @SHELL@
-CC     = @CC@
-CFLAGS = @CFLAGS@ -I. -DDEBUG
-OBJS   = triostr.o trio.o trionan.o
-TARGETLIB      = libtrio.a
-TARGETINCS     = trio.h triop.h triodef.h trionan.h triostr.h
-LDFLAGS        = -L. -ltrio -lm
-AR     = ar
-RANLIB = @RANLIB@
-ERASE  = rm -f
-MKDIR  = mkdir -p
-GENDOC = doxygen
-srcdir = @srcdir@
-# VPATH doesn't seem to work with /usr/xpg4/bin/make on Solaris
-# (use /usr/ccs/bin/make), and doesn't work on older Solaris make
-# such as Solaris 2.6.
-VPATH = @srcdir@
-
-# Installation settings
-INSTALL                = @INSTALL@
-INSTALL_DATA   = @INSTALL_DATA@
-prefix         = @prefix@
-exec_prefix    = @exec_prefix@
-includedir     = @includedir@
-libdir         = @libdir@
-
-all: $(TARGETLIB) $(TARGET)
-
-.PHONY: all check test install doc clean
-
-$(srcdir)/configure: configure.in
-       cd $(srcdir) && autoconf
-
-Makefile: Makefile.in config.status
-       CONFIG_COMMANDS= CONFIG_LINKS= CONFIG_HEADERS= \
-       CONFIG_FILES=Makefile ./config.status
-
-config.status: configure
-       ./config.status --recheck
-
-check: test
-test:  regression
-       ./regression
-
-install:       $(TARGETLIB)
-       $(MKDIR) $(libdir)
-       $(MKDIR) $(includedir)
-       $(INSTALL_DATA) $(TARGETLIB) $(libdir)/$(TARGETLIB)
-       for i in $(TARGETINCS);do \
-       (set -x;$(INSTALL_DATA) $(srcdir)/$$i $(includedir)); \
-       done
-
-regression: regression.o $(TARGETLIB)
-       $(CC) $(CFLAGS) regression.o $(LDFLAGS) -o $@
-
-example: example.o $(TARGETLIB)
-       $(CC) $(CFLAGS) example.o $(LDFLAGS) -o $@
-
-compare: compare.o $(TARGETLIB)
-       $(CC) $(CFLAGS) compare.o $(LDFLAGS) -o $@
-
-userdef: userdef.o $(TARGETLIB)
-       $(CC) $(CFLAGS) userdef.o $(LDFLAGS) -o $@
-
-$(TARGETLIB): $(OBJS)
-       $(AR) ruv $(TARGETLIB) $(OBJS)
-       $(RANLIB) $(TARGETLIB)
-
-doc::
-       (cd $(srcdir) && $(GENDOC) doc/trio.cfg)
-
-clean:
-       $(ERASE) *~ core core.* regression example $(TOBJS) $(OBJS) $(TARGET) $(TARGETLIB) example.o regression.o
diff --git a/trio/README b/trio/README
deleted file mode 100644 (file)
index 55ad1b0..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-README -- trio
-
-Trio is a package with portable string functions. Including printf() clones
-and others.
-
- Copyright (C) 1998-2001 by Bjorn Reese and Daniel Stenberg.
-
- Permission to use, copy, modify, and distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-
-Trio is intended to be an integral part of another application, so we
-have not done anything to create a proper installation.
-
-Compile with 'make' (edit the Makefile if you want a release build)
-
-Test the package with 'make test'
-
-Install by copying trio.h, triop.h, and libtrio.a (and man/man?/* if
-you want documentation) to the appropriate directories.
-
-Catch some usage examples in example.c
-
-Send feedback and patches to the mailing list, subscription and other
-information is found here:
-
-        http://lists.sourceforge.net/lists/listinfo/ctrio-talk
-
-Enjoy!
-
-Trio web page
-
-        http://daniel.haxx.se/trio/
diff --git a/trio/autogen.sh b/trio/autogen.sh
deleted file mode 100644 (file)
index 9299034..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-autoconf
-rm -rf autom4te.cache
diff --git a/trio/compare.c b/trio/compare.c
deleted file mode 100644 (file)
index 3823aa2..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-#include "trio.h"
-
-#define compare(format, value) printf("FORMAT: %s\n", format); printf("TRIO: "); trio_printf(format,value); printf("\nLIBC: "); \
-printf(format,value); printf("\n\n"); 
-
-int main()
-{
-   compare("\"%e\"",2.342E+02);
-   compare("\"%10.4e\"",-2.342E-02);
-   compare("\"%11.4e\"",-2.342E-02);
-   compare("\"%12.4e\"",-2.342E-02);
-   compare("\"%13.4e\"",-2.342E-02);
-   compare("\"%14.4e\"",-2.342E-02);
-   compare("\"%15.4e\"",-2.342E-02);
-   compare("\"%16.4e\"",-2.342E-02);
-   compare("\"%16.4e\"",-2.342E-22);
-   compare("\"%G\"",-2.342E-02);
-   compare("\"%G\"",3.1415e-6);
-   compare("%016e", 3141.5);
-   compare("%16e", 3141.5);
-   compare("%-16e", 3141.5);
-   compare("%010.3e", 3141.5);
-
-   compare("*%5f*", 3.3);
-   compare("*%5f*", 3.0);
-   compare("*%5f*", .999999E-4);
-   compare("*%5f*", .99E-3);
-   compare("*%5f*", 3333.0);
-
-   compare("*%5g*", 3.3);
-   compare("*%5g*", 3.0);
-   compare("*%5g*", .999999E-4);
-   compare("*%5g*", .99E-3);
-   compare("*%5g*", 3333.0);
-   compare("*%5g*", 0.01);
-
-   compare("*%5.g*", 3.3);
-   compare("*%5.g*", 3.0);
-   compare("*%5.g*", .999999E-4);
-   compare("*%5.g*", 1.0E-4);
-   compare("*%5.g*", .99E-3);
-   compare("*%5.g*", 3333.0);
-   compare("*%5.g*", 0.01);
-
-   compare("*%5.2g*", 3.3);
-   compare("*%5.2g*", 3.0);
-   compare("*%5.2g*", .999999E-4);
-   compare("*%5.2g*", .99E-3);
-   compare("*%5.2g*", 3333.0);
-   compare("*%5.2g*", 0.01);
-
-   return 0;
-}
diff --git a/trio/configure.in b/trio/configure.in
deleted file mode 100644 (file)
index f1ed765..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-dnl
-dnl Configuration for trio
-dnl
-
-AC_INIT
-AC_CONFIG_SRCDIR([triodef.h])
-AC_PREREQ(2.55) dnl autoconf 2.55 was released in 2002
-
-AC_PROG_CC
-ifdef([AC_PROG_CC_STDC], [AC_PROG_CC_STDC])
-AC_LANG([C])
-
-AC_PROG_INSTALL
-AC_PROG_RANLIB
-
-dnl
-dnl Alpha floating-point compiler option.
-dnl
-
-AC_MSG_CHECKING(for IEEE compilation options)
-AC_CACHE_VAL(ac_cv_ieee_option, [
-  AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[
-    #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__))) && (defined(VMS) || defined(__VMS)))
-    # error "Option needed"
-    typedef int option_needed[-1];
-    #endif
-    ]]]),
-    ac_cv_ieee_option="/IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE",
-    AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[
-      #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__))) && !(defined(VMS) || defined(__VMS)) && !defined(_CFE))
-      # error "Option needed"
-      typedef int option_needed[-1];
-      #endif
-      ]]]),
-      ac_cv_ieee_option="-ieee",
-      AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[
-       #if !(defined(__alpha) && (defined(__GNUC__) && (defined(__osf__) || defined(__linux__))))
-       # error "Option needed"
-       typedef int option_needed[-1];
-       #endif
-       ]]]),
-       ac_cv_ieee_option="-mieee",
-       ac_cv_ieee_option="none"
-      )
-    )
-  )
-])
-AC_MSG_RESULT($ac_cv_ieee_option)
-if test $ac_cv_ieee_option != none; then
-  CFLAGS="${CFLAGS} ${ac_cv_ieee_option}"
-fi
-
-AC_CONFIG_FILES([Makefile])
-AC_OUTPUT
diff --git a/trio/doc/doc.h b/trio/doc/doc.h
deleted file mode 100644 (file)
index 49de146..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*************************************************************************
- *
- * $Id: doc.h,v 1.20 2006/08/18 11:32:08 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/**
-@mainpage
-
-@author Bjørn Reese
-@author Daniel Stenberg
-
-@section intro Introduction
-
-Trio is a fully matured and stable set of printf and string functions
-designed be used by applications with focus on portability or with the
-need for additional features that are not supported by standard stdio
-implementation.
-
-There are several cases where you may want to consider using trio:
-
-@li Portability across heterogeneous platforms.
-@li Embedded systems without stdio support.
-@li Extendability of unsupported features.
-@li Your native version does not do everything you need.
-
-When you write applications that must be portable to a wide range of
-platforms you often have to deal with inadequate implementations of the
-stdio library functions. Most notably is the lack of secure formatting
-functions, such as snprintf, or the lack of parameter reordering commonly
-used for the internationalization of applications, such as the <num>$
-modifier. Sometimes the feature you need is simply not present in stdio.
-So you end up spending much effort on determining which platforms supports
-what, and to write your own versions of various features. This is where
-trio can help you. Trio is a platform-independent implementation of the
-stdio printf and scanf functions and the string library functions.
-
-The functionality described in the stdio standards is a compromise, and
-does unfortunately not include a mechanism to extend the functionality for
-an individual application. Oftentimes an application has the need for an
-extra feature, and the application code can become much more clear and
-readable by using an extension mechanism. Trio supports a range of useful
-extensions such as user-defined specifiers, passing of arguments in arrays,
-localized string scanning, thousand-separators, and arbitrary integer bases.
-
-Trio fully implements the C99 (ISO/IEC 9899:1999) and UNIX98 (the Single
-Unix Specification, Version 2) standards, as well as many features from
-other implemenations, e.g. the GNU libc and BSD4.
-
-@section examples Examples
-
-@subsection ex1 Binary Numbers
-Output an integer as a binary number using a trio extension.
-@verbatim
-  trio_printf("%..2i\n", number);
-@endverbatim
-
-@subsection ex2 Thousand-separator
-Output a number with thousand-separator using a trio extension.
-@verbatim
-  trio_printf("%'f\n", 12345.6);
-@endverbatim
-The thousand-separator described by the locale is used. 
-
-@subsection ex3 Fixed Length Array and Sticky Modifier
-Output an fixed length array of floating-point numbers.
-@verbatim
-  double array[] = {1.0, 2.0, 3.0};
-  printf("%.2f %.2f %.2f\n", array[0], array[1], array[2]);
-@endverbatim
-The same with two trio extensions (arguments are passed in an array, and
-the first formatting specifier sets the sticky option so we do not have
-to type all the formatting modifiers for the remaining formatting specifiers)
-@verbatim
-  trio_printfv("%!.2f %f %f\n", array);
-@endverbatim
-Another, and more powerful, application of being able to pass arguments in
-an array is the creation of the printf/scanf statement at run-time, where
-the formatting string, and thus the argument list, is based on an external
-configuration file.
-
-@subsection ex4 Localized scanning
-Parse a string consisting of one or more upper-case alphabetic characters
-followed by one or more numeric characters.
-@verbatim
-  sscanf(buffer, "%[A-Z]%[0-9]", alphabetic, numeric);
-@endverbatim
-The same but with locale using a trio extension.
-@verbatim
-  trio_sscanf(buffer, "%[[:upper:]]%[[:digit:]]", alphabetic, numeric);
-@endverbatim
-
-@section legal Legal Issues
-Trio is distributed under the following license, which allows practically
-anybody to use it in almost any kind of software, including proprietary
-software, without difficulty.
-
-"Copyright (C) 1998-2001 Bjorn Reese and Daniel Stenberg.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
-MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
-CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER."
-
-@section contribution Contribution
-
-@subsection contribute Contribute
-We appreciate any type of contribution, from ideas over improvements to
-error corrections.
-
-The project space contains references to bug and feature tracking,
-mailing-list, and the CVS repository. We prefer communication via the
-mailing-list, but do not require you to be subscribed, because trio is a
-small project.
-
-The project space is located at http://sourceforge.net/projects/ctrio/
-
-@subsection contributors Contributors
-We have received contributions from the following persons (in alphabetic
-order sorted by surname)
-
-@li Craig Berry
-@li Karl Bochert
-@li Stan Boehm
-@li David Byron
-@li Brian Chapman
-@li Robert Collins
-@li Danny Dulai
-@li Bob Friesenhahn
-@li Jon Foster
-@li John Fotheringham
-@li Markus Henke
-@li Ken Gibson
-@li Paul Janzen
-@li Patrick Jessee
-@li Richard Jinks
-@li Tero Jänkä
-@li Howard Kapustein
-@li Rune Enggaard Lausen
-@li Mehdi Lavasani
-@li Alexander Lukyanov
-@li Andreas Maus
-@li Mikey Menezes
-@li Emmanuel Mogenet
-@li Jacob Navia
-@li Jose Ortiz
-@li Joe Orton
-@li Gisli Ottarsson
-@li Mark Pickelmann
-@li Olli Savia
-@li Shaun Tancheff
-@li Marc Werwerft
-@li Igor Zlatkovic
-
-Please let us know, and accept our apology, if we have omitted anybody.
-
-*/
diff --git a/trio/doc/doc_dynamic.h b/trio/doc/doc_dynamic.h
deleted file mode 100644 (file)
index 9248267..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*************************************************************************
- *
- * $Id: doc_dynamic.h,v 1.1 2001/12/27 17:29:20 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/** @addtogroup DynamicStrings Dynamic String Functions.
-Dynamic string functions.
-
-@b SYNOPSIS
-
-@verbatim
-cc ... -ltrio -lm
-
-#include <triostr.h>
-@endverbatim
-
-@b DESCRIPTION
-
-*/
diff --git a/trio/doc/doc_nan.h b/trio/doc/doc_nan.h
deleted file mode 100644 (file)
index bfb3ffc..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*************************************************************************
- *
- * $Id: doc_nan.h,v 1.1 2001/12/30 12:47:41 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/** @addtogroup SpecialQuantities Special Quantifies.
-Functions to detect and fabricate special quantities in floating-point
-numbers.
-
-@b SYNOPSIS
-
-@verbatim
-cc ... -ltrio -lm
-
-#include <trionan.h>
-@endverbatim
-
-@b DESCRIPTION
-
-Certain arithmetical operations does not result in normal numbers. Instead
-they result in special quantities that must be handled differently by the
-floating-point hardware. These includes Infinity and Not-A-Number (NaN).
-
-For example, 0/0 (zero divided by zero) yields NaN. Any operation which
-involves a NaN will result in NaN. Any comparison involving NaN will be
-unsuccessful, even if NaN is compared to NaN.
-
-These special quantities are represented with special bit patterns by the
-floating-point hardware, and this bit patterns depend on the hardware.
-There may even be hardware that does not support special quantities, so
-the functions in this module are not guaranteed to work on all platforms.
-
-The approach used in this module is to (in decreasing order of importance)
-@li Use C99 functionality when available.
-@li Use IEEE 754-1985 bit patterns if possible.
-@li Use platform-specific techniques.
-
-@b NOTES
-
-This module does not depend on the rest of trio, and can thus be reused
-separately. The following files are necessary:
-@li @c triodef.h
-@li @c trionan.h
-@li @c trionan.c
-
-*/
diff --git a/trio/doc/doc_printf.h b/trio/doc/doc_printf.h
deleted file mode 100644 (file)
index 32439e2..0000000
+++ /dev/null
@@ -1,532 +0,0 @@
-/*************************************************************************
- *
- * $Id: doc_printf.h,v 1.5 2008/10/12 12:09:51 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/** @addtogroup Printf Formatted Printing Functions.
-Variations of formatted printing functions.
-
-@b SYNOPSIS
-
-@verbatim
-cc ... -ltrio -lm
-
-#include <trio.h>
-@endverbatim
-
-@b DESCRIPTION
-
-This documentation is incomplete.
-The documentation of the printf family in [C99] and [UNIX98] also applies
-to the trio counterparts.
-
-All these functions outputs a string which is formatted according to the
-@p format string and the consecutive arguments. The @p format string is
-described in the Formatting section below.
-
-@ref trio_printf, @ref trio_vprintf, and @ref trio_printfv writes the
-output to the standard output stream (stdout).
-
-@ref trio_fprintf, @ref trio_vfprintf, and @ref trio_fprintfv writes the
-output to a given output stream.
-
-@ref trio_dprintf, @ref trio_vdprintf, and @ref trio_dprintfv writes the
-output to a file descriptor (this includes, for example, sockets).
-
-@ref trio_sprintf, @ref trio_vsprintf, and @ref trio_sprintfv writes the
-output into @p buffer.
-
-@ref trio_snprintf, @ref trio_vsnprintf, and @ref trio_snprintfv writes @p
-max - 1 characters into @p buffer followed by a terminating zero character.
-If @p max is 1, then @p buffer will be an empty string. If @p max is 0,
-then @p buffer is left untouched, and can consequently be NULL. The number
-of characters that would have been written to @p buffer, had there been
-sufficient space, is returned.
-
-@ref trio_snprintfcat appends the formatted text at the end of @p buffer.
-
-@ref trio_asprintf, @ref trio_vasprintf, and @ref trio_asprintfv allocates
-and returns an allocated string in @p buffer containing the formatted text.
-
-@b FORMATTING
-
-The @p format string can contain normal text and conversion indicators.
-The normal text can be any character except the nil character (\000 =
-'\0') and the percent character (\045 = '%'). Conversion indicators
-consists of an indication character (%), followed by zero or more conversion
-modifiers, and exactly one conversion specifier.
-
-@b Modifiers
-
-Some modifiers exhibit the same behaviour for all specifiers, other modifiers
-indicate different behaviours for different specifiers, and other modifiers
-are only applicable to certain specifiers. The relationship is described for
-each modifier. The number 9 is used to denotes an arbitrary integer.
-
-@em Positional ( @c 9$ ) [UNIX98]
-
-Normally the arguments supplied to these functions are interpreted
-incrementially from left to right. Arguments can be referenced specifically in
-the format string. The modifier n$ selects the nth argument. The first
-argument is referred as 1$. If this modifier is used, it must be the first
-modifier after the indication character. n$ can also be used for argument
-width, precision, and base.
-
-The performance penalty of using positionals is almost neglible (contrary to
-most other printf implementations).
-
-@li @em Reference @em Mix.
-Mixing normal and positional specifiers is allowed [TRIO]. For example,
-@verbatim
-  trio_printf("%d %3$d %2$d\n", 1, 2, 3);
-@endverbatim
-results in
-@verbatim
-  1 3 2
-@endverbatim
-Arguments for the printf family are passed on the stack. On most platforms it
-is not possible to determine the size of individual stack elements, so it is
-essential that the format string corresponds exactly to the passed arguments.
-If this is not the case, incorrect values may be put into the result.
-
-@li @em Reference @em Gap.
-For the same reason it is also essential that the format string does not
-contain any &quot;gaps&quot; in the positional arguments. For example,
-@verbatim
-  trio_printf("%1$d %3$d\n", 1, 2, 3);
-@endverbatim
-is NOT allowed. The format string parser has no knowledge about whether the
-second argument is, say, an integer or a long double (which have different
-sizes).
-@verbatim
-@endverbatim
-[UNIX98] describes this as unspecified behaviour. [TRIO] will detect reference
-gaps and return an error.
-
-@li @em Double @em Reference.
-It is also not allowed to reference an argument twice or more. For example,
-@verbatim
-  trio_printf("%1$d %1$lf\n", 1);
-@endverbatim
-is NOT allowed, because it references the first argument as two differently
-sized objects.
-@verbatim
-@endverbatim
-[UNIX98] describes this as unspecified behaviour. [TRIO] will detect double
-references and return an error.
-
-The following two statements are equivalent
-@verbatim
-  trio_printf("|%d %s\n|", 42, "meanings");
-  |42 meanings|
-
-  trio_printf("|%1$d %2$s|\n", 42, "meanings");
-  |42 meanings|
-@endverbatim
-
-@em Width ( @c 9 )
-
-Specifies the minimum width of a field. If the fields has less characters than
-specified by the width, the field will be left adjusted and padded by spaces.
-The adjustment and padding can be changed by the Alignment ( @c - ) and
-Padding ( @c 0 ) modifiers.
-
-The width is specified as a number. If an asterix ( @c * ) is used instead, the
-width will be read from the argument list.
-
-Prefixes, such as 0x for hexadecimal integers, are part of width.
-@verbatim
-  trio_printf("|%10i|\n", 42);
-  |        42|
-@endverbatim
-
-@em Precision ( @c .9 )
-
-The precision has different semantics for the various data types.
-The precision specifies the maximum number of printed characters for strings,
-the number of digits after the decimal-point for floating-point numbers,
-the number of significant digits for the @c g (and @c G) representation of
-floating-point numbers, the minimum number of printed digits for integers.
-@verbatim
-  trio_printf("|%10.8i|%.8i|\n", 42, 42);
-  |  00000042|00000042|
-@endverbatim
-@em Base ( @c ..9 ) [TRIO]
-
-Sets the base that the associated integer must be converted to. The base can
-be between 2 and 36 (both included).
-@verbatim
-  trio_printf("|%10.8.2i|%10..2i|%..2i|\n", 42, 42, 42);
-  |  00101010|    101010|101010|
-
-  trio_printf("|%*.8.*i|\n", 10, 2, 42);
-  |  00101010|
-@endverbatim
-@em Padding ( @c 0 )
-
-Integer and floating point numbers are prepended by zeros. The number of
-leading zeros are determined by the precision. If precision is not present,
-width is used instead.
-
-@em Short ( @c h )
-
-Integer arguments are read as an ( @c unsigned ) @c short @c int. String
-and character arguments are read as @c char @c * and @c char respectively.
-
-@em Short @em short ( @c hh ) [C99, GNU]
-
-The argument is read as an ( @c unsigned ) @c char.
-
-@em Fixed @em Size ( @c I ) [MSVC]
-
-The argument is read as a fixed sized integer. The modifier is followed by
-a number, which specifies the number of bits in the integer, and can be one
-of the following
-
-@li @c I8
-@li @c I16
-@li @c I32
-@li @c I64 (if 64-bits integers are supported)
-
-Works only for integers (i, u, d, o, x, X)
-
-@em Largest ( @c j ) [C99]
-
-The argument is read as an @c intmax_t / @c uintmax_t, which is defined to
-be the largest signed/unsigned integer.
-
-@em Long ( @c l )
-
-An integral argument is read as an ( @c unsigned ) @c long @c int. A string
-argument is read as a @c wchar_t @c *, and output as a multi-byte character
-sequence.
-
-@em Long @em long ( @c ll ) [C99, UNIX98, GNU]
-
-The argument is read as an ( @c unsigned ) @c long @c long @c int.
-
-@em Long @em double ( @c L ) [C99, UNIX98, GNU]
-
-The argument is read as a @c long @c double.
-
-@em ptrdiff_t ( @c t ) [C99]
-
-The argument is read as a @c ptrdiff_t, which is defined to be the signed
-integer type of the result of subtracting two pointers.
-
-@em Quad ( @c q ) [BSD, GNU]
-
-Corresponds to the long long modifier ( @c ll ).
-
-@em Wide ( @c w ) [MISC]
-
-For a string argument this is equivalent to using the long modifier ( @c l ).
-
-@em size_t ( @c z ) [C99]
-
-The argument is read as a @c size_t, which is defined to be the type
-returned by the @c sizeof operator.
-
-@em size_t ( @c Z ) [GNU]
-
-Corresponds to the size_t modifier ( @c z ).
-
-@em Alternative ( @c # )
-
-Prepend radix indicator for hexadecimal, octal, and binary integer numbers
-and for pointers.
-Always add a decimal-point for floating-point numbers.
-Escape non-printable characters for strings.
-
-@em Spacing ( )
-
-Prepend leading spaces when necessary.
-
-@em Sign ( @c + )
-
-Always prepend a sign to numbers. Normally only the negative sign is prepended
-to a number. With this modifier the positive sign may also be prepended.
-
-@em Alignment ( @c - )
-
-The output will be left-justified in the field specified by the width.
-
-@em Argument ( @c * )
-
-Width, precision, or base is read from the argument list, rather than from
-the formatting string.
-
-@em Quote / @em Grouping ( @c ' ) [MISC]
-
-Groups integers and the integer-part of floating-point numbers according to
-the locale. Quote strings and characters.
-
-@em Sticky ( @c ! ) [TRIO]
-
-The modifiers listed for the current specifier will be reused by subsequent
-specifiers of the same group.
-The following specifier groups exists
-@li Integer ( @c i, @c u, @c d, @c o, @c x, @c X )
-@li Floating-point ( @c f, @c F, @c e, @c E, @c g, @c G, @c a, @c A )
-@li Character ( @c c )
-@li String ( @c s )
-@li Pointer ( @c p )
-@li Count ( @c n )
-@li Errno ( @c m )
-@li Group ( @c [] )
-
-The sticky modifiers are active until superseeded by other sticky modifiers,
-or the end of the format string is reached.
-Local modifiers overrides sticky modifiers for the given specifier only.
-@verbatim
-  trio_printf("|%!08#x|%04x|%x|\n", 42, 42, 42);
-  |0x00002a|0x2a|0x00002a|
-@endverbatim
-
-@b Specifiers
-
-@em Percent ( @c % )
-
-Produce a percent ( @c % ) character. This is used to quote the indication
-character. No modifiers are allowed.
-The full syntax is @c %%.
-@verbatim
-  trio_printf("Percent is %%\n");
-  Percent is %
-@endverbatim
-
-@em Hex @em floats ( @c a, @c A ) [C99]
-
-Output a hexadecimal (base 16) representation of a floating point number. The
-number is automatically preceeded by @c 0x ( or @c 0X ). The exponent is
-@c p ( or @c P ).
-@verbatim
-  trio_printf("|%a|%A|\n", 3.1415, 3.1415e20);
-  |0x3.228bc|0X3.228BCP+14|
-@endverbatim
-
-@em Binary @em numbers ( @c b, @c B ) [MISC - SCO UnixWare 7]
-
-DEPRECATED: Use Base modifier @c %..2i instead.
-
-@em Character ( @c c )
-
-Output a single character.
-
-@li Quote ( @c ' ) [TRIO].
-Quote the character.
-
-@em Decimal ( @c d )
-
-Output a decimal (base 10) representation of a number.
-
-@li Grouping ( @c ' ) [TRIO].
-The number is separated by the locale thousand separator.
-@verbatim
-  trio_printf("|%'ld|\n", 1234567);
-  |1,234,567|
-@endverbatim
-
-@em Floating-point ( @c e, @c E)
-
-Output a decimal floating-point number.
-The style is @c [-]9.99e[-]9, where
-@li @c [-]9.99 is the mantissa (as described for the @c f, @c F specifier), and
-@li @c e[-]9 is the exponent indicator (either @c e or @c E, depending on the
-floating-point specifier), followed by an optional sign and the exponent
-
-If the precision is wider than the maximum number of digits that can be
-represented by the floating-point unit, then the number will be adequately
-rounded. For example, assuming DBL_DIG is 15
-@verbatim
-  trio_printf("|%.18e|\n", (1.0 / 3.0));
-  |3.333333333333333000e-01|
-@endverbatim
-
-@em Floating-point ( @c f, @c F )
-
-Output a decimal floating-point number.
-The style is @c [-]9.99, where
-@li @c [-] is an optional sign (either @c + or @c -),
-@li @c 9 is the integer-part (possibly interspersed with thousand-separators),
-@li @c . is the decimal-point (depending on the locale), and
-@li @c 99 is the fractional-part.
-
-If more digits are needed to output the number, than can be represented with
-the accuracy of the floating-point unit, then the number will be adequately
-rounded. For example, assuming that DBL_DIG is 15
-@verbatim
-  trio_printf("|%f|\n", (2.0 / 3.0) * 1E18);
-  |666666666666666700.000000|
-@endverbatim
-
-The following modifiers holds a special meaning for this specifier
-@li Alternative ( @c # ) [C99].
-Add decimal point.
-@li Grouping ( @c ' ) [TRIO].
-Group integer part of number into thousands (according to locale).
-
-@em Floating-point ( @c g, @c G)
-
-Output a decimal floating-point representation of a number. The format of
-either the @c f, @c F specifier or the @c e, @c E specifier is used, whatever
-produces the shortest result.
-
-@em Integer ( @c i )
-
-Output a signed integer. Default base is 10.
-
-@em Errno ( @c m ) [GNU]
-
-@em Count ( @c n )
-
-Insert into the location pointed to by the argument, the number of octets
-written to the output so far.
-
-@em Octal ( @c o )
-
-Output an octal (base 8) representation of a number.
-
-@em Pointer ( @c p )
-
-Ouput the address of the argument. The address is printed as a hexadecimal
-number. If the argument is the NULL pointer the text @c (nil) will be used
-instead.
-@li Alternative ( @c # ) [TRIO].
-Prepend 0x
-
-@em String ( @c s, @c S )
-
-Output a string. The argument must point to a zero terminated string. If the
-argument is the NULL pointer the text @c (nil) will be used instead.
-@c S is equivalent to @c ls.
-@li Alternative ( @c # ) [TRIO].
-Escape non-printable characters.
-
-Non-printable characters are converted into C escapes, or hexadecimal numbers
-where no C escapes exists for the character. The C escapes, the hexadecimal
-number, and all backslashes are prepended by a backslash ( @c \ ).
-The supported C escapes are
-@li @c \a (\007) = alert
-@li @c \b (\010) = backspace
-@li @c \f (\014) = formfeed
-@li @c \n (\012) = newline
-@li @c \r (\015) = carriage return
-@li @c \t (\011) = horizontal tab
-@li @c \v (\013) = vertical tab
-
-@verbatim
-  trio_printf("|One %s Three|One %'s Three|\n", "Two", "Two");
-  |One Two Three|One "Two" Three|
-
-  trio_printf("|Argument missing %s|\n", NULL);
-  |Argument missing (nil)|
-
-  trio_printf("|%#s|\n", "\007 \a.");
-  |\a \a.|
-@endverbatim
-
-@em Unsigned ( @c u )
-
-Output an unsigned integer. Default base is 10.
-
-@em Hex ( @c x, @c X )
-
-Output a hexadecimal (base 16) representation of a number.
-
-@li Alternative ( @c # ).
-Preceed the number by @c 0x ( or @c 0X ). The two characters are counted
-as part of the width.
-
-@em User-defined ( @c <> )
-
-Invoke user-defined formatting.
-See @ref trio_register for further information.
-
-@b RETURN @b VALUES
-
-All functions returns the number of outputted characters. If an error occured
-then a negative error code is returned [TRIO]. Note that this is a deviation
-from the standard, which simply returns -1 (or EOF) and errno set
-appropriately.
-The error condition can be detected by checking whether the function returns
-a negative number or not, and the number can be parsed with the following
-macros. The error codes are primarily intended as debugging aide for the
-developer.
-
-@li TRIO_EINVAL: Invalid argument.
-@li TRIO_ETOOMANY: Too many arguments.
-@li TRIO_EDBLREF: Double argument reference.
-@li TRIO_EGAP: Argument reference gap.
-@li TRIO_ENOMEM: Out of memory.
-@li TRIO_ERANGE: Invalid range.
-@li TRIO_ERRNO: The error is specified by the errno variable.
-
-Example:
-@verbatim
-  int rc;
-
-  rc = trio_printf("%r\n", 42);
-  if (rc < 0) {
-    if (TRIO_ERROR_CODE(rc) != TRIO_EOF) {
-      trio_printf("Error: %s at position %d\n",
-                  TRIO_ERROR_NAME(rc),
-                  TRIO_ERROR_POSITION(rc));
-    }
-  }
-@endverbatim
-
-@b SEE @b ALSO
-
-@e trio_scanf, @e trio_register.
-
-@b NOTES
-
-The printfv family uses an array rather than the stack to pass arguments.
-This means that @c short @c int and @c float values will not be handled by
-the default argument promotion in C. Instead, these values must be explicitly
-converted with the Short (h) modifier in both cases.
-
-Example:
-@verbatim
-  void *array[2];
-  float float_number = 42.0;
-  short short_number = 42;
-
-  array[0] = &float_number;
-  array[1] = &short_number;
-
-  trio_printfv("%hf %hd\n", array); /* CORRECT */
-  trio_printfv("%f %d\n", array); /* WRONG */
-@endverbatim
-
-@b CONFORMING @b TO
-
-Throughout this document the following abbreviations have been used to
-indicate what standard a feature conforms to. If nothing else is indicated
-ANSI C (C89) is assumed.
-
-@li [C89] ANSI X3.159-1989
-@li [C99] ISO/IEC 9899:1999
-@li [UNIX98] The Single UNIX Specification, Version 2
-@li [BSD] 4.4BSD
-@li [GNU] GNU libc
-@li [MSVC] Microsoft Visual C
-@li [MISC] Other non-standard sources
-@li [TRIO] Extensions specific for this package
-
-*/
diff --git a/trio/doc/doc_register.h b/trio/doc/doc_register.h
deleted file mode 100644 (file)
index 3ce86c5..0000000
+++ /dev/null
@@ -1,384 +0,0 @@
-/*************************************************************************
- *
- * $Id: doc_register.h,v 1.3 2008/10/12 12:09:51 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/** @addtogroup UserDefined User-defined Formatted Printing Functions.
-Functions for using customized formatting specifiers.
-
-@b SYNOPSIS
-
-@verbatim
-cc ... -ltrio -lm
-
-#include <trio.h>
-#include <triop.h>
-@endverbatim
-
-@b DESCRIPTION
-
-This documentation is incomplete.
-
-@b User-defined @b Specifier
-
-The user-defined specifier consists of a start character (\074 = '<'), an
-optional namespace string followed by a namespace separator (\072 = ':'),
-a format string, an optional skipping separator (\174 = '|'), and an end
-character (\076 = '>').
-
-The namespace string can consist of alphanumeric characters, and is used to
-define a named reference (see below). The namespace is case-sensitive. If no
-namespace is specified, then we use an unnamed reference (see below).
-
-The format can consist of any character except the end character ('>'), the
-namespace separator (':'), the skipping separator ('|'), and the nil character
-(\000).
-
-Any modifier can be used together with the user-defined specifier.
-
-There are two formats for invoking a user-defined specifier. The first format
-is an extension of the normal printf/scanf formatting. It uses the percent
-character (\045 = '%') followed by optional qualifiers and a specifier. For
-example:
-
-@verbatim
-  trio_printf("%<format>\n", my_handle, my_data);
-@endverbatim
-
-Some C compilers can issue a warning if there is a mismatch between specifiers
-and arguments. Unfortunately, these warnings does not work with the first
-format for user-defined specifiers. Therefore the second format has been
-introduced. The second format can only be applied to user-defined specifiers.
-
-The second format starts with a dollar character (\044 = '$') instead of the
-percent character, and is followed by optional qualifiers and the user-defined
-specifier. If the specifier contains a pipe character (\174 = '|'), then
-everything between the pipe character and the end character ('>') is ignored.
-The ignored part can be used to list the normal specifiers that the C compiler
-uses to determine mismatches. For example:
-
-@verbatim
-  trio_printf("$<format|%p%p>\n", my_handle, my_data);
-@endverbatim
-
-@b Registering
-
-A user-defined specifier must be registered before it can be used.
-Unregistered user-defined specifiers are ignored. The @ref trio_register
-function is used to register a user-defined specifier. It takes two argument,
-a callback function and a namespace, and it returns a handle. The handle must
-be used to unregister the specifier later.
-
-The following example registers a user-define specifier with the "my_namespace"
-namespace:
-
-@verbatim
-  my_handle = trio_register(my_callback, "my_namespace");
-@endverbatim
-
-There can only be one user-defined specifier with a given namespace. There
-can be an unlimited number (subject to maximum length of the namespace) of
-different user-defined specifiers.
-
-Passing NULL as the namespace argument results in an anonymous reference.
-There can be an unlimited number of anonymous references.
-
-@b REFERENCES
-
-There are two ways that a registered callback can be called. Either the
-user-defined specifier must contain the registered namespace in the format
-string, or the handle is passed as an argument to the formatted printing
-function.
-
-If the namespace is used, then a user-defined pointer must be passed as an
-argument:
-
-@verbatim
-  trio_printf("%<my_namespace:format>\n", my_data);
-@endverbatim
-
-If the handle is used, then the user-defined specifier must not contain a
-namespace. Instead the handle must be passed as an argument, followed by a
-user-defined pointer:
-
-@verbatim
-  trio_printf("%<format>\n", my_handle, my_data);
-@endverbatim
-
-The two examples above are equivalent.
-
-There must be exactly one user-defined pointer per user-defined specifier.
-This pointer can be used within the callback function with the
-@ref trio_get_argument getter function (see below).
-
-The format string is optional. It can be used within the callback function
-with the @ref trio_get_format getter function.
-
-@b Anonymous @b References
-Anonymous references are specified by passing NULL as the namespace.
-
-The handle must be passed as an argument followed by a user-defined pointer.
-No namespace can be specified.
-
-@verbatim
-  anon_handle = trio_register(callback, NULL);
-  trio_printf("%<format>\n", anon_handle, my_data);
-@endverbatim
-
-@b Restrictions
-
-@li The length of the namespace string cannot exceed 63 characters.
-@li The length of the user-defined format string cannot exceed 255 characters.
-@li User-defined formatting cannot re-define existing specifiers.
-This restriction was imposed because the existing formatting specifiers have
-a well-defined behaviour, and any re-definition would apply globally to an
-application (imagine a third-party library changing the behaviour of a
-specifier that is crusial to your application).
-
-@b CALLBACK @b FUNCTION
-
-The callback function will be called if a matching user-defined specifier
-is found within the formatting string. The callback function takes one input
-parameter, an opaque reference which is needed by the private functions. It
-returns an @c int, which is currently ignored. The prototype is
-
-@verbatim
-  int (*trio_callback_t)(void *ref);
-@endverbatim
-
-See the Example section for full examples.
-
-@b PRINTING @b FUNCTIONS
-
-The following printing functions must only be used inside a callback function.
-These functions will print to the same output medium as the printf function
-which invoked the callback function. For example, if the user-defined
-specifier is used in an sprintf function, then these print functions will
-output their result to the same string.
-
-@b Elementary @b Printing
-
-There are a number of function to print elementary data types.
-
-@li @ref trio_print_int Print a signed integer. For example:
-@verbatim
-  trio_print_int(42);
-@endverbatim
-@li @ref trio_print_uint Print an unsigned integer.
-@li @ref trio_print_double Print a floating-point number.
-@li @ref trio_print_string Print a string. For example:
-@verbatim
-  trio_print_string("Hello World");
-  trio_print_string(trio_get_format());
-@endverbatim
-@li @ref trio_print_pointer Print a pointer.
-
-@b Formatted @b Printing
-
-The functions @ref trio_print_ref, @ref trio_vprint_ref, and
-@ref trio_printv_ref outputs a formatted string just like its printf
-equivalents.
-
-@verbatim
-  trio_print_ref(ref, "There are %d towels\n", 42);
-  trio_print_ref(ref, "%<recursive>\n", recursive_writer, trio_get_argument(ref));
-@endverbatim
-
-@b GETTER @b AND @b SETTER @b FUNCTIONS
-
-The following getter and setter functions must only be used inside a callback
-function. They can either operate on the modifiers or on special data.
-
-@b Modifiers
-
-The value of a modifier, or a boolean indication of its presence or absence,
-can be found or set with the getter and setter functions.
-The generic prototypes of the these getter and setter functions are
-
-@verbatim
-  int  trio_get_???(void *ref);
-  void trio_set_???(void *ref, int);
-@endverbatim
-
-where @c ??? refers to a modifier. For example, to get the width of the
-user-defined specifier use
-
-@verbatim
-  int width = trio_get_width(ref);
-@endverbatim
-
-@b Special @b Data
-
-Consider the following user-defined specifier, in its two possible referencing
-presentations.
-
-@verbatim
-  trio_printf("%<format>\n", namespace_writer, argument);
-  trio_printf("%<namespace:format>\n", argument);
-@endverbatim
-
-@ref trio_get_format will get the @p format string, and
-@ref trio_get_argument} will get the @p argument parameter.
-There are no associated setter functions.
-
-@b EXAMPLES
-
-The following examples show various types of user-defined specifiers. Although
-each specifier is demonstrated in isolation, they can all co-exist within the
-same application.
-
-@b Time @b Example
-
-Print the time in the format "HOUR:MINUTE:SECOND" if "time" is specified inside
-the user-defined specifier.
-
-@verbatim
-  static int time_print(void *ref)
-  {
-    const char *format;
-    time_t *data;
-    char buffer[256];
-
-    format = trio_get_format(ref);
-    if ((format) && (strcmp(format, "time") == 0)) {
-      data = trio_get_argument(ref);
-      if (data == NULL)
-        return -1;
-      strftime(buffer, sizeof(buffer), "%H:%M:%S", localtime(data));
-      trio_print_string(ref, buffer);
-    }
-    return 0;
-  }
-@endverbatim
-
-@verbatim
-  int main(void)
-  {
-    void *handle;
-    time_t now = time(NULL);
-
-    handle = trio_register(time_print, "my_time");
-
-    trio_printf("%<time>\n", handle, &now);
-    trio_printf("%<my_time:time>\n", &now);
-
-    trio_unregister(handle);
-    return 0;
-  }
-@endverbatim
-
-@b Complex @b Numbers @b Example
-
-Consider a complex number consisting of a real part, re, and an imaginary part,
-im.
-
-@verbatim
-  struct Complex {
-    double re;
-    double im;
-  };
-@endverbatim
-
-This example can print such a complex number in one of two formats.
-The default format is "re + i im". If the alternative modifier is used, then
-the format is "r exp(i theta)", where r is the length of the complex vector
-(re, im) and theta is its angle.
-
-@verbatim
-  static int complex_print(void *ref)
-  {
-    struct Complex *data;
-    const char *format;
-
-    data = (struct Complex *)trio_get_argument(ref);
-    if (data) {
-      format = trio_get_format(ref);
-
-      if (trio_get_alternative(ref)) {
-        double r, theta;
-
-        r = sqrt(pow(data->re, 2) + pow(data->im, 2));
-        theta = acos(data->re / r);
-        trio_print_ref(ref, "%#f exp(i %#f)", r, theta);
-
-      } else {
-        trio_print_ref(ref, "%#f + i %#f", data->re, data->im);
-      }
-    }
-    return 0;
-  }
-@endverbatim
-
-@verbatim
-  int main(void)
-  {
-    void *handle;
-
-    handle = trio_register(complex_print, "complex");
-
-    /* Normal format. With handle and the with namespace */
-    trio_printf("%<>\n", handle, &complex);
-    trio_printf("%<complex:>\n", &complex);
-    /* In exponential notation */
-    trio_printf("%#<>\n", handle, &complex);
-    trio_printf("%#<complex:unused data>\n", &complex);
-
-    trio_unregister(handle);
-    return 0;
-  }
-@endverbatim
-
-@b RETURN @b VALUES
-
-@ref trio_register returns a handle, or NULL if an error occured.
-
-@b SEE @b ALSO
-
-@ref trio_printf
-
-@b NOTES
-
-User-defined specifiers, @ref trio_register, and @ref trio_unregister are
-not thread-safe. In multi-threaded applications they must be guarded by
-mutexes. Trio provides two special callback functions, called ":enter" and
-":leave", which are invoked every time a thread-unsafe operation is attempted.
-As the thread model is determined by the application, these callback functions
-must be implemented by the application.
-
-The following callback functions are for demonstration-purposes only.
-Replace their bodies with locking and unlocking of a mutex to achieve
-thread-safety.
-@verbatim
-  static int enter_region(void *ref)
-  {
-    fprintf(stderr, "Enter Region\n");
-    return 1;
-  }
-
-  static int leave_region(void *ref)
-  {
-    fprintf(stderr, "Leave Region\n");
-    return 1;
-  }
-@endverbatim
-These two callbacks must be registered before other callbacks are registered.
-@verbatim
-  trio_register(enter_region, ":enter");
-  trio_register(leave_region, ":leave");
-
-  another_handle = trio_register(another_callback, NULL);
-@endverbatim
-
-*/
diff --git a/trio/doc/doc_scanf.h b/trio/doc/doc_scanf.h
deleted file mode 100644 (file)
index 4d997d4..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*************************************************************************
- *
- * $Id: doc_scanf.h,v 1.1 2001/12/27 17:29:20 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/** @addtogroup Scanf Formatted Scanning Functions.
-Variations of formatted scanning functions.
-
-@b SYNOPSIS
-
-@verbatim
-cc ... -ltrio -lm
-
-#include <trio.h>
-@endverbatim
-
-@b DESCRIPTION
-
-This documentation is incomplete.
-The documentation of the scanf family in [C99] and [UNIX98] also applies
-to the trio counterparts.
-
-@b SCANNING
-
-The scanning is controlled by the format string.
-The format string can contain normal text and conversion indicators.
-The normal text can be any character except the nil character
-(\000) and the percent character (\045 = '\%').
-Conversion indicators consists of an indication character (%), followed by
-zero or more conversion modifiers, and exactly one conversion specifier.
-
-@b Modifiers
-
-@em Positional ( @c 9$ ) [UNIX98]
-
-See @ref trio_printf.
-
-@b Specifiers
-
-@em Percent ( @c % )
-
-@em Character ( @c c )
-
-@em Decimal ( @c d )
-
-@em Floating-point ( @c a, @c A, @c e, @c E, @c f, @c F, @c g, @c G )
-
-@em Integer ( @c i )
-
-@em Count ( @c n )
-
-@em Octal ( @c o )
-
-@em Pointer ( @c p )
-
-@em String ( @c s )
-
-@em Unsigned ( @c u )
-
-@em Hex ( @c x, @c X )
-
-@em Scanlist ( @c [] )
-
-Scanlist Exclusion (@c ^ )
-
-Scanlist Range ( @c - ) [TRIO]
-
-@li Only increasing ranges, i.e. @c [a-b], but not @c [b-a].
-@li Transitive ranges, ie. @c [a-b-c] equals @c [a-c].
-@li Trailing minus, ie. @c [a-] is interpreted as an @c a and a @c -.
-@li Duplicates are ignored.
-
-Scanlist Equivalence Class Expression ( @c [= @c =] ) [TRIO]
-
-Locale dependent (LC_COLLATE).
-Only one expression can appear inside the delimiters.
-@li @c [=a=] All letters in the same equivalence class as the letter @c a.
-@verbatim
-  trio_scanf("%[[=a=]b]\n", buffer);
-  trio_scanf("%[[=a=][=b=]]\n", buffer);
-@endverbatim
-
-Scanlist Character Class Expression ( @c [: @c :]) [TRIO]
-Locale dependent (LC_CTYPE).
-Only one expression can appear inside the delimiters.
-@li @c [:alnum:] Same as @c [:alpha:] and @c [:digit:]
-@li @c [:alpha:] Same as @c [:lower:] and @c [:upper:]
-@li @c [:cntrl:] Control characters
-@li @c [:digit:] Decimal digits
-@li @c [:graph:] Printable characters except space
-@li @c [:lower:] Lower case alphabetic letters
-@li @c [:print:] Printable characters
-@li @c [:punct:] Punctuation
-@li @c [:space:] Whitespace characters
-@li @c [:upper:] Upper case alphabetic letters
-@li @c [:xdigit:] Hexadecimal digits
-@verbatim
-  trio_scanf("%[[:alnum:]]\n", buffer);
-  trio_scanf("%[[:alpha:][:digit:]]\n", buffer);
-@endverbatim
-
-@b RETURN @b VALUES
-
-@b SEE @b ALSO
-
-@ref trio_printf
-
-*/
diff --git a/trio/doc/doc_static.h b/trio/doc/doc_static.h
deleted file mode 100644 (file)
index 6816196..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/*************************************************************************
- *
- * $Id: doc_static.h,v 1.1 2001/12/27 17:29:20 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/** @addtogroup StaticStrings Static String Functions.
-Replacements for the standard C string functions.
-
-@b SYNOPSIS
-
-@verbatim
-cc ... -ltrio -lm
-
-#include <triostr.h>
-@endverbatim
-
-@b DESCRIPTION
-
-This package renames, fixes, and extends the standard C string handling
-functions.
-
-@b Naming
-
-Renaming is done to provide more clear names, to provide a consistant naming
-and argument policy, and to hide portability issues.
-
-@li All functions starts with "trio_".
-@li Target is always the first argument, if present, except where the target
-is optional, such as @ref trio_to_double.
-@li Functions requiring a size for target includes "_max" in its name, and
-the size is always the second argument.
-@li Functions performing case-sensitive operations includes "_case" in its
-name.
-
-@b Fixing
-
-Fixing is done to avoid subtle error conditions.
-For example, @c strncpy does not terminate the result with a zero if the
-source string is bigger than the maximal length, so technically the result
-is not a C string anymore. @ref trio_copy_max makes sure that the result
-is zero terminated.
-
-@b Extending
-
-Extending is done to provide a richer set of fundamental functions.
-This includes functionality such as wildcard matching ( @c trio_match )
-and calculation of hash values ( @c trio_hash ).
-
-*/
diff --git a/trio/doc/footer.html b/trio/doc/footer.html
deleted file mode 100644 (file)
index f149fa2..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-<HR>
-<center class="copyright">Copyright (C) 2001 - 2006 Bj&oslash;rn Reese and Daniel Stenberg.</center>
-</body>
-</html>
diff --git a/trio/doc/header.html b/trio/doc/header.html
deleted file mode 100644 (file)
index fd2edd1..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
- <title>TRIO</title>
- <link href="trio.css" rel="stylesheet" type="text/css">
-</head>
-<body>
diff --git a/trio/doc/trio.cfg b/trio/doc/trio.cfg
deleted file mode 100644 (file)
index 4bc1ee6..0000000
+++ /dev/null
@@ -1,873 +0,0 @@
-# Doxyfile 1.2.12
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-#       TAG = value [value, ...]
-# For lists items can also be appended using:
-#       TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# General configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
-# by quotes) that should identify the project.
-
-PROJECT_NAME           = TRIO
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
-# This could be handy for archiving the generated documentation or 
-# if some version control system is used.
-
-PROJECT_NUMBER         = 
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
-# base path where the generated documentation will be put. 
-# If a relative path is entered, it will be relative to the location 
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY       = 
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
-# documentation generated by doxygen is written. Doxygen will use this 
-# information to generate all constant output in the proper language. 
-# The default language is English, other supported languages are: 
-# Brazilian, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French, 
-# German, Hungarian, Italian, Japanese, Korean, Norwegian, Polish, 
-# Portuguese, Romanian, Russian, Slovak, Slovene, Spanish and Swedish.
-
-OUTPUT_LANGUAGE        = English
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
-# documentation are documented, even if no documentation was available. 
-# Private class members and static file members will be hidden unless 
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL            = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
-# will be included in the documentation.
-
-EXTRACT_PRIVATE        = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file 
-# will be included in the documentation.
-
-EXTRACT_STATIC         = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
-# undocumented members of documented classes, files or namespaces. 
-# If set to NO (the default) these members will be included in the 
-# various overviews, but no documentation section is generated. 
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS     = YES
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
-# undocumented classes that are normally visible in the class hierarchy. 
-# If set to NO (the default) these class will be included in the various 
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES     = YES
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
-# include brief member descriptions after the members that are listed in 
-# the file and class documentation (similar to JavaDoc). 
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC      = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
-# the brief description of a member or function before the detailed description. 
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF           = YES
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
-# Doxygen will generate a detailed section even if there is only a brief 
-# description.
-
-ALWAYS_DETAILED_SEC    = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
-# path before files name in the file list and in the header files. If set 
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES        = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
-# can be used to strip a user defined part of the path. Stripping is 
-# only done if one of the specified strings matches the left-hand part of 
-# the path. It is allowed to use relative paths in the argument list.
-
-STRIP_FROM_PATH        = 
-
-# The INTERNAL_DOCS tag determines if documentation 
-# that is typed after a \internal command is included. If the tag is set 
-# to NO (the default) then the documentation will be excluded. 
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS          = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
-# doxygen to hide any special comment blocks from generated source code 
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS    = YES
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
-# file names in lower case letters. If set to YES upper case letters are also 
-# allowed. This is useful if you have classes or files whose names only differ 
-# in case and if your file system supports case sensitive file names. Windows 
-# users are adviced to set this option to NO.
-
-CASE_SENSE_NAMES       = NO
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
-# (but less readable) file names. This can be useful is your file systems 
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES            = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
-# will show members with their full class and namespace scopes in the 
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES       = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
-# will generate a verbatim copy of the header file for each class for 
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS       = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
-# will put list of the files that are included by a file in the documentation 
-# of that file.
-
-SHOW_INCLUDE_FILES     = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
-# will interpret the first line (until the first dot) of a JavaDoc-style 
-# comment as the brief description. If set to NO, the JavaDoc 
-# comments  will behave just like the Qt-style comments (thus requiring an 
-# explict @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF      = YES
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
-# member inherits the documentation from any documented member that it 
-# reimplements.
-
-INHERIT_DOCS           = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
-# is inserted in the documentation for inline members.
-
-INLINE_INFO            = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
-# will sort the (detailed) documentation of file and class members 
-# alphabetically by member name. If set to NO the members will appear in 
-# declaration order.
-
-SORT_MEMBER_DOCS       = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
-# tag is set to YES, then doxygen will reuse the documentation of the first 
-# member in the group (if any) for the other members of the group. By default 
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC   = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE               = 8
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or 
-# disable (NO) the todo list. This list is created by putting \todo 
-# commands in the documentation.
-
-GENERATE_TODOLIST      = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or 
-# disable (NO) the test list. This list is created by putting \test 
-# commands in the documentation.
-
-GENERATE_TESTLIST      = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or 
-# disable (NO) the bug list. This list is created by putting \bug 
-# commands in the documentation.
-
-GENERATE_BUGLIST       = YES
-
-# This tag can be used to specify a number of aliases that acts 
-# as commands in the documentation. An alias has the form "name=value". 
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
-# put the command \sideeffect (or @sideeffect) in the documentation, which 
-# will result in a user defined paragraph with heading "Side Effects:". 
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES                = 
-
-# The ENABLED_SECTIONS tag can be used to enable conditional 
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS       = 
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
-# the initial value of a variable or define consist of for it to appear in 
-# the documentation. If the initializer consists of more lines than specified 
-# here it will be hidden. Use a value of 0 to hide initializers completely. 
-# The appearance of the initializer of individual variables and defines in the 
-# documentation can be controlled using \showinitializer or \hideinitializer 
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES  = 30
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
-# only. Doxygen will then generate output that is more tailored for C. 
-# For instance some of the names that are used will be different. The list 
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C  = YES
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
-# at the bottom of the documentation of classes and structs. If set to YES the 
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES        = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated 
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET                  = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are 
-# generated by doxygen. Possible values are YES and NO. If left blank 
-# NO is used.
-
-WARNINGS               = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED   = YES
-
-# The WARN_FORMAT tag determines the format of the warning messages that 
-# doxygen can produce. The string should contain the $file, $line, and $text 
-# tags, which will be replaced by the file and line number from which the 
-# warning originated and the warning text.
-
-WARN_FORMAT            = 
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning 
-# and error messages should be written. If left blank the output is written 
-# to stderr.
-
-WARN_LOGFILE           = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain 
-# documented source files. You may enter file names like "myfile.cpp" or 
-# directories like "/usr/src/myproject". Separate the files or directories 
-# with spaces.
-
-INPUT                  = . doc
-
-# If the value of the INPUT tag contains directories, you can use the 
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank file matching one of the following patterns are included: 
-# *.c *.cc *.cxx *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp 
-# *.h++ *.idl
-
-FILE_PATTERNS          = *.h *.c
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
-# should be searched for input files as well. Possible values are YES and NO. 
-# If left blank NO is used.
-
-RECURSIVE              = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should 
-# excluded from the INPUT source files. This way you can easily exclude a 
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE                = 
-
-# If the value of the INPUT tag contains directories, you can use the 
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
-# certain files from those directories.
-
-EXCLUDE_PATTERNS       = 
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or 
-# directories that contain example code fragments that are included (see 
-# the \include command).
-
-EXAMPLE_PATH           = doc
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
-# and *.h) to filter out the source-files in the directories. If left 
-# blank all files are included.
-
-EXAMPLE_PATTERNS       = 
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
-# searched for input files to be used with the \include or \dontinclude 
-# commands irrespective of the value of the RECURSIVE tag. 
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE      = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or 
-# directories that contain image that are included in the documentation (see 
-# the \image command).
-
-IMAGE_PATH             = 
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should 
-# invoke to filter for each input file. Doxygen will invoke the filter program 
-# by executing (via popen()) the command <filter> <input-file>, where <filter> 
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
-# input file. Doxygen will then use the output that the filter program writes 
-# to standard output.
-
-INPUT_FILTER           = 
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
-# INPUT_FILTER) will be used to filter the input files when producing source 
-# files to browse.
-
-FILTER_SOURCE_FILES    = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
-# be generated. Documented entities will be cross-referenced with these sources.
-
-SOURCE_BROWSER         = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body 
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES         = NO
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
-# then for each documented function all documented 
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default) 
-# then for each documented function all documented entities 
-# called/used by that function will be listed.
-
-REFERENCES_RELATION    = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
-# of all compounds will be generated. Enable this if the project 
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX     = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX    = 5
-
-# In case all classes in a project start with a common prefix, all 
-# classes will be put under the same header in the alphabetical index. 
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX          = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
-# generate HTML output.
-
-GENERATE_HTML          = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT            = 
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard header.
-
-HTML_HEADER            = doc/header.html
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
-# each generated HTML page. If it is left blank doxygen will generate a 
-# standard footer.
-
-HTML_FOOTER            = doc/footer.html
-
-# The HTML_STYLESHEET tag can be used to specify a user defined cascading 
-# style sheet that is used by each HTML page. It can be used to 
-# fine-tune the look of the HTML output. If the tag is left blank doxygen 
-# will generate a default style sheet
-
-HTML_STYLESHEET        = doc/trio.css
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
-# files or namespaces will be aligned in HTML using tables. If set to 
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS     = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
-# will be generated that can be used as input for tools like the 
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP      = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
-# controls if a separate .chi index file is generated (YES) or that 
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI           = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
-# controls whether a binary table of contents is generated (YES) or a 
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC             = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members 
-# to the contents of the Html help documentation and to the tree view.
-
-TOC_EXPAND             = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
-# top of each HTML page. The value NO (the default) enables the index and 
-# the value YES disables it.
-
-DISABLE_INDEX          = NO
-
-# This tag can be used to set the number of enum values (range [1..20]) 
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE   = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that 
-# is generated for HTML Help). For this to work a browser that supports 
-# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+, 
-# or Internet explorer 4.0+). Note that for large projects the tree generation 
-# can take a very long time. In such cases it is better to disable this feature. 
-# Windows users are probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW      = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
-# used to set the initial width (in pixels) of the frame in which the tree 
-# is shown.
-
-TREEVIEW_WIDTH         = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
-# generate Latex output.
-
-GENERATE_LATEX         = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT           = 
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
-# LaTeX documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_LATEX          = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used 
-# by the printer. Possible values are: a4, a4wide, letter, legal and 
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE             = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES         = 
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
-# the generated latex document. The header should contain everything until 
-# the first chapter. If it is left blank doxygen will generate a 
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER           = 
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
-# contain links (just like the HTML output) instead of page references 
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS         = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
-# plain latex in the generated Makefile. Set this option to YES to get a 
-# higher quality PDF documentation.
-
-USE_PDFLATEX           = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
-# command to the generated LaTeX files. This will instruct LaTeX to keep 
-# running if errors occur, instead of asking the user for help. 
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE        = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
-# The RTF output is optimised for Word 97 and may not look very pretty with 
-# other RTF readers or editors.
-
-GENERATE_RTF           = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT             = 
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
-# RTF documents. This may be useful for small projects and may help to 
-# save some trees in general.
-
-COMPACT_RTF            = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
-# will contain hyperlink fields. The RTF file will 
-# contain links (just like the HTML output) instead of page references. 
-# This makes the output suitable for online browsing using WORD or other 
-# programs which support those fields. 
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS         = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's 
-# config file, i.e. a series of assigments. You only have to provide 
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE    = 
-
-# Set optional variables used in the generation of an rtf document. 
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE    = 
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
-# generate man pages
-
-GENERATE_MAN           = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT             = 
-
-# The MAN_EXTENSION tag determines the extension that is added to 
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION          = 
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS              = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will 
-# generate an XML file that captures the structure of 
-# the code including all documentation. Note that this 
-# feature is still experimental and incomplete at the 
-# moment.
-
-GENERATE_XML           = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor   
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
-# evaluate all C-preprocessor directives found in the sources and include 
-# files.
-
-ENABLE_PREPROCESSING   = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
-# names in the source code. If set to NO (the default) only conditional 
-# compilation will be performed. Macro expansion can be done in a controlled 
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION        = YES
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
-# then the macro expansion is limited to the macros specified with the 
-# PREDEFINED and EXPAND_AS_PREDEFINED tags.
-
-EXPAND_ONLY_PREDEF     = YES
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES        = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that 
-# contain include files that are not input files but should be processed by 
-# the preprocessor.
-
-INCLUDE_PATH           = 
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
-# patterns (like *.h and *.hpp) to filter out the header-files in the 
-# directories. If left blank, the patterns specified with FILE_PATTERNS will 
-# be used.
-
-INCLUDE_FILE_PATTERNS  = 
-
-# The PREDEFINED tag can be used to specify one or more macro names that 
-# are defined before the preprocessor is started (similar to the -D option of 
-# gcc). The argument of the tag is a list of macros of the form: name 
-# or name=definition (no spaces). If the definition and the = are 
-# omitted =1 is assumed.
-
-PREDEFINED             = __STDC__=1 TRIO_DOCUMENTATION= TRIO_PUBLIC= TRIO_PRIVATE=static TRIO_CONST=const TRIO_VOLATILE=volatile TRIO_SIGNED=signed TRIO_INLINE=inline TRIO_NOARGS=void TRIO_ARGS1(z,a)=(a) TRIO_ARGS2(z,a,b)=(a,b) TRIO_ARGS3(z,a,b,c)=(a,b,c) TRIO_ARGS4(z,a,b,c,d)=(a,b,c,d) TRIO_ARGS5(z,a,b,c,d,e)=(a,b,c,d,e) TRIO_ARGS6(z,a,b,c,d,e,f)=(a,b,c,d,e,f) TRIO_VARGS2(z,a,b)=(a,b) TRIO_VARGS3(z,a,b,c)=(a,b,c) TRIO_VARGS4(z,a,b,c,d)=(a,b,c,d) TRIO_VARGS5(z,a,b,c,d,e)=(a,b,c,d,e)
-
-# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then 
-# this tag can be used to specify a list of macro names that should be expanded. 
-# The macro definition that is found in the sources will be used. 
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED      = 
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
-# doxygen's preprocessor will remove all function-like macros that are alone 
-# on a line and do not end with a semicolon. Such function macros are typically 
-# used for boiler-plate code, and will confuse the parser if not removed.
-
-SKIP_FUNCTION_MACROS   = YES
-
-#---------------------------------------------------------------------------
-# Configuration::addtions related to external references   
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tagfiles.
-
-TAGFILES               = 
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE       = 
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
-# in the class index. If set to NO only the inherited external classes 
-# will be listed.
-
-ALLEXTERNALS           = NO
-
-# The PERL_PATH should be the absolute path and name of the perl script 
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH              = 
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool   
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
-# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or 
-# super classes. Setting the tag to NO turns the diagrams off. Note that this 
-# option is superceded by the HAVE_DOT option below. This is only a fallback. It is 
-# recommended to install and use dot, since it yield more powerful graphs.
-
-CLASS_DIAGRAMS         = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
-# available from the path. This tool is part of Graphviz, a graph visualization 
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT               = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect inheritance relations. Setting this tag to YES will force the 
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH            = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
-# will generate a graph for each documented class showing the direct and 
-# indirect implementation dependencies (inheritance, containment, and 
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH    = YES
-
-# If set to YES, the inheritance and collaboration graphs will show the 
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS     = YES
-
-# If set to YES, the inheritance and collaboration graphs will hide 
-# inheritance and usage relations if the target is undocumented 
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS   = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
-# tags are set to YES then doxygen will generate a graph for each documented 
-# file showing the direct and indirect include dependencies of the file with 
-# other documented files.
-
-INCLUDE_GRAPH          = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
-# documented header file showing the documented files that directly or 
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH      = YES
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY    = YES
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be 
-# found. If left blank, it is assumed the dot tool can be found on the path.
-
-DOT_PATH               = 
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that 
-# contain dot files that are included in the documentation (see the 
-# \dotfile command).
-
-DOTFILE_DIRS           = 
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images.
-
-MAX_DOT_GRAPH_WIDTH    = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
-# this value, doxygen will try to truncate the graph, so that it fits within 
-# the specified constraint. Beware that most browsers cannot cope with very 
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT   = 1024
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
-# generate a legend page explaining the meaning of the various boxes and 
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND        = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
-# remove the intermedate dot files that are used to generate 
-# the various graphs.
-
-DOT_CLEANUP            = YES
-
-#---------------------------------------------------------------------------
-# Configuration::addtions related to the search engine   
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be 
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE           = NO
-
-# The CGI_NAME tag should be the name of the CGI script that 
-# starts the search engine (doxysearch) with the correct parameters. 
-# A script with this name will be generated by doxygen.
-
-CGI_NAME               = 
-
-# The CGI_URL tag should be the absolute URL to the directory where the 
-# cgi binaries are located. See the documentation of your http daemon for 
-# details.
-
-CGI_URL                = 
-
-# The DOC_URL tag should be the absolute URL to the directory where the 
-# documentation is located. If left blank the absolute path to the 
-# documentation, with file:// prepended to it, will be used.
-
-DOC_URL                = 
-
-# The DOC_ABSPATH tag should be the absolute path to the directory where the 
-# documentation is located. If left blank the directory on the local machine 
-# will be used.
-
-DOC_ABSPATH            = 
-
-# The BIN_ABSPATH tag must point to the directory where the doxysearch binary 
-# is installed.
-
-BIN_ABSPATH            = 
-
-# The EXT_DOC_PATHS tag can be used to specify one or more paths to 
-# documentation generated for other projects. This allows doxysearch to search 
-# the documentation for these projects as well.
-
-EXT_DOC_PATHS          = 
diff --git a/trio/doc/trio.css b/trio/doc/trio.css
deleted file mode 100644 (file)
index 1b3a992..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* HTML tags */
-
-BODY {
- background-color: white;
- color: darkblue;
-}
-
-TD { color: darkblue; }
-
-H1 { text-align: center; }
-
-H3 { font-style: italic; }
-
-HR {
- width: 85%;
- align: center;
-}
-
-.copyright { color: darkblue; }
-
-/* Links */
-
-:link { color: blue; }
-
-:visited { color: purple; }
-
-:active { color: red; }
-
-.el:link { font-style: italic; }
-
-/* Examples */
-
-DIV.fragment {
- color: maroon;
-}
diff --git a/trio/example.c b/trio/example.c
deleted file mode 100644 (file)
index 279ff14..0000000
+++ /dev/null
@@ -1,451 +0,0 @@
-/*************************************************************************
- * For testing purposes
- */
-
-#include <stdarg.h>
-#include <limits.h>
-#include <math.h>
-#include <unistd.h>
-/*  #include <nan.h> */
-#include <wchar.h>
-#include "strio.h"
-#include "trio.h"
-#undef printf
-
-#if !defined(USE_LONGLONG)
-# if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-#  define USE_LONGLONG
-# elif defined(__SUNPRO_C)
-#  define USE_LONGLONG
-# endif
-#endif
-
-#if defined(USE_LONGLONG)
-# define LONGLONG long long
-#else
-# define LONGLONG long
-#endif
-
-#if defined(TRIO_C99)
-# define LONGEST intmax_t
-#else
-# define LONGEST LONGLONG
-#endif
-
-static const char rcsid[] = "@(#)$Id: example.c,v 1.9 2001/11/25 13:47:38 breese Exp $";
-
-/*************************************************************************
- *
- */
-void Dump(char *buffer, int rc)
-{
-  if (rc < 0)
-    {
-      printf("Err = %d (%s), Pos = %d\n",
-            TRIO_ERROR_CODE(rc),
-            TRIO_ERROR_NAME(rc),
-            TRIO_ERROR_POSITION(rc));
-    }
-  else
-    printf("buffer[% 3d] = \"%s\"\n", rc, buffer);
-}
-
-/*************************************************************************
- *
- */
-int main(void)
-{
-  char buffer[512];
-  int rc;
-  LONGLONG int dummy;
-  char *fool;
-  int num;
-  int num2;
-  int count;
-  double dnum;
-  char *end;
-  char text[256];
-  char ch;
-  int nerrors = 0;
-  void *p1;
-  char *p2;
-
-  printf("%s\n", rcsid);
-
-/*    printf("%d %u %d %u\n", */
-/*      INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
-/*    trio_printf("%d %u %d %u\n", */
-/*           INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
-/*    printf("%d %u\n", INT_MIN, INT_MIN); */
-/*    trio_printf("%d %u\n", INT_MIN, INT_MIN); */
-  
-/*    printf("%ld %lu %ld %lu\n", */
-/*      INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
-/*    trio_printf("%ld %lu %ld %lu\n", */
-/*           INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
-/*    printf("%ld %lu\n", INT_MIN, INT_MIN); */
-/*    trio_printf("%ld %lu\n", INT_MIN, INT_MIN); */
-
-/*    printf("%lld %llu %lld %llu\n", */
-/*      INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
-/*    trio_printf("%lld %llu %lld %llu\n", */
-/*           INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
-/*    printf("%lld %llu\n", INT_MIN, INT_MIN); */
-/*    trio_printf("%lld %llu\n", INT_MIN, INT_MIN); */
-
-/*    return 0; */
-
-  
-/*    dnum = StrToDouble("3.14e+44", (const char **)&end); */
-/*    printf("double = %e (%s)\n", dnum, end); */
-/*    dnum = StrToDouble("0xA3.14p44", (const char **)&end); */
-/*    printf("double = %e (%s)\n", dnum, end); */
-
-  /*    trio_printf("%.*stext\n", 0, "-----"); */ /* fails */
-  
-/*    trio_printf("%Zd\n", (size_t)sizeof(char)); */
-  
-/*   rc = StrFormat(buffer, "%a", 3.14e+44); */
-/*   Dump(buffer, rc); */
-  
-  /*  rc = StrFormat(buffer, "Filled string: %-16<fill=_>s", "test"); */
-
-/*   errno = EINTR; */
-/*   rc = StrFormat(buffer, "Error: %m"); */
-
-/*   rc = StrFormat(buffer, "Count %lln", &dummy); */
-/*   printf("dummy = %lld\n", dummy); */
-
-/*   rc = StrFormat(buffer, "Char %<quote='>c", 'X'); */
-
-/*   rc = StrFormatMax(buffer, 20, "Here goes %-20<adjust=_>s", "test"); */
-
-/*    rc = StrFormat(buffer, "Hex-float %a", 3.1415); */
-/*    Dump(buffer, rc); */
-/*    rc = StrFormat(buffer, "Hex-float %A", 3.1415e20); */
-/*    Dump(buffer, rc); */
-/*    rc = StrFormat(buffer, "Double %#g", 3.1415e20); */
-/*    Dump(buffer, rc); */
-/*    rc = StrFormat(buffer, "Double %.3f", 3.1415); */
-/*    Dump(buffer, rc); */
-/*    rc = StrFormat(buffer, "Double %+e", 3.1415); */
-/*    Dump(buffer, rc); */
-
-/*    printf("'%.2f'\n", 99.99999); */
-/*    trio_printf("'%.2f'\n", 99.99999); */
-/*    printf("'%f'\n", 0.0); */
-/*    trio_printf("'%f'\n", 0.0); */
-/*    printf("'%f'\n", 3141.0); */
-/*    trio_printf("'%f'\n", 3141.0); */
-/*    printf("'%#f'\n", 3141.0); */
-/*    trio_printf("'%#f'\n", 3141.0); */
-/*    printf("'%'f'\n", 31415.2); */
-/*    trio_printf("'%'f'\n", 31415.2); */
-/*    printf("'%-16e'\n", 3141.5); */
-/*    trio_printf("'%-16e'\n", 3141.5); */
-/*    printf("'%#f'\n", 3141.0); */
-/*    trio_printf("'%#f'\n", 3141.0); */
-/*    printf("'%f'\n", 3141.5); */
-/*    trio_printf("'%f'\n", 3141.5); */
-/*    printf("'%#.6g'\n", 3141.5); */
-/*    trio_printf("'%#.6g'\n", 3141.5); */
-  
-/*    printf("'%20e'\n", 314.5); */
-/*    trio_printf("'%20e'\n", 314.5); */
-  
-/*    printf("'%-16e'\n", 3141.5); */
-/*    trio_printf("'%-16e'\n", 3141.5); */
-  
-/*    printf("'%#.4g'\n", 314151.5); */
-/*    trio_printf("'%#.4g'\n", 314151.5); */
-  
-/*    printf("'%#.4g'\n", 0.0); */
-/*    trio_printf("'%#.4g'\n", 0.0); */
-  
-/*    printf("'%#.4g'\n", 11.0); */
-/*    trio_printf("'%#.4g'\n", 11.0); */
-
-/*    printf("%f\n", HUGE_VAL); */
-/*    trio_printf("%f\n", HUGE_VAL); */
-/*    printf("%f\n", -HUGE_VAL); */
-/*    trio_printf("%f\n", -HUGE_VAL); */
-/*  #define NAN (cos(HUGE_VAL)) */
-/*    printf("%f\n", NAN); */
-/*    trio_printf("%f\n", NAN); */
-  
-/*    printf("'%+06d'\n", 1234); */
-/*    trio_printf("'%+06d'\n", 1234); */
-/*    printf("'%-#6.3x'\n", 12); */
-/*    trio_printf("'%-#06.3x'\n", 12); */
-/*    printf("'%+6d'\n", 1234); */
-/*    trio_printf("'%+6d'\n", 1234); */
-/*    printf("'%-08d'\n", 12); */
-/*    trio_printf("'%-08d'\n", 12); */
-/*    printf("'%08.6d'\n", 12); */
-/*    trio_printf("'%08.6d'\n", 12); */
-/*    printf("'%4d'\n", 123456); */
-/*    trio_printf("'%4d'\n", 123456); */
-/*    printf("'%.4d'\n", 12); */
-/*    trio_printf("'%.4d'\n", 12); */
-
-/*    trio_printf("%!#08x %04x %..10x\n", 42, 42, 42); */
-/*    trio_printf("%*.*.*i\n", 8, 4, 2, 23); */
-/*    trio_printf("%8.4.2i %<base=2>08i %.8.2i %..2i\n", 23, 23, 23, 23); */
-
-/*    trio_printf("%8i\n", 42); */
-/*    trio_printf("%.7i\n", 42); */
-/*    trio_printf("%..2i\n", 42); */
-/*    trio_printf("%8.7i\n", 42); */
-/*    trio_printf("%8..2i\n", 42); */
-/*    trio_printf("%8.7.2i\n", 42); */
-/*    trio_printf("%*.*.*i\n", 8, 7, 2, 42); */
-
-/*    { */
-/*      LONGLONG ll = 1234567890; */
-/*      rc = trio_printf("%&i %d\n", sizeof(ll), ll, 42); */
-/*      Dump(buffer, rc); */
-/*    } */
-/*    { */
-/*      char ch = 12; */
-/*      rc = trio_printf("%&i %d\n", sizeof(ch), ch, 42); */
-/*      Dump(buffer, rc); */
-/*    } */
-/*    { */
-/*      pid_t pid = 99; */
-/*      rc = trio_printf("%&i %d\n", sizeof(pid), pid, 42); */
-/*      Dump(buffer, rc); */
-/*    } */
-  
-/*    rc = trio_printf("%*.*.*i\n", 6, 4, 10, 12); */
-/*    Dump(buffer, rc); */
-/*    rc = trio_printf("%1$0*3$.*2$d\n", 3141, 6, 10); */
-/*    Dump(buffer, rc); */
-
-/*    rc = trio_asprintf(&end, "%s%n", "0123456789", &num); */
-/*    printf("%d %d '%s'\n", rc, num, end); */
-/*    if (end) */
-/*      free(end); */
-  
-/*    trio_printf("%016e\n", 3141.5); */
-/*    trio_printf("%'f\n", 424242.42); */
-/*    trio_printf("%#.4f\n", 0.0); */
-/*    trio_printf("%'d\n", 424242); */
-
-/*    rc = trio_sprintf(buffer, "%4$d %3$*8$d %2$.*7$d %1$*6$.*5$d\n", */
-/*                 123, */
-/*                 1234, */
-/*                 12345, */
-/*                 123456, */
-/*                 5, 6, 7, 8 */
-/*                 ); */
-/*    Dump(buffer, rc); */
-/*    rc = trio_sprintf(buffer, "%2$s %1$#s", "111", "222"); */
-/*    Dump(buffer, rc); */
-  
-/*    trio_printf("  %x %!#x %g %09x %x\n", 123456, 123456, 123456.0, 123456, 123456); */
-/*    trio_printf("%!'i %f %i\n", 12345, 12345.0, 12345); */
-/*    trio_printf("%!<base=2>i %i\n", 23, 23); */
-
-/*    rc = trio_sprintf(buffer, "%I32d", 12345); */
-/*    Dump(buffer, rc); */
-/*    rc = trio_sprintf(buffer, "%I32I8d", 12345); */
-/*    Dump(buffer, rc); */
-
-/*    rc = trio_sprintf(buffer, "*%5f*", 3.3); */
-/*    Dump(buffer, rc); */
-  
-/*    { */
-/*      wchar_t *wstring = L"some data"; */
-/*      wchar_t wbuffer[512]; */
-    
-/*      rc = trio_sprintf(buffer, "%ls", wstring); */
-/*      Dump(buffer, rc); */
-
-/*      rc = trio_sscanf(buffer, "%ls", wbuffer); */
-/*      Dump(buffer, rc); */
-/*      rc = trio_sprintf(buffer, "%ls", wbuffer); */
-/*      Dump(buffer, rc); */
-/*    } */
-  
-  /* rc = StrFormat(buffer, "\040-\040\040-\n"); */
-
-/*   rc = StrFormat(buffer, "%.*s@%s", 3, "Daniel", "Fool"); */
-/*   rc = StrFormatAppendMax(buffer, 512, " %s is a doh", "Simpson"); */
-
-/*   rc = StrFormat(buffer, "hello %1$d %1$d", 31, 32); */
-/*   Dump(buffer, rc); */
-/*   rc = StrFormat(buffer, "%2$d %3$d", 31, 32, 33); */
-/*   Dump(buffer, rc); */
-  
-/*    rc = trio_sprintf(buffer, "%d say %g hey %s", 42, 3.14, "text"); */
-/*    Dump(buffer, rc); */
-/*    trio_sscanf(buffer, "%d %*s %e hey %s", &num, &dnum, text); */
-/*    printf("num = %d, dnum = %e, text = \"%s\"\n", num, dnum, text); */
-
-/*    rc = trio_sprintf(buffer, "%g", HUGE_VAL); */
-/*    Dump(buffer, rc); */
-/*    trio_sscanf(buffer, "%f", &dnum); */
-/*    printf("dnum = %e\n", dnum); */
-
-/*    rc = trio_sprintf(buffer, "%g", -HUGE_VAL); */
-/*    Dump(buffer, rc); */
-/*    trio_sscanf(buffer, "%f", &dnum); */
-/*    printf("dnum = %e\n", dnum); */
-
-/*  #if defined(NAN) */
-/*    rc = trio_sprintf(buffer, "%g", NAN); */
-/*    Dump(buffer, rc); */
-/*    if ((rc = trio_sscanf(buffer, "%f", &dnum)) < 0) */
-/*      Dump(buffer, rc); */
-/*    else */
-/*      printf("dnum = %e\n", dnum); */
-/*  #endif */
-
-/*    rc = trio_sprintf(buffer, "%*d", 6, 1234); */
-/*    Dump(buffer, rc); */
-
-/*    rc = trio_sprintf(buffer, "'%!08.6d' '%!d' '%d'", 4, 6, 8); */
-/*    Dump(buffer, rc); */
-
-/*    rc = trio_sprintf(buffer, "%0g", 0.123); */
-/*    Dump(buffer, rc); */
-  
-/*    { */
-/*      void *argarray[4]; */
-/*      int value = 42; */
-/*      double number = 123.456; */
-/*      float small_number = 123.456; */
-    
-/*      argarray[0] = &value; */
-/*      argarray[1] = "my string"; */
-/*      rc = trio_sprintfv(buffer, "%d %s", argarray); */
-/*      Dump(buffer, rc); */
-/*      rc = trio_snprintfv(buffer, 8, "%d %s", argarray); */
-/*      Dump(buffer, rc); */
-
-/*      argarray[0] = &num; */
-/*      argarray[1] = text; */
-/*      rc = trio_sscanfv(buffer, "%d %s", argarray); */
-/*      Dump(buffer, rc); */
-/*      printf("num = %d  text = \"%s\"\n", num, text); */
-    
-/*      argarray[0] = &number; */
-/*      argarray[1] = &small_number; */
-/*      rc = trio_sprintfv(buffer, "%f %hf", argarray); */
-/*      Dump(buffer, rc); */
-/*      printf("number = %f  small_number = \"%f\"\n", number, small_number); */
-/*    } */
-  
-  rc = trio_sprintf(buffer, "abcba");
-  Dump(buffer, rc);
-  trio_sscanf(buffer, "%[ab]", text);
-  printf("text = \"%s\"\n", text);
-  trio_sscanf(buffer, "%*[ab]c%[^\n]", text);
-  printf("text = \"%s\"\n", text);
-
-  trio_sprintf(buffer, "aabcdba aaa");
-  rc = trio_sscanf(buffer, "%s", text);
-  Dump(buffer, rc);
-  printf("text = \"%s\"\n", text);
-  rc = trio_sscanf(buffer, "%*1[aA]%[a-c]", text);
-  Dump(buffer, rc);
-  printf("text = \"%s\"\n", text);
-
-  rc = trio_sprintf(buffer, "10021");
-  rc = trio_sscanf(buffer, "%b%n%d", &num, &count, &num2);
-  Dump(buffer, rc);
-  printf("num = %d %d %d\n", num, num2, count);
-
-/*    rc = trio_sprintf(buffer, "%'d", 10000); */
-/*    rc = trio_sscanf(buffer, "%'d", &num); */
-/*    Dump(buffer, rc); */
-/*    printf("num = %d\n", num); */
-
-/*    rc = trio_dprintf(STDOUT_FILENO, "%s\n", "hello there"); */
-/*    Dump(buffer, rc); */
-/*    rc = trio_dscanf(STDIN_FILENO, "%s", buffer); */
-/*    Dump(buffer, rc); */
-
-/*    rc = trio_scanf("%s", buffer); */
-/*    Dump(buffer, rc); */
-  
-/*    rc = trio_sprintf(buffer, "Ttext"); */
-/*    Dump(buffer, rc); */
-/*    trio_sscanf(buffer, "%*[Tt]e%c", &ch); */
-/*    printf("ch = %c\n", ch); */
-
-/*    printf("%p\n", &main); */
-/*    rc = trio_sprintf(buffer, "%p %p", &main, NULL); */
-/*    Dump(buffer, rc); */
-/*    trio_sscanf(buffer, "%p %p", &p1, &p2); */
-/*    printf("pointer = %p %p\n", p1, p2); */
-
-/*    rc = trio_sprintf(buffer, "%@.@.@i", 8, 7, 2, 42); */
-/*    Dump(buffer, rc); */
-/*    trio_sprintf(buffer, "abcdefghijklmnopqrstuvwxyz"); */
-/*    rc = trio_sscanf(buffer, "%100s", text); */
-/*    Dump(text, rc); */
-/*    rc = trio_sscanf(buffer, "%@s", 100, text); */
-/*    Dump(text, rc); */
-  
-/*    rc = trio_sprintf(buffer, "%..2i", 42); */
-/*    Dump(buffer, rc); */
-/*    rc = trio_sscanf(buffer, "%..2i", &num); */
-/*    printf("%d\n", num); */
-/*    rc = trio_sscanf(buffer, "%..@i", 2, &num); */
-/*    printf("%d\n", num); */
-
-/*    { */
-/*      int num1, num2, num3, num4; */
-    
-/*      rc = trio_sprintf(buffer, "123_456 [12%%-34%%]"); */
-/*      Dump(buffer, rc); */
-/*      rc = trio_sscanf(buffer, "%5i%*1s%5i%*1s%5i%*2s%5i", */
-/*                  &num1, &num2, &num3, &num4); */
-/*      Dump(buffer, rc); */
-/*      printf("%d %d %d %d %d\n", rc, num1, num2, num3, num4); */
-/*      rc = trio_sscanf(buffer, "%d_%d [%d%%-%d%%]", */
-/*                  &num1, &num2, &num3, &num4); */
-/*      Dump(buffer, rc); */
-/*      printf("%d %d %d %d %d\n", rc, num1, num2, num3, num4); */
-/*    } */
-
-/*    rc = trio_sprintf(buffer, "01 3456789"); */
-/*    Dump(buffer, rc); */
-/*    memset(&text, 0, sizeof(text)); */
-/*    rc = trio_sscanf(buffer, "%4c", &text); */
-/*    Dump(text, rc); */
-/*    memset(&text, 0, sizeof(text)); */
-/*    rc = sscanf(buffer, "%4c", &text); */
-/*    Dump(text, rc); */
-  
-/*    rc = trio_sprintf(buffer, "12345 6"); */
-/*    Dump(buffer, rc); */
-/*    rc = trio_sscanf(buffer, "%2d", &num); */
-/*    Dump(buffer, rc); */
-/*    printf("%d\n", num); */
-/*    rc = sscanf(buffer, "%2d", &num); */
-/*    Dump(buffer, rc); */
-/*    printf("%d\n", num); */
-  
-/*    rc = trio_sprintf(buffer, "aa\\x0abb"); */
-/*    Dump(buffer, rc); */
-/*    rc = trio_sscanf(buffer, "aa%#sbb", &text); */
-/*    Dump(text, rc); */
-
-/*    rc = trio_sscanf("0 ", "%f", &dnum, text); */
-/*    printf("%d %f\n", rc, dnum); */
-/*    rc = sscanf("0 ", "%f %s", &dnum, text); */
-/*    printf("%d %f\n", rc, dnum); */
-  
-/*    rc = trio_sscanf("lære", "%[:alpha:]", text); */
-/*    Dump(text, rc); */
-  
-/*    rc = trio_sscanf("-0.123e3", "%8e", &dnum); */
-/*    printf("%d %f\n", rc, dnum); */
-
-/*    rc = trio_sscanf("123,456.78", "%'f", &dnum); */
-/*    printf("%d %f\n", rc, dnum); */
-
-  return 0;
-}
diff --git a/trio/install-sh b/trio/install-sh
deleted file mode 100755 (executable)
index e843669..0000000
+++ /dev/null
@@ -1,250 +0,0 @@
-#!/bin/sh
-#
-# install - install a program, script, or datafile
-# This comes from X11R5 (mit/util/scripts/install.sh).
-#
-# Copyright 1991 by the Massachusetts Institute of Technology
-#
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation, and that the name of M.I.T. not be used in advertising or
-# publicity pertaining to distribution of the software without specific,
-# written prior permission.  M.I.T. makes no representations about the
-# suitability of this software for any purpose.  It is provided "as is"
-# without express or implied warranty.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch.  It can only install one file at a time, a restriction
-# shared with many OS's install programs.
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
-    case $1 in
-       -c) instcmd="$cpprog"
-           shift
-           continue;;
-
-       -d) dir_arg=true
-           shift
-           continue;;
-
-       -m) chmodcmd="$chmodprog $2"
-           shift
-           shift
-           continue;;
-
-       -o) chowncmd="$chownprog $2"
-           shift
-           shift
-           continue;;
-
-       -g) chgrpcmd="$chgrpprog $2"
-           shift
-           shift
-           continue;;
-
-       -s) stripcmd="$stripprog"
-           shift
-           continue;;
-
-       -t=*) transformarg=`echo $1 | sed 's/-t=//'`
-           shift
-           continue;;
-
-       -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
-           shift
-           continue;;
-
-       *)  if [ x"$src" = x ]
-           then
-               src=$1
-           else
-               # this colon is to work around a 386BSD /bin/sh bug
-               :
-               dst=$1
-           fi
-           shift
-           continue;;
-    esac
-done
-
-if [ x"$src" = x ]
-then
-       echo "install:  no input file specified"
-       exit 1
-else
-       true
-fi
-
-if [ x"$dir_arg" != x ]; then
-       dst=$src
-       src=""
-       
-       if [ -d $dst ]; then
-               instcmd=:
-       else
-               instcmd=mkdir
-       fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad 
-# if $src (and thus $dsttmp) contains '*'.
-
-       if [ -f $src -o -d $src ]
-       then
-               true
-       else
-               echo "install:  $src does not exist"
-               exit 1
-       fi
-       
-       if [ x"$dst" = x ]
-       then
-               echo "install:  no destination specified"
-               exit 1
-       else
-               true
-       fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
-       if [ -d $dst ]
-       then
-               dst="$dst"/`basename $src`
-       else
-               true
-       fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-#  this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='   
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
-       pathcomp="${pathcomp}${1}"
-       shift
-
-       if [ ! -d "${pathcomp}" ] ;
-        then
-               $mkdirprog "${pathcomp}"
-       else
-               true
-       fi
-
-       pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
-       $doit $instcmd $dst &&
-
-       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
-       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
-       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
-       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
-       if [ x"$transformarg" = x ] 
-       then
-               dstfile=`basename $dst`
-       else
-               dstfile=`basename $dst $transformbasename | 
-                       sed $transformarg`$transformbasename
-       fi
-
-# don't allow the sed command to completely eliminate the filename
-
-       if [ x"$dstfile" = x ] 
-       then
-               dstfile=`basename $dst`
-       else
-               true
-       fi
-
-# Make a temp file name in the proper directory.
-
-       dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
-       $doit $instcmd $src $dsttmp &&
-
-       trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing.  If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
-       if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
-       if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
-       if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
-       if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
-       $doit $rmcmd -f $dstdir/$dstfile &&
-       $doit $mvcmd $dsttmp $dstdir/$dstfile 
-
-fi &&
-
-
-exit 0
diff --git a/trio/maketgz b/trio/maketgz
deleted file mode 100755 (executable)
index aed8cf5..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#! /bin/sh
-# Script to build archives with
-#
-
-echo "Version number?"
-read version
-
-# get current dir
-dir=`pwd`
-
-# Get basename
-orig=`basename $dir`
-
-# Get the left part of the dash (-)
-new=`echo $orig | cut -d- -f1`
-
-# Build new directory name
-n=$new-$version;
-
-# Tell the world what we're doing
-echo "creates $n.tar.gz";
-
-if [ -r $n ]; then
-  echo "Directory already exists!"
-  exit
-fi
-
-# Create the new dir
-mkdir $n
-
-# Copy all relevant files, with path and permissions!
-tar -cf - `cat FILES` | (cd $n; tar -xBpf -) || exit 1
-
-(cd $n && sh autogen.sh) || exit 1
-
-# Make a tar archive of it all
-tar -cvf $n.tar $n
-
-# gzip the archive
-gzip $n.tar
-
-# Make it world readable
-chmod a+r $n.tar.gz ;
-
-# Delete the temp dir
-rm -rf $n
diff --git a/trio/regression.c b/trio/regression.c
deleted file mode 100644 (file)
index 57c0347..0000000
+++ /dev/null
@@ -1,1640 +0,0 @@
-/*************************************************************************
- * Regression test
- */
-
-#include "triodef.h"
-#if defined(TRIO_COMPILER_ANCIENT)
-# include <varargs.h>
-#else
-# include <stdarg.h>
-#endif
-#include <math.h>
-#include <limits.h>
-#include <float.h>
-#include <errno.h>
-
-#include "trio.h"
-#include "triop.h"
-#if defined(TRIO_EMBED_NAN)
-# define TRIO_PUBLIC_NAN static
-# define TRIO_FUNC_NINF
-# define TRIO_FUNC_PINF
-# define TRIO_FUNC_NAN
-# define TRIO_FUNC_ISINF
-# define TRIO_FUNC_ISNAN
-# if TRIO_FEATURE_FLOAT
-#  define TRIO_FUNC_NZERO
-# endif
-#endif
-#include "trionan.h"
-#if defined(TRIO_EMBED_STRING)
-# define TRIO_PUBLIC_STRING static
-# define TRIO_FUNC_EQUAL_CASE
-#endif
-#include "triostr.h"
-#undef printf
-
-#if TRIO_FEATURE_WIDECHAR
-# include <wchar.h>
-#endif
-
-#define QUOTE(x) #x
-
-#define DOUBLE_EQUAL(x,y) (((x)>(y)-DBL_EPSILON) && ((x)<(y)+DBL_EPSILON))
-#define FLOAT_EQUAL(x,y) (((x)>(y)-FLT_EPSILON) && ((x)<(y)+FLT_EPSILON))
-
-static TRIO_CONST char rcsid[] = "@(#)$Id: regression.c,v 1.67 2010/01/26 13:02:02 breese Exp $";
-
-#if defined(TRIO_EMBED_NAN)
-# include "trionan.c"
-#endif
-#if defined(TRIO_EMBED_STRING)
-# include "triostr.c"
-#endif
-
-/*************************************************************************
- *
- */
-static void
-Dump
-TRIO_ARGS2((buffer, rc),
-          char *buffer,
-          int rc)
-{
-  if (rc < 0)
-    {
-      printf("Err = %d (%s), Pos = %d\n",
-            TRIO_ERROR_CODE(rc),
-            TRIO_ERROR_NAME(rc),
-            TRIO_ERROR_POSITION(rc));
-    }
-  else if (buffer)
-    printf("buffer[% 3d] = \"%s\"\n", rc, buffer);
-}
-
-/*************************************************************************
- *
- */
-static void
-Report0
-TRIO_ARGS2((file, line),
-          TRIO_CONST char *file,
-          int line)
-{
-  printf("Verification failed in %s:%d.\n", file, line);
-}
-
-/*************************************************************************
- *
- */
-static void
-Report
-TRIO_ARGS4((file, line, expected, got),
-          TRIO_CONST char *file,
-          int line,
-          TRIO_CONST char *expected,
-          TRIO_CONST char *got)
-{
-  Report0(file, line);
-  printf("  Expected \"%s\"\n", expected);
-  printf("  Got      \"%s\"\n", got);
-}
-
-/*************************************************************************
- *
- */
-int
-Verify
-TRIO_VARGS5((file, line, result, fmt, va_alist),
-           TRIO_CONST char *file,
-           int line,
-           TRIO_CONST char *result,
-           TRIO_CONST char *fmt,
-           TRIO_VA_DECL)
-{
-  int rc;
-  va_list args;
-  char buffer[4096];
-
-  TRIO_VA_START(args, fmt);
-  rc = trio_vsnprintf(buffer, sizeof(buffer), fmt, args);
-  if (rc < 0)
-    Dump(buffer, rc);
-  TRIO_VA_END(args);
-
-  if (!trio_equal_case(result, buffer))
-    {
-      Report(file, line, result, buffer);
-      return 1;
-    }
-  return 0;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyReturnValues(TRIO_NOARGS)
-{
-  int nerrors = 0;
-  int rc;
-  int count;
-  char *expected;
-  char buffer[4096];
-  char result[4096];
-
-  rc = trio_sprintf(buffer, "%s%n", "0123456789", &count);
-  trio_sprintf(result, "%d %d %s", rc, count, buffer);
-  expected = "10 10 0123456789";
-  if (!trio_equal_case(result, expected))
-    {
-      nerrors++;
-      Report(__FILE__, __LINE__, expected, result);
-    }
-  
-  rc = trio_snprintf(buffer, sizeof(buffer), "%s%n", "0123456789", &count);
-  trio_sprintf(result, "%d %d %s", rc, count, buffer);
-  expected = "10 10 0123456789";
-  if (!trio_equal_case(result, expected))
-    {
-      nerrors++;
-      Report(__FILE__, __LINE__, expected, result);
-    }
-  
-  rc = trio_snprintf(buffer, 4, "%s%n", "0123456789", &count);
-  trio_sprintf(result, "%d %d %s", rc, count, buffer);
-  expected = "10 3 012";
-  if (!trio_equal_case(result, expected))
-    {
-      nerrors++;
-      Report(__FILE__, __LINE__, expected, result);
-    }
-
-  /* The output buffer contains the empty string */
-  rc = trio_snprintf(buffer, 1, "%s%n", "0123456789", &count);
-  trio_sprintf(result, "%d %d %s", rc, count, buffer);
-  expected = "10 0 ";
-  if (!trio_equal_case(result, expected))
-    {
-      nerrors++;
-      Report(__FILE__, __LINE__, expected, result);
-    }
-
-  /* The output buffer should be left untouched when max size is 0 */
-  trio_sprintf(buffer, "DO NOT TOUCH");
-  rc = trio_snprintf(buffer, 0, "%s%n", "0123456789", &count);
-  trio_sprintf(result, "%d %d %s", rc, count, buffer);
-  expected = "10 0 DO NOT TOUCH";
-  if (!trio_equal_case(result, expected))
-    {
-      nerrors++;
-      Report(__FILE__, __LINE__, expected, result);
-    }
-  
-  return nerrors;
-}
-
-/*************************************************************************
- *
- */
-#define TEST_STRING "0123456789"
-
-int
-VerifyAllocate(TRIO_NOARGS)
-{
-  int nerrors = 0;
-#if TRIO_FEATURE_DYNAMICSTRING
-  int rc;
-  char *string;
-  int count;
-  int test_size = sizeof(TEST_STRING) - 1;
-
-  /* Allocate a string with the result */
-  rc = trio_asprintf(&string, "%s%n", TEST_STRING, &count);
-  if (rc < 0)
-    {
-      nerrors++;
-      Dump(string, rc);
-    }
-  else if (count != test_size)
-    {
-      nerrors++;
-      printf("Validation failed in %s:%d\n", __FILE__, __LINE__);
-      printf("  Expected %%n = %d\n", test_size);
-      printf("  Got      %%n = %d\n", count);
-    }
-  else if (!trio_equal_case(string, TEST_STRING))
-    {
-      nerrors++;
-      Report(__FILE__, __LINE__, TEST_STRING, string);
-    }
-  if (string)
-    free(string);
-#endif
-  
-  return nerrors;
-}
-
-
-/*************************************************************************
- *
- */
-int
-VerifyFormattingStrings(TRIO_NOARGS)
-{
-  int nerrors = 0;
-
-  /* Normal text */
-  nerrors += Verify(__FILE__, __LINE__, "Hello world",
-                  "Hello world");
-  /* String */
-  nerrors += Verify(__FILE__, __LINE__, "Hello world",
-                  "%s", "Hello world");
-
-  return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyFormattingIntegers(TRIO_NOARGS)
-{
-  int nerrors = 0;
-  char buffer[256];
-  
-  /* Integer */
-  nerrors += Verify(__FILE__, __LINE__, "Number 42",
-                  "Number %d", 42);
-  nerrors += Verify(__FILE__, __LINE__, "Number -42",
-                  "Number %d", -42);
-  nerrors += Verify(__FILE__, __LINE__, "Number 42",
-                  "Number %ld", 42L);
-  nerrors += Verify(__FILE__, __LINE__, "Number -42",
-                  "Number %ld", -42L);
-  /* Integer width */
-  nerrors += Verify(__FILE__, __LINE__, "  1234",
-                   "%6d", 1234);
-  nerrors += Verify(__FILE__, __LINE__, "  1234",
-                   "%*d", 6, 1234);
-  /* Integer width overrun */
-  nerrors += Verify(__FILE__, __LINE__, "123456",
-                   "%4d", 123456);
-  /* Integer precision */
-  nerrors += Verify(__FILE__, __LINE__, "0012",
-                   "%.4d", 12);
-  nerrors += Verify(__FILE__, __LINE__, "0012",
-                   "%.*d", 4, 12);
-  nerrors += Verify(__FILE__, __LINE__, "  0012",
-                   "%6.*d", 4, 12);
-  nerrors += Verify(__FILE__, __LINE__, "  0012",
-                   "%*.*d", 6, 4, 12);
-  nerrors += Verify(__FILE__, __LINE__, "  0012",
-                   "%*.*.*d", 6, 4, 2, 12);
-  nerrors += Verify(__FILE__, __LINE__, "  0012",
-                   "%*.*.*i", 6, 4, 10, 12);
-  /* Integer sign, zero-padding, and width */
-  nerrors += Verify(__FILE__, __LINE__, "+01234",
-                   "%+06d", 1234);
-  nerrors += Verify(__FILE__, __LINE__, " 01234",
-                   "% 06d", 1234);
-  nerrors += Verify(__FILE__, __LINE__, "+01234",
-                   "% +06d", 1234);
-  /* Integer adjust, zero-padding, and width */
-  nerrors += Verify(__FILE__, __LINE__, "12      ",
-                   "%-08d", 12);
-  /* Integer zero-padding, width, and precision */
-  nerrors += Verify(__FILE__, __LINE__, "  000012",
-                   "%08.6d", 12);
-  /* Integer base */
-  nerrors += Verify(__FILE__, __LINE__, "42",
-                  "%u", 42);
-  nerrors += Verify(__FILE__, __LINE__, "-1",
-                  "%d", -1);
-  nerrors += Verify(__FILE__, __LINE__, "52",
-                  "%o", 42);
-  nerrors += Verify(__FILE__, __LINE__, "052",
-                  "%#o", 42);
-  nerrors += Verify(__FILE__, __LINE__, "0",
-                  "%#o", 0);
-  nerrors += Verify(__FILE__, __LINE__, "2a",
-                   "%x", 42);
-  nerrors += Verify(__FILE__, __LINE__, "2A",
-                   "%X", 42);
-  nerrors += Verify(__FILE__, __LINE__, "0x2a",
-                  "%#x", 42);
-  nerrors += Verify(__FILE__, __LINE__, "0X2A",
-                  "%#X", 42);
-  nerrors += Verify(__FILE__, __LINE__, "0x00c ",
-                  "%-#6.3x", 12);
-  nerrors += Verify(__FILE__, __LINE__, "",
-                  "%.d", 0);
-  nerrors += Verify(__FILE__, __LINE__, "",
-                  "%#.d", 0);
-  nerrors += Verify(__FILE__, __LINE__, "42",
-                  "%.d", 42);
-  nerrors += Verify(__FILE__, __LINE__, "",
-                  "%.o", 0);
-  nerrors += Verify(__FILE__, __LINE__, "    0000",
-                  "%8.4o", 0);
-  nerrors += Verify(__FILE__, __LINE__, "       0",
-                  "%8o", 0);
-  nerrors += Verify(__FILE__, __LINE__, "00000000",
-                  "%08o", 0);
-  nerrors += Verify(__FILE__, __LINE__, "0",
-                  "%#.o", 0);
-  nerrors += Verify(__FILE__, __LINE__, "52",
-                  "%.o", 42);
-  nerrors += Verify(__FILE__, __LINE__, "",
-                  "%.x", 0);
-  nerrors += Verify(__FILE__, __LINE__, "",
-                  "%#.x", 0);
-  nerrors += Verify(__FILE__, __LINE__, "2a",
-                  "%.x", 42);
-  sprintf(buffer, "%u", UINT_MAX);
-  nerrors += Verify(__FILE__, __LINE__, buffer,
-                  "%u", -1);
-  sprintf(buffer, "%x", UINT_MAX);
-  nerrors += Verify(__FILE__, __LINE__, buffer,
-                   "%x", -1);
-
-  return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyFormattingFloats(TRIO_NOARGS)
-{
-  int nerrors = 0;
-
-#if TRIO_FEATURE_FLOAT
-  /* Double */
-  nerrors += Verify(__FILE__, __LINE__, "3141.000000",
-                   "%f", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "3141.500000",
-                   "%f", 3141.5);
-  nerrors += Verify(__FILE__, __LINE__, "3.141000e+03",
-                   "%e", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "     -2.3420e-02",
-                   "%16.4e", -2.342E-02);
-  nerrors += Verify(__FILE__, __LINE__, "     -2.3420e-22",
-                   "%16.4e", -2.342E-22);
-  nerrors += Verify(__FILE__, __LINE__, "      2.3420e-02",
-                   "% 16.4e", 2.342E-02);
-  nerrors += Verify(__FILE__, __LINE__, " 2.3420e-02",
-                   "% 1.4e", 2.342E-02);
-  nerrors += Verify(__FILE__, __LINE__, "3.141000E-44",
-                   "%E", 3.141e-44);
-  nerrors += Verify(__FILE__, __LINE__, "0",
-                   "%g", 0.0);
-  nerrors += Verify(__FILE__, __LINE__, "-0",
-                   "%g", trio_nzero());
-  nerrors += Verify(__FILE__, __LINE__, "3141.5",
-                   "%g", 3141.5);
-  nerrors += Verify(__FILE__, __LINE__, "3.1415E-06",
-                   "%G", 3.1415e-6);
-  nerrors += Verify(__FILE__, __LINE__, "+3141.000000",
-                   "%+f", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "-3141.000000",
-                   "%+f", -3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "0.333333",
-                   "%f", 1.0/3.0);
-  nerrors += Verify(__FILE__, __LINE__, "0.666667",
-                   "%f", 2.0/3.0);
-  /* Beyond accuracy */
-  nerrors += Verify(__FILE__, __LINE__, "0.000000",
-                   "%f", 1.234567890123456789e-20);
-# if defined(TRIO_BREESE)
-  nerrors += Verify(__FILE__, __LINE__, "1.3999999999999999111821580299875",
-                   "%.32g", 1.4);
-  nerrors += Verify(__FILE__, __LINE__, "1.39999999999999991118215802998748",
-                   "%.32f", 1.4);
-  nerrors += Verify(__FILE__, __LINE__, "1.3999999999999999111821580300",
-                   "%.28f", 1.4);
-  nerrors += Verify(__FILE__, __LINE__, "1.399999999999999911182158",
-                   "%.24f", 1.4);
-  nerrors += Verify(__FILE__, __LINE__, "1.39999999999999991",
-                   "%.17f", 1.4);
-  nerrors += Verify(__FILE__, __LINE__, "1.40000000000000",
-                   "%.14f", 1.4);
-  nerrors += Verify(__FILE__, __LINE__, "39413.800000000002910383045673370361",
-                   "%.30f", 39413.80);
-# endif
-  /* 2^-1 + 2^-15 */
-  nerrors += Verify(__FILE__, __LINE__, "0.500030517578125",
-                   "%.*g", DBL_DIG + 10, 0.500030517578125);
-  /* Double decimal point */
-  nerrors += Verify(__FILE__, __LINE__, "3141",
-                   "%.0f", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "3142",
-                   "%.0f", 3141.5);
-  nerrors += Verify(__FILE__, __LINE__, "3141",
-                   "%.f", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "12",
-                   "%.f", 12.34);
-  nerrors += Verify(__FILE__, __LINE__, "3141.000",
-                   "%.3f", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "3141.000000",
-                   "%#f", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "0.0000",
-                   "%#.4f", 0.0);
-  nerrors += Verify(__FILE__, __LINE__, "0.000",
-                   "%#.4g", 0.0);
-  nerrors += Verify(__FILE__, __LINE__, "0.001000",
-                   "%#.4g", 1e-3);
-  nerrors += Verify(__FILE__, __LINE__, "3141.0000",
-                   "%#.4f", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "3141.",
-                   "%#.0f", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "3141.",
-                   "%#.f", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "11.0000",
-                   "%#.4f", 11.0);
-  nerrors += Verify(__FILE__, __LINE__, "100.00",
-                   "%.2f", 99.9999);
-  nerrors += Verify(__FILE__, __LINE__, "3e+03",
-                   "%.e", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "3.e+03",
-                   "%#.e", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "1.23457e+06",
-                   "%g", 1234567.0);
-  nerrors += Verify(__FILE__, __LINE__, "1e+02",
-                   "%.2g", 99.9999);
-  nerrors += Verify(__FILE__, __LINE__, "1.0e+02",
-                   "%#.2g", 99.9999);
-  nerrors += Verify(__FILE__, __LINE__, "0.123",
-                   "%0g", 0.123);
-  nerrors += Verify(__FILE__, __LINE__, "1.00e+00",
-                   "%.2e", 0.9999);
-  nerrors += Verify(__FILE__, __LINE__, "1",
-                   "%.2g", 0.9999);
-  nerrors += Verify(__FILE__, __LINE__, "2",
-                   "%.0g", 1.5);
-  nerrors += Verify(__FILE__, __LINE__, "2",
-                   "%.g", 1.5);
-  nerrors += Verify(__FILE__, __LINE__, "0.01",
-                   "%.2g", 0.01);
-  nerrors += Verify(__FILE__, __LINE__, "0.010",
-                   "%#.2g", 0.01);
-  nerrors += Verify(__FILE__, __LINE__, "1e-04",
-                   "%5.g", 0.999999e-4);
-  /* Double width and precision */
-  nerrors += Verify(__FILE__, __LINE__, "      1e-05",
-                   "%11.5g", 1e-5);
-  nerrors += Verify(__FILE__, __LINE__, "     0.0001",
-                   "%11.5g", 1e-4);
-  nerrors += Verify(__FILE__, __LINE__, "      0.001",
-                   "%11.5g", 1e-3);
-  nerrors += Verify(__FILE__, __LINE__, "       0.01",
-                   "%11.5g", 1e-2);
-  nerrors += Verify(__FILE__, __LINE__, "        0.1",
-                   "%11.5g", 1e-1);
-  nerrors += Verify(__FILE__, __LINE__, "          1",
-                   "%11.5g", 1e0);
-  nerrors += Verify(__FILE__, __LINE__, "         10",
-                   "%11.5g", 1e1);
-  nerrors += Verify(__FILE__, __LINE__, "        100",
-                   "%11.5g", 1e2);
-  nerrors += Verify(__FILE__, __LINE__, "       1000",
-                   "%11.5g", 1e3);
-  nerrors += Verify(__FILE__, __LINE__, "      10000",
-                   "%11.5g", 1e4);
-  nerrors += Verify(__FILE__, __LINE__, "      1e+05",
-                   "%11.5g", 1e5);
-  nerrors += Verify(__FILE__, __LINE__, "    9.9e-05",
-                   "%11.2g", 0.99e-4);
-  nerrors += Verify(__FILE__, __LINE__, "    0.00099",
-                   "%11.2g", 0.99e-3);
-  nerrors += Verify(__FILE__, __LINE__, "     0.0099",
-                   "%11.2g", 0.99e-2);
-  nerrors += Verify(__FILE__, __LINE__, "      0.099",
-                   "%11.2g", 0.99e-1);
-  nerrors += Verify(__FILE__, __LINE__, "       0.99",
-                   "%11.2g", 0.99e0);
-  nerrors += Verify(__FILE__, __LINE__, "        9.9",
-                   "%11.2g", 0.99e1);
-  nerrors += Verify(__FILE__, __LINE__, "         99",
-                   "%11.2g", 0.99e2);
-  nerrors += Verify(__FILE__, __LINE__, "    9.9e+02",
-                   "%11.2g", 0.99e3);
-  nerrors += Verify(__FILE__, __LINE__, "    9.9e+03",
-                   "%11.2g", 0.99e4);
-  nerrors += Verify(__FILE__, __LINE__, "    9.9e+04",
-                   "%11.2g", 0.99e5);
-  /* Double width, precision, and alternative */
-  nerrors += Verify(__FILE__, __LINE__, " 1.0000e-05",
-                   "%#11.5g", 1e-5);
-  nerrors += Verify(__FILE__, __LINE__, " 0.00010000",
-                   "%#11.5g", 1e-4);
-  nerrors += Verify(__FILE__, __LINE__, "  0.0010000",
-                   "%#11.5g", 1e-3);
-  nerrors += Verify(__FILE__, __LINE__, "  0.0010000",
-                   "%#11.5g", 0.999999e-3);
-  nerrors += Verify(__FILE__, __LINE__, "   0.010000",
-                   "%#11.5g", 1e-2);
-  nerrors += Verify(__FILE__, __LINE__, "   0.010000",
-                   "%#11.5g", 0.999999e-2);
-  nerrors += Verify(__FILE__, __LINE__, "    0.10000",
-                   "%#11.5g", 1e-1);
-  nerrors += Verify(__FILE__, __LINE__, "    0.10000",
-                   "%#11.5g", 0.999999e-1);
-  nerrors += Verify(__FILE__, __LINE__, "     1.0000",
-                   "%#11.5g", 1e0);
-  nerrors += Verify(__FILE__, __LINE__, "     1.0000",
-                   "%#11.5g", 0.999999e0);
-  nerrors += Verify(__FILE__, __LINE__, "     10.000",
-                   "%#11.5g", 1e1);
-  nerrors += Verify(__FILE__, __LINE__, "     100.00",
-                   "%#11.5g", 1e2);
-  nerrors += Verify(__FILE__, __LINE__, "     1000.0",
-                   "%#11.5g", 1e3);
-  nerrors += Verify(__FILE__, __LINE__, "     10000.",
-                   "%#11.5g", 1e4);
-  nerrors += Verify(__FILE__, __LINE__, " 1.0000e+05",
-                   "%#11.5g", 1e5);
-  nerrors += Verify(__FILE__, __LINE__, "    9.9e-05",
-                   "%#11.2g", 0.99e-4);
-  nerrors += Verify(__FILE__, __LINE__, "    0.00099",
-                   "%#11.2g", 0.99e-3);
-  nerrors += Verify(__FILE__, __LINE__, "     0.0099",
-                   "%#11.2g", 0.99e-2);
-  nerrors += Verify(__FILE__, __LINE__, "      0.099",
-                   "%#11.2g", 0.99e-1);
-  nerrors += Verify(__FILE__, __LINE__, "       0.99",
-                   "%#11.2g", 0.99e0);
-  nerrors += Verify(__FILE__, __LINE__, "        9.9",
-                   "%#11.2g", 0.99e1);
-  nerrors += Verify(__FILE__, __LINE__, "        99.",
-                   "%#11.2g", 0.99e2);
-  nerrors += Verify(__FILE__, __LINE__, "    9.9e+02",
-                   "%#11.2g", 0.99e3);
-  nerrors += Verify(__FILE__, __LINE__, "    9.9e+03",
-                   "%#11.2g", 0.99e4);
-  nerrors += Verify(__FILE__, __LINE__, "    9.9e+04",
-                   "%#11.2g", 0.99e5);
-  /* Double width, precision, and zero padding */
-  nerrors += Verify(__FILE__, __LINE__, "00003.141500e+03",
-                   "%016e", 3141.5);
-  nerrors += Verify(__FILE__, __LINE__, "    3.141500e+03",
-                   "%16e", 3141.5);
-  nerrors += Verify(__FILE__, __LINE__, "3.141500e+03    ",
-                   "%-16e", 3141.5);
-  nerrors += Verify(__FILE__, __LINE__, "03.142e+03",
-                   "%010.3e", 3141.5);
-#if !defined(TRIO_COMPILER_ANCIENT)
-  /* Long double */
-  nerrors += Verify(__FILE__, __LINE__, "1.400000",
-                   "%Lf", 1.4L);
-#endif
-  
-  /* Special cases */
-  nerrors += Verify(__FILE__, __LINE__, "1.00",
-                   "%.2f", 0.999);
-  nerrors += Verify(__FILE__, __LINE__, "100",
-                   "%.0f", 99.9);
-  nerrors += Verify(__FILE__, __LINE__, "inf",
-                   "%f", trio_pinf());
-  nerrors += Verify(__FILE__, __LINE__, "-inf",
-                   "%f", trio_ninf());
-  nerrors += Verify(__FILE__, __LINE__, "INF",
-                   "%F", trio_pinf());
-  nerrors += Verify(__FILE__, __LINE__, "-INF",
-                   "%F", trio_ninf());
-  /* May fail if NaN is unsupported */
-  nerrors += Verify(__FILE__, __LINE__, "nan",
-                   "%f", trio_nan());
-  nerrors += Verify(__FILE__, __LINE__, "NAN",
-                   "%F", trio_nan());
-  
-# if TRIO_FEATURE_HEXFLOAT
-  nerrors += Verify(__FILE__, __LINE__, "0x2.ap+4",
-                   "%a", 42.0);
-  nerrors += Verify(__FILE__, __LINE__, "-0x2.ap+4",
-                   "%a", -42.0);
-  nerrors += Verify(__FILE__, __LINE__, "0x1.8p+0",
-                   "%a", 1.5);
-  nerrors += Verify(__FILE__, __LINE__, "0x1.6666666666666p+0",
-                   "%a", 1.4);
-  nerrors += Verify(__FILE__, __LINE__, "0xc.45p+8",
-                   "%a", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "0XC.45P+8",
-                   "%A", 3141.0);
-  nerrors += Verify(__FILE__, __LINE__, "0xb.351c434a98fa8p-148",
-                   "%a", 3.141e-44);
-# endif
-  
-#endif /* TRIO_FEATURE_FLOAT */
-  
-  return nerrors;
-}
-
-/*************************************************************************
- *
- */
-#if TRIO_EXTENSION
-int number_writer(void *ref)
-{
-  const char *format;
-  int *data;
-
-  format = trio_get_format(ref);
-  if ((format) && trio_equal(format, "integer"))
-    {
-      data = trio_get_argument(ref);
-      if (data)
-       {
-         trio_print_int(ref, *data);
-       }
-    }
-  return 0;
-}
-
-#endif
-
-int
-VerifyFormattingUserDefined(TRIO_NOARGS)
-{
-  int nerrors = 0;
-#if TRIO_EXTENSION
-  void *number_handle;
-  int integer = 123;
-
-  number_handle = trio_register(number_writer, "number");
-
-  /* Old style */
-  nerrors += Verify(__FILE__, __LINE__, "123",
-                   "%<number:integer>", &integer);
-
-  /* New style */
-  nerrors += Verify(__FILE__, __LINE__, "123",
-                   "$<number:integer|%p>", &integer);
-  nerrors += Verify(__FILE__, __LINE__, "123",
-                   "$<integer|%p%p>", number_handle, &integer);
-  nerrors += Verify(__FILE__, __LINE__, "$<integer|123",
-                   "$<integer|%d", 123);
-  nerrors += Verify(__FILE__, __LINE__, "$integer|123>",
-                   "$integer|%d>", 123);
-
-  trio_unregister(number_handle);
-#endif
-
-  return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyFormattingRegression(TRIO_NOARGS)
-{
-  int nerrors = 0;
-
-#if TRIO_FEATURE_FLOAT
-  /* 0.6 was formatted as 0.600000e+00 */
-  nerrors += Verify(__FILE__, __LINE__, "5.000000e-01",
-                   "%e", 0.5);
-  nerrors += Verify(__FILE__, __LINE__, "6.000000e-01",
-                   "%e", 0.6);
-#endif
-
-  return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyFormatting(TRIO_NOARGS)
-{
-  int nerrors = 0;
-#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
-  char buffer[256];
-#endif
-
-  nerrors += VerifyFormattingStrings();
-  nerrors += VerifyFormattingIntegers();
-  nerrors += VerifyFormattingFloats();
-  nerrors += VerifyFormattingRegression();
-  nerrors += VerifyFormattingUserDefined();
-
-  /* Pointer */
-  if (sizeof(void *) == 4)
-    {
-      nerrors += Verify(__FILE__, __LINE__, "Pointer 0x01234567",
-                       "Pointer %p", 0x1234567);
-    }
-#if defined(TRIO_COMPILER_SUPPORTS_LL)
-  else if (sizeof(void *) == 8)
-    {
-      nerrors += Verify(__FILE__, __LINE__, "Pointer 0x0123456789012345",
-                       "Pointer %p", 0x123456789012345LL);
-    }
-#endif
-  /* Nil pointer */
-  nerrors += Verify(__FILE__, __LINE__, "Pointer (nil)",
-                  "Pointer %p", NULL);
-  
-  /* Char width alignment */
-  nerrors += Verify(__FILE__, __LINE__, "Char X   .",
-        "Char %-4c.", 'X');
-  /* String width / precision */
-  nerrors += Verify(__FILE__, __LINE__, " testing",
-                   "%8s", "testing");
-  nerrors += Verify(__FILE__, __LINE__, "testing ",
-                   "%-8s", "testing");
-  nerrors += Verify(__FILE__, __LINE__, " testing",
-                   "%*s", 8, "testing");
-  nerrors += Verify(__FILE__, __LINE__, "testing ",
-                   "%*s", -8, "testing");
-  nerrors += Verify(__FILE__, __LINE__, "test",
-                   "%.4s", "testing");
-  nerrors += Verify(__FILE__, __LINE__, "test",
-                   "%.*s", 4, "testing");
-  nerrors += Verify(__FILE__, __LINE__, "testing",
-                   "%.*s", -4, "testing");
-#if TRIO_FEATURE_POSITIONAL
-  /* Positional */
-  nerrors += Verify(__FILE__, __LINE__, "222 111",
-                   "%2$s %1$s", "111", "222");
-  nerrors += Verify(__FILE__, __LINE__, "123456    12345 0001234  00123",
-                   "%4$d %3$*8$d %2$.*7$d %1$*6$.*5$d",
-                   123, 1234, 12345, 123456, 5, 6, 7, 8);
-#endif
-  
-#if TRIO_FEATURE_SIZE_T_UPPER
-  nerrors += Verify(__FILE__, __LINE__, "256",
-                   "%Zd", sizeof(buffer));
-#endif
-
-#if TRIO_FEATURE_ERRNO
-  errno = EINTR;
-# if defined(TRIO_PLATFORM_LYNX)
-#  if defined(PREDEF_STANDARD_POSIX_1996)
-  nerrors += Verify(__FILE__, __LINE__, "Interrupted system call ",
-                   "%m");
-#  else
-  nerrors += Verify(__FILE__, __LINE__, "System call interrupted",
-                   "%m");
-#  endif
-# else
-  nerrors += Verify(__FILE__, __LINE__, "Interrupted system call",
-                   "%m");
-# endif
-#endif
-  
-#if TRIO_FEATURE_QUAD
-# if defined(TRIO_COMPILER_SUPPORTS_LL)
-  /* This may fail if the preprocessor does not recognize LL */
-  nerrors += Verify(__FILE__, __LINE__, "42",
-                   "%qd", 42LL);
-# endif
-#endif
-
-#if TRIO_FEATURE_SIZE_T
-  nerrors += Verify(__FILE__, __LINE__, "256",
-                   "%zd", sizeof(buffer));
-#endif
-#if TRIO_FEATURE_PTRDIFF_T
-  nerrors += Verify(__FILE__, __LINE__, "42",
-                   "%td", 42);
-#endif
-#if TRIO_FEATURE_INTMAX_T
-# if defined(TRIO_COMPILER_SUPPORTS_LL)
-  /* Some compilers may not handle the LL suffix correctly */
-  nerrors += Verify(__FILE__, __LINE__, "42",
-                   "%jd", 42LL);
-# endif
-#endif
-
-#if TRIO_FEATURE_WIDECHAR
-  nerrors += Verify(__FILE__, __LINE__, "Hello World",
-                   "%ls", L"Hello World");
-  nerrors += Verify(__FILE__, __LINE__, "\\aHello World",
-                   "%#ls", L"\aHello World");
-  nerrors += Verify(__FILE__, __LINE__, "A",
-                   "%lc", L'A');
-  nerrors += Verify(__FILE__, __LINE__, "\\a",
-                   "%#lc", L'\a');
-#endif
-
-#if TRIO_FEATURE_FIXED_SIZE
-  nerrors += Verify(__FILE__, __LINE__, "42",
-                   "%I8d", 42);
-  nerrors += Verify(__FILE__, __LINE__, "ffffffff",
-                   "%I16x", -1);
-#endif
-  
-#if TRIO_EXTENSION
-  nerrors += Verify(__FILE__, __LINE__, "  42   86",
-                   "%!4d %d", 42, 86);
-  nerrors += Verify(__FILE__, __LINE__, "0042 0086",
-                   "%!04d %d", 42, 86);
-  nerrors += Verify(__FILE__, __LINE__, "42",
-                   "%&d", sizeof(long), 42L);
-  /* Non-printable string */
-  nerrors += Verify(__FILE__, __LINE__, "NonPrintable \\x01 \\a \\\\",
-                   "NonPrintable %#s", "\01 \07 \\");
-  nerrors += Verify(__FILE__, __LINE__, "\\a \\b \\t \\n \\v \\f \\r",
-                   "%#s", "\007 \010 \011 \012 \013 \014 \015");
-  /* Quote flag */
-  nerrors += Verify(__FILE__, __LINE__, "Another \"quoted\" string",
-                  "Another %'s string", "quoted");
-  /* Integer base */
-  nerrors += Verify(__FILE__, __LINE__, "Number 42 == 1120 (base 3)",
-                   "Number %d == %..3i (base 3)", 42, 42);
-  /* Integer base (specifier base must be used instead of base modifier) */
-  nerrors += Verify(__FILE__, __LINE__, "42",
-                   "%..3d", 42);
-  nerrors += Verify(__FILE__, __LINE__, "52",
-                   "%..3o", 42);
-  nerrors += Verify(__FILE__, __LINE__, "2a",
-                   "%..3x", 42);
-  /* Integer thousand separator */
-  nerrors += Verify(__FILE__, __LINE__, "Number 100",
-                   "Number %'d", 100);
-  nerrors += Verify(__FILE__, __LINE__, "Number 1,000,000",
-                   "Number %'d", 1000000);
-# if TRIO_FEATURE_FLOAT
-  /* Float thousand separator */
-  nerrors += Verify(__FILE__, __LINE__, "31,415.200000",
-                   "%'f", 31415.2);
-  nerrors += Verify(__FILE__, __LINE__, "1,000,000.000000",
-                   "%'f", 1000000.0);
-  /* Rounding modifier */
-  nerrors += Verify(__FILE__, __LINE__, "1.4",
-                   "%.32Rf", 1.4);
-  nerrors += Verify(__FILE__, __LINE__, "1.4",
-                   "%.17Rf", 1.4);
-  nerrors += Verify(__FILE__, __LINE__, "39413.8",
-                   "%.30Rf", 39413.80);
-#  if !defined(TRIO_COMPILER_ANCIENT)
-  /* Long double */
-  nerrors += Verify(__FILE__, __LINE__, "1.4",
-                   "%RLf", 1.4L);
-  nerrors += Verify(__FILE__, __LINE__, "1.4",
-                   "%.30RLf", 1.4L);
-#  endif
-# endif
-#endif
-
-#if defined(TRIO_BREESE)
-  /*
-   * These results depends on issues beyond our control. For example,
-   * the accuracy of floating-point numbers depends on the underlying
-   * floating-point hardware (e.g. whether IEEE 754 double or extended-
-   * double format is used).
-   *
-   * These tests are therefore not part of the normal regression test,
-   * but we keep them here for development purposes.
-   */
-  nerrors += Verify(__FILE__, __LINE__, "123456789012345680868.000000",
-                   "%f", 1.234567890123456789e20);
-  nerrors += Verify(__FILE__, __LINE__, "1.23456789012345677901e-20",
-                   "%.20e", 1.2345678901234567e-20);
-  nerrors += Verify(__FILE__, __LINE__, "0.666666666666666629659233",
-                   "%.*g", DBL_DIG + 10, 2.0/3.0);
-  nerrors += Verify(__FILE__, __LINE__, "123456789012345700000",
-                   "%Rf", 1.234567890123456789e20);
-# if !defined(TRIO_COMPILER_ANCIENT)
-  nerrors += Verify(__FILE__, __LINE__, "0.666666666666666667",
-                   "%RLf", (2.0L/3.0L));
-  nerrors += Verify(__FILE__, __LINE__, "0.666666666666666667",
-                   "%.30RLf", (2.0L/3.0L));
-# endif
-#endif
-  
-  return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyErrors(TRIO_NOARGS)
-{
-  char buffer[512];
-  int rc;
-  int nerrors = 0;
-  
-  /* Error: Invalid argument 1 */
-  rc = trio_snprintf(buffer, sizeof(buffer), "%d %r", 42, "text");
-#if TRIO_FEATURE_ERRORCODE
-# if TRIO_FEATURE_STRERR
-  trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
-               TRIO_ERROR_CODE(rc),
-               TRIO_ERROR_NAME(rc),
-               TRIO_ERROR_POSITION(rc));
-  nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 5",
-                   "%s", buffer);
-# else
-  trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
-               TRIO_ERROR_CODE(rc),
-               TRIO_ERROR_POSITION(rc));
-  nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 5",
-                   "%s", buffer);
-# endif
-#else
-  nerrors += (rc != -1);
-#endif
-  
-  /* Error: Invalid argument 2 */
-  rc = trio_snprintf(buffer, sizeof(buffer), "%#");
-#if TRIO_FEATURE_ERRORCODE
-# if TRIO_FEATURE_STRERR
-  trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
-               TRIO_ERROR_CODE(rc),
-               TRIO_ERROR_NAME(rc),
-               TRIO_ERROR_POSITION(rc));
-  nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 3",
-                   "%s", buffer);
-# else
-  trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
-               TRIO_ERROR_CODE(rc),
-               TRIO_ERROR_POSITION(rc));
-  nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 3",
-                   "%s", buffer);
-# endif
-#else
-  nerrors += (rc != -1);
-#endif
-  
-  /* Error: Invalid argument 3 */
-  rc = trio_snprintf(buffer, sizeof(buffer), "%hhhd", 42);
-#if TRIO_FEATURE_ERRORCODE
-# if TRIO_FEATURE_STRERR
-  trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
-               TRIO_ERROR_CODE(rc),
-               TRIO_ERROR_NAME(rc),
-               TRIO_ERROR_POSITION(rc));
-  nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 4",
-                   "%s", buffer);
-# else
-  trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
-               TRIO_ERROR_CODE(rc),
-               TRIO_ERROR_POSITION(rc));
-  nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 4",
-                   "%s", buffer);
-# endif
-#else
-  nerrors += (rc != -1);
-#endif
-  
-  /* Error: Double reference */
-  rc = trio_snprintf(buffer, sizeof(buffer), "hello %1$d %1$d", 31, 32);
-#if TRIO_FEATURE_ERRORCODE
-# if TRIO_FEATURE_STRERR
-  trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
-               TRIO_ERROR_CODE(rc),
-               TRIO_ERROR_NAME(rc),
-               TRIO_ERROR_POSITION(rc));
-#  if TRIO_UNIX98
-  nerrors += Verify(__FILE__, __LINE__, "Err = 4 (Double reference), Pos = 0",
-                   "%s", buffer);
-#  else
-  nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 9",
-                   "%s", buffer);
-#  endif
-# else
-  trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
-               TRIO_ERROR_CODE(rc),
-               TRIO_ERROR_POSITION(rc));
-#  if TRIO_UNIX98
-  nerrors += Verify(__FILE__, __LINE__, "Err = 4, Pos = 0",
-                   "%s", buffer);
-#  else
-  nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 9",
-                   "%s", buffer);
-#  endif
-# endif
-#else
-  nerrors += (rc != -1);
-#endif
-  
-  /* Error: Reference gap */
-  rc = trio_snprintf(buffer, sizeof(buffer), "%3$d %1$d", 31, 32, 33);
-#if TRIO_FEATURE_ERRORCODE
-# if TRIO_FEATURE_STRERR
-  trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
-               TRIO_ERROR_CODE(rc),
-               TRIO_ERROR_NAME(rc),
-               TRIO_ERROR_POSITION(rc));
-#  if TRIO_UNIX98
-  nerrors += Verify(__FILE__, __LINE__, "Err = 5 (Reference gap), Pos = 1",
-                   "%s", buffer);
-#  else
-  nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 3",
-                   "%s", buffer);
-#  endif
-# else
-  trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
-               TRIO_ERROR_CODE(rc),
-               TRIO_ERROR_POSITION(rc));
-#  if TRIO_UNIX98
-  nerrors += Verify(__FILE__, __LINE__, "Err = 5, Pos = 1",
-                   "%s", buffer);
-#  else
-  nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 3",
-                   "%s", buffer);
-#  endif
-# endif
-#else
-  nerrors += (rc != -1);
-#endif
-  
-  return nerrors;
-}
-
-/*************************************************************************
- *
- */
-#if TRIO_FEATURE_SCANF
-int
-VerifyScanningOneInteger
-TRIO_ARGS5((file, line, expected, format, original),
-          TRIO_CONST char *file,
-          int line,
-          TRIO_CONST char *expected,
-          TRIO_CONST char *format,
-          int original)
-{
-  int number;
-  char data[512];
-  
-  trio_snprintf(data, sizeof(data), format, original);
-  trio_sscanf(data, format, &number);
-  return Verify(file, line, expected, format, number);
-}
-
-int
-VerifyScanningIntegers(TRIO_NOARGS)
-{
-  int nerrors = 0;
-
-  nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
-                                     "%i", 42);
-  nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
-                                     "%d", 42);
-  nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "-42",
-                                     "%d", -42);
-  nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "2147483647",
-                                     "%d", 2147483647);
-  nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
-                                     "%u", 42);
-  nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "2a",
-                                     "%x", 42);
-  nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "52",
-                                     "%o", 42);
-  nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "101010",
-                                     "%..2i", 42);
-  nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "0x2a",
-                                     "%#x", 42);
-  nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "052",
-                                     "%#o", 42);
-
-  return nerrors;
-}
-#endif
-
-/*************************************************************************
- *
- */
-#if TRIO_FEATURE_SCANF
-int
-VerifyScanningOneFloat
-TRIO_ARGS5((file, line, expected, format, original),
-          TRIO_CONST char *file,
-          int line,
-          TRIO_CONST char *expected,
-          TRIO_CONST char *format,
-          double original)
-{
-  float number;
-  char data[512];
-  
-  trio_snprintf(data, sizeof(data), format, original);
-  trio_sscanf(data, format, &number);
-  return Verify(file, line, expected, format, number);
-}
-
-int
-VerifyScanningOneDouble
-TRIO_ARGS5((file, line, expected, format, original),
-          TRIO_CONST char *file,
-          int line,
-          TRIO_CONST char *expected,
-          TRIO_CONST char *format,
-          double original)
-{
-  double number;
-  char data[512];
-  
-  trio_snprintf(data, sizeof(data), format, original);
-  trio_sscanf(data, format, &number);
-  return Verify(file, line, expected, format, number);
-}
-
-int
-VerifyScanningFloats(TRIO_NOARGS)
-{
-  int nerrors = 0;
-
-#if TRIO_FEATURE_FLOAT
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "42.000000",
-                                     "%f", 42.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "-42.000000",
-                                     "%f", -42.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "4.200000e+01",
-                                     "%e", 42.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "4.200000E+01",
-                                     "%E", 42.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "42",
-                                     "%g", 42.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e+06",
-                                     "%g", 1234567.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e-06",
-                                     "%g", 1.234567e-6);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457E+06",
-                                     "%G", 1234567.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234567e+06",
-                                     "%12e", 1234567.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234500e+00",
-                                     "%6e", 1234567.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234567e+06",
-                                     "%.6e", 1234567.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.2345670000e+06",
-                                     "%.10e", 1234567.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e+06",
-                                     "%.6g", 1234567.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1234567",
-                                     "%.10g", 1234567.0);
-# if TRIO_FEATURE_HEXFLOAT
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0x2.ap+4",
-                                     "%a", 42.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0x1.2d687p+20",
-                                     "%a", 1234567.0);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0X1.2D687P+20",
-                                     "%A", 1234567.0);
-# endif
-  nerrors += VerifyScanningOneDouble(__FILE__, __LINE__, "1.79769e+308",
-                                     "%lg", 1.79769e+308);
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "nan",
-                                     "%f", trio_nan());
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "NAN",
-                                     "%F", trio_nan());
-  nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "-inf",
-                                     "%f", trio_ninf());
-#endif
-  
-  return nerrors;
-}
-#endif
-
-/*************************************************************************
- *
- */
-#if TRIO_FEATURE_SCANF
-int
-VerifyScanningOneString
-TRIO_ARGS5((file, line, expected, format, original),
-          TRIO_CONST char *file,
-          int line,
-          TRIO_CONST char *expected,
-          TRIO_CONST char *format,
-          char *original)
-{
-  char string[512];
-  char data[512];
-  
-  trio_snprintf(data, sizeof(data), "%s", original);
-  string[0] = 0;
-  trio_sscanf(data, format, string);
-  return Verify(file, line, expected, "%s", string);
-}
-
-int
-VerifyScanningStrings(TRIO_NOARGS)
-{
-  int nerrors = 0;
-
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "",
-                                    "hello", "hello");
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "",
-                                    "", "");
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
-                                    "%s", "hello");
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
-                                    "%s", "hello world");
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello world",
-                                    "%[^\n]", "hello world");
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "(nil)",
-                                    "%s", NULL);
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
-                                    "%20s", "hello");
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "he",
-                                    "%2s", "hello");
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "ab",
-                                    "%[ab]", "abcba");
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
-                                    "%[abc]", "abcba");
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
-                                    "%[a-c]", "abcba");
-#if TRIO_EXTENSION
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
-                                    "%[[:alpha:]]", "abcba");
-#endif
-  nerrors += VerifyScanningOneString(__FILE__, __LINE__, "ba",
-                                    "%*[ab]c%[^\n]", "abcba");
-
-  return nerrors;
-}
-#endif
-
-/*************************************************************************
- *
- */
-#if TRIO_FEATURE_SCANF
-int
-VerifyScanningRegression(TRIO_NOARGS)
-{
-  int nerrors = 0;
-  int rc;
-#if TRIO_FEATURE_FLOAT
-  int offset;
-  double dnumber;
-# if defined(TRIO_BREESE)
-  trio_long_double_t ldnumber;
-# endif
-#endif
-  long lnumber;
-  int number;
-  char ch;
-  char buffer[4096];
-  FILE *stream;
-
-#if TRIO_FEATURE_FLOAT
-  rc = trio_sscanf("1.5", "%lf%n", &dnumber, &offset);
-  nerrors += Verify(__FILE__, __LINE__, "1 3 1.500000",
-                   "%d %d %f", rc, offset, dnumber);
-#endif
-  rc = trio_sscanf("q 123", "%c%ld", &ch, &lnumber);
-  nerrors += Verify(__FILE__, __LINE__, "q 123",
-                   "%c %ld", ch, lnumber);
-  rc = trio_sscanf("abc", "%*s%n", &number);
-  nerrors += Verify(__FILE__, __LINE__, "0 3",
-                   "%d %d", rc, number);
-  rc = trio_sscanf("abc def", "%*s%n", &number);
-  nerrors += Verify(__FILE__, __LINE__, "0 3",
-                   "%d %d", rc, number);
-#if TRIO_FEATURE_FLOAT
-  rc = trio_sscanf("0.141882295971771490", "%lf", &dnumber);
-  /* FIXME: Verify */
-#endif
-  number = 33;
-  rc = trio_sscanf("total 1", "total %d", &number);
-  nerrors += Verify(__FILE__, __LINE__, "1 1",
-                   "%d %d", rc, number);
-#if defined(TRIO_BREESE)
-# if TRIO_FEATURE_FLOAT
-  nerrors += Verify(__FILE__, __LINE__, "1 0.141882295971771488",
-                   "%d %.18f", rc, dnumber);
-  rc = trio_sscanf("0.141882295971771490", "%Lf", &ldnumber);
-  nerrors += Verify(__FILE__, __LINE__, "1 0.141882295971771490",
-                   "%d %.18Lf", rc, ldnumber);
-# endif
-#endif
-#if TRIO_FEATURE_FLOAT
-  rc = trio_sscanf("1.e-6", "%lg", &dnumber);
-  nerrors += Verify(__FILE__, __LINE__, "1e-06",
-                   "%g", dnumber);
-  rc = trio_sscanf("1e-6", "%lg", &dnumber);
-  nerrors += Verify(__FILE__, __LINE__, "1e-06",
-                   "%g", dnumber);
-#endif
-
-  /* Do not overwrite result on matching error */
-  ch = 'a';
-  rc = trio_sscanf("0123456789", "%1[c]", &ch);
-  nerrors += Verify(__FILE__, __LINE__, "a",
-                   "%c", ch);
-
-  /* Scan plus prefix for unsigned integer */
-  rc = trio_sscanf("+42", "%u", &number);
-  nerrors += Verify(__FILE__, __LINE__, "1 42",
-                   "%d %u", rc, number);
-
-  /* Scan minus prefix even for unsigned integer */
-  rc = trio_sscanf("-42", "%u", &number);
-  sprintf(buffer, "1 %u", -42U);
-  nerrors += Verify(__FILE__, __LINE__, buffer,
-                   "%d %u", rc, number);
-
-  /* A scangroup match failure should not bind its argument,
-   * i.e., it shouldn't match the empty string. */
-  sprintf(buffer, "SPQR");
-  rc = trio_sscanf("asdf", "%[c]", buffer);
-  nerrors += Verify(__FILE__, __LINE__, "0 SPQR",
-                   "%d %s", rc, buffer);
-
-  /* Even whitespace scanning shouldn't try to read past EOF */
-  stream = tmpfile();
-  trio_fprintf(stream, "");
-  rewind(stream);
-  rc = trio_fscanf(stream, " ");
-  nerrors += Verify(__FILE__, __LINE__, "0",
-                   "%d", rc);
-  fclose(stream);
-
-  /* Idem, after a succesfull read */
-  stream = tmpfile();
-  trio_fprintf(stream, "123");
-  rewind(stream);
-  rc = trio_fscanf(stream, "%i ", &number);
-  nerrors += Verify(__FILE__, __LINE__, "1 123",
-                   "%d %i", rc, number);
-  fclose(stream);
-
-  /* The scanner should unget its read-ahead char */
-  stream = tmpfile();
-  trio_fprintf(stream, "123");
-  rewind(stream);
-  trio_fscanf(stream, "%*c");
-  trio_fscanf(stream, "%c", &ch);
-  nerrors += Verify(__FILE__, __LINE__, "2",
-                   "%c", ch);
-  fclose(stream);
-
-  return nerrors;
-}
-#endif
-
-/*************************************************************************
- *
- */
-int
-VerifyScanning(TRIO_NOARGS)
-{
-  int nerrors = 0;
-#if TRIO_FEATURE_SCANF
-  nerrors += VerifyScanningIntegers();
-  nerrors += VerifyScanningFloats();
-  nerrors += VerifyScanningStrings();
-  nerrors += VerifyScanningRegression();
-#endif
-  return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyStrings(TRIO_NOARGS)
-{
-  int nerrors = 0;
-#if !defined(TRIO_MINIMAL)
-  char buffer[512];
-#if TRIO_FEATURE_FLOAT
-  double dnumber;
-  float fnumber;
-#endif
-  char *end;
-
-  /* Comparison */
-  trio_copy(buffer, "Find me now");
-  if (trio_length(buffer) != sizeof("Find me now") - 1) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (!trio_equal(buffer, "Find me now")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (!trio_equal_case(buffer, "Find me now")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (trio_equal_case(buffer, "FIND ME NOW")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (!trio_equal_max(buffer, sizeof("Find me") - 1, "Find ME")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (!trio_contains(buffer, "me")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (trio_contains(buffer, "and me")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (trio_substring(buffer, "me") == NULL) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (trio_substring_max(buffer, 4, "me") != NULL) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (!trio_match(buffer, "* me *")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (trio_match_case(buffer, "* ME *")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (trio_index(buffer, 'n') == NULL) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (trio_index(buffer, '_') != NULL) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (trio_index_last(buffer, 'n') == NULL) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-
-  /* Append */
-  trio_copy(buffer, "Find me now");
-  if (!trio_append(buffer, " and again")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (!trio_equal(buffer, "Find me now and again")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (!trio_append_max(buffer, 0, "should not appear")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (!trio_equal(buffer, "Find me now and again")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  
-  /* To upper/lower */
-  trio_copy(buffer, "Find me now");
-  trio_upper(buffer);
-  if (!trio_equal_case(buffer, "FIND ME NOW")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  trio_lower(buffer);
-  if (!trio_equal_case(buffer, "find me now")) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-
-#if TRIO_FEATURE_FLOAT
-  /* Double conversion */
-  trio_copy(buffer, "3.1415");
-  dnumber = trio_to_double(buffer, NULL);
-  if (!DOUBLE_EQUAL(dnumber, 3.1415)) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  fnumber = trio_to_float(buffer, NULL);
-  if (!FLOAT_EQUAL(fnumber, 3.1415)) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-#endif
-
-  /* Long conversion */
-  trio_copy(buffer, "3.1415");
-  if (trio_to_long(buffer, NULL, 10) != 3L) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  if (trio_to_long(buffer, NULL, 4) != 3L) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  trio_to_long(buffer, &end, 2);
-  if (end != buffer) {
-    nerrors++;
-    Report0(__FILE__, __LINE__);
-  }
-  
-#endif /* !defined(TRIO_MINIMAL) */
-  return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyDynamicStrings(TRIO_NOARGS)
-{
-  int nerrors = 0;
-#if !defined(TRIO_MINIMAL)
-  trio_string_t *string;
-  const char no_terminate[5] = { 'h', 'e', 'l', 'l', 'o' };
-
-  string = trio_xstring_duplicate("Find me now");
-  if (string == NULL) {
-    nerrors++;
-    goto error;
-  }
-  if (!trio_xstring_equal(string, "FIND ME NOW"))
-    nerrors++;
-  if (!trio_xstring_append(string, " and again") ||
-      !trio_xstring_equal(string, "FIND ME NOW AND AGAIN"))
-    nerrors++;
-  if (!trio_xstring_contains(string, "me"))
-    nerrors++;
-  if (trio_xstring_contains(string, "ME"))
-    nerrors++;
-  if (!trio_xstring_match(string, "* me *"))
-    nerrors++;
-  if (trio_xstring_match_case(string, "* ME *"))
-    nerrors++;
-  if (!trio_xstring_append_max(string, no_terminate, 5) ||
-      !trio_xstring_equal(string, "FIND ME NOW AND AGAINhello"))
-    nerrors++;
-  
- error:
-  if (string)
-    trio_string_destroy(string);
-  
-#endif /* !defined(TRIO_MINIMAL) */
-  return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyNaN(TRIO_NOARGS)
-{
-  double ninf_number = trio_ninf();
-  double pinf_number = trio_pinf();
-  double nan_number = trio_nan();
-  int nerrors = 0;
-  
-  nerrors += Verify(__FILE__, __LINE__, "-1",
-                   "%d", trio_isinf(ninf_number));
-  nerrors += Verify(__FILE__, __LINE__, "0",
-                   "%d", trio_isinf(42.0));
-  nerrors += Verify(__FILE__, __LINE__, "1",
-                   "%d", trio_isinf(pinf_number));
-  nerrors += Verify(__FILE__, __LINE__, "1",
-                   "%d", trio_isnan(nan_number));
-  nerrors += Verify(__FILE__, __LINE__, "0",
-                   "%d", trio_isnan(42.0));
-
-  return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-main(TRIO_NOARGS)
-{
-  int nerrors = 0;
-
-  printf("%s\n", rcsid);
-
-#if TRIO_EXTENSION
-  /* Override system locale settings */
-  trio_locale_set_decimal_point(".");
-  trio_locale_set_thousand_separator(",");
-  trio_locale_set_grouping("\3");
-#endif
-
-  printf("Verifying strings\n");
-  nerrors += VerifyStrings();
-  
-  printf("Verifying dynamic strings\n");
-  nerrors += VerifyDynamicStrings();
-
-  printf("Verifying special quantities\n");
-  nerrors += VerifyNaN();
-  
-  printf("Verifying formatting\n");
-  nerrors += VerifyFormatting();
-  
-  printf("Verifying scanning\n");
-  nerrors += VerifyScanning();
-  
-  printf("Verifying return values\n");
-  nerrors += VerifyErrors();
-  nerrors += VerifyReturnValues();
-  
-  printf("Verifying allocation\n");
-  nerrors += VerifyAllocate();
-
-  if (nerrors == 0)
-    printf("Regression test succeeded\n");
-  else
-    printf("Regression test failed in %d instance(s)\n", nerrors);
-  
-  return nerrors ? 1 : 0;
-}
diff --git a/trio/strio.h b/trio/strio.h
deleted file mode 100644 (file)
index d90cfcf..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-/*************************************************************************
- *
- * $Id: strio.h,v 1.11 2001/12/27 17:29:20 breese Exp $
- *
- * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************
- *
- * This maintains backwards compatibility with the strio functions.
- *
- ************************************************************************/
-
-#ifndef TRIO_STRIO_H
-#define TRIO_STRIO_H
-
-#if !(defined(DEBUG) || defined(NDEBUG))
-# define NDEBUG
-#endif
-#include "triostr.h"
-
-enum {
-  STRIO_HASH_NONE = TRIO_HASH_NONE,
-  STRIO_HASH_PLAIN = TRIO_HASH_PLAIN,
-  STRIO_HASH_TWOSIGNED = TRIO_HASH_TWOSIGNED
-};
-
-#define StrAlloc(n) trio_create(n)
-#define StrAppend(x,y) ((void)trio_append((x),(y)),(x))
-#define StrAppendMax(x,n,y) ((void)trio_append_max((x),(n),(y)),(x))
-#define StrContains(x,y) trio_contains((x),(y))
-#define StrCopy(x,y) ((void)trio_copy((x),(y)),(x))
-#define StrCopyMax(x,n,y) ((void)trio_copy_max((x),(n),(y)),(x))
-#define StrDuplicate(x) trio_duplicate(x)
-#define StrDuplicateMax(x,n) trio_duplicate((x),(n))
-#define StrEqual(x,y) trio_equal((x),(y))
-#define StrEqualCase(x,y) trio_equal_case((x),(y))
-#define StrEqualCaseMax(x,n,y) trio_equal_case_max((x),(n),(y))
-#define StrEqualLocale(x,y) trio_equal_locale((x),(y))
-#define StrEqualMax(x,n,y) trio_equal_max((x),(n),(y))
-#define StrError(n) trio_error(n)
-#define StrFree(x) trio_destroy(x)
-#define StrFormat trio_sprintf
-#define StrFormatAlloc trio_aprintf
-#define StrFormatAppendMax trio_snprintfcat
-#define StrFormatDateMax(x,n,y,t) trio_format_date_max((x),(n),(y),(t))
-#define StrFormatMax trio_snprintf
-#define StrHash(x,n) trio_hash((x),(n))
-#define StrIndex(x,y) trio_index((x),(y))
-#define StrIndexLast(x,y) trio_index_last((x),(y))
-#define StrLength(x) trio_length((x))
-#define StrMatch(x,y) trio_match((x),(y))
-#define StrMatchCase(x,y) trio_match_case((x),(y))
-#define StrScan trio_sscanf
-#define StrSpanFunction(x,f) trio_span_function((x),(f))
-#define StrSubstring(x,y) trio_substring((x),(y))
-#define StrSubstringMax(x,n,y) trio_substring_max((x),(n),(y))
-#define StrToDouble(x,y) trio_to_double((x),(y))
-#define StrToFloat(x,y) trio_to_float((x),(y))
-#define StrTokenize(x,y) trio_tokenize((x),(y))
-#define StrToLong(x,y,n) trio_to_long((x),(y),(n))
-#define StrToUnsignedLong(x,y,n) trio_to_unsigned_long((x),(n),(y))
-#define StrToUpper(x) trio_upper(x)
-
-#endif /* TRIO_STRIO_H */
diff --git a/trio/trio.c b/trio/trio.c
deleted file mode 100644 (file)
index 61d7c40..0000000
+++ /dev/null
@@ -1,7765 +0,0 @@
-/*************************************************************************
- *
- * $Id: trio.c,v 1.129 2009/09/20 11:37:15 breese Exp $
- *
- * Copyright (C) 1998, 2009 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- *************************************************************************
- *
- * A note to trio contributors:
- *
- * Avoid heap allocation at all costs to ensure that the trio functions
- * are async-safe. The exceptions are the printf/fprintf functions, which
- * uses fputc, and the asprintf functions and the <alloc> modifier, which
- * by design are required to allocate form the heap.
- *
- ************************************************************************/
-
-/*
- * TODO:
- *  - Scan is probably too permissive about its modifiers.
- *  - C escapes in %#[] ?
- *  - Multibyte characters (done for format parsing, except scan groups)
- *  - Complex numbers? (C99 _Complex)
- *  - Boolean values? (C99 _Bool)
- *  - C99 NaN(n-char-sequence) missing. The n-char-sequence can be used
- *    to print the mantissa, e.g. NaN(0xc000000000000000)
- *  - Should we support the GNU %a alloc modifier? GNU has an ugly hack
- *    for %a, because C99 used %a for other purposes. If specified as
- *    %as or %a[ it is interpreted as the alloc modifier, otherwise as
- *    the C99 hex-float. This means that you cannot scan %as as a hex-float
- *    immediately followed by an 's'.
- *  - Scanning of collating symbols.
- */
-
-/*************************************************************************
- * Trio include files
- */
-#include "triodef.h"
-#include "trio.h"
-#include "triop.h"
-
-#if defined(TRIO_EMBED_NAN)
-# define TRIO_PUBLIC_NAN static
-# if TRIO_FEATURE_FLOAT
-#  define TRIO_FUNC_NAN
-#  define TRIO_FUNC_NINF
-#  define TRIO_FUNC_PINF
-#  define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT
-#  define TRIO_FUNC_ISINF
-# endif
-#endif
-#include "trionan.h"
-
-#if defined(TRIO_EMBED_STRING)
-# define TRIO_PUBLIC_STRING static
-# define TRIO_FUNC_LENGTH
-# define TRIO_FUNC_LENGTH_MAX
-# define TRIO_FUNC_TO_LONG
-# if TRIO_FEATURE_LOCALE
-#  define TRIO_FUNC_COPY_MAX
-# endif
-# if TRIO_FEATURE_DYNAMICSTRING
-#  define TRIO_FUNC_XSTRING_DUPLICATE
-# endif
-# if TRIO_EXTENSION && TRIO_FEATURE_SCANF
-#  define TRIO_FUNC_EQUAL_LOCALE
-# endif
-# if TRIO_FEATURE_ERRNO
-#  define TRIO_FUNC_ERROR
-# endif
-# if TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF
-#  define TRIO_FUNC_TO_DOUBLE
-# endif
-# if TRIO_FEATURE_DYNAMICSTRING
-#  define TRIO_FUNC_STRING_EXTRACT
-# endif
-# if TRIO_FEATURE_DYNAMICSTRING
-#  define TRIO_FUNC_STRING_TERMINATE
-# endif
-# if TRIO_FEATURE_USER_DEFINED
-#  define TRIO_FUNC_DUPLICATE
-# endif
-# if TRIO_FEATURE_DYNAMICSTRING
-#  define TRIO_FUNC_STRING_DESTROY
-# endif
-# if TRIO_FEATURE_USER_DEFINED
-#  define TRIO_FUNC_DESTROY
-# endif
-# if TRIO_FEATURE_USER_DEFINED || (TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF)
-#  define TRIO_FUNC_EQUAL
-# endif
-# if TRIO_FEATURE_USER_DEFINED || TRIO_FEATURE_SCANF
-#  define TRIO_FUNC_EQUAL_CASE
-# endif
-# if (TRIO_EXTENSION && TRIO_FEATURE_SCANF)
-#  define TRIO_FUNC_EQUAL_MAX
-# endif
-# if TRIO_FEATURE_SCANF
-#  define TRIO_FUNC_TO_UPPER
-# endif
-# if TRIO_FEATURE_DYNAMICSTRING
-#  define TRIO_FUNC_XSTRING_APPEND_CHAR
-# endif
-#endif
-#include "triostr.h"
-
-/**************************************************************************
- *
- * Definitions
- *
- *************************************************************************/
-
-#include <limits.h>
-#if TRIO_FEATURE_FLOAT
-# include <math.h>
-# include <float.h>
-#endif
-
-#if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_FEATURE_WIDECHAR
-# if !defined(TRIO_PLATFORM_WINCE)
-#  define TRIO_COMPILER_SUPPORTS_MULTIBYTE
-#  if !defined(MB_LEN_MAX)
-#   define MB_LEN_MAX 6
-#  endif
-# endif
-#endif
-
-#if (TRIO_COMPILER_VISUALC - 0 >= 1100) || defined(TRIO_COMPILER_BORLAND)
-# define TRIO_COMPILER_SUPPORTS_VISUALC_INT
-#endif
-
-#if TRIO_FEATURE_FLOAT
-# if defined(PREDEF_STANDARD_C99) \
-  || defined(PREDEF_STANDARD_UNIX03)
-#  if !defined(HAVE_FLOORL) && !defined(TRIO_NO_FLOORL)
-#   define HAVE_FLOORL
-#  endif
-#  if !defined(HAVE_CEILL) && !defined(TRIO_NO_CEILL)
-#   define HAVE_CEILL
-#  endif
-#  if !defined(HAVE_POWL) && !defined(TRIO_NO_POWL)
-#   define HAVE_POWL
-#  endif
-#  if !defined(HAVE_FMODL) && !defined(TRIO_NO_FMODL)
-#   define HAVE_FMODL
-#  endif
-#  if !defined(HAVE_LOG10L) && !defined(TRIO_NO_LOG10L)
-#   define HAVE_LOG10L
-#  endif
-# endif
-# if defined(TRIO_COMPILER_VISUALC)
-#  if defined(floorl)
-#   define HAVE_FLOORL
-#  endif
-#  if defined(ceill)
-#   define HAVE_CEILL
-#  endif
-#  if defined(powl)
-#   define HAVE_POWL
-#  endif
-#  if defined(fmodl)
-#   define HAVE_FMODL
-#  endif
-#  if defined(log10l)
-#   define HAVE_LOG10L
-#  endif
-# endif
-#endif
-
-/*************************************************************************
- * Generic definitions
- */
-
-#if !(defined(DEBUG) || defined(NDEBUG))
-# define NDEBUG
-#endif
-
-#include <assert.h>
-#include <ctype.h>
-#if defined(PREDEF_STANDARD_C99) && !defined(isascii)
-# define isascii(x) ((x) & 0x7F)
-#endif
-#if defined(TRIO_COMPILER_ANCIENT)
-# include <varargs.h>
-#else
-# include <stdarg.h>
-#endif
-#include <stddef.h>
-#if defined(TRIO_PLATFORM_WINCE)
-extern int errno;
-#else
-# include <errno.h>
-#endif
-
-#ifndef NULL
-# define NULL 0
-#endif
-#define NIL ((char)0)
-#ifndef FALSE
-# define FALSE (1 == 0)
-# define TRUE (! FALSE)
-#endif
-#define BOOLEAN_T int
-
-/* mincore() can be used for debugging purposes */
-#define VALID(x) (NULL != (x))
-
-#if TRIO_FEATURE_ERRORCODE
-  /*
-   * Encode the error code and the position. This is decoded
-   * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION.
-   */
-# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8)))
-#else
-# define TRIO_ERROR_RETURN(x,y) (-1)
-#endif
-
-typedef unsigned long trio_flags_t;
-
-
-/*************************************************************************
- * Platform specific definitions
- */
-#if defined(TRIO_PLATFORM_UNIX)
-# include <unistd.h>
-# include <signal.h>
-# include <locale.h>
-# if !defined(TRIO_FEATURE_LOCALE)
-#  define USE_LOCALE
-# endif
-#endif /* TRIO_PLATFORM_UNIX */
-#if defined(TRIO_PLATFORM_VMS)
-# include <unistd.h>
-#endif
-#if defined(TRIO_PLATFORM_WIN32)
-# if defined(TRIO_PLATFORM_WINCE)
-int read(int handle, char *buffer, unsigned int length);
-int write(int handle, const char *buffer, unsigned int length);
-# else
-#  include <io.h>
-#  define read _read
-#  define write _write
-# endif
-#endif /* TRIO_PLATFORM_WIN32 */
-
-#if TRIO_FEATURE_WIDECHAR
-# if defined(PREDEF_STANDARD_C94)
-#  include <wchar.h>
-#  include <wctype.h>
-typedef wchar_t trio_wchar_t;
-typedef wint_t trio_wint_t;
-# else
-typedef char trio_wchar_t;
-typedef int trio_wint_t;
-#  define WCONST(x) L ## x
-#  define WEOF EOF
-#  define iswalnum(x) isalnum(x)
-#  define iswalpha(x) isalpha(x)
-#  define iswcntrl(x) iscntrl(x)
-#  define iswdigit(x) isdigit(x)
-#  define iswgraph(x) isgraph(x)
-#  define iswlower(x) islower(x)
-#  define iswprint(x) isprint(x)
-#  define iswpunct(x) ispunct(x)
-#  define iswspace(x) isspace(x)
-#  define iswupper(x) isupper(x)
-#  define iswxdigit(x) isxdigit(x)
-# endif
-#endif
-
-
-/*************************************************************************
- * Compiler dependent definitions
- */
-
-/* Support for long long */
-#ifndef __cplusplus
-# if !defined(USE_LONGLONG)
-#  if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__)
-#   define USE_LONGLONG
-#  else
-#   if defined(TRIO_COMPILER_SUNPRO)
-#    define USE_LONGLONG
-#   else
-#    if defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= 1400)
-#     define USE_LONGLONG
-#    else
-#     if defined(_LONG_LONG) || defined(_LONGLONG)
-#      define USE_LONGLONG
-#     endif
-#    endif
-#   endif
-#  endif
-# endif
-#endif
-
-/* The extra long numbers */
-#if defined(USE_LONGLONG)
-typedef signed long long int trio_longlong_t;
-typedef unsigned long long int trio_ulonglong_t;
-#else
-# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT)
-typedef signed __int64 trio_longlong_t;
-typedef unsigned __int64 trio_ulonglong_t;
-# else
-typedef TRIO_SIGNED long int trio_longlong_t;
-typedef unsigned long int trio_ulonglong_t;
-# endif
-#endif
-
-/* Maximal and fixed integer types */
-#if defined(PREDEF_STANDARD_C99)
-# include <stdint.h>
-typedef intmax_t trio_intmax_t;
-typedef uintmax_t trio_uintmax_t;
-typedef int8_t trio_int8_t;
-typedef int16_t trio_int16_t;
-typedef int32_t trio_int32_t;
-typedef int64_t trio_int64_t;
-#else
-# if defined(PREDEF_STANDARD_UNIX98)
-#  include <inttypes.h>
-typedef intmax_t trio_intmax_t;
-typedef uintmax_t trio_uintmax_t;
-typedef int8_t trio_int8_t;
-typedef int16_t trio_int16_t;
-typedef int32_t trio_int32_t;
-typedef int64_t trio_int64_t;
-# else
-#  if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT)
-typedef trio_longlong_t trio_intmax_t;
-typedef trio_ulonglong_t trio_uintmax_t;
-typedef __int8 trio_int8_t;
-typedef __int16 trio_int16_t;
-typedef __int32 trio_int32_t;
-typedef __int64 trio_int64_t;
-#  else
-typedef trio_longlong_t trio_intmax_t;
-typedef trio_ulonglong_t trio_uintmax_t;
-#   if defined(TRIO_INT8_T)
-typedef TRIO_INT8_T trio_int8_t;
-#   else
-typedef TRIO_SIGNED char trio_int8_t;
-#   endif
-#   if defined(TRIO_INT16_T)
-typedef TRIO_INT16_T trio_int16_t;
-#   else
-typedef TRIO_SIGNED short trio_int16_t;
-#   endif
-#   if defined(TRIO_INT32_T)
-typedef TRIO_INT32_T trio_int32_t;
-#   else
-typedef TRIO_SIGNED int trio_int32_t;
-#   endif
-#   if defined(TRIO_INT64_T)
-typedef TRIO_INT64_T trio_int64_t;
-#   else
-typedef trio_longlong_t trio_int64_t;
-#   endif
-#  endif
-# endif
-#endif
-
-#if defined(HAVE_FLOORL)
-# define trio_floor(x) floorl((x))
-#else
-# define trio_floor(x) floor((double)(x))
-#endif
-
-#if defined(HAVE_CEILL)
-# define trio_ceil(x) ceill((x))
-#else
-# define trio_ceil(x) ceil((double)(x))
-#endif
-
-#if defined(HAVE_FMODL)
-# define trio_fmod(x,y) fmodl((x),(y))
-#else
-# define trio_fmod(x,y) fmod((double)(x),(double)(y))
-#endif
-
-#if defined(HAVE_POWL)
-# define trio_pow(x,y) powl((x),(y))
-#else
-# define trio_pow(x,y) pow((double)(x),(double)(y))
-#endif
-
-#if defined(HAVE_LOG10L)
-# define trio_log10(x) log10l((x))
-#else
-# define trio_log10(x) log10((double)(x))
-#endif
-
-#if TRIO_FEATURE_FLOAT
-# define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x))
-#endif
-
-/*************************************************************************
- * Internal Definitions
- */
-
-#if TRIO_FEATURE_FLOAT
-
-# if !defined(DECIMAL_DIG)
-#  define DECIMAL_DIG DBL_DIG
-# endif
-
-/* Long double sizes */
-# ifdef LDBL_DIG
-#  define MAX_MANTISSA_DIGITS LDBL_DIG
-#  define MAX_EXPONENT_DIGITS 4
-#  define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP
-# else
-#  define MAX_MANTISSA_DIGITS DECIMAL_DIG
-#  define MAX_EXPONENT_DIGITS 3
-#  define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP
-# endif
-
-# if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG)
-#  undef LDBL_DIG
-#  undef LDBL_MANT_DIG
-#  undef LDBL_EPSILON
-#  define LDBL_DIG DBL_DIG
-#  define LDBL_MANT_DIG DBL_MANT_DIG
-#  define LDBL_EPSILON DBL_EPSILON
-# endif
-
-#endif /* TRIO_FEATURE_FLOAT */
-
-/* The maximal number of digits is for base 2 */
-#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT)
-/* The width of a pointer. The number of bits in a hex digit is 4 */
-#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4)
-
-#if TRIO_FEATURE_FLOAT
-/* Infinite and Not-A-Number for floating-point */
-# define INFINITE_LOWER "inf"
-# define INFINITE_UPPER "INF"
-# define LONG_INFINITE_LOWER "infinite"
-# define LONG_INFINITE_UPPER "INFINITE"
-# define NAN_LOWER "nan"
-# define NAN_UPPER "NAN"
-#endif
-
-/* Various constants */
-enum {
-  TYPE_PRINT = 1,
-#if TRIO_FEATURE_SCANF
-  TYPE_SCAN  = 2,
-#endif
-
-  /* Flags. FLAGS_LAST must be less than ULONG_MAX */
-  FLAGS_NEW                 = 0,
-  FLAGS_STICKY              = 1,
-  FLAGS_SPACE               = 2 * FLAGS_STICKY,
-  FLAGS_SHOWSIGN            = 2 * FLAGS_SPACE,
-  FLAGS_LEFTADJUST          = 2 * FLAGS_SHOWSIGN,
-  FLAGS_ALTERNATIVE         = 2 * FLAGS_LEFTADJUST,
-  FLAGS_SHORT               = 2 * FLAGS_ALTERNATIVE,
-  FLAGS_SHORTSHORT          = 2 * FLAGS_SHORT,
-  FLAGS_LONG                = 2 * FLAGS_SHORTSHORT,
-  FLAGS_QUAD                = 2 * FLAGS_LONG,
-  FLAGS_LONGDOUBLE          = 2 * FLAGS_QUAD,
-  FLAGS_SIZE_T              = 2 * FLAGS_LONGDOUBLE,
-  FLAGS_PTRDIFF_T           = 2 * FLAGS_SIZE_T,
-  FLAGS_INTMAX_T            = 2 * FLAGS_PTRDIFF_T,
-  FLAGS_NILPADDING          = 2 * FLAGS_INTMAX_T,
-  FLAGS_UNSIGNED            = 2 * FLAGS_NILPADDING,
-  FLAGS_UPPER               = 2 * FLAGS_UNSIGNED,
-  FLAGS_WIDTH               = 2 * FLAGS_UPPER,
-  FLAGS_WIDTH_PARAMETER     = 2 * FLAGS_WIDTH,
-  FLAGS_PRECISION           = 2 * FLAGS_WIDTH_PARAMETER,
-  FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION,
-  FLAGS_BASE                = 2 * FLAGS_PRECISION_PARAMETER,
-  FLAGS_BASE_PARAMETER      = 2 * FLAGS_BASE,
-  FLAGS_FLOAT_E             = 2 * FLAGS_BASE_PARAMETER,
-  FLAGS_FLOAT_G             = 2 * FLAGS_FLOAT_E,
-  FLAGS_QUOTE               = 2 * FLAGS_FLOAT_G,
-  FLAGS_WIDECHAR            = 2 * FLAGS_QUOTE,
-  FLAGS_IGNORE              = 2 * FLAGS_WIDECHAR,
-  FLAGS_IGNORE_PARAMETER    = 2 * FLAGS_IGNORE,
-  FLAGS_VARSIZE_PARAMETER   = 2 * FLAGS_IGNORE_PARAMETER,
-  FLAGS_FIXED_SIZE          = 2 * FLAGS_VARSIZE_PARAMETER,
-  FLAGS_LAST                = FLAGS_FIXED_SIZE,
-  /* Reused flags */
-  FLAGS_EXCLUDE             = FLAGS_SHORT,
-  FLAGS_USER_DEFINED        = FLAGS_IGNORE,
-  FLAGS_USER_DEFINED_PARAMETER = FLAGS_IGNORE_PARAMETER,
-  FLAGS_ROUNDING            = FLAGS_INTMAX_T,
-  /* Compounded flags */
-  FLAGS_ALL_VARSIZES        = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T,
-  FLAGS_ALL_SIZES           = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT,
-
-  NO_POSITION  = -1,
-  NO_WIDTH     =  0,
-  NO_PRECISION = -1,
-  NO_SIZE      = -1,
-
-  /* Do not change these */
-  NO_BASE      = -1,
-  MIN_BASE     =  2,
-  MAX_BASE     = 36,
-  BASE_BINARY  =  2,
-  BASE_OCTAL   =  8,
-  BASE_DECIMAL = 10,
-  BASE_HEX     = 16,
-
-  /* Maximal number of allowed parameters */
-  MAX_PARAMETERS = 64,
-  /* Maximal number of characters in class */
-  MAX_CHARACTER_CLASS = UCHAR_MAX + 1,
-
-#if TRIO_FEATURE_USER_DEFINED
-  /* Maximal string lengths for user-defined specifiers */
-  MAX_USER_NAME = 64,
-  MAX_USER_DATA = 256,
-#endif
-  
-  /* Maximal length of locale separator strings */
-  MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX,
-  /* Maximal number of integers in grouping */
-  MAX_LOCALE_GROUPS = 64
-};
-
-#define NO_GROUPING ((int)CHAR_MAX)
-
-/* Fundamental formatting parameter types */
-#define FORMAT_SENTINEL  -1    /* marks end of parameters array */
-#define FORMAT_UNKNOWN   0
-#define FORMAT_INT       1
-#define FORMAT_DOUBLE    2
-#define FORMAT_CHAR      3
-#define FORMAT_STRING    4
-#define FORMAT_POINTER   5
-#define FORMAT_COUNT     6
-#define FORMAT_PARAMETER 7
-#define FORMAT_GROUP     8
-#define FORMAT_ERRNO     9
-#define FORMAT_USER_DEFINED 10
-
-/* Character constants */
-#define CHAR_IDENTIFIER '%'
-#define CHAR_ALT_IDENTIFIER '$'
-#define CHAR_BACKSLASH '\\'
-#define CHAR_QUOTE '\"'
-#define CHAR_ADJUST ' '
-
-#if TRIO_EXTENSION
-/* Character class expressions */
-# define CLASS_ALNUM "[:alnum:]"
-# define CLASS_ALPHA "[:alpha:]"
-# define CLASS_BLANK "[:blank:]"
-# define CLASS_CNTRL "[:cntrl:]"
-# define CLASS_DIGIT "[:digit:]"
-# define CLASS_GRAPH "[:graph:]"
-# define CLASS_LOWER "[:lower:]"
-# define CLASS_PRINT "[:print:]"
-# define CLASS_PUNCT "[:punct:]"
-# define CLASS_SPACE "[:space:]"
-# define CLASS_UPPER "[:upper:]"
-# define CLASS_XDIGIT "[:xdigit:]"
-#endif
-
-/*
- * SPECIFIERS:
- *
- *
- * a  Hex-float
- * A  Hex-float
- * c  Character
- * C  Widechar character (wint_t)
- * d  Decimal
- * e  Float
- * E  Float
- * F  Float
- * F  Float
- * g  Float
- * G  Float
- * i  Integer
- * m  Error message
- * n  Count
- * o  Octal
- * p  Pointer
- * s  String
- * S  Widechar string (wchar_t *)
- * u  Unsigned
- * x  Hex
- * X  Hex
- * [] Group
- * <> User-defined
- *
- * Reserved:
- *
- * D  Binary Coded Decimal %D(length,precision) (OS/390)
- */
-#define SPECIFIER_CHAR 'c'
-#define SPECIFIER_STRING 's'
-#define SPECIFIER_DECIMAL 'd'
-#define SPECIFIER_INTEGER 'i'
-#define SPECIFIER_UNSIGNED 'u'
-#define SPECIFIER_OCTAL 'o'
-#define SPECIFIER_HEX 'x'
-#define SPECIFIER_HEX_UPPER 'X'
-#if TRIO_FEATURE_FLOAT
-# define SPECIFIER_FLOAT_E 'e'
-# define SPECIFIER_FLOAT_E_UPPER 'E'
-# define SPECIFIER_FLOAT_F 'f'
-# define SPECIFIER_FLOAT_F_UPPER 'F'
-# define SPECIFIER_FLOAT_G 'g'
-# define SPECIFIER_FLOAT_G_UPPER 'G'
-#endif
-#define SPECIFIER_POINTER 'p'
-#if TRIO_FEATURE_SCANF
-# define SPECIFIER_GROUP '['
-# define SPECIFIER_UNGROUP ']'
-#endif
-#define SPECIFIER_COUNT 'n'
-#if TRIO_UNIX98
-# define SPECIFIER_CHAR_UPPER 'C'
-# define SPECIFIER_STRING_UPPER 'S'
-#endif
-#define SPECIFIER_HEXFLOAT 'a'
-#define SPECIFIER_HEXFLOAT_UPPER 'A'
-#define SPECIFIER_ERRNO 'm'
-#if TRIO_FEATURE_BINARY
-# define SPECIFIER_BINARY 'b'
-# define SPECIFIER_BINARY_UPPER 'B'
-#endif
-#if TRIO_FEATURE_USER_DEFINED
-# define SPECIFIER_USER_DEFINED_BEGIN '<'
-# define SPECIFIER_USER_DEFINED_END '>'
-# define SPECIFIER_USER_DEFINED_SEPARATOR ':'
-# define SPECIFIER_USER_DEFINED_EXTRA '|'
-#endif
-
-/*
- * QUALIFIERS:
- *
- *
- * Numbers = d,i,o,u,x,X
- * Float = a,A,e,E,f,F,g,G
- * String = s
- * Char = c
- *
- *
- * 9$ Position
- *      Use the 9th parameter. 9 can be any number between 1 and
- *      the maximal argument
- *
- * 9 Width
- *      Set width to 9. 9 can be any number, but must not be postfixed
- *      by '$'
- *
- * h  Short
- *    Numbers:
- *      (unsigned) short int
- *
- * hh Short short
- *    Numbers:
- *      (unsigned) char
- *
- * l  Long
- *    Numbers:
- *      (unsigned) long int
- *    String:
- *      as the S specifier
- *    Char:
- *      as the C specifier
- *
- * ll Long Long
- *    Numbers:
- *      (unsigned) long long int
- *
- * L  Long Double
- *    Float
- *      long double
- *
- * #  Alternative
- *    Float:
- *      Decimal-point is always present
- *    String:
- *      non-printable characters are handled as \number
- *
- *    Spacing
- *
- * +  Sign
- *
- * -  Alignment
- *
- * .  Precision
- *
- * *  Parameter
- *    print: use parameter
- *    scan: no parameter (ignore)
- *
- * q  Quad
- *
- * Z  size_t
- *
- * w  Widechar
- *
- * '  Thousands/quote
- *    Numbers:
- *      Integer part grouped in thousands
- *    Binary numbers:
- *      Number grouped in nibbles (4 bits)
- *    String:
- *      Quoted string
- *
- * j  intmax_t
- * t  prtdiff_t
- * z  size_t
- *
- * !  Sticky
- * @  Parameter (for both print and scan)
- *
- * I  n-bit Integer
- *    Numbers:
- *      The following options exists
- *        I8  = 8-bit integer
- *        I16 = 16-bit integer
- *        I32 = 32-bit integer
- *        I64 = 64-bit integer
- */
-#define QUALIFIER_POSITION '$'
-#define QUALIFIER_SHORT 'h'
-#define QUALIFIER_LONG 'l'
-#define QUALIFIER_LONG_UPPER 'L'
-#define QUALIFIER_ALTERNATIVE '#'
-#define QUALIFIER_SPACE ' '
-#define QUALIFIER_PLUS '+'
-#define QUALIFIER_MINUS '-'
-#define QUALIFIER_DOT '.'
-#define QUALIFIER_STAR '*'
-#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */
-#define QUALIFIER_SIZE_T 'z'
-#define QUALIFIER_PTRDIFF_T 't'
-#define QUALIFIER_INTMAX_T 'j'
-#define QUALIFIER_QUAD 'q'
-#define QUALIFIER_SIZE_T_UPPER 'Z'
-#if TRIO_MISC
-# define QUALIFIER_WIDECHAR 'w'
-#endif
-#define QUALIFIER_FIXED_SIZE 'I'
-#define QUALIFIER_QUOTE '\''
-#define QUALIFIER_STICKY '!'
-#define QUALIFIER_VARSIZE '&' /* This should remain undocumented */
-#define QUALIFIER_ROUNDING_UPPER 'R'
-#if TRIO_EXTENSION
-# define QUALIFIER_PARAM '@' /* Experimental */
-# define QUALIFIER_COLON ':' /* For scanlists */
-# define QUALIFIER_EQUAL '=' /* For scanlists */
-#endif
-
-
-/*************************************************************************
- *
- * Internal Structures
- *
- *************************************************************************/
-
-/* Parameters */
-typedef struct {
-  /* An indication of which entry in the data union is used */
-  int type;
-  /* The flags */
-  trio_flags_t flags;
-  /* The width qualifier */
-  int width;
-  /* The precision qualifier */
-  int precision;
-  /* The base qualifier */
-  int base;
-  /* Base from specifier */
-  int baseSpecifier;
-  /* The size for the variable size qualifier */
-  int varsize;
-  /* Offset of the first character of the specifier */
-  int beginOffset;
-  /* Offset of the first character after the specifier */
-  int endOffset;
-  /* Position in the argument list that this parameter refers to */
-  int position;
-  /* The data from the argument list */
-  union {
-    char *string;
-#if TRIO_FEATURE_WIDECHAR
-    trio_wchar_t *wstring;
-#endif
-    trio_pointer_t pointer;
-    union {
-      trio_intmax_t as_signed;
-      trio_uintmax_t as_unsigned;
-    } number;
-#if TRIO_FEATURE_FLOAT
-    double doubleNumber;
-    double *doublePointer;
-    trio_long_double_t longdoubleNumber;
-    trio_long_double_t *longdoublePointer;
-#endif
-    int errorNumber;
-  } data;
-#if TRIO_FEATURE_USER_DEFINED
-  /* For the user-defined specifier */
-  union {
-    char namespace[MAX_USER_NAME];
-    int handler;        /* if flags & FLAGS_USER_DEFINED_PARAMETER */
-  } user_defined;
-  char user_data[MAX_USER_DATA];
-#endif
-} trio_parameter_t;
-
-/* Container for customized functions */
-typedef struct {
-  union {
-    trio_outstream_t out;
-    trio_instream_t in;
-  } stream;
-  trio_pointer_t closure;
-} trio_custom_t;
-
-/* General trio "class" */
-typedef struct _trio_class_t {
-  /*
-   * The function to write characters to a stream.
-   */
-  void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int));
-  /*
-   * The function to read characters from a stream.
-   */
-  void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *));
-  /*
-   * The function to undo read characters from a stream.
-   */
-  void (*UndoStream) TRIO_PROTO((struct _trio_class_t *));
-  /*
-   * The current location in the stream.
-   */
-  trio_pointer_t location;
-  /*
-   * The character currently being processed.
-   */
-  int current;
-  /*
-   * The number of characters that would have been written/read
-   * if there had been sufficient space.
-   */
-  int processed;
-  union {
-    /*
-     * The number of characters that are actually written. Processed and
-     * committed will only differ for the *nprintf functions.
-     */
-    int committed;
-    /*
-     * The number of look-ahead characters read.
-     */
-    int cached;
-  } actually;
-  /*
-   * The upper limit of characters that may be written/read.
-   */
-  int max;
-  /*
-   * The last output error that was detected.
-   */
-  int error;
-} trio_class_t;
-
-/* References (for user-defined callbacks) */
-typedef struct _trio_reference_t {
-  trio_class_t *data;
-  trio_parameter_t *parameter;
-} trio_reference_t;
-
-#if TRIO_FEATURE_USER_DEFINED
-/* Registered entries (for user-defined callbacks) */
-typedef struct _trio_userdef_t {
-  struct _trio_userdef_t *next;
-  trio_callback_t callback;
-  char *name;
-} trio_userdef_t;
-#endif
-
-/*************************************************************************
- *
- * Internal Variables
- *
- *************************************************************************/
-
-static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.129 2009/09/20 11:37:15 breese Exp $";
-
-#if TRIO_FEATURE_FLOAT
-/*
- * Need this to workaround a parser bug in HP C/iX compiler that fails
- * to resolves macro definitions that includes type 'long double',
- * e.g: va_arg(arg_ptr, long double)
- */
-# if defined(TRIO_PLATFORM_MPEIX)
-static TRIO_CONST trio_long_double_t ___dummy_long_double = 0;
-# endif
-#endif
-
-static TRIO_CONST char internalNullString[] = "(nil)";
-
-#if defined(USE_LOCALE)
-static struct lconv *internalLocaleValues = NULL;
-#endif
-
-/*
- * UNIX98 says "in a locale where the radix character is not defined,
- * the radix character defaults to a period (.)"
- */
-#if TRIO_FEATURE_FLOAT || TRIO_FEATURE_LOCALE || defined(USE_LOCALE)
-static int internalDecimalPointLength = 1;
-static char internalDecimalPoint = '.';
-static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ".";
-#endif
-#if TRIO_FEATURE_QUOTE || TRIO_FEATURE_LOCALE || TRIO_EXTENSION
-static int internalThousandSeparatorLength = 1;
-static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ",";
-static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING };
-#endif
-
-static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-#if TRIO_FEATURE_SCANF
-static BOOLEAN_T internalDigitsUnconverted = TRUE;
-static int internalDigitArray[128];
-# if TRIO_EXTENSION
-static BOOLEAN_T internalCollationUnconverted = TRUE;
-static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS];
-# endif
-#endif
-
-#if TRIO_FEATURE_USER_DEFINED
-static TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL;
-static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL;
-static trio_userdef_t *internalUserDef = NULL;
-#endif
-
-
-/*************************************************************************
- *
- * Internal Functions
- *
- ************************************************************************/
-
-#if defined(TRIO_EMBED_NAN)
-# include "trionan.c"
-#endif
-
-#if defined(TRIO_EMBED_STRING)
-# include "triostr.c"
-#endif
-
-/*************************************************************************
- * TrioInitializeParameter
- *
- * Description:
- *  Initialize a trio_parameter_t struct.
- */
-TRIO_PRIVATE void
-TrioInitializeParameter
-TRIO_ARGS1((parameter),
-          trio_parameter_t *parameter)
-{
-  parameter->type = FORMAT_UNKNOWN;
-  parameter->flags = 0;
-  parameter->width = 0;
-  parameter->precision = 0;
-  parameter->base = 0;
-  parameter->baseSpecifier = 0;
-  parameter->varsize = 0;
-  parameter->beginOffset = 0;
-  parameter->endOffset = 0;
-  parameter->position = 0;
-  parameter->data.pointer = 0;
-#if TRIO_FEATURE_USER_DEFINED
-  parameter->user_defined.handler = 0;
-  parameter->user_data[0] = 0;
-#endif
-}
-
-/*************************************************************************
- * TrioCopyParameter
- *
- * Description:
- *  Copies one trio_parameter_t struct to another.
- */
-TRIO_PRIVATE void
-TrioCopyParameter
-TRIO_ARGS2((target, source),
-          trio_parameter_t *target,
-          TRIO_CONST trio_parameter_t *source)
-{
-#if TRIO_FEATURE_USER_DEFINED
-  size_t i;
-#endif
-
-  target->type = source->type;
-  target->flags = source->flags;
-  target->width = source->width;
-  target->precision = source->precision;
-  target->base = source->base;
-  target->baseSpecifier = source->baseSpecifier;
-  target->varsize = source->varsize;
-  target->beginOffset = source->beginOffset;
-  target->endOffset = source->endOffset;
-  target->position = source->position;
-  target->data = source->data;
-
-#if TRIO_FEATURE_USER_DEFINED
-  target->user_defined = source->user_defined;
-
-  for (i = 0U; i < sizeof(target->user_data); ++i)
-    {
-      if ((target->user_data[i] = source->user_data[i]) == NIL)
-       break;
-    }
-#endif
-}
-
-/*************************************************************************
- * TrioIsQualifier
- *
- * Description:
- *  Remember to add all new qualifiers to this function.
- *  QUALIFIER_POSITION must not be added.
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioIsQualifier
-TRIO_ARGS1((character),
-          TRIO_CONST char character)
-{
-  /* QUALIFIER_POSITION is not included */
-  switch (character)
-    {
-    case '0': case '1': case '2': case '3': case '4':
-    case '5': case '6': case '7': case '8': case '9':
-    case QUALIFIER_PLUS:
-    case QUALIFIER_MINUS:
-    case QUALIFIER_SPACE:
-    case QUALIFIER_DOT:
-    case QUALIFIER_STAR:
-    case QUALIFIER_ALTERNATIVE:
-    case QUALIFIER_SHORT:
-    case QUALIFIER_LONG:
-    case QUALIFIER_CIRCUMFLEX:
-    case QUALIFIER_LONG_UPPER:
-    case QUALIFIER_SIZE_T:
-    case QUALIFIER_PTRDIFF_T:
-    case QUALIFIER_INTMAX_T:
-    case QUALIFIER_QUAD:
-    case QUALIFIER_SIZE_T_UPPER:
-#if defined(QUALIFIER_WIDECHAR)
-    case QUALIFIER_WIDECHAR:
-#endif
-    case QUALIFIER_QUOTE:
-    case QUALIFIER_STICKY:
-    case QUALIFIER_VARSIZE:
-#if defined(QUALIFIER_PARAM)
-    case QUALIFIER_PARAM:
-#endif
-    case QUALIFIER_FIXED_SIZE:
-    case QUALIFIER_ROUNDING_UPPER:
-      return TRUE;
-    default:
-      return FALSE;
-    }
-}
-
-/*************************************************************************
- * TrioSetLocale
- */
-#if defined(USE_LOCALE)
-TRIO_PRIVATE void
-TrioSetLocale(TRIO_NOARGS)
-{
-  internalLocaleValues = (struct lconv *)localeconv();
-  if (internalLocaleValues)
-    {
-      if ((internalLocaleValues->decimal_point) &&
-         (internalLocaleValues->decimal_point[0] != NIL))
-       {
-         internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point);
-         if (internalDecimalPointLength == 1)
-           {
-             internalDecimalPoint = internalLocaleValues->decimal_point[0];
-           }
-         else
-           {
-             internalDecimalPoint = NIL;
-             trio_copy_max(internalDecimalPointString,
-                           sizeof(internalDecimalPointString),
-                           internalLocaleValues->decimal_point);
-           }
-       }
-# if TRIO_EXTENSION
-      if ((internalLocaleValues->thousands_sep) &&
-         (internalLocaleValues->thousands_sep[0] != NIL))
-       {
-         trio_copy_max(internalThousandSeparator,
-                       sizeof(internalThousandSeparator),
-                       internalLocaleValues->thousands_sep);
-         internalThousandSeparatorLength = trio_length(internalThousandSeparator);
-       }
-# endif
-# if TRIO_EXTENSION
-      if ((internalLocaleValues->grouping) &&
-         (internalLocaleValues->grouping[0] != NIL))
-       {
-         trio_copy_max(internalGrouping,
-                       sizeof(internalGrouping),
-                       internalLocaleValues->grouping);
-       }
-# endif
-    }
-}
-#endif /* defined(USE_LOCALE) */
-
-#if TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE
-TRIO_PRIVATE int
-TrioCalcThousandSeparatorLength
-TRIO_ARGS1((digits),
-          int digits)
-{
-  int count = 0;
-  int step = NO_GROUPING;
-  char *groupingPointer = internalGrouping;
-
-  while (digits > 0)
-    {
-      if (*groupingPointer == CHAR_MAX)
-       {
-         /* Disable grouping */
-         break; /* while */
-       }
-      else if (*groupingPointer == 0)
-       {
-         /* Repeat last group */
-         if (step == NO_GROUPING)
-           {
-             /* Error in locale */
-             break; /* while */
-           }
-       }
-      else
-       {
-         step = *groupingPointer++;
-       }
-      if (digits > step)
-       count += internalThousandSeparatorLength;
-      digits -= step;
-    }
-  return count;
-}
-#endif /* TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE */
-
-#if TRIO_FEATURE_QUOTE
-TRIO_PRIVATE BOOLEAN_T
-TrioFollowedBySeparator
-TRIO_ARGS1((position),
-          int position)
-{
-  int step = 0;
-  char *groupingPointer = internalGrouping;
-
-  position--;
-  if (position == 0)
-    return FALSE;
-  while (position > 0)
-    {
-      if (*groupingPointer == CHAR_MAX)
-       {
-         /* Disable grouping */
-         break; /* while */
-       }
-      else if (*groupingPointer != 0)
-       {
-         step = *groupingPointer++;
-       }
-      if (step == 0)
-       break;
-      position -= step;
-    }
-  return (position == 0);
-}
-#endif /* TRIO_FEATURE_QUOTE */
-
-/*************************************************************************
- * TrioGetPosition
- *
- * Get the %n$ position.
- */
-TRIO_PRIVATE int
-TrioGetPosition
-TRIO_ARGS2((format, offsetPointer),
-          TRIO_CONST char *format,
-          int *offsetPointer)
-{
-#if TRIO_FEATURE_POSITIONAL
-  char *tmpformat;
-  int number = 0;
-  int offset = *offsetPointer;
-
-  number = (int)trio_to_long(&format[offset], &tmpformat, BASE_DECIMAL);
-  offset = (int)(tmpformat - format);
-  if ((number != 0) && (QUALIFIER_POSITION == format[offset++]))
-    {
-      *offsetPointer = offset;
-      /*
-       * number is decreased by 1, because n$ starts from 1, whereas
-       * the array it is indexing starts from 0.
-       */
-      return number - 1;
-    }
-#endif
-  return NO_POSITION;
-}
-
-/*************************************************************************
- * TrioFindNamespace
- *
- * Find registered user-defined specifier.
- * The prev argument is used for optimization only.
- */
-#if TRIO_FEATURE_USER_DEFINED
-TRIO_PRIVATE trio_userdef_t *
-TrioFindNamespace
-TRIO_ARGS2((name, prev),
-          TRIO_CONST char *name,
-          trio_userdef_t **prev)
-{
-  trio_userdef_t *def;
-  
-  if (internalEnterCriticalRegion)
-    (void)internalEnterCriticalRegion(NULL);
-  
-  for (def = internalUserDef; def; def = def->next)
-    {
-      /* Case-sensitive string comparison */
-      if (trio_equal_case(def->name, name))
-       break;
-      
-      if (prev)
-       *prev = def;
-    }
-  
-  if (internalLeaveCriticalRegion)
-    (void)internalLeaveCriticalRegion(NULL);
-  
-  return def;
-}
-#endif
-
-/*************************************************************************
- * TrioPower
- *
- * Description:
- *  Calculate pow(base, exponent), where number and exponent are integers.
- */
-#if TRIO_FEATURE_FLOAT
-TRIO_PRIVATE trio_long_double_t
-TrioPower
-TRIO_ARGS2((number, exponent),
-          int number,
-          int exponent)
-{
-  trio_long_double_t result;
-
-  if (number == 10)
-    {
-      switch (exponent)
-       {
-         /* Speed up calculation of common cases */
-       case 0:
-         result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1);
-         break;
-       case 1:
-         result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0);
-         break;
-       case 2:
-         result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1);
-         break;
-       case 3:
-         result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2);
-         break;
-       case 4:
-         result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3);
-         break;
-       case 5:
-         result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4);
-         break;
-       case 6:
-         result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5);
-         break;
-       case 7:
-         result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6);
-         break;
-       case 8:
-         result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7);
-         break;
-       case 9:
-         result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8);
-         break;
-       default:
-         result = trio_pow((trio_long_double_t)number,
-                           (trio_long_double_t)exponent);
-         break;
-       }
-    }
-  else
-    {
-      return trio_pow((trio_long_double_t)number,
-                     (trio_long_double_t)exponent);
-    }
-  return result;
-}
-#endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * TrioLogarithm
- */
-#if TRIO_FEATURE_FLOAT
-TRIO_PRIVATE trio_long_double_t
-TrioLogarithm
-TRIO_ARGS2((number, base),
-          trio_long_double_t number,
-          int base)
-{
-  trio_long_double_t result;
-
-  if (number <= 0.0)
-    {
-      /* xlC crashes on log(0) */
-      result = (number == 0.0) ? trio_ninf() : trio_nan();
-    }
-  else
-    {
-      if (base == 10)
-       {
-         result = trio_log10(number);
-       }
-      else
-       {
-         result = trio_log10(number) / trio_log10((double)base);
-       }
-    }
-  return result;
-}
-#endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * TrioLogarithmBase
- */
-#if TRIO_FEATURE_FLOAT
-TRIO_PRIVATE double
-TrioLogarithmBase
-TRIO_ARGS1((base),
-          int base)
-{
-  switch (base)
-    {
-    case BASE_BINARY : return 1.0;
-    case BASE_OCTAL  : return 3.0;
-    case BASE_DECIMAL: return 3.321928094887362345;
-    case BASE_HEX    : return 4.0;
-    default          : return TrioLogarithm((double)base, 2);
-    }
-}
-#endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * TrioParseQualifiers
- *
- * Description:
- *  Parse the qualifiers of a potential conversion specifier
- */
-TRIO_PRIVATE int
-TrioParseQualifiers
-TRIO_ARGS4((type, format, offset, parameter),
-          int type,
-          TRIO_CONST char *format,
-          int offset,
-          trio_parameter_t *parameter)
-{
-  char ch;
-  int dots = 0;  /* Count number of dots in modifier part */
-  char *tmpformat;
-
-  parameter->beginOffset = offset - 1;
-  parameter->flags = FLAGS_NEW;
-  parameter->position = TrioGetPosition(format, &offset);
-
-  /* Default values */
-  parameter->width = NO_WIDTH;
-  parameter->precision = NO_PRECISION;
-  parameter->base = NO_BASE;
-  parameter->varsize = NO_SIZE;
-
-  while (TrioIsQualifier(format[offset]))
-    {
-      ch = format[offset++];
-
-      switch (ch)
-        {
-       case QUALIFIER_SPACE:
-         parameter->flags |= FLAGS_SPACE;
-         break;
-
-       case QUALIFIER_PLUS:
-         parameter->flags |= FLAGS_SHOWSIGN;
-         break;
-
-       case QUALIFIER_MINUS:
-         parameter->flags |= FLAGS_LEFTADJUST;
-         parameter->flags &= ~FLAGS_NILPADDING;
-         break;
-
-       case QUALIFIER_ALTERNATIVE:
-         parameter->flags |= FLAGS_ALTERNATIVE;
-         break;
-
-       case QUALIFIER_DOT:
-         if (dots == 0) /* Precision */
-           {
-             dots++;
-
-             /* Skip if no precision */
-             if (QUALIFIER_DOT == format[offset])
-               break;
-
-             /* After the first dot we have the precision */
-             parameter->flags |= FLAGS_PRECISION;
-             if ((QUALIFIER_STAR == format[offset])
-#if defined(QUALIFIER_PARAM)
-                 || (QUALIFIER_PARAM == format[offset])
-#endif
-                 )
-               {
-                 offset++;
-                 parameter->flags |= FLAGS_PRECISION_PARAMETER;
-                 parameter->precision = TrioGetPosition(format, &offset);
-               }
-             else
-               {
-                 parameter->precision = trio_to_long(&format[offset],
-                                                     &tmpformat,
-                                                     BASE_DECIMAL);
-                 offset = (int)(tmpformat - format);
-               }
-           }
-         else if (dots == 1) /* Base */
-           {
-             dots++;
-
-             /* After the second dot we have the base */
-             parameter->flags |= FLAGS_BASE;
-             if ((QUALIFIER_STAR == format[offset])
-#if defined(QUALIFIER_PARAM)
-                 || (QUALIFIER_PARAM == format[offset])
-#endif
-                 )
-               {
-                 offset++;
-                 parameter->flags |= FLAGS_BASE_PARAMETER;
-                 parameter->base = TrioGetPosition(format, &offset);
-               }
-             else
-               {
-                 parameter->base = trio_to_long(&format[offset],
-                                                &tmpformat,
-                                                BASE_DECIMAL);
-                 if (parameter->base > MAX_BASE)
-                   return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-                 offset = (int)(tmpformat - format);
-               }
-           }
-         else
-           {
-             return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-           }
-         break; /* QUALIFIER_DOT */
-
-#if defined(QUALIFIER_PARAM)
-       case QUALIFIER_PARAM:
-         parameter->type = TYPE_PRINT;
-         /* FALLTHROUGH */
-#endif
-       case QUALIFIER_STAR:
-         /* This has different meanings for print and scan */
-         if (TYPE_PRINT == type)
-           {
-             /* Read with from parameter */
-             int width = TrioGetPosition(format, &offset);
-             parameter->flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER);
-             if (NO_POSITION != width)
-                parameter->width = width;
-             /* else keep parameter->width = NO_WIDTH which != NO_POSITION */
-           }
-#if TRIO_FEATURE_SCANF
-         else
-           {
-             /* Scan, but do not store result */
-             parameter->flags |= FLAGS_IGNORE;
-           }
-#endif
-         break; /* QUALIFIER_STAR */
-
-       case '0':
-         if (! (parameter->flags & FLAGS_LEFTADJUST))
-           parameter->flags |= FLAGS_NILPADDING;
-         /* FALLTHROUGH */
-       case '1': case '2': case '3': case '4':
-       case '5': case '6': case '7': case '8': case '9':
-         parameter->flags |= FLAGS_WIDTH;
-         /*
-          * &format[offset - 1] is used to "rewind" the read
-          * character from format
-          */
-         parameter->width = trio_to_long(&format[offset - 1],
-                                         &tmpformat,
-                                         BASE_DECIMAL);
-         offset = (int)(tmpformat - format);
-         break;
-
-       case QUALIFIER_SHORT:
-         if (parameter->flags & FLAGS_SHORTSHORT)
-           return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-         else if (parameter->flags & FLAGS_SHORT)
-           parameter->flags |= FLAGS_SHORTSHORT;
-         else
-           parameter->flags |= FLAGS_SHORT;
-         break;
-
-       case QUALIFIER_LONG:
-         if (parameter->flags & FLAGS_QUAD)
-           return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-         else if (parameter->flags & FLAGS_LONG)
-           parameter->flags |= FLAGS_QUAD;
-         else
-           parameter->flags |= FLAGS_LONG;
-         break;
-
-#if TRIO_FEATURE_LONGDOUBLE
-       case QUALIFIER_LONG_UPPER:
-         parameter->flags |= FLAGS_LONGDOUBLE;
-         break;
-#endif
-
-#if TRIO_FEATURE_SIZE_T
-       case QUALIFIER_SIZE_T:
-         parameter->flags |= FLAGS_SIZE_T;
-         /* Modify flags for later truncation of number */
-         if (sizeof(size_t) == sizeof(trio_ulonglong_t))
-           parameter->flags |= FLAGS_QUAD;
-         else if (sizeof(size_t) == sizeof(long))
-           parameter->flags |= FLAGS_LONG;
-         break;
-#endif
-
-#if TRIO_FEATURE_PTRDIFF_T
-       case QUALIFIER_PTRDIFF_T:
-         parameter->flags |= FLAGS_PTRDIFF_T;
-         if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t))
-           parameter->flags |= FLAGS_QUAD;
-         else if (sizeof(ptrdiff_t) == sizeof(long))
-           parameter->flags |= FLAGS_LONG;
-         break;
-#endif
-
-#if TRIO_FEATURE_INTMAX_T
-       case QUALIFIER_INTMAX_T:
-         parameter->flags |= FLAGS_INTMAX_T;
-         if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t))
-           parameter->flags |= FLAGS_QUAD;
-         else if (sizeof(trio_intmax_t) == sizeof(long))
-           parameter->flags |= FLAGS_LONG;
-         break;
-#endif
-
-#if TRIO_FEATURE_QUAD
-       case QUALIFIER_QUAD:
-         parameter->flags |= FLAGS_QUAD;
-         break;
-#endif
-
-#if TRIO_FEATURE_FIXED_SIZE
-       case QUALIFIER_FIXED_SIZE:
-         if (parameter->flags & FLAGS_FIXED_SIZE)
-           return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-
-         if (parameter->flags & (FLAGS_ALL_SIZES |
-                                 FLAGS_LONGDOUBLE |
-                                 FLAGS_WIDECHAR |
-                                 FLAGS_VARSIZE_PARAMETER))
-           return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-
-         if ((format[offset] == '6') &&
-             (format[offset + 1] == '4'))
-           {
-             parameter->varsize = sizeof(trio_int64_t);
-             offset += 2;
-           }
-         else if ((format[offset] == '3') &&
-                  (format[offset + 1] == '2'))
-           {
-             parameter->varsize = sizeof(trio_int32_t);
-             offset += 2;
-           }
-         else if ((format[offset] == '1') &&
-                  (format[offset + 1] == '6'))
-           {
-             parameter->varsize = sizeof(trio_int16_t);
-             offset += 2;
-           }
-         else if (format[offset] == '8')
-           {
-             parameter->varsize = sizeof(trio_int8_t);
-             offset++;
-           }
-         else
-           return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-
-         parameter->flags |= FLAGS_FIXED_SIZE;
-         break;
-#endif /* TRIO_FEATURE_FIXED_SIZE */
-
-#if defined(QUALIFIER_WIDECHAR)
-       case QUALIFIER_WIDECHAR:
-         parameter->flags |= FLAGS_WIDECHAR;
-         break;
-#endif
-
-#if TRIO_FEATURE_SIZE_T_UPPER
-       case QUALIFIER_SIZE_T_UPPER:
-         break;
-#endif
-
-#if TRIO_FEATURE_QUOTE
-       case QUALIFIER_QUOTE:
-         parameter->flags |= FLAGS_QUOTE;
-         break;
-#endif
-
-#if TRIO_FEATURE_STICKY
-       case QUALIFIER_STICKY:
-         parameter->flags |= FLAGS_STICKY;
-         break;
-#endif
-
-#if TRIO_FEATURE_VARSIZE
-       case QUALIFIER_VARSIZE:
-         parameter->flags |= FLAGS_VARSIZE_PARAMETER;
-         break;
-#endif
-
-#if TRIO_FEATURE_ROUNDING
-       case QUALIFIER_ROUNDING_UPPER:
-         parameter->flags |= FLAGS_ROUNDING;
-         break;
-#endif
-
-       default:
-         /* Bail out completely to make the error more obvious */
-         return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-       }
-    } /* while qualifier */
-
-  parameter->endOffset = offset;
-
-  return 0;
-}
-
-/*************************************************************************
- * TrioParseSpecifier
- *
- * Description:
- *  Parse the specifier part of a potential conversion specifier
- */
-TRIO_PRIVATE int
-TrioParseSpecifier
-TRIO_ARGS4((type, format, offset, parameter),
-          int type,
-          TRIO_CONST char *format,
-          int offset,
-          trio_parameter_t *parameter)
-{
-  parameter->baseSpecifier = NO_BASE;
-
-  switch (format[offset++])
-    {
-#if defined(SPECIFIER_CHAR_UPPER)
-    case SPECIFIER_CHAR_UPPER:
-      parameter->flags |= FLAGS_WIDECHAR;
-      /* FALLTHROUGH */
-#endif
-    case SPECIFIER_CHAR:
-      if (parameter->flags & FLAGS_LONG)
-       parameter->flags |= FLAGS_WIDECHAR;
-      else if (parameter->flags & FLAGS_SHORT)
-       parameter->flags &= ~FLAGS_WIDECHAR;
-      parameter->type = FORMAT_CHAR;
-      break;
-
-#if defined(SPECIFIER_STRING_UPPER)
-    case SPECIFIER_STRING_UPPER:
-      parameter->flags |= FLAGS_WIDECHAR;
-      /* FALLTHROUGH */
-#endif
-    case SPECIFIER_STRING:
-      if (parameter->flags & FLAGS_LONG)
-       parameter->flags |= FLAGS_WIDECHAR;
-      else if (parameter->flags & FLAGS_SHORT)
-       parameter->flags &= ~FLAGS_WIDECHAR;
-      parameter->type = FORMAT_STRING;
-      break;
-
-#if defined(SPECIFIER_GROUP)
-    case SPECIFIER_GROUP:
-      if (TYPE_SCAN == type)
-       {
-         int depth = 1;
-         parameter->type = FORMAT_GROUP;
-         if (format[offset] == QUALIFIER_CIRCUMFLEX)
-           offset++;
-         if (format[offset] == SPECIFIER_UNGROUP)
-           offset++;
-         if (format[offset] == QUALIFIER_MINUS)
-           offset++;
-         /* Skip nested brackets */
-         while (format[offset] != NIL)
-           {
-             if (format[offset] == SPECIFIER_GROUP)
-               {
-                 depth++;
-               }
-             else if (format[offset] == SPECIFIER_UNGROUP)
-             {
-               if (--depth <= 0)
-                 {
-                   offset++;
-                   break;
-                 }
-             }
-             offset++;
-           }
-       }
-      break;
-#endif /* defined(SPECIFIER_GROUP) */
-
-    case SPECIFIER_INTEGER:
-      parameter->type = FORMAT_INT;
-      break;
-
-    case SPECIFIER_UNSIGNED:
-      parameter->flags |= FLAGS_UNSIGNED;
-      parameter->type = FORMAT_INT;
-      break;
-
-    case SPECIFIER_DECIMAL:
-      parameter->baseSpecifier = BASE_DECIMAL;
-      parameter->type = FORMAT_INT;
-      break;
-
-    case SPECIFIER_OCTAL:
-      parameter->flags |= FLAGS_UNSIGNED;
-      parameter->baseSpecifier = BASE_OCTAL;
-      parameter->type = FORMAT_INT;
-      break;
-
-#if TRIO_FEATURE_BINARY
-    case SPECIFIER_BINARY_UPPER:
-      parameter->flags |= FLAGS_UPPER;
-      /* FALLTHROUGH */
-    case SPECIFIER_BINARY:
-      parameter->flags |= FLAGS_NILPADDING;
-      parameter->baseSpecifier = BASE_BINARY;
-      parameter->type = FORMAT_INT;
-      break;
-#endif
-
-    case SPECIFIER_HEX_UPPER:
-      parameter->flags |= FLAGS_UPPER;
-      /* FALLTHROUGH */
-    case SPECIFIER_HEX:
-      parameter->flags |= FLAGS_UNSIGNED;
-      parameter->baseSpecifier = BASE_HEX;
-      parameter->type = FORMAT_INT;
-      break;
-
-#if defined(SPECIFIER_FLOAT_E)
-# if defined(SPECIFIER_FLOAT_E_UPPER)
-    case SPECIFIER_FLOAT_E_UPPER:
-      parameter->flags |= FLAGS_UPPER;
-      /* FALLTHROUGH */
-# endif
-    case SPECIFIER_FLOAT_E:
-      parameter->flags |= FLAGS_FLOAT_E;
-      parameter->type = FORMAT_DOUBLE;
-      break;
-#endif
-
-#if defined(SPECIFIER_FLOAT_G)
-# if defined(SPECIFIER_FLOAT_G_UPPER)
-    case SPECIFIER_FLOAT_G_UPPER:
-      parameter->flags |= FLAGS_UPPER;
-      /* FALLTHROUGH */
-# endif
-    case SPECIFIER_FLOAT_G:
-      parameter->flags |= FLAGS_FLOAT_G;
-      parameter->type = FORMAT_DOUBLE;
-      break;
-#endif
-
-#if defined(SPECIFIER_FLOAT_F)
-# if defined(SPECIFIER_FLOAT_F_UPPER)
-    case SPECIFIER_FLOAT_F_UPPER:
-      parameter->flags |= FLAGS_UPPER;
-      /* FALLTHROUGH */
-# endif
-    case SPECIFIER_FLOAT_F:
-      parameter->type = FORMAT_DOUBLE;
-      break;
-#endif
-
-#if defined(TRIO_COMPILER_VISUALC)
-# pragma warning( push )
-# pragma warning( disable : 4127 ) /* Conditional expression is constant */
-#endif
-    case SPECIFIER_POINTER:
-      if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t))
-       parameter->flags |= FLAGS_QUAD;
-      else if (sizeof(trio_pointer_t) == sizeof(long))
-       parameter->flags |= FLAGS_LONG;
-      parameter->type = FORMAT_POINTER;
-      break;
-#if defined(TRIO_COMPILER_VISUALC)
-# pragma warning( pop )
-#endif
-
-    case SPECIFIER_COUNT:
-      parameter->type = FORMAT_COUNT;
-      break;
-
-#if TRIO_FEATURE_HEXFLOAT
-    case SPECIFIER_HEXFLOAT_UPPER:
-      parameter->flags |= FLAGS_UPPER;
-      /* FALLTHROUGH */
-    case SPECIFIER_HEXFLOAT:
-      parameter->baseSpecifier = BASE_HEX;
-      parameter->type = FORMAT_DOUBLE;
-      break;
-#endif
-
-#if TRIO_FEATURE_ERRNO
-    case SPECIFIER_ERRNO:
-      parameter->type = FORMAT_ERRNO;
-      break;
-#endif
-
-#if TRIO_FEATURE_USER_DEFINED
-    case SPECIFIER_USER_DEFINED_BEGIN:
-      {
-       unsigned int max;
-       int without_namespace = TRUE;
-       char* tmpformat = (char *)&format[offset];
-       int ch;
-
-       parameter->type = FORMAT_USER_DEFINED;
-       parameter->user_defined.namespace[0] = NIL;
-
-       while ((ch = format[offset]) != NIL)
-         {
-           offset++;
-           if ((ch == SPECIFIER_USER_DEFINED_END) || (ch == SPECIFIER_USER_DEFINED_EXTRA))
-             {
-               if (without_namespace)
-                 /* No namespace, handler will be passed as an argument */
-                 parameter->flags |= FLAGS_USER_DEFINED_PARAMETER;
-
-               /* Copy the user data */
-               max = (unsigned int)(&format[offset] - tmpformat);
-               if (max > MAX_USER_DATA)
-                 max = MAX_USER_DATA;
-               trio_copy_max(parameter->user_data, max, tmpformat);
-
-               /* Skip extra data (which is only there to keep the compiler happy) */
-               while ((ch != NIL) && (ch != SPECIFIER_USER_DEFINED_END))
-                 ch = format[offset++];
-
-               break; /* while */
-             }
-
-           if (ch == SPECIFIER_USER_DEFINED_SEPARATOR)
-             {
-               without_namespace = FALSE;
-               /* Copy the namespace for later looking-up */
-               max = (int)(&format[offset] - tmpformat);
-               if (max > MAX_USER_NAME)
-                 max = MAX_USER_NAME;
-               trio_copy_max(parameter->user_defined.namespace, max, tmpformat);
-               tmpformat = (char *)&format[offset];
-             }
-         }
-
-       if (ch != SPECIFIER_USER_DEFINED_END)
-         return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-      }
-      break;
-#endif /* TRIO_FEATURE_USER_DEFINED */
-
-    default:
-      /* Bail out completely to make the error more obvious */
-      return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-  }
-
-  parameter->endOffset = offset;
-
-  return 0;
-}
-
-/*************************************************************************
- * TrioParse
- *
- * Description:
- *  Parse the format string
- */
-TRIO_PRIVATE int
-TrioParse
-TRIO_ARGS5((type, format, parameters, arglist, argarray),
-          int type,
-          TRIO_CONST char *format,
-          trio_parameter_t *parameters,
-          va_list arglist,
-          trio_pointer_t *argarray)
-{
-  /* Count the number of times a parameter is referenced */
-  unsigned short usedEntries[MAX_PARAMETERS];
-  /* Parameter counters */
-  int parameterPosition;
-  int maxParam = -1;
-  /* Utility variables */
-  int offset;  /* Offset into formatting string */
-  BOOLEAN_T positional;  /* Does the specifier have a positional? */
-#if TRIO_FEATURE_STICKY
-  BOOLEAN_T gotSticky = FALSE;  /* Are there any sticky modifiers at all? */
-#endif
-  /*
-   * indices specifies the order in which the parameters must be
-   * read from the va_args (this is necessary to handle positionals)
-   */
-  int indices[MAX_PARAMETERS];
-  int pos = 0;
-  /* Various variables */
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
-  int charlen;
-#endif
-  int save_errno;
-  int i = -1;
-  int num;
-  trio_parameter_t workParameter;
-  int status;
-
-  /*
-   * The 'parameters' array is not initialized, but we need to
-   * know which entries we have used.
-   */
-  memset(usedEntries, 0, sizeof(usedEntries));
-
-  save_errno = errno;
-  offset = 0;
-  parameterPosition = 0;
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
-  (void)mblen(NULL, 0);
-#endif
-  
-  while (format[offset])
-    {
-      TrioInitializeParameter(&workParameter);
-
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
-      if (! isascii(format[offset]))
-       {
-         /*
-          * Multibyte characters cannot be legal specifiers or
-          * modifiers, so we skip over them.
-          */
-         charlen = mblen(&format[offset], MB_LEN_MAX);
-         offset += (charlen > 0) ? charlen : 1;
-         continue; /* while */
-       }
-#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
-
-      switch(format[offset++]) {
-
-      case CHAR_IDENTIFIER:
-       {
-         if (CHAR_IDENTIFIER == format[offset])
-           {
-             /* skip double "%" */
-             offset++;
-             continue; /* while */
-           }
-
-         status = TrioParseQualifiers(type, format, offset, &workParameter);
-         if (status < 0)
-           return status; /* Return qualifier syntax error */
-
-         status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter);
-         if (status < 0)
-           return status; /* Return specifier syntax error */
-       }
-       break;
-
-#if TRIO_EXTENSION
-      case CHAR_ALT_IDENTIFIER:
-       {
-         status = TrioParseQualifiers(type, format, offset, &workParameter);
-         if (status < 0)
-           continue; /* False alert, not a user defined specifier */
-
-         status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter);
-         if ((status < 0) || (FORMAT_USER_DEFINED != workParameter.type))
-           continue; /* False alert, not a user defined specifier */
-       }
-       break;
-#endif
-
-      default:
-       continue; /* while */
-      }
-
-      /* now handle the parsed conversion specification */
-      positional = (NO_POSITION != workParameter.position);
-
-      /*
-       * Parameters only need the type and value. The value is
-       * read later.
-       */
-      if (workParameter.flags & FLAGS_WIDTH_PARAMETER)
-        {
-         if (workParameter.width == NO_WIDTH)
-           {
-             workParameter.width = parameterPosition++;
-           }
-         else
-           {
-             if (! positional)
-                 workParameter.position = workParameter.width + 1;
-           }
-
-         usedEntries[workParameter.width] += 1;
-         if (workParameter.width > maxParam)
-           maxParam = workParameter.width;
-         parameters[pos].type = FORMAT_PARAMETER;
-         parameters[pos].flags = 0;
-         indices[workParameter.width] = pos;
-         workParameter.width = pos++;
-       }
-      if (workParameter.flags & FLAGS_PRECISION_PARAMETER)
-       {
-         if (workParameter.precision == NO_PRECISION)
-           {
-             workParameter.precision = parameterPosition++;
-           }
-         else
-           {
-             if (! positional)
-                 workParameter.position = workParameter.precision + 1;
-           }
-
-         usedEntries[workParameter.precision] += 1;
-         if (workParameter.precision > maxParam)
-           maxParam = workParameter.precision;
-         parameters[pos].type = FORMAT_PARAMETER;
-         parameters[pos].flags = 0;
-         indices[workParameter.precision] = pos;
-         workParameter.precision = pos++;
-       }
-      if (workParameter.flags & FLAGS_BASE_PARAMETER)
-       {
-         if (workParameter.base == NO_BASE)
-           {
-             workParameter.base = parameterPosition++;
-           }
-         else
-           {
-             if (! positional)
-                 workParameter.position = workParameter.base + 1;
-           }
-
-         usedEntries[workParameter.base] += 1;
-         if (workParameter.base > maxParam)
-           maxParam = workParameter.base;
-         parameters[pos].type = FORMAT_PARAMETER;
-         parameters[pos].flags = 0;
-         indices[workParameter.base] = pos;
-         workParameter.base = pos++;
-       }
-#if TRIO_FEATURE_VARSIZE
-      if (workParameter.flags & FLAGS_VARSIZE_PARAMETER)
-       {
-         workParameter.varsize = parameterPosition++;
-
-         usedEntries[workParameter.varsize] += 1;
-         if (workParameter.varsize > maxParam)
-           maxParam = workParameter.varsize;
-         parameters[pos].type = FORMAT_PARAMETER;
-         parameters[pos].flags = 0;
-         indices[workParameter.varsize] = pos;
-         workParameter.varsize = pos++;
-       }
-#endif
-#if TRIO_FEATURE_USER_DEFINED
-      if (workParameter.flags & FLAGS_USER_DEFINED_PARAMETER)
-       {
-         workParameter.user_defined.handler = parameterPosition++;
-
-         usedEntries[workParameter.user_defined.handler] += 1;
-         if (workParameter.user_defined.handler > maxParam)
-           maxParam = workParameter.user_defined.handler;
-         parameters[pos].type = FORMAT_PARAMETER;
-         parameters[pos].flags = FLAGS_USER_DEFINED;
-         indices[workParameter.user_defined.handler] = pos;
-         workParameter.user_defined.handler = pos++;
-       }
-#endif
-
-      if (NO_POSITION == workParameter.position)
-       {
-         workParameter.position = parameterPosition++;
-       }
-
-      if (workParameter.position > maxParam)
-       maxParam = workParameter.position;
-
-      if (workParameter.position >= MAX_PARAMETERS)
-       {
-         /* Bail out completely to make the error more obvious */
-         return TRIO_ERROR_RETURN(TRIO_ETOOMANY, offset);
-       }
-
-      indices[workParameter.position] = pos;
-
-      /*  Count the number of times this entry has been used */
-      usedEntries[workParameter.position] += 1;
-
-      /* Find last sticky parameters */
-#if TRIO_FEATURE_STICKY
-      if (workParameter.flags & FLAGS_STICKY)
-       {
-         gotSticky = TRUE;
-       }
-      else if (gotSticky)
-       {
-         for (i = pos - 1; i >= 0; i--)
-           {
-             if (parameters[i].type == FORMAT_PARAMETER)
-               continue;
-             if ((parameters[i].flags & FLAGS_STICKY) &&
-                 (parameters[i].type == workParameter.type))
-               {
-                 /* Do not overwrite current qualifiers */
-                 workParameter.flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY);
-                 if (workParameter.width == NO_WIDTH)
-                   workParameter.width = parameters[i].width;
-                 if (workParameter.precision == NO_PRECISION)
-                   workParameter.precision = parameters[i].precision;
-                 if (workParameter.base == NO_BASE)
-                   workParameter.base = parameters[i].base;
-                 break;
-               }
-           }
-       }
-#endif
-
-      if (workParameter.base == NO_BASE)
-       workParameter.base = BASE_DECIMAL;
-
-      offset = workParameter.endOffset;
-
-      TrioCopyParameter(&parameters[pos++], &workParameter);
-    } /* while format characters left */
-
-  parameters[pos].type = FORMAT_SENTINEL;  /* end parameter array with sentinel */
-  parameters[pos].beginOffset = offset;
-
-  for (num = 0; num <= maxParam; num++)
-    {
-      if (usedEntries[num] != 1)
-       {
-         if (usedEntries[num] == 0) /* gap detected */
-           return TRIO_ERROR_RETURN(TRIO_EGAP, num);
-         else /* double references detected */
-           return TRIO_ERROR_RETURN(TRIO_EDBLREF, num);
-       }
-      
-      i = indices[num];
-
-      /*
-       * FORMAT_PARAMETERS are only present if they must be read,
-       * so it makes no sense to check the ignore flag (besides,
-       * the flags variable is not set for that particular type)
-       */
-      if ((parameters[i].type != FORMAT_PARAMETER) &&
-         (parameters[i].flags & FLAGS_IGNORE))
-       continue; /* for all arguments */
-
-      /*
-       * The stack arguments are read according to ANSI C89
-       * default argument promotions:
-       *
-       *  char           = int
-       *  short          = int
-       *  unsigned char  = unsigned int
-       *  unsigned short = unsigned int
-       *  float          = double
-       *
-       * In addition to the ANSI C89 these types are read (the
-       * default argument promotions of C99 has not been
-       * considered yet)
-       *
-       *  long long
-       *  long double
-       *  size_t
-       *  ptrdiff_t
-       *  intmax_t
-       */
-      switch (parameters[i].type)
-       {
-       case FORMAT_GROUP:
-       case FORMAT_STRING:
-#if TRIO_FEATURE_WIDECHAR
-         if (parameters[i].flags & FLAGS_WIDECHAR)
-           {
-             parameters[i].data.wstring = (argarray == NULL)
-               ? va_arg(arglist, trio_wchar_t *)
-               : (trio_wchar_t *)(argarray[num]);
-           }
-         else
-#endif
-           {
-             parameters[i].data.string = (argarray == NULL)
-               ? va_arg(arglist, char *)
-               : (char *)(argarray[num]);
-           }
-         break;
-
-#if TRIO_FEATURE_USER_DEFINED
-       case FORMAT_USER_DEFINED:
-#endif
-       case FORMAT_POINTER:
-       case FORMAT_COUNT:
-       case FORMAT_UNKNOWN:
-         parameters[i].data.pointer = (argarray == NULL)
-           ? va_arg(arglist, trio_pointer_t )
-           : argarray[num];
-         break;
-
-       case FORMAT_CHAR:
-       case FORMAT_INT:
-#if TRIO_FEATURE_SCANF
-         if (TYPE_SCAN == type)
-           {
-              if (argarray == NULL)
-                parameters[i].data.pointer = 
-                  (trio_pointer_t)va_arg(arglist, trio_pointer_t);
-              else
-                {
-                  if (parameters[i].type == FORMAT_CHAR)
-                    parameters[i].data.pointer =
-                      (trio_pointer_t)((char *)argarray[num]);
-                  else if (parameters[i].flags & FLAGS_SHORT)
-                    parameters[i].data.pointer =
-                      (trio_pointer_t)((short *)argarray[num]);
-                  else
-                    parameters[i].data.pointer =
-                      (trio_pointer_t)((int *)argarray[num]);
-                }
-           }
-         else
-#endif /* TRIO_FEATURE_SCANF */
-           {
-#if TRIO_FEATURE_VARSIZE || TRIO_FEATURE_FIXED_SIZE
-             if (parameters[i].flags
-                 & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE))
-               {
-                 int varsize;
-                 if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER)
-                   {
-                     /*
-                      * Variable sizes are mapped onto the fixed sizes, in
-                      * accordance with integer promotion.
-                      *
-                      * Please note that this may not be portable, as we
-                      * only guess the size, not the layout of the numbers.
-                      * For example, if int is little-endian, and long is
-                      * big-endian, then this will fail.
-                      */
-                     varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned;
-                   }
-                 else
-                   {
-                     /* Used for the I<bits> modifiers */
-                     varsize = parameters[i].varsize;
-                   }
-                 parameters[i].flags &= ~FLAGS_ALL_VARSIZES;
-                 
-                 if (varsize <= (int)sizeof(int))
-                   ;
-                 else if (varsize <= (int)sizeof(long))
-                   parameters[i].flags |= FLAGS_LONG;
-#if TRIO_FEATURE_INTMAX_T
-                 else if (varsize <= (int)sizeof(trio_longlong_t))
-                   parameters[i].flags |= FLAGS_QUAD;
-                 else
-                   parameters[i].flags |= FLAGS_INTMAX_T;
-#else
-                 else
-                   parameters[i].flags |= FLAGS_QUAD;
-#endif
-               }
-#endif /* TRIO_FEATURE_VARSIZE */
-#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
-             if (parameters[i].flags & FLAGS_SIZE_T)
-               parameters[i].data.number.as_unsigned = (argarray == NULL)
-                 ? (trio_uintmax_t)va_arg(arglist, size_t)
-                 : (trio_uintmax_t)(*((size_t *)argarray[num]));
-             else
-#endif
-#if TRIO_FEATURE_PTRDIFF_T
-             if (parameters[i].flags & FLAGS_PTRDIFF_T)
-               parameters[i].data.number.as_unsigned = (argarray == NULL)
-                 ? (trio_uintmax_t)va_arg(arglist, ptrdiff_t)
-                 : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num]));
-             else
-#endif
-#if TRIO_FEATURE_INTMAX_T
-             if (parameters[i].flags & FLAGS_INTMAX_T)
-               parameters[i].data.number.as_unsigned = (argarray == NULL)
-                 ? (trio_uintmax_t)va_arg(arglist, trio_intmax_t)
-                 : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num]));
-             else
-#endif
-             if (parameters[i].flags & FLAGS_QUAD)
-               parameters[i].data.number.as_unsigned = (argarray == NULL)
-                 ? (trio_uintmax_t)va_arg(arglist, trio_ulonglong_t)
-                 : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num]));
-             else if (parameters[i].flags & FLAGS_LONG)
-               parameters[i].data.number.as_unsigned = (argarray == NULL)
-                 ? (trio_uintmax_t)va_arg(arglist, long)
-                 : (trio_uintmax_t)(*((long *)argarray[num]));
-             else
-               {
-                 if (argarray == NULL)
-                   parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(arglist, int);
-                 else
-                   {
-                     if (parameters[i].type == FORMAT_CHAR)
-                       parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num]));
-                     else if (parameters[i].flags & FLAGS_SHORT)
-                       parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num]));
-                     else
-                       parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num]));
-                   }
-               }
-           }
-         break;
-
-       case FORMAT_PARAMETER:
-         /*
-          * The parameter for the user-defined specifier is a pointer,
-          * whereas the rest (width, precision, base) uses an integer.
-          */
-         if (parameters[i].flags & FLAGS_USER_DEFINED)
-           parameters[i].data.pointer = (argarray == NULL)
-             ? va_arg(arglist, trio_pointer_t )
-             : argarray[num];
-         else
-           parameters[i].data.number.as_unsigned = (argarray == NULL)
-             ? (trio_uintmax_t)va_arg(arglist, int)
-             : (trio_uintmax_t)(*((int *)argarray[num]));
-         break;
-
-#if TRIO_FEATURE_FLOAT
-       case FORMAT_DOUBLE:
-# if TRIO_FEATURE_SCANF
-         if (TYPE_SCAN == type)
-           {
-             if (parameters[i].flags & FLAGS_LONGDOUBLE)
-               parameters[i].data.longdoublePointer = (argarray == NULL)
-                 ? va_arg(arglist, trio_long_double_t *)
-                 : (trio_long_double_t *)argarray[num];
-             else
-                {
-                 if (parameters[i].flags & FLAGS_LONG)
-                   parameters[i].data.doublePointer = (argarray == NULL)
-                     ? va_arg(arglist, double *)
-                     : (double *)argarray[num];
-                 else
-                   parameters[i].data.doublePointer = (argarray == NULL)
-                     ? (double *)va_arg(arglist, float *)
-                     : (double *)((float *)argarray[num]);
-                }
-           }
-         else
-# endif /* TRIO_FEATURE_SCANF */
-           {
-             if (parameters[i].flags & FLAGS_LONGDOUBLE)
-               parameters[i].data.longdoubleNumber = (argarray == NULL)
-                 ? va_arg(arglist, trio_long_double_t)
-                 : (trio_long_double_t)(*((trio_long_double_t *)argarray[num]));
-             else
-               {
-                 if (argarray == NULL)
-                   parameters[i].data.longdoubleNumber =
-                     (trio_long_double_t)va_arg(arglist, double);
-                 else
-                   {
-                     if (parameters[i].flags & FLAGS_SHORT)
-                       parameters[i].data.longdoubleNumber =
-                         (trio_long_double_t)(*((float *)argarray[num]));
-                     else
-                       parameters[i].data.longdoubleNumber =
-                         (trio_long_double_t)(*((double *)argarray[num]));
-                   }
-               }
-           }
-         break;
-#endif /* TRIO_FEATURE_FLOAT */
-
-#if TRIO_FEATURE_ERRNO
-       case FORMAT_ERRNO:
-         parameters[i].data.errorNumber = save_errno;
-         break;
-#endif
-
-       default:
-         break;
-       }
-    } /* for all specifiers */
-  return num;
-}
-
-
-/*************************************************************************
- *
- * FORMATTING
- *
- ************************************************************************/
-
-
-/*************************************************************************
- * TrioWriteNumber
- *
- * Description:
- *  Output a number.
- *  The complexity of this function is a result of the complexity
- *  of the dependencies of the flags.
- */
-TRIO_PRIVATE void
-TrioWriteNumber
-TRIO_ARGS6((self, number, flags, width, precision, base),
-          trio_class_t *self,
-          trio_uintmax_t number,
-          trio_flags_t flags,
-          int width,
-          int precision,
-          int base)
-{
-  BOOLEAN_T isNegative;
-  BOOLEAN_T isNumberZero;
-  BOOLEAN_T isPrecisionZero;
-  BOOLEAN_T ignoreNumber;
-  char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1];
-  char *bufferend;
-  char *pointer;
-  TRIO_CONST char *digits;
-  int i;
-#if TRIO_FEATURE_QUOTE
-  int length;
-  char *p;
-#endif
-  int count;
-  int digitOffset;
-
-  assert(VALID(self));
-  assert(VALID(self->OutStream));
-  assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
-
-  digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
-  if (base == NO_BASE)
-    base = BASE_DECIMAL;
-
-  isNumberZero = (number == 0);
-  isPrecisionZero = (precision == 0);
-  ignoreNumber = (isNumberZero
-                 && isPrecisionZero
-                 && !((flags & FLAGS_ALTERNATIVE) && (base == BASE_OCTAL)));
-
-  if (flags & FLAGS_UNSIGNED)
-    {
-      isNegative = FALSE;
-      flags &= ~FLAGS_SHOWSIGN;
-    }
-  else
-    {
-      isNegative = ((trio_intmax_t)number < 0);
-      if (isNegative)
-       number = -((trio_intmax_t)number);
-    }
-
-  if (flags & FLAGS_QUAD)
-    number &= (trio_ulonglong_t)-1;
-  else if (flags & FLAGS_LONG)
-    number &= (unsigned long)-1;
-  else
-    number &= (unsigned int)-1;
-  
-  /* Build number */
-  pointer = bufferend = &buffer[sizeof(buffer) - 1];
-  *pointer-- = NIL;
-  for (i = 1; i < (int)sizeof(buffer); i++)
-    {
-      digitOffset = number % base;
-      *pointer-- = digits[digitOffset];
-      number /= base;
-      if (number == 0)
-       break;
-
-#if TRIO_FEATURE_QUOTE
-      if ((flags & FLAGS_QUOTE) && TrioFollowedBySeparator(i + 1))
-       {
-         /*
-          * We are building the number from the least significant
-          * to the most significant digit, so we have to copy the
-          * thousand separator backwards
-          */
-         length = internalThousandSeparatorLength;
-         if (((int)(pointer - buffer) - length) > 0)
-           {
-             p = &internalThousandSeparator[length - 1];
-             while (length-- > 0)
-               *pointer-- = *p--;
-           }
-       }
-#endif
-    }
-
-  if (! ignoreNumber)
-    {
-      /* Adjust width */
-      width -= (bufferend - pointer) - 1;
-    }
-
-  /* Adjust precision */
-  if (NO_PRECISION != precision)
-    {
-      precision -= (bufferend - pointer) - 1;
-      if (precision < 0)
-       precision = 0;
-      flags |= FLAGS_NILPADDING;
-    }
-
-  /* Calculate padding */
-  count = (! ((flags & FLAGS_LEFTADJUST) || (precision == NO_PRECISION)))
-    ? precision
-    : 0;
-  
-  /* Adjust width further */
-  if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
-    width--;
-  if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero)
-    {
-      switch (base)
-       {
-       case BASE_BINARY:
-       case BASE_HEX:
-         width -= 2;
-         break;
-       case BASE_OCTAL:
-         if (!(flags & FLAGS_NILPADDING) || (count == 0))
-           width--;
-         break;
-       default:
-         break;
-       }
-    }
-
-  /* Output prefixes spaces if needed */
-  if (! ((flags & FLAGS_LEFTADJUST) ||
-        ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION))))
-    {
-      while (width-- > count)
-       self->OutStream(self, CHAR_ADJUST);
-    }
-
-  /* width has been adjusted for signs and alternatives */
-  if (isNegative)
-    self->OutStream(self, '-');
-  else if (flags & FLAGS_SHOWSIGN)
-    self->OutStream(self, '+');
-  else if (flags & FLAGS_SPACE)
-    self->OutStream(self, ' ');
-
-  /* Prefix is not written when the value is zero */
-  if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero)
-    {
-      switch (base)
-       {
-       case BASE_BINARY:
-         self->OutStream(self, '0');
-         self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b');
-         break;
-
-       case BASE_OCTAL:
-         if (!(flags & FLAGS_NILPADDING) || (count == 0))
-           self->OutStream(self, '0');
-         break;
-
-       case BASE_HEX:
-         self->OutStream(self, '0');
-         self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
-         break;
-
-       default:
-         break;
-       } /* switch base */
-    }
-
-  /* Output prefixed zero padding if needed */
-  if (flags & FLAGS_NILPADDING)
-    {
-      if (precision == NO_PRECISION)
-       precision = width;
-      while (precision-- > 0)
-       {
-         self->OutStream(self, '0');
-         width--;
-       }
-    }
-
-  if (! ignoreNumber)
-    {
-      /* Output the number itself */
-      while (*(++pointer))
-       {
-         self->OutStream(self, *pointer);
-       }
-    }
-
-  /* Output trailing spaces if needed */
-  if (flags & FLAGS_LEFTADJUST)
-    {
-      while (width-- > 0)
-       self->OutStream(self, CHAR_ADJUST);
-    }
-}
-
-/*************************************************************************
- * TrioWriteStringCharacter
- *
- * Description:
- *  Output a single character of a string
- */
-TRIO_PRIVATE void
-TrioWriteStringCharacter
-TRIO_ARGS3((self, ch, flags),
-          trio_class_t *self,
-          int ch,
-          trio_flags_t flags)
-{
-  if (flags & FLAGS_ALTERNATIVE)
-    {
-      if (! isprint(ch))
-       {
-         /*
-          * Non-printable characters are converted to C escapes or
-          * \number, if no C escape exists.
-          */
-         self->OutStream(self, CHAR_BACKSLASH);
-         switch (ch)
-           {
-           case '\007': self->OutStream(self, 'a'); break;
-           case '\b': self->OutStream(self, 'b'); break;
-           case '\f': self->OutStream(self, 'f'); break;
-           case '\n': self->OutStream(self, 'n'); break;
-           case '\r': self->OutStream(self, 'r'); break;
-           case '\t': self->OutStream(self, 't'); break;
-           case '\v': self->OutStream(self, 'v'); break;
-           case '\\': self->OutStream(self, '\\'); break;
-           default:
-             self->OutStream(self, 'x');
-             TrioWriteNumber(self, (trio_uintmax_t)ch,
-                             FLAGS_UNSIGNED | FLAGS_NILPADDING,
-                             2, 2, BASE_HEX);
-             break;
-           }
-       }
-      else if (ch == CHAR_BACKSLASH)
-       {
-         self->OutStream(self, CHAR_BACKSLASH);
-         self->OutStream(self, CHAR_BACKSLASH);
-       }
-      else
-       {
-         self->OutStream(self, ch);
-       }
-    }
-  else
-    {
-      self->OutStream(self, ch);
-    }
-}
-
-/*************************************************************************
- * TrioWriteString
- *
- * Description:
- *  Output a string
- */
-TRIO_PRIVATE void
-TrioWriteString
-TRIO_ARGS5((self, string, flags, width, precision),
-          trio_class_t *self,
-          TRIO_CONST char *string,
-          trio_flags_t flags,
-          int width,
-          int precision)
-{
-  int length;
-  int ch;
-
-  assert(VALID(self));
-  assert(VALID(self->OutStream));
-
-  if (string == NULL)
-    {
-      string = internalNullString;
-      length = sizeof(internalNullString) - 1;
-#if TRIO_FEATURE_QUOTE
-      /* Disable quoting for the null pointer */
-      flags &= (~FLAGS_QUOTE);
-#endif
-      width = 0;
-    }
-  else
-    {
-      if (precision == 0)
-       {
-         length = trio_length(string);
-       }
-      else
-       {
-         length = trio_length_max(string, precision);
-       }
-    }
-  if ((NO_PRECISION != precision) &&
-      (precision < length))
-    {
-      length = precision;
-    }
-  width -= length;
-
-#if TRIO_FEATURE_QUOTE
-  if (flags & FLAGS_QUOTE)
-    self->OutStream(self, CHAR_QUOTE);
-#endif
-
-  if (! (flags & FLAGS_LEFTADJUST))
-    {
-      while (width-- > 0)
-       self->OutStream(self, CHAR_ADJUST);
-    }
-
-  while (length-- > 0)
-    {
-      /* The ctype parameters must be an unsigned char (or EOF) */
-      ch = (int)((unsigned char)(*string++));
-      TrioWriteStringCharacter(self, ch, flags);
-    }
-
-  if (flags & FLAGS_LEFTADJUST)
-    {
-      while (width-- > 0)
-       self->OutStream(self, CHAR_ADJUST);
-    }
-#if TRIO_FEATURE_QUOTE
-  if (flags & FLAGS_QUOTE)
-    self->OutStream(self, CHAR_QUOTE);
-#endif
-}
-
-/*************************************************************************
- * TrioWriteWideStringCharacter
- *
- * Description:
- *  Output a wide string as a multi-byte sequence
- */
-#if TRIO_FEATURE_WIDECHAR
-TRIO_PRIVATE int
-TrioWriteWideStringCharacter
-TRIO_ARGS4((self, wch, flags, width),
-          trio_class_t *self,
-          trio_wchar_t wch,
-          trio_flags_t flags,
-          int width)
-{
-  int size;
-  int i;
-  int ch;
-  char *string;
-  char buffer[MB_LEN_MAX + 1];
-
-  if (width == NO_WIDTH)
-    width = sizeof(buffer);
-  
-  size = wctomb(buffer, wch);
-  if ((size <= 0) || (size > width) || (buffer[0] == NIL))
-    return 0;
-
-  string = buffer;
-  i = size;
-  while ((width >= i) && (width-- > 0) && (i-- > 0))
-    {
-      /* The ctype parameters must be an unsigned char (or EOF) */
-      ch = (int)((unsigned char)(*string++));
-      TrioWriteStringCharacter(self, ch, flags);
-    }
-  return size;
-}
-#endif /* TRIO_FEATURE_WIDECHAR */
-
-/*************************************************************************
- * TrioWriteWideString
- *
- * Description:
- *  Output a wide character string as a multi-byte string
- */
-#if TRIO_FEATURE_WIDECHAR
-TRIO_PRIVATE void
-TrioWriteWideString
-TRIO_ARGS5((self, wstring, flags, width, precision),
-          trio_class_t *self,
-          TRIO_CONST trio_wchar_t *wstring,
-          trio_flags_t flags,
-          int width,
-          int precision)
-{
-  int length;
-  int size;
-
-  assert(VALID(self));
-  assert(VALID(self->OutStream));
-
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
-  /* Required by TrioWriteWideStringCharacter */
-  (void)mblen(NULL, 0);
-#endif
-  
-  if (wstring == NULL)
-    {
-      TrioWriteString(self, NULL, flags, width, precision);
-      return;
-    }
-  
-  if (NO_PRECISION == precision)
-    {
-      length = INT_MAX;
-    }
-  else
-    {
-      length = precision;
-      width -= length;
-    }
-
-#if TRIO_FEATURE_QUOTE
-  if (flags & FLAGS_QUOTE)
-    self->OutStream(self, CHAR_QUOTE);
-#endif
-
-  if (! (flags & FLAGS_LEFTADJUST))
-    {
-      while (width-- > 0)
-       self->OutStream(self, CHAR_ADJUST);
-    }
-
-  while (length > 0)
-    {
-      size = TrioWriteWideStringCharacter(self, *wstring++, flags, length);
-      if (size == 0)
-       break; /* while */
-      length -= size;
-    }
-
-  if (flags & FLAGS_LEFTADJUST)
-    {
-      while (width-- > 0)
-       self->OutStream(self, CHAR_ADJUST);
-    }
-#if TRIO_FEATURE_QUOTE
-  if (flags & FLAGS_QUOTE)
-    self->OutStream(self, CHAR_QUOTE);
-#endif
-}
-#endif /* TRIO_FEATURE_WIDECHAR */
-
-/*************************************************************************
- * TrioWriteDouble
- *
- * http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_211.htm
- *
- * "5.2.4.2.2 paragraph #4
- *
- *  The accuracy [...] is implementation defined, as is the accuracy
- *  of the conversion between floating-point internal representations
- *  and string representations performed by the libray routine in
- *  <stdio.h>"
- */
-/* FIXME: handle all instances of constant long-double number (L)
- *   and *l() math functions.
- */
-#if TRIO_FEATURE_FLOAT
-TRIO_PRIVATE void
-TrioWriteDouble
-TRIO_ARGS6((self, number, flags, width, precision, base),
-          trio_class_t *self,
-          trio_long_double_t number,
-          trio_flags_t flags,
-          int width,
-          int precision,
-          int base)
-{
-  trio_long_double_t integerNumber;
-  trio_long_double_t fractionNumber;
-  trio_long_double_t workNumber;
-  int integerDigits;
-  int fractionDigits;
-  int exponentDigits;
-  int workDigits;
-  int baseDigits;
-  int integerThreshold;
-  int fractionThreshold;
-  int expectedWidth;
-  int exponent = 0;
-  unsigned int uExponent = 0;
-  int exponentBase;
-  trio_long_double_t dblBase;
-  trio_long_double_t dblFractionBase;
-  trio_long_double_t integerAdjust;
-  trio_long_double_t fractionAdjust;
-  trio_long_double_t workFractionNumber;
-  trio_long_double_t workFractionAdjust;
-  int fractionDigitsInspect;
-  BOOLEAN_T isNegative;
-  BOOLEAN_T isExponentNegative = FALSE;
-  BOOLEAN_T requireTwoDigitExponent;
-  BOOLEAN_T isHex;
-  TRIO_CONST char *digits;
-# if TRIO_FEATURE_QUOTE
-  char *groupingPointer;
-# endif
-  int i;
-  int offset;
-  BOOLEAN_T hasOnlyZeroes;
-  int leadingFractionZeroes = -1;
-  register int trailingZeroes;
-  BOOLEAN_T keepTrailingZeroes;
-  BOOLEAN_T keepDecimalPoint;
-  trio_long_double_t epsilon;
-  BOOLEAN_T adjustNumber = FALSE;
-  
-  assert(VALID(self));
-  assert(VALID(self->OutStream));
-  assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
-
-  /* Determine sign and look for special quantities */
-  switch (trio_fpclassify_and_signbit(number, &isNegative))
-    {
-    case TRIO_FP_NAN:
-      TrioWriteString(self,
-                     (flags & FLAGS_UPPER)
-                     ? NAN_UPPER
-                     : NAN_LOWER,
-                     flags, width, precision);
-      return;
-      
-    case TRIO_FP_INFINITE:
-      if (isNegative)
-       {
-         /* Negative infinity */
-         TrioWriteString(self,
-                         (flags & FLAGS_UPPER)
-                         ? "-" INFINITE_UPPER
-                         : "-" INFINITE_LOWER,
-                         flags, width, precision);
-         return;
-       }
-      else
-       {
-         /* Positive infinity */
-         TrioWriteString(self,
-                         (flags & FLAGS_UPPER)
-                         ? INFINITE_UPPER
-                         : INFINITE_LOWER,
-                         flags, width, precision);
-         return;
-       }
-
-    default:
-      /* Finitude */
-      break;
-    }
-  
-  /* Normal numbers */
-  if (flags & FLAGS_LONGDOUBLE)
-    {
-      baseDigits = (base == 10)
-       ? LDBL_DIG
-       : (int)trio_floor(LDBL_MANT_DIG / TrioLogarithmBase(base));
-      epsilon = LDBL_EPSILON;
-    }
-  else if (flags & FLAGS_SHORT)
-    {
-      baseDigits = (base == BASE_DECIMAL)
-       ? FLT_DIG
-       : (int)trio_floor(FLT_MANT_DIG / TrioLogarithmBase(base));
-      epsilon = FLT_EPSILON;
-    }
-  else
-    {
-      baseDigits = (base == BASE_DECIMAL)
-       ? DBL_DIG
-       : (int)trio_floor(DBL_MANT_DIG / TrioLogarithmBase(base));
-      epsilon = DBL_EPSILON;
-    }
-
-  digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
-  isHex = (base == BASE_HEX);
-  if (base == NO_BASE)
-    base = BASE_DECIMAL;
-  dblBase = (trio_long_double_t)base;
-  keepTrailingZeroes = !( (flags & FLAGS_ROUNDING) ||
-                         ( (flags & FLAGS_FLOAT_G) &&
-                           !(flags & FLAGS_ALTERNATIVE) ) );
-
-# if TRIO_FEATURE_ROUNDING
-  if (flags & FLAGS_ROUNDING)
-    {
-      precision = baseDigits;
-    }
-# endif
-
-  if (precision == NO_PRECISION)
-    {
-      if (isHex)
-       {
-         keepTrailingZeroes = FALSE;
-         precision = FLT_MANT_DIG;
-       }
-      else
-       {
-         precision = FLT_DIG;
-       }
-    }
-  
-  if (isNegative)
-    {
-      number = -number;
-    }
-
-  if (isHex)
-    {
-      flags |= FLAGS_FLOAT_E;
-    }
-
- reprocess:
-
-  if (flags & FLAGS_FLOAT_G)
-    {
-      if (precision == 0)
-       precision = 1;
-
-      if ( (number < TRIO_SUFFIX_LONG(1.0E-4)) ||
-          (number >= TrioPower(base, (trio_long_double_t)precision)) )
-       {
-         /* Use scientific notation */
-         flags |= FLAGS_FLOAT_E;
-       }
-      else if (number < 1.0)
-       {
-         /*
-          * Use normal notation. If the integer part of the number is
-          * zero, then adjust the precision to include leading fractional
-          * zeros.
-          */
-         workNumber = TrioLogarithm(number, base);
-         workNumber = TRIO_FABS(workNumber);
-         if (workNumber - trio_floor(workNumber) < epsilon)
-           workNumber--;
-         leadingFractionZeroes = (int)trio_floor(workNumber);
-       }
-    }
-
-  if (flags & FLAGS_FLOAT_E)
-    {
-      /* Scale the number */
-      workNumber = TrioLogarithm(number, base);
-      if (trio_isinf(workNumber) == -1)
-       {
-         exponent = 0;
-         /* Undo setting */
-         if (flags & FLAGS_FLOAT_G)
-           flags &= ~FLAGS_FLOAT_E;
-       }
-      else
-       {
-         exponent = (int)trio_floor(workNumber);
-         workNumber = number;
-         /*
-          * The expression A * 10^-B is equivalent to A / 10^B but the former
-          * usually gives better accuracy.
-          */
-         workNumber *= TrioPower(dblBase, (trio_long_double_t)-exponent);
-         if (trio_isinf(workNumber)) {
-           /*
-            * Scaling is done it two steps to avoid problems with subnormal
-            * numbers.
-            */
-           workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent / 2));
-           workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent - (exponent / 2)));
-         }
-         number = workNumber;
-         isExponentNegative = (exponent < 0);
-         uExponent = (isExponentNegative) ? -exponent : exponent;
-         if (isHex)
-           uExponent *= 4; /* log16(2) */
-#if TRIO_FEATURE_QUOTE
-         /* No thousand separators */
-         flags &= ~FLAGS_QUOTE;
-#endif
-       }
-    }
-
-  integerNumber = trio_floor(number);
-  fractionNumber = number - integerNumber;
-
-  /*
-   * Truncated number.
-   *
-   * Precision is number of significant digits for FLOAT_G and number of
-   * fractional digits for others.
-   */
-  integerDigits = 1;
-  if (integerNumber > epsilon)
-    {
-      integerDigits += (int)TrioLogarithm(integerNumber, base);
-    }
-
-  fractionDigits = precision;
-  if (flags & FLAGS_FLOAT_G)
-    {
-      if (leadingFractionZeroes > 0)
-       {
-         fractionDigits += leadingFractionZeroes;
-       }
-      if ((integerNumber > epsilon) || (number <= epsilon))
-       {
-         fractionDigits -= integerDigits;
-       }
-    }
-
-  dblFractionBase = TrioPower(base, fractionDigits);
-
-  if (integerNumber < 1.0)
-    {
-      workNumber = number * dblFractionBase + TRIO_SUFFIX_LONG(0.5);
-      if (trio_floor(number * dblFractionBase) != trio_floor(workNumber))
-       {
-         adjustNumber = TRUE;
-         /* Remove a leading fraction zero if fraction is rounded up */
-         if ((int)TrioLogarithm(number * dblFractionBase, base) != (int)TrioLogarithm(workNumber, base))
-           {
-             --leadingFractionZeroes;
-           }
-       }
-      workNumber /= dblFractionBase;
-    }
-  else
-    {
-      workNumber = number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase;
-      adjustNumber = (trio_floor(number) != trio_floor(workNumber));
-    }
-  if (adjustNumber)
-    {
-      if ((flags & FLAGS_FLOAT_G) && !(flags & FLAGS_FLOAT_E))
-       {
-         /* The adjustment may require a change to scientific notation */
-         if ( (workNumber < TRIO_SUFFIX_LONG(1.0E-4)) ||
-              (workNumber >= TrioPower(base, (trio_long_double_t)precision)) )
-           {
-             /* Use scientific notation */
-             flags |= FLAGS_FLOAT_E;
-             goto reprocess;
-           }
-       }
-      
-      if (flags & FLAGS_FLOAT_E)
-       {
-         workDigits = 1 + TrioLogarithm(trio_floor(workNumber), base);
-         if (integerDigits == workDigits)
-           {
-             /* Adjust if the same number of digits are used */
-             number += TRIO_SUFFIX_LONG(0.5) / dblFractionBase;
-             integerNumber = trio_floor(number);
-             fractionNumber = number - integerNumber;
-           }
-         else
-           {
-             /* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */
-             exponent++;
-             isExponentNegative = (exponent < 0);
-             uExponent = (isExponentNegative) ? -exponent : exponent;
-             if (isHex)
-               uExponent *= 4; /* log16(2) */
-             workNumber = (number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase) / dblBase;
-             integerNumber = trio_floor(workNumber);
-             fractionNumber = workNumber - integerNumber;
-           }
-       }
-      else
-       {
-         if (workNumber > 1.0)
-           {
-             /* Adjust if number was rounded up one digit (ie. 99 to 100) */
-             integerNumber = trio_floor(workNumber);
-             fractionNumber = 0.0;
-             integerDigits = (integerNumber > epsilon)
-               ? 1 + (int)TrioLogarithm(integerNumber, base)
-               : 1;
-             if (flags & FLAGS_FLOAT_G)
-               {
-                 if (flags & FLAGS_ALTERNATIVE)
-                   {
-                     if ((integerNumber > epsilon) || (number <= epsilon))
-                       {
-                         fractionDigits -= integerDigits;
-                       }
-                   }
-                 else
-                   {
-                     fractionDigits = 0;
-                   }
-               }
-           }
-         else
-           {
-             integerNumber = trio_floor(workNumber);
-             fractionNumber = workNumber - integerNumber;
-             if (flags & FLAGS_FLOAT_G)
-               {
-                 if (flags & FLAGS_ALTERNATIVE)
-                   {
-                     fractionDigits = precision;
-                     if (leadingFractionZeroes > 0)
-                       {
-                         fractionDigits += leadingFractionZeroes;
-                       }
-                     if ((integerNumber > epsilon) || (number <= epsilon))
-                       {
-                         fractionDigits -= integerDigits;
-                       }
-                   }
-               }
-           }
-       }
-    }
-
-  /* Estimate accuracy */
-  integerAdjust = fractionAdjust = TRIO_SUFFIX_LONG(0.5);
-# if TRIO_FEATURE_ROUNDING
-  if (flags & FLAGS_ROUNDING)
-    {
-      if (integerDigits > baseDigits)
-       {
-         integerThreshold = baseDigits;
-         fractionDigits = 0;
-         dblFractionBase = 1.0;
-         fractionThreshold = 0;
-         precision = 0; /* Disable decimal-point */
-         integerAdjust = TrioPower(base, integerDigits - integerThreshold - 1);
-         fractionAdjust = 0.0;
-       }
-      else
-       {
-         integerThreshold = integerDigits;
-         fractionThreshold = fractionDigits - integerThreshold;
-         fractionAdjust = 1.0;
-       }
-    }
-  else
-# endif
-    {
-      integerThreshold = INT_MAX;
-      fractionThreshold = INT_MAX;
-    }
-  
-  /*
-   * Calculate expected width.
-   *  sign + integer part + thousands separators + decimal point
-   *  + fraction + exponent
-   */
-  fractionAdjust /= dblFractionBase;
-  hasOnlyZeroes = (trio_floor((fractionNumber + fractionAdjust) *
-                              dblFractionBase) < epsilon);
-  keepDecimalPoint = ( (flags & FLAGS_ALTERNATIVE) ||
-                      !((precision == 0) ||
-                        (!keepTrailingZeroes && hasOnlyZeroes)) );
-
-  expectedWidth = integerDigits + fractionDigits;
-
-  if (!keepTrailingZeroes)
-    {
-      trailingZeroes = 0;
-      workFractionNumber = fractionNumber;
-      workFractionAdjust = fractionAdjust;
-      fractionDigitsInspect = fractionDigits;
-
-      if (integerDigits > integerThreshold)
-       {
-         fractionDigitsInspect = 0;
-       }
-      else if (fractionThreshold  <= fractionDigits)
-       {
-         fractionDigitsInspect = fractionThreshold + 1;
-       }
-
-      trailingZeroes = fractionDigits - fractionDigitsInspect;
-      for (i = 0; i < fractionDigitsInspect; i++)
-       {
-         workFractionNumber *= dblBase;
-         workFractionAdjust *= dblBase;
-         workNumber = trio_floor(workFractionNumber + workFractionAdjust);
-         workFractionNumber -= workNumber;
-         offset = (int)trio_fmod(workNumber, dblBase);
-         if (offset == 0)
-           {
-             trailingZeroes++;
-           }
-         else
-           {
-             trailingZeroes = 0;
-           }
-       }
-      expectedWidth -= trailingZeroes;
-    }
-  
-  if (keepDecimalPoint)
-    {
-      expectedWidth += internalDecimalPointLength;
-    }
-  
-#if TRIO_FEATURE_QUOTE
-  if (flags & FLAGS_QUOTE)
-    {
-      expectedWidth += TrioCalcThousandSeparatorLength(integerDigits);
-    }
-#endif
-  
-  if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
-    {
-      expectedWidth += sizeof("-") - 1;
-    }
-  
-  exponentDigits = 0;
-  if (flags & FLAGS_FLOAT_E)
-    {
-      exponentDigits = (uExponent == 0)
-       ? 1
-       : (int)trio_ceil(TrioLogarithm((double)(uExponent + 1),
-                                      (isHex) ? 10 : base));
-    }
-  requireTwoDigitExponent = ((base == BASE_DECIMAL) && (exponentDigits == 1));
-  if (exponentDigits > 0)
-    {
-      expectedWidth += exponentDigits;
-      expectedWidth += (requireTwoDigitExponent
-                       ? sizeof("E+0") - 1
-                       : sizeof("E+") - 1);
-    }
-  
-  if (isHex)
-    {
-      expectedWidth += sizeof("0X") - 1;
-    }
-  
-  /* Output prefixing */
-  if (flags & FLAGS_NILPADDING)
-    {
-      /* Leading zeros must be after sign */
-      if (isNegative)
-       self->OutStream(self, '-');
-      else if (flags & FLAGS_SHOWSIGN)
-       self->OutStream(self, '+');
-      else if (flags & FLAGS_SPACE)
-       self->OutStream(self, ' ');
-      if (isHex)
-       {
-         self->OutStream(self, '0');
-         self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
-       }
-      if (!(flags & FLAGS_LEFTADJUST))
-       {
-         for (i = expectedWidth; i < width; i++)
-           {
-             self->OutStream(self, '0');
-           }
-       }
-    }
-  else
-    {
-      /* Leading spaces must be before sign */
-      if (!(flags & FLAGS_LEFTADJUST))
-       {
-         for (i = expectedWidth; i < width; i++)
-           {
-             self->OutStream(self, CHAR_ADJUST);
-           }
-       }
-      if (isNegative)
-       self->OutStream(self, '-');
-      else if (flags & FLAGS_SHOWSIGN)
-       self->OutStream(self, '+');
-      else if (flags & FLAGS_SPACE)
-       self->OutStream(self, ' ');
-      if (isHex)
-       {
-         self->OutStream(self, '0');
-         self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
-       }
-    }
-  
-  /* Output the integer part and thousand separators */
-  for (i = 0; i < integerDigits; i++)
-    {
-      workNumber = trio_floor(((integerNumber + integerAdjust)
-                              / TrioPower(base, integerDigits - i - 1)));
-      if (i > integerThreshold)
-       {
-         /* Beyond accuracy */
-         self->OutStream(self, digits[0]);
-       }
-      else
-       {
-         self->OutStream(self, digits[(int)trio_fmod(workNumber, dblBase)]);
-       }
-
-#if TRIO_FEATURE_QUOTE
-      if (((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE)
-         && TrioFollowedBySeparator(integerDigits - i))
-       {
-         for (groupingPointer = internalThousandSeparator;
-              *groupingPointer != NIL;
-              groupingPointer++)
-           {
-             self->OutStream(self, *groupingPointer);
-           }
-       }
-#endif
-    }
-  
-  /* Insert decimal point and build the fraction part */
-  trailingZeroes = 0;
-
-  if (keepDecimalPoint)
-    {
-      if (internalDecimalPoint)
-       {
-         self->OutStream(self, internalDecimalPoint);
-       }
-      else
-       {
-         for (i = 0; i < internalDecimalPointLength; i++)
-           {
-             self->OutStream(self, internalDecimalPointString[i]);
-           }
-       }
-    }
-
-  for (i = 0; i < fractionDigits; i++)
-    {
-      if ((integerDigits > integerThreshold) || (i > fractionThreshold))
-       {
-         /* Beyond accuracy */
-         trailingZeroes++;
-       }
-      else
-       {
-         fractionNumber *= dblBase;
-         fractionAdjust *= dblBase;
-         workNumber = trio_floor(fractionNumber + fractionAdjust);
-         if (workNumber > fractionNumber)
-           {
-             /* fractionNumber should never become negative */
-             fractionNumber = 0.0;
-             fractionAdjust = 0.0;
-           }
-         else
-           {
-             fractionNumber -= workNumber;
-           }
-         offset = (int)trio_fmod(workNumber, dblBase);
-         if (offset == 0)
-           {
-             trailingZeroes++;
-           }
-         else
-           {
-             while (trailingZeroes > 0)
-               {
-                 /* Not trailing zeroes after all */
-                 self->OutStream(self, digits[0]);
-                 trailingZeroes--;
-               }
-             self->OutStream(self, digits[offset]);
-           }
-       }
-    }
-  
-  if (keepTrailingZeroes)
-    {
-      while (trailingZeroes > 0)
-       {
-         self->OutStream(self, digits[0]);
-         trailingZeroes--;
-       }
-    }
-  
-  /* Output exponent */
-  if (exponentDigits > 0)
-    {
-      self->OutStream(self,
-                     isHex
-                     ? ((flags & FLAGS_UPPER) ? 'P' : 'p')
-                     : ((flags & FLAGS_UPPER) ? 'E' : 'e'));
-      self->OutStream(self, (isExponentNegative) ? '-' : '+');
-
-      /* The exponent must contain at least two digits */
-      if (requireTwoDigitExponent)
-        self->OutStream(self, '0');
-
-      if (isHex)
-       base = 10;
-      exponentBase = (int)TrioPower(base, exponentDigits - 1);
-      for (i = 0; i < exponentDigits; i++)
-       {
-         self->OutStream(self, digits[(uExponent / exponentBase) % base]);
-         exponentBase /= base;
-       }
-    }
-  /* Output trailing spaces */
-  if (flags & FLAGS_LEFTADJUST)
-    {
-      for (i = expectedWidth; i < width; i++)
-       {
-         self->OutStream(self, CHAR_ADJUST);
-       }
-    }
-}
-#endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * TrioFormatProcess
- *
- * Description:
- *  This is the main engine for formatting output
- */
-TRIO_PRIVATE int
-TrioFormatProcess
-TRIO_ARGS3((data, format, parameters),
-          trio_class_t *data,
-          TRIO_CONST char *format,
-          trio_parameter_t *parameters)
-{
-  int i;
-#if TRIO_FEATURE_ERRNO
-  TRIO_CONST char *string;
-#endif
-  trio_pointer_t pointer;
-  trio_flags_t flags;
-  int width;
-  int precision;
-  int base;
-  int offset;
-  
-  offset = 0;
-  i = 0;
-
-  for (;;)
-    {
-      /* Skip the parameter entries */
-      while (parameters[i].type == FORMAT_PARAMETER)
-       i++;
-
-      /* Copy non conversion-specifier part of format string */
-      while (offset < parameters[i].beginOffset)
-        {
-         if (CHAR_IDENTIFIER == format[offset] && CHAR_IDENTIFIER == format[offset + 1])
-           {
-             data->OutStream(data, CHAR_IDENTIFIER);
-             offset += 2;
-           }
-         else
-           {
-             data->OutStream(data, format[offset++]);
-           }
-       }
-
-      /* Abort if we reached end of format string */
-      if (parameters[i].type == FORMAT_SENTINEL)
-       break;
-
-      /* Ouput parameter */
-      flags = parameters[i].flags;
-
-      /* Find width */
-      width = parameters[i].width;
-      if (flags & FLAGS_WIDTH_PARAMETER)
-       {
-         /* Get width from parameter list */
-         width = (int)parameters[width].data.number.as_signed;
-         if (width < 0)
-           {
-             /*
-              * A negative width is the same as the - flag and
-              * a positive width.
-              */
-             flags |= FLAGS_LEFTADJUST;
-             flags &= ~FLAGS_NILPADDING;
-             width = -width;
-           }
-       }
-
-      /* Find precision */
-      if (flags & FLAGS_PRECISION)
-       {
-         precision = parameters[i].precision;
-         if (flags & FLAGS_PRECISION_PARAMETER)
-           {
-             /* Get precision from parameter list */
-             precision = (int)parameters[precision].data.number.as_signed;
-             if (precision < 0)
-               {
-                 /*
-                  * A negative precision is the same as no
-                  * precision
-                  */
-                 precision = NO_PRECISION;
-               }
-           }
-       }
-      else
-       {
-         precision = NO_PRECISION;
-       }
-
-      /* Find base */
-      if (NO_BASE != parameters[i].baseSpecifier)
-       {
-         /* Base from specifier has priority */
-         base = parameters[i].baseSpecifier;
-       }
-      else if (flags & FLAGS_BASE_PARAMETER)
-       {
-         /* Get base from parameter list */
-         base = parameters[i].base;
-         base = (int)parameters[base].data.number.as_signed;
-       }
-      else
-       {
-         /* Use base from format string */
-         base = parameters[i].base;
-       }
-
-      switch (parameters[i].type)
-        {
-       case FORMAT_CHAR:
-#if TRIO_FEATURE_QUOTE
-         if (flags & FLAGS_QUOTE)
-           data->OutStream(data, CHAR_QUOTE);
-#endif
-         if (! (flags & FLAGS_LEFTADJUST))
-           {
-             while (--width > 0)
-               data->OutStream(data, CHAR_ADJUST);
-           }
-#if TRIO_FEATURE_WIDECHAR
-         if (flags & FLAGS_WIDECHAR)
-           {
-             TrioWriteWideStringCharacter(data,
-                                          (trio_wchar_t)parameters[i].data.number.as_signed,
-                                          flags,
-                                          NO_WIDTH);
-           }
-         else
-#endif
-         {
-           TrioWriteStringCharacter(data,
-                                    (int)parameters[i].data.number.as_signed,
-                                    flags);
-         }
-
-         if (flags & FLAGS_LEFTADJUST)
-           {
-             while(--width > 0)
-               data->OutStream(data, CHAR_ADJUST);
-           }
-#if TRIO_FEATURE_QUOTE
-         if (flags & FLAGS_QUOTE)
-           data->OutStream(data, CHAR_QUOTE);
-#endif
-
-         break; /* FORMAT_CHAR */
-
-       case FORMAT_INT:
-         TrioWriteNumber(data,
-                         parameters[i].data.number.as_unsigned,
-                         flags,
-                         width,
-                         precision,
-                         base);
-
-         break; /* FORMAT_INT */
-
-#if TRIO_FEATURE_FLOAT
-       case FORMAT_DOUBLE:
-         TrioWriteDouble(data,
-                         parameters[i].data.longdoubleNumber,
-                         flags,
-                         width,
-                         precision,
-                         base);
-         break; /* FORMAT_DOUBLE */
-#endif
-
-       case FORMAT_STRING:
-#if TRIO_FEATURE_WIDECHAR
-         if (flags & FLAGS_WIDECHAR)
-           {
-             TrioWriteWideString(data,
-                                 parameters[i].data.wstring,
-                                 flags,
-                                 width,
-                                 precision);
-           }
-         else
-#endif
-           {
-             TrioWriteString(data,
-                             parameters[i].data.string,
-                             flags,
-                             width,
-                             precision);
-           }
-         break; /* FORMAT_STRING */
-
-       case FORMAT_POINTER:
-         {
-           trio_reference_t reference;
-
-           reference.data = data;
-           reference.parameter = &parameters[i];
-           trio_print_pointer(&reference, parameters[i].data.pointer);
-         }
-         break; /* FORMAT_POINTER */
-
-       case FORMAT_COUNT:
-         pointer = parameters[i].data.pointer;
-         if (NULL != pointer)
-           {
-             /*
-              * C99 paragraph 7.19.6.1.8 says "the number of
-              * characters written to the output stream so far by
-              * this call", which is data->actually.committed
-              */
-#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
-             if (flags & FLAGS_SIZE_T)
-               *(size_t *)pointer = (size_t)data->actually.committed;
-             else
-#endif
-#if TRIO_FEATURE_PTRDIFF_T
-             if (flags & FLAGS_PTRDIFF_T)
-               *(ptrdiff_t *)pointer = (ptrdiff_t)data->actually.committed;
-             else
-#endif
-#if TRIO_FEATURE_INTMAX_T
-             if (flags & FLAGS_INTMAX_T)
-               *(trio_intmax_t *)pointer = (trio_intmax_t)data->actually.committed;
-             else
-#endif
-             if (flags & FLAGS_QUAD)
-               {
-                 *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->actually.committed;
-               }
-             else if (flags & FLAGS_LONG)
-               {
-                 *(long int *)pointer = (long int)data->actually.committed;
-               }
-             else if (flags & FLAGS_SHORT)
-               {
-                 *(short int *)pointer = (short int)data->actually.committed;
-               }
-             else
-               {
-                 *(int *)pointer = (int)data->actually.committed;
-               }
-           }
-         break; /* FORMAT_COUNT */
-
-       case FORMAT_PARAMETER:
-         break; /* FORMAT_PARAMETER */
-
-#if TRIO_FEATURE_ERRNO
-       case FORMAT_ERRNO:
-         string = trio_error(parameters[i].data.errorNumber);
-         if (string)
-           {
-             TrioWriteString(data,
-                             string,
-                             flags,
-                             width,
-                             precision);
-           }
-         else
-         {
-           data->OutStream(data, '#');
-           TrioWriteNumber(data,
-                           (trio_uintmax_t)parameters[i].data.errorNumber,
-                           flags,
-                           width,
-                           precision,
-                           BASE_DECIMAL);
-         }
-         break; /* FORMAT_ERRNO */
-#endif /* TRIO_FEATURE_ERRNO */
-
-#if TRIO_FEATURE_USER_DEFINED
-       case FORMAT_USER_DEFINED:
-         {
-           trio_reference_t reference;
-           trio_userdef_t *def = NULL;
-
-           if (parameters[i].flags & FLAGS_USER_DEFINED_PARAMETER)
-             {
-               /* Use handle */
-               if ((i > 0) ||
-                   (parameters[i - 1].type == FORMAT_PARAMETER))
-                 def = (trio_userdef_t *)parameters[i - 1].data.pointer;
-             }
-           else
-             {
-               /* Look up namespace */
-               def = TrioFindNamespace(parameters[i].user_defined.namespace, NULL);
-             }
-           if (def)
-             {
-               reference.data = data;
-               reference.parameter = &parameters[i];
-               def->callback(&reference);
-             }
-         }
-         break;
-#endif /* TRIO_FEATURE_USER_DEFINED */
-
-       default:
-         break;
-       } /* switch parameter type */
-
-      /* Prepare for next */
-      offset = parameters[i].endOffset;
-      i++;
-    }
-
-  return data->processed;
-}
-
-/*************************************************************************
- * TrioFormatRef
- */
-#if TRIO_EXTENSION
-TRIO_PRIVATE int
-TrioFormatRef
-TRIO_ARGS4((reference, format, arglist, argarray),
-          trio_reference_t *reference,
-          TRIO_CONST char *format,
-          va_list arglist,
-          trio_pointer_t *argarray)
-{
-  int status;
-  trio_parameter_t parameters[MAX_PARAMETERS];
-
-  status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);
-  if (status < 0)
-    return status;
-
-  status = TrioFormatProcess(reference->data, format, parameters);
-  if (reference->data->error != 0)
-    {
-      status = reference->data->error;
-    }
-  return status;
-}
-#endif /* TRIO_EXTENSION */
-
-/*************************************************************************
- * TrioFormat
- */
-TRIO_PRIVATE int
-TrioFormat
-TRIO_ARGS6((destination, destinationSize, OutStream, format, arglist, argarray),
-          trio_pointer_t destination,
-          size_t destinationSize,
-          void (*OutStream) TRIO_PROTO((trio_class_t *, int)),
-          TRIO_CONST char *format,
-          va_list arglist,
-          trio_pointer_t *argarray)
-{
-  int status;
-  trio_class_t data;
-  trio_parameter_t parameters[MAX_PARAMETERS];
-
-  assert(VALID(OutStream));
-  assert(VALID(format));
-
-  memset(&data, 0, sizeof(data));
-  data.OutStream = OutStream;
-  data.location = destination;
-  data.max = destinationSize;
-  data.error = 0;
-
-#if defined(USE_LOCALE)
-  if (NULL == internalLocaleValues)
-    {
-      TrioSetLocale();
-    }
-#endif
-
-  status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);
-  if (status < 0)
-    return status;
-
-  status = TrioFormatProcess(&data, format, parameters);
-  if (data.error != 0)
-    {
-      status = data.error;
-    }
-  return status;
-}
-
-/*************************************************************************
- * TrioOutStreamFile
- */
-#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO
-TRIO_PRIVATE void
-TrioOutStreamFile
-TRIO_ARGS2((self, output),
-          trio_class_t *self,
-          int output)
-{
-  FILE *file;
-
-  assert(VALID(self));
-  assert(VALID(self->location));
-
-  file = (FILE *)self->location;
-  self->processed++;
-  if (fputc(output, file) == EOF)
-    {
-      self->error = TRIO_ERROR_RETURN(TRIO_EOF, 0);
-    }
-  else
-    {
-      self->actually.committed++;
-    }
-}
-#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */
-
-/*************************************************************************
- * TrioOutStreamFileDescriptor
- */
-#if TRIO_FEATURE_FD
-TRIO_PRIVATE void
-TrioOutStreamFileDescriptor
-TRIO_ARGS2((self, output),
-          trio_class_t *self,
-          int output)
-{
-  int fd;
-  char ch;
-
-  assert(VALID(self));
-
-  fd = *((int *)self->location);
-  ch = (char)output;
-  self->processed++;
-  if (write(fd, &ch, sizeof(char)) == -1)
-    {
-      self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);
-    }
-  else
-    {
-      self->actually.committed++;
-    }
-}
-#endif /* TRIO_FEATURE_FD */
-
-/*************************************************************************
- * TrioOutStreamCustom
- */
-#if TRIO_FEATURE_CLOSURE
-TRIO_PRIVATE void
-TrioOutStreamCustom
-TRIO_ARGS2((self, output),
-          trio_class_t *self,
-          int output)
-{
-  int status;
-  trio_custom_t *data;
-
-  assert(VALID(self));
-  assert(VALID(self->location));
-
-  data = (trio_custom_t *)self->location;
-  if (data->stream.out)
-    {
-      status = (data->stream.out)(data->closure, output);
-      if (status >= 0)
-       {
-         self->actually.committed++;
-       }
-      else
-       {
-         if (self->error == 0)
-           {
-             self->error = TRIO_ERROR_RETURN(TRIO_ECUSTOM, -status);
-           }
-       }
-    }
-  self->processed++;
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-/*************************************************************************
- * TrioOutStreamString
- */
-TRIO_PRIVATE void
-TrioOutStreamString
-TRIO_ARGS2((self, output),
-          trio_class_t *self,
-          int output)
-{
-  char **buffer;
-
-  assert(VALID(self));
-  assert(VALID(self->location));
-
-  buffer = (char **)self->location;
-  **buffer = (char)output;
-  (*buffer)++;
-  self->processed++;
-  self->actually.committed++;
-}
-
-/*************************************************************************
- * TrioOutStreamStringMax
- */
-TRIO_PRIVATE void
-TrioOutStreamStringMax
-TRIO_ARGS2((self, output),
-          trio_class_t *self,
-          int output)
-{
-  char **buffer;
-
-  assert(VALID(self));
-  assert(VALID(self->location));
-  
-  buffer = (char **)self->location;
-
-  if (self->processed < self->max)
-    {
-      **buffer = (char)output;
-      (*buffer)++;
-      self->actually.committed++;
-    }
-  self->processed++;
-}
-
-/*************************************************************************
- * TrioOutStreamStringDynamic
- */
-#if TRIO_FEATURE_DYNAMICSTRING
-TRIO_PRIVATE void
-TrioOutStreamStringDynamic
-TRIO_ARGS2((self, output),
-          trio_class_t *self,
-          int output)
-{
-  assert(VALID(self));
-  assert(VALID(self->location));
-
-  if (self->error == 0)
-    {
-      trio_xstring_append_char((trio_string_t *)self->location,
-                              (char)output);
-      self->actually.committed++;
-    }
-  /* The processed variable must always be increased */
-  self->processed++;
-}
-#endif /* TRIO_FEATURE_DYNAMICSTRING */
-
-/*************************************************************************
- *
- * Formatted printing functions
- *
- ************************************************************************/
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_printf.h"
-#endif
-/** @addtogroup Printf
-    @{
-*/
-
-/*************************************************************************
- * printf
- */
-
-/**
-   Print to standard output stream.
-
-   @param format Formatting string.
-   @param ... Arguments.
-   @return Number of printed characters.
- */
-#if TRIO_FEATURE_STDIO
-TRIO_PUBLIC int
-trio_printf
-TRIO_VARGS2((format, va_alist),
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list args;
-
-  assert(VALID(format));
-  
-  TRIO_VA_START(args, format);
-  status = TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL);
-  TRIO_VA_END(args);
-  return status;
-}
-#endif /* TRIO_FEATURE_STDIO */
-
-/**
-   Print to standard output stream.
-
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of printed characters.
- */
-#if TRIO_FEATURE_STDIO
-TRIO_PUBLIC int
-trio_vprintf
-TRIO_ARGS2((format, args),
-          TRIO_CONST char *format,
-          va_list args)
-{
-  assert(VALID(format));
-
-  return TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL);
-}
-#endif /* TRIO_FEATURE_STDIO */
-
-/**
-   Print to standard output stream.
-
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of printed characters.
- */
-#if TRIO_FEATURE_STDIO
-TRIO_PUBLIC int
-trio_printfv
-TRIO_ARGS2((format, args),
-          TRIO_CONST char *format,
-          trio_pointer_t * args)
-{
-  static va_list unused;
-  
-  assert(VALID(format));
-
-  return TrioFormat(stdout, 0, TrioOutStreamFile, format, unused, args);
-}
-#endif /* TRIO_FEATURE_STDIO */
-
-/*************************************************************************
- * fprintf
- */
-
-/**
-   Print to file.
-
-   @param file File pointer.
-   @param format Formatting string.
-   @param ... Arguments.
-   @return Number of printed characters.
- */
-#if TRIO_FEATURE_FILE
-TRIO_PUBLIC int
-trio_fprintf
-TRIO_VARGS3((file, format, va_alist),
-           FILE *file,
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list args;
-
-  assert(VALID(file));
-  assert(VALID(format));
-  
-  TRIO_VA_START(args, format);
-  status = TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL);
-  TRIO_VA_END(args);
-  return status;
-}
-#endif /* TRIO_FEATURE_FILE */
-
-/**
-   Print to file.
-
-   @param file File pointer.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of printed characters.
- */
-#if TRIO_FEATURE_FILE
-TRIO_PUBLIC int
-trio_vfprintf
-TRIO_ARGS3((file, format, args),
-          FILE *file,
-          TRIO_CONST char *format,
-          va_list args)
-{
-  assert(VALID(file));
-  assert(VALID(format));
-  
-  return TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL);
-}
-#endif /* TRIO_FEATURE_FILE */
-
-/**
-   Print to file.
-
-   @param file File pointer.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of printed characters.
- */
-#if TRIO_FEATURE_FILE
-TRIO_PUBLIC int
-trio_fprintfv
-TRIO_ARGS3((file, format, args),
-          FILE *file,
-          TRIO_CONST char *format,
-          trio_pointer_t * args)
-{
-  static va_list unused;
-  
-  assert(VALID(file));
-  assert(VALID(format));
-  
-  return TrioFormat(file, 0, TrioOutStreamFile, format, unused, args);
-}
-#endif /* TRIO_FEATURE_FILE */
-
-/*************************************************************************
- * dprintf
- */
-
-/**
-   Print to file descriptor.
-
-   @param fd File descriptor.
-   @param format Formatting string.
-   @param ... Arguments.
-   @return Number of printed characters.
- */
-#if TRIO_FEATURE_FD
-TRIO_PUBLIC int
-trio_dprintf
-TRIO_VARGS3((fd, format, va_alist),
-           int fd,
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list args;
-
-  assert(VALID(format));
-  
-  TRIO_VA_START(args, format);
-  status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL);
-  TRIO_VA_END(args);
-  return status;
-}
-#endif /* TRIO_FEATURE_FD */
-
-/**
-   Print to file descriptor.
-
-   @param fd File descriptor.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of printed characters.
- */
-#if TRIO_FEATURE_FD
-TRIO_PUBLIC int
-trio_vdprintf
-TRIO_ARGS3((fd, format, args),
-          int fd,
-          TRIO_CONST char *format,
-          va_list args)
-{
-  assert(VALID(format));
-  
-  return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL);
-}
-#endif /* TRIO_FEATURE_FD */
-
-/**
-   Print to file descriptor.
-
-   @param fd File descriptor.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of printed characters.
- */
-#if TRIO_FEATURE_FD
-TRIO_PUBLIC int
-trio_dprintfv
-TRIO_ARGS3((fd, format, args),
-          int fd,
-          TRIO_CONST char *format,
-          trio_pointer_t *args)
-{
-  static va_list unused;
-  
-  assert(VALID(format));
-  
-  return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, unused, args);
-}
-#endif /* TRIO_FEATURE_FD */
-
-/*************************************************************************
- * cprintf
- */
-#if TRIO_FEATURE_CLOSURE
-TRIO_PUBLIC int
-trio_cprintf
-TRIO_VARGS4((stream, closure, format, va_alist),
-           trio_outstream_t stream,
-           trio_pointer_t closure,
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list args;
-  trio_custom_t data;
-
-  assert(VALID(stream));
-  assert(VALID(format));
-
-  TRIO_VA_START(args, format);
-  data.stream.out = stream;
-  data.closure = closure;
-  status = TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL);
-  TRIO_VA_END(args);
-  return status;
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-#if TRIO_FEATURE_CLOSURE
-TRIO_PUBLIC int
-trio_vcprintf
-TRIO_ARGS4((stream, closure, format, args),
-          trio_outstream_t stream,
-          trio_pointer_t closure,
-          TRIO_CONST char *format,
-          va_list args)
-{
-  trio_custom_t data;
-
-  assert(VALID(stream));
-  assert(VALID(format));
-
-  data.stream.out = stream;
-  data.closure = closure;
-  return TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL);
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-#if TRIO_FEATURE_CLOSURE
-TRIO_PUBLIC int
-trio_cprintfv
-TRIO_ARGS4((stream, closure, format, args),
-          trio_outstream_t stream,
-          trio_pointer_t closure,
-          TRIO_CONST char *format,
-          void **args)
-{
-  static va_list unused;
-  trio_custom_t data;
-
-  assert(VALID(stream));
-  assert(VALID(format));
-
-  data.stream.out = stream;
-  data.closure = closure;
-  return TrioFormat(&data, 0, TrioOutStreamCustom, format, unused, args);
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-/*************************************************************************
- * sprintf
- */
-
-/**
-   Print to string.
-
-   @param buffer Output string.
-   @param format Formatting string.
-   @param ... Arguments.
-   @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_sprintf
-TRIO_VARGS3((buffer, format, va_alist),
-           char *buffer,
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list args;
-
-  assert(VALID(buffer));
-  assert(VALID(format));
-  
-  TRIO_VA_START(args, format);
-  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL);
-  *buffer = NIL; /* Terminate with NIL character */
-  TRIO_VA_END(args);
-  return status;
-}
-
-/**
-   Print to string.
-
-   @param buffer Output string.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vsprintf
-TRIO_ARGS3((buffer, format, args),
-          char *buffer,
-          TRIO_CONST char *format,
-          va_list args)
-{
-  int status;
-
-  assert(VALID(buffer));
-  assert(VALID(format));
-
-  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL);
-  *buffer = NIL;
-  return status;
-}
-
-/**
-   Print to string.
-
-   @param buffer Output string.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_sprintfv
-TRIO_ARGS3((buffer, format, args),
-          char *buffer,
-          TRIO_CONST char *format,
-          trio_pointer_t *args)
-{
-  static va_list unused;
-  int status;
-  
-  assert(VALID(buffer));
-  assert(VALID(format));
-
-  status = TrioFormat(&buffer, 0, TrioOutStreamString, format, unused, args);
-  *buffer = NIL;
-  return status;
-}
-
-/*************************************************************************
- * snprintf
- */
-
-/**
-   Print at most @p max characters to string.
-
-   @param buffer Output string.
-   @param max Maximum number of characters to print.
-   @param format Formatting string.
-   @param ... Arguments.
-   @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_snprintf
-TRIO_VARGS4((buffer, max, format, va_alist),
-           char *buffer,
-           size_t max,
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list args;
-
-  assert(VALID(buffer) || (max == 0));
-  assert(VALID(format));
-
-  TRIO_VA_START(args, format);
-  status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
-                     TrioOutStreamStringMax, format, args, NULL);
-  if (max > 0)
-    *buffer = NIL;
-  TRIO_VA_END(args);
-  return status;
-}
-
-/**
-   Print at most @p max characters to string.
-
-   @param buffer Output string.
-   @param max Maximum number of characters to print.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vsnprintf
-TRIO_ARGS4((buffer, max, format, args),
-          char *buffer,
-          size_t max,
-          TRIO_CONST char *format,
-          va_list args)
-{
-  int status;
-
-  assert(VALID(buffer) || (max == 0));
-  assert(VALID(format));
-
-  status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
-                     TrioOutStreamStringMax, format, args, NULL);
-  if (max > 0)
-    *buffer = NIL;
-  return status;
-}
-
-/**
-   Print at most @p max characters to string.
-
-   @param buffer Output string.
-   @param max Maximum number of characters to print.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_snprintfv
-TRIO_ARGS4((buffer, max, format, args),
-          char *buffer,
-          size_t max,
-          TRIO_CONST char *format,
-          trio_pointer_t *args)
-{
-  static va_list unused;
-  int status;
-
-  assert(VALID(buffer) || (max == 0));
-  assert(VALID(format));
-
-  status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
-                     TrioOutStreamStringMax, format, unused, args);
-  if (max > 0)
-    *buffer = NIL;
-  return status;
-}
-
-/*************************************************************************
- * snprintfcat
- * Appends the new string to the buffer string overwriting the '\0'
- * character at the end of buffer.
- */
-#if TRIO_EXTENSION
-TRIO_PUBLIC int
-trio_snprintfcat
-TRIO_VARGS4((buffer, max, format, va_alist),
-           char *buffer,
-           size_t max,
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list args;
-  size_t buf_len;
-
-  TRIO_VA_START(args, format);
-
-  assert(VALID(buffer));
-  assert(VALID(format));
-
-  buf_len = trio_length(buffer);
-  buffer = &buffer[buf_len];
-
-  status = TrioFormat(&buffer, max - 1 - buf_len,
-                     TrioOutStreamStringMax, format, args, NULL);
-  TRIO_VA_END(args);
-  *buffer = NIL;
-  return status;
-}
-#endif
-
-#if TRIO_EXTENSION
-TRIO_PUBLIC int
-trio_vsnprintfcat
-TRIO_ARGS4((buffer, max, format, args),
-          char *buffer,
-          size_t max,
-          TRIO_CONST char *format,
-          va_list args)
-{
-  int status;
-  size_t buf_len;
-  
-  assert(VALID(buffer));
-  assert(VALID(format));
-
-  buf_len = trio_length(buffer);
-  buffer = &buffer[buf_len];
-  status = TrioFormat(&buffer, max - 1 - buf_len,
-                     TrioOutStreamStringMax, format, args, NULL);
-  *buffer = NIL;
-  return status;
-}
-#endif
-
-/*************************************************************************
- * trio_aprintf
- */
-
-#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING
-TRIO_PUBLIC char *
-trio_aprintf
-TRIO_VARGS2((format, va_alist),
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  va_list args;
-  trio_string_t *info;
-  char *result = NULL;
-
-  assert(VALID(format));
-  
-  info = trio_xstring_duplicate("");
-  if (info)
-    {
-      TRIO_VA_START(args, format);
-      (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
-                      format, args, NULL);
-      TRIO_VA_END(args);
-
-      trio_string_terminate(info);
-      result = trio_string_extract(info);
-      trio_string_destroy(info);
-    }
-  return result;
-}
-#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */
-
-#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING
-TRIO_PUBLIC char *
-trio_vaprintf
-TRIO_ARGS2((format, args),
-          TRIO_CONST char *format,
-          va_list args)
-{
-  trio_string_t *info;
-  char *result = NULL;
-  
-  assert(VALID(format));
-  
-  info = trio_xstring_duplicate("");
-  if (info)
-    {
-      (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
-                      format, args, NULL);
-      trio_string_terminate(info);
-      result = trio_string_extract(info);
-      trio_string_destroy(info);
-    }
-  return result;
-}
-#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */
-
-/**
-   Allocate and print to string.
-   The memory allocated and returned by @p result must be freed by the
-   calling application.
-
-   @param result Output string.
-   @param format Formatting string.
-   @param ... Arguments.
-   @return Number of printed characters.
- */
-#if TRIO_FEATURE_DYNAMICSTRING
-TRIO_PUBLIC int
-trio_asprintf
-TRIO_VARGS3((result, format, va_alist),
-           char **result,
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  va_list args;
-  int status;
-  trio_string_t *info;
-
-  assert(VALID(format));
-
-  *result = NULL;
-  
-  info = trio_xstring_duplicate("");
-  if (info == NULL)
-    {
-      status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
-    }
-  else
-    {
-      TRIO_VA_START(args, format);
-      status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
-                         format, args, NULL);
-      TRIO_VA_END(args);
-      if (status >= 0)
-       {
-         trio_string_terminate(info);
-         *result = trio_string_extract(info);
-       }
-      trio_string_destroy(info);
-    }
-  return status;
-}
-#endif /* TRIO_FEATURE_DYNAMICSTRING */
-
-/**
-   Allocate and print to string.
-   The memory allocated and returned by @p result must be freed by the
-   calling application.
-
-   @param result Output string.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of printed characters.
- */
-#if TRIO_FEATURE_DYNAMICSTRING
-TRIO_PUBLIC int
-trio_vasprintf
-TRIO_ARGS3((result, format, args),
-          char **result,
-          TRIO_CONST char *format,
-          va_list args)
-{
-  int status;
-  trio_string_t *info;
-  
-  assert(VALID(format));
-
-  *result = NULL;
-  
-  info = trio_xstring_duplicate("");
-  if (info == NULL)
-    {
-      status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
-    }
-  else
-    {
-      status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
-                         format, args, NULL);
-      if (status >= 0)
-       {
-         trio_string_terminate(info);
-         *result = trio_string_extract(info);
-       }
-      trio_string_destroy(info);
-    }
-  return status;
-}
-#endif /* TRIO_FEATURE_DYNAMICSTRING */
-
-/**
-   Allocate and print to string.
-   The memory allocated and returned by @p result must be freed by the
-   calling application.
-
-   @param result Output string.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of printed characters.
- */
-#if TRIO_FEATURE_DYNAMICSTRING
-TRIO_PUBLIC int
-trio_asprintfv
-TRIO_ARGS3((result, format, args),
-           char **result,
-           TRIO_CONST char *format,
-           trio_pointer_t * args)
-{
-  static va_list unused;
-  int status;
-  trio_string_t *info;
-  
-  assert(VALID(format));
-
-  *result = NULL;
-
-  info = trio_xstring_duplicate("");
-  if (info == NULL)
-    {
-      status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
-    }
-  else
-    {
-      status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
-                          format, unused, args);
-      if (status >= 0)
-        {
-          trio_string_terminate(info);
-          *result = trio_string_extract(info);
-        }
-      trio_string_destroy(info);
-    }
-  return status;
-}
-#endif /* TRIO_FEATURE_DYNAMICSTRING */
-
-/** @} End of Printf documentation module */
-
-/*************************************************************************
- *
- * CALLBACK
- *
- ************************************************************************/
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_register.h"
-#endif
-/**
-   @addtogroup UserDefined
-   @{
-*/
-
-#if TRIO_FEATURE_USER_DEFINED
-
-/*************************************************************************
- * trio_register
- */
-
-/**
-   Register new user-defined specifier.
-
-   @param callback
-   @param name
-   @return Handle.
- */
-TRIO_PUBLIC trio_pointer_t 
-trio_register
-TRIO_ARGS2((callback, name),
-          trio_callback_t callback,
-          TRIO_CONST char *name)
-{
-  trio_userdef_t *def;
-  trio_userdef_t *prev = NULL;
-
-  if (callback == NULL)
-    return NULL;
-
-  if (name)
-    {
-      /* Handle built-in namespaces */
-      if (name[0] == ':')
-       {
-         if (trio_equal(name, ":enter"))
-           {
-             internalEnterCriticalRegion = callback;
-           }
-         else if (trio_equal(name, ":leave"))
-           {
-             internalLeaveCriticalRegion = callback;
-           }
-         return NULL;
-       }
-      
-      /* Bail out if namespace is too long */
-      if (trio_length(name) >= MAX_USER_NAME)
-       return NULL;
-      
-      /* Bail out if namespace already is registered */
-      def = TrioFindNamespace(name, &prev);
-      if (def)
-       return NULL;
-    }
-  
-  def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t));
-  if (def)
-    {
-      if (internalEnterCriticalRegion)
-       (void)internalEnterCriticalRegion(NULL);
-      
-      if (name)
-       {
-         /* Link into internal list */
-         if (prev == NULL)
-           internalUserDef = def;
-         else
-           prev->next = def;
-       }
-      /* Initialize */
-      def->callback = callback;
-      def->name = (name == NULL)
-       ? NULL
-       : trio_duplicate(name);
-      def->next = NULL;
-
-      if (internalLeaveCriticalRegion)
-       (void)internalLeaveCriticalRegion(NULL);
-    }
-  return (trio_pointer_t)def;
-}
-
-/**
-   Unregister an existing user-defined specifier.
-
-   @param handle
- */
-void
-trio_unregister
-TRIO_ARGS1((handle),
-          trio_pointer_t handle)
-{
-  trio_userdef_t *self = (trio_userdef_t *)handle;
-  trio_userdef_t *def;
-  trio_userdef_t *prev = NULL;
-
-  assert(VALID(self));
-
-  if (self->name)
-    {
-      def = TrioFindNamespace(self->name, &prev);
-      if (def)
-       {
-         if (internalEnterCriticalRegion)
-           (void)internalEnterCriticalRegion(NULL);
-         
-         if (prev == NULL)
-           internalUserDef = internalUserDef->next;
-         else
-           prev->next = def->next;
-         
-         if (internalLeaveCriticalRegion)
-           (void)internalLeaveCriticalRegion(NULL);
-       }
-      trio_destroy(self->name);
-    }
-  TRIO_FREE(self);
-}
-
-/*************************************************************************
- * trio_get_format [public]
- */
-TRIO_CONST char *
-trio_get_format
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-#if TRIO_FEATURE_USER_DEFINED
-  assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
-#endif
-  
-  return (((trio_reference_t *)ref)->parameter->user_data);
-}
-
-/*************************************************************************
- * trio_get_argument [public]
- */
-TRIO_CONST trio_pointer_t
-trio_get_argument
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-#if TRIO_FEATURE_USER_DEFINED
-  assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
-#endif
-
-  return ((trio_reference_t *)ref)->parameter->data.pointer;
-}
-
-/*************************************************************************
- * trio_get_width / trio_set_width [public]
- */
-int
-trio_get_width
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return ((trio_reference_t *)ref)->parameter->width;
-}
-
-void
-trio_set_width
-TRIO_ARGS2((ref, width),
-          trio_pointer_t ref,
-          int width)
-{
-  ((trio_reference_t *)ref)->parameter->width = width;
-}
-
-/*************************************************************************
- * trio_get_precision / trio_set_precision [public]
- */
-int
-trio_get_precision
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->precision);
-}
-
-void
-trio_set_precision
-TRIO_ARGS2((ref, precision),
-          trio_pointer_t ref,
-          int precision)
-{
-  ((trio_reference_t *)ref)->parameter->precision = precision;
-}
-
-/*************************************************************************
- * trio_get_base / trio_set_base [public]
- */
-int
-trio_get_base
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->base);
-}
-
-void
-trio_set_base
-TRIO_ARGS2((ref, base),
-          trio_pointer_t ref,
-          int base)
-{
-  ((trio_reference_t *)ref)->parameter->base = base;
-}
-
-/*************************************************************************
- * trio_get_long / trio_set_long [public]
- */
-int
-trio_get_long
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_long
-TRIO_ARGS2((ref, is_long),
-          trio_pointer_t ref,
-          int is_long)
-{
-  if (is_long)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONG;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONG;
-}
-
-/*************************************************************************
- * trio_get_longlong / trio_set_longlong [public]
- */
-int
-trio_get_longlong
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_longlong
-TRIO_ARGS2((ref, is_longlong),
-          trio_pointer_t ref,
-          int is_longlong)
-{
-  if (is_longlong)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUAD;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUAD;
-}
-
-/*************************************************************************
- * trio_get_longdouble / trio_set_longdouble [public]
- */
-# if TRIO_FEATURE_FLOAT
-int
-trio_get_longdouble
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_longdouble
-TRIO_ARGS2((ref, is_longdouble),
-          trio_pointer_t ref,
-          int is_longdouble)
-{
-  if (is_longdouble)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONGDOUBLE;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE;
-}
-# endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * trio_get_short / trio_set_short [public]
- */
-int
-trio_get_short
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_short
-TRIO_ARGS2((ref, is_short),
-          trio_pointer_t ref,
-          int is_short)
-{
-  if (is_short)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORT;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORT;
-}
-
-/*************************************************************************
- * trio_get_shortshort / trio_set_shortshort [public]
- */
-int
-trio_get_shortshort
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_shortshort
-TRIO_ARGS2((ref, is_shortshort),
-          trio_pointer_t ref,
-          int is_shortshort)
-{
-  if (is_shortshort)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORTSHORT;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT;
-}
-
-/*************************************************************************
- * trio_get_alternative / trio_set_alternative [public]
- */
-int
-trio_get_alternative
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_alternative
-TRIO_ARGS2((ref, is_alternative),
-          trio_pointer_t ref,
-          int is_alternative)
-{
-  if (is_alternative)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_ALTERNATIVE;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE;
-}
-
-/*************************************************************************
- * trio_get_alignment / trio_set_alignment [public]
- */
-int
-trio_get_alignment
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_alignment
-TRIO_ARGS2((ref, is_leftaligned),
-          trio_pointer_t ref,
-          int is_leftaligned)
-{
-  if (is_leftaligned)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LEFTADJUST;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST;
-}
-
-/*************************************************************************
- * trio_get_spacing /trio_set_spacing [public]
- */
-int
-trio_get_spacing
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_spacing
-TRIO_ARGS2((ref, is_space),
-          trio_pointer_t ref,
-          int is_space)
-{
-  if (is_space)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SPACE;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SPACE;
-}
-
-/*************************************************************************
- * trio_get_sign / trio_set_sign [public]
- */
-int
-trio_get_sign
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_sign
-TRIO_ARGS2((ref, is_sign),
-          trio_pointer_t ref,
-          int is_sign)
-{
-  if (is_sign)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHOWSIGN;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN;
-}
-
-/*************************************************************************
- * trio_get_padding / trio_set_padding [public]
- */
-int
-trio_get_padding
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_padding
-TRIO_ARGS2((ref, is_padding),
-          trio_pointer_t ref,
-          int is_padding)
-{
-  if (is_padding)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_NILPADDING;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_NILPADDING;
-}
-
-/*************************************************************************
- * trio_get_quote / trio_set_quote [public]
- */
-# if TRIO_FEATURE_QUOTE
-int
-trio_get_quote
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_quote
-TRIO_ARGS2((ref, is_quote),
-          trio_pointer_t ref,
-          int is_quote)
-{
-  if (is_quote)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUOTE;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUOTE;
-}
-#endif /* TRIO_FEATURE_QUOTE */
-
-/*************************************************************************
- * trio_get_upper / trio_set_upper [public]
- */
-int
-trio_get_upper
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_upper
-TRIO_ARGS2((ref, is_upper),
-          trio_pointer_t ref,
-          int is_upper)
-{
-  if (is_upper)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_UPPER;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_UPPER;
-}
-
-/*************************************************************************
- * trio_get_largest / trio_set_largest [public]
- */
-#if TRIO_FEATURE_INTMAX_T
-int
-trio_get_largest
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_largest
-TRIO_ARGS2((ref, is_largest),
-          trio_pointer_t ref,
-          int is_largest)
-{
-  if (is_largest)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_INTMAX_T;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_INTMAX_T;
-}
-#endif /* TRIO_FEATURE_INTMAX_T */
-
-/*************************************************************************
- * trio_get_ptrdiff / trio_set_ptrdiff [public]
- */
-#if TRIO_FEATURE_PTRDIFF_T
-int
-trio_get_ptrdiff
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_ptrdiff
-TRIO_ARGS2((ref, is_ptrdiff),
-          trio_pointer_t ref,
-          int is_ptrdiff)
-{
-  if (is_ptrdiff)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_PTRDIFF_T;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T;
-}
-#endif /* TRIO_FEATURE_PTRDIFF_T */
-
-/*************************************************************************
- * trio_get_size / trio_set_size [public]
- */
-#if TRIO_FEATURE_SIZE_T
-int
-trio_get_size
-TRIO_ARGS1((ref),
-          trio_pointer_t ref)
-{
-  return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T)
-    ? TRUE
-    : FALSE;
-}
-
-void
-trio_set_size
-TRIO_ARGS2((ref, is_size),
-          trio_pointer_t ref,
-          int is_size)
-{
-  if (is_size)
-    ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SIZE_T;
-  else
-    ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SIZE_T;
-}
-#endif /* TRIO_FEATURE_SIZE_T */
-
-/*************************************************************************
- * trio_print_int [public]
- */
-void
-trio_print_int
-TRIO_ARGS2((ref, number),
-          trio_pointer_t ref,
-          int number)
-{
-  trio_reference_t *self = (trio_reference_t *)ref;
-
-  TrioWriteNumber(self->data,
-                 (trio_uintmax_t)number,
-                 self->parameter->flags,
-                 self->parameter->width,
-                 self->parameter->precision,
-                 self->parameter->base);
-}
-
-/*************************************************************************
- * trio_print_uint [public]
- */
-void
-trio_print_uint
-TRIO_ARGS2((ref, number),
-          trio_pointer_t ref,
-          unsigned int number)
-{
-  trio_reference_t *self = (trio_reference_t *)ref;
-
-  TrioWriteNumber(self->data,
-                 (trio_uintmax_t)number,
-                 self->parameter->flags | FLAGS_UNSIGNED,
-                 self->parameter->width,
-                 self->parameter->precision,
-                 self->parameter->base);
-}
-
-/*************************************************************************
- * trio_print_double [public]
- */
-#if TRIO_FEATURE_FLOAT
-void
-trio_print_double
-TRIO_ARGS2((ref, number),
-          trio_pointer_t ref,
-          double number)
-{
-  trio_reference_t *self = (trio_reference_t *)ref;
-
-  TrioWriteDouble(self->data,
-                 number,
-                 self->parameter->flags,
-                 self->parameter->width,
-                 self->parameter->precision,
-                 self->parameter->base);
-}
-#endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * trio_print_string [public]
- */
-void
-trio_print_string
-TRIO_ARGS2((ref, string),
-          trio_pointer_t ref,
-          TRIO_CONST char *string)
-{
-  trio_reference_t *self = (trio_reference_t *)ref;
-
-  TrioWriteString(self->data,
-                 string,
-                 self->parameter->flags,
-                 self->parameter->width,
-                 self->parameter->precision);
-}
-
-/*************************************************************************
- * trio_print_ref [public]
- */
-int
-trio_print_ref
-TRIO_VARGS3((ref, format, va_alist),
-           trio_pointer_t ref,
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list arglist;
-
-  assert(VALID(format));
-  
-  TRIO_VA_START(arglist, format);
-  status = TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL);
-  TRIO_VA_END(arglist);
-  return status;
-}
-
-/*************************************************************************
- * trio_vprint_ref [public]
- */
-int
-trio_vprint_ref
-TRIO_ARGS3((ref, format, arglist),
-          trio_pointer_t ref,
-          TRIO_CONST char *format,
-          va_list arglist)
-{
-  assert(VALID(format));
-  
-  return TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL);
-}
-
-/*************************************************************************
- * trio_printv_ref [public]
- */
-int
-trio_printv_ref
-TRIO_ARGS3((ref, format, argarray),
-          trio_pointer_t ref,
-          TRIO_CONST char *format,
-          trio_pointer_t *argarray)
-{
-  static va_list unused;
-  
-  assert(VALID(format));
-  
-  return TrioFormatRef((trio_reference_t *)ref, format, unused, argarray);
-}
-
-#endif
-
-/*************************************************************************
- * trio_print_pointer [public]
- */
-void
-trio_print_pointer
-TRIO_ARGS2((ref, pointer),
-          trio_pointer_t ref,
-          trio_pointer_t pointer)
-{
-  trio_reference_t *self = (trio_reference_t *)ref;
-  trio_flags_t flags;
-  trio_uintmax_t number;
-
-  if (NULL == pointer)
-    {
-      TRIO_CONST char *string = internalNullString;
-      while (*string)
-       self->data->OutStream(self->data, *string++);
-    }
-  else
-    {
-      /*
-       * The subtraction of the null pointer is a workaround
-       * to avoid a compiler warning. The performance overhead
-       * is negligible (and likely to be removed by an
-       * optimizing compiler). The (char *) casting is done
-       * to please ANSI C++.
-       */
-      number = (trio_uintmax_t)((char *)pointer - (char *)0);
-      /* Shrink to size of pointer */
-      number &= (trio_uintmax_t)-1;
-      flags = self->parameter->flags;
-      flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE |
-               FLAGS_NILPADDING);
-      TrioWriteNumber(self->data,
-                     number,
-                     flags,
-                     POINTER_WIDTH,
-                     NO_PRECISION,
-                     BASE_HEX);
-    }
-}
-
-/** @} End of UserDefined documentation module */
-
-/*************************************************************************
- *
- * LOCALES
- *
- ************************************************************************/
-
-/*************************************************************************
- * trio_locale_set_decimal_point
- *
- * Decimal point can only be one character. The input argument is a
- * string to enable multibyte characters. At most MB_LEN_MAX characters
- * will be used.
- */
-#if TRIO_FEATURE_LOCALE
-TRIO_PUBLIC void
-trio_locale_set_decimal_point
-TRIO_ARGS1((decimalPoint),
-          char *decimalPoint)
-{
-#if defined(USE_LOCALE)
-  if (NULL == internalLocaleValues)
-    {
-      TrioSetLocale();
-    }
-#endif
-  internalDecimalPointLength = trio_length(decimalPoint);
-  if (internalDecimalPointLength == 1)
-    {
-      internalDecimalPoint = *decimalPoint;
-    }
-  else
-    {
-      internalDecimalPoint = NIL;
-      trio_copy_max(internalDecimalPointString,
-                   sizeof(internalDecimalPointString),
-                   decimalPoint);
-    }
-}
-#endif
-
-/*************************************************************************
- * trio_locale_set_thousand_separator
- *
- * See trio_locale_set_decimal_point
- */
-#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION
-TRIO_PUBLIC void
-trio_locale_set_thousand_separator
-TRIO_ARGS1((thousandSeparator),
-          char *thousandSeparator)
-{
-# if defined(USE_LOCALE)
-  if (NULL == internalLocaleValues)
-    {
-      TrioSetLocale();
-    }
-# endif
-  trio_copy_max(internalThousandSeparator,
-               sizeof(internalThousandSeparator),
-               thousandSeparator);
-  internalThousandSeparatorLength = trio_length(internalThousandSeparator);
-}
-#endif
-
-/*************************************************************************
- * trio_locale_set_grouping
- *
- * Array of bytes. Reversed order.
- *
- *  CHAR_MAX : No further grouping
- *  0        : Repeat last group for the remaining digits (not necessary
- *             as C strings are zero-terminated)
- *  n        : Set current group to n
- *
- * Same order as the grouping attribute in LC_NUMERIC.
- */
-#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION
-TRIO_PUBLIC void
-trio_locale_set_grouping
-TRIO_ARGS1((grouping),
-          char *grouping)
-{
-# if defined(USE_LOCALE)
-  if (NULL == internalLocaleValues)
-    {
-      TrioSetLocale();
-    }
-# endif
-  trio_copy_max(internalGrouping,
-               sizeof(internalGrouping),
-               grouping);
-}
-#endif
-
-
-/*************************************************************************
- *
- * SCANNING
- *
- ************************************************************************/
-
-#if TRIO_FEATURE_SCANF
-
-/*************************************************************************
- * TrioSkipWhitespaces
- */
-TRIO_PRIVATE int
-TrioSkipWhitespaces
-TRIO_ARGS1((self),
-          trio_class_t *self)
-{
-  int ch;
-
-  ch = self->current;
-  while (isspace(ch))
-    {
-      self->InStream(self, &ch);
-    }
-  return ch;
-}
-
-/*************************************************************************
- * TrioGetCollation
- */
-#if TRIO_EXTENSION
-TRIO_PRIVATE void
-TrioGetCollation(TRIO_NOARGS)
-{
-  int i;
-  int j;
-  int k;
-  char first[2];
-  char second[2];
-
-  /* This is computationally expensive */
-  first[1] = NIL;
-  second[1] = NIL;
-  for (i = 0; i < MAX_CHARACTER_CLASS; i++)
-    {
-      k = 0;
-      first[0] = (char)i;
-      for (j = 0; j < MAX_CHARACTER_CLASS; j++)
-       {
-         second[0] = (char)j;
-         if (trio_equal_locale(first, second))
-           internalCollationArray[i][k++] = (char)j;
-       }
-      internalCollationArray[i][k] = NIL;
-    }
-}
-#endif
-
-/*************************************************************************
- * TrioGetCharacterClass
- *
- * FIXME:
- *  multibyte
- */
-TRIO_PRIVATE int
-TrioGetCharacterClass
-TRIO_ARGS4((format, offsetPointer, flagsPointer, characterclass),
-          TRIO_CONST char *format,
-          int *offsetPointer,
-          trio_flags_t *flagsPointer,
-          int *characterclass)
-{
-  int offset = *offsetPointer;
-  int i;
-  char ch;
-  char range_begin;
-  char range_end;
-
-  *flagsPointer &= ~FLAGS_EXCLUDE;
-
-  if (format[offset] == QUALIFIER_CIRCUMFLEX)
-    {
-      *flagsPointer |= FLAGS_EXCLUDE;
-      offset++;
-    }
-  /*
-   * If the ungroup character is at the beginning of the scanlist,
-   * it will be part of the class, and a second ungroup character
-   * must follow to end the group.
-   */
-  if (format[offset] == SPECIFIER_UNGROUP)
-    {
-      characterclass[(int)SPECIFIER_UNGROUP]++;
-      offset++;
-    }
-  /*
-   * Minus is used to specify ranges. To include minus in the class,
-   * it must be at the beginning of the list
-   */
-  if (format[offset] == QUALIFIER_MINUS)
-    {
-      characterclass[(int)QUALIFIER_MINUS]++;
-      offset++;
-    }
-  /* Collect characters */
-  for (ch = format[offset];
-       (ch != SPECIFIER_UNGROUP) && (ch != NIL);
-       ch = format[++offset])
-    {
-      switch (ch)
-       {
-       case QUALIFIER_MINUS: /* Scanlist ranges */
-         
-         /*
-          * Both C99 and UNIX98 describes ranges as implementation-
-          * defined.
-          *
-          * We support the following behaviour (although this may
-          * change as we become wiser)
-          * - only increasing ranges, ie. [a-b] but not [b-a]
-          * - transitive ranges, ie. [a-b-c] == [a-c]
-          * - trailing minus, ie. [a-] is interpreted as an 'a'
-          *   and a '-'
-          * - duplicates (although we can easily convert these
-          *   into errors)
-          */
-         range_begin = format[offset - 1];
-         range_end = format[++offset];
-         if (range_end == SPECIFIER_UNGROUP)
-           {
-             /* Trailing minus is included */
-             characterclass[(int)ch]++;
-             ch = range_end;
-             break; /* for */
-           }
-         if (range_end == NIL)
-           return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-         if (range_begin > range_end)
-           return TRIO_ERROR_RETURN(TRIO_ERANGE, offset);
-           
-         for (i = (int)range_begin; i <= (int)range_end; i++)
-           characterclass[i]++;
-           
-         ch = range_end;
-         break;
-         
-#if TRIO_EXTENSION
-
-       case SPECIFIER_GROUP:
-         
-         switch (format[offset + 1])
-           {
-           case QUALIFIER_DOT: /* Collating symbol */
-             /*
-              * FIXME: This will be easier to implement when multibyte
-              * characters have been implemented. Until now, we ignore
-              * this feature.
-              */
-             for (i = offset + 2; ; i++)
-               {
-                 if (format[i] == NIL)
-                   /* Error in syntax */
-                   return -1;
-                 else if (format[i] == QUALIFIER_DOT)
-                   break; /* for */
-               }
-             if (format[++i] != SPECIFIER_UNGROUP)
-               return -1;
-             
-             offset = i;
-             break;
-         
-           case QUALIFIER_EQUAL: /* Equivalence class expressions */
-             {
-               unsigned int j;
-               unsigned int k;
-           
-               if (internalCollationUnconverted)
-                 {
-                   /* Lazy evaluation of collation array */
-                   TrioGetCollation();
-                   internalCollationUnconverted = FALSE;
-                 }
-               for (i = offset + 2; ; i++)
-                 {
-                   if (format[i] == NIL)
-                     /* Error in syntax */
-                     return -1;
-                   else if (format[i] == QUALIFIER_EQUAL)
-                     break; /* for */
-                   else
-                     {
-                       /* Mark any equivalent character */
-                       k = (unsigned int)format[i];
-                       for (j = 0; internalCollationArray[k][j] != NIL; j++)
-                         characterclass[(int)internalCollationArray[k][j]]++;
-                     }
-                 }
-               if (format[++i] != SPECIFIER_UNGROUP)
-                 return -1;
-               
-               offset = i;
-             }
-             break;
-         
-           case QUALIFIER_COLON: /* Character class expressions */
-         
-             if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1,
-                                &format[offset]))
-               {
-                 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
-                   if (isalnum(i))
-                     characterclass[i]++;
-                 offset += sizeof(CLASS_ALNUM) - 1;
-               }
-             else if (trio_equal_max(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1,
-                                     &format[offset]))
-               {
-                 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
-                   if (isalpha(i))
-                     characterclass[i]++;
-                 offset += sizeof(CLASS_ALPHA) - 1;
-               }
-             else if (trio_equal_max(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1,
-                                     &format[offset]))
-               {
-                 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
-                   if (iscntrl(i))
-                     characterclass[i]++;
-                 offset += sizeof(CLASS_CNTRL) - 1;
-               }
-             else if (trio_equal_max(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1,
-                                     &format[offset]))
-               {
-                 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
-                   if (isdigit(i))
-                     characterclass[i]++;
-                 offset += sizeof(CLASS_DIGIT) - 1;
-               }
-             else if (trio_equal_max(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1,
-                                     &format[offset]))
-               {
-                 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
-                   if (isgraph(i))
-                     characterclass[i]++;
-                 offset += sizeof(CLASS_GRAPH) - 1;
-               }
-             else if (trio_equal_max(CLASS_LOWER, sizeof(CLASS_LOWER) - 1,
-                                     &format[offset]))
-               {
-                 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
-                   if (islower(i))
-                     characterclass[i]++;
-                 offset += sizeof(CLASS_LOWER) - 1;
-               }
-             else if (trio_equal_max(CLASS_PRINT, sizeof(CLASS_PRINT) - 1,
-                                     &format[offset]))
-               {
-                 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
-                   if (isprint(i))
-                     characterclass[i]++;
-                 offset += sizeof(CLASS_PRINT) - 1;
-               }
-             else if (trio_equal_max(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1,
-                                     &format[offset]))
-               {
-                 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
-                   if (ispunct(i))
-                     characterclass[i]++;
-                 offset += sizeof(CLASS_PUNCT) - 1;
-               }
-             else if (trio_equal_max(CLASS_SPACE, sizeof(CLASS_SPACE) - 1,
-                                     &format[offset]))
-               {
-                 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
-                   if (isspace(i))
-                     characterclass[i]++;
-                 offset += sizeof(CLASS_SPACE) - 1;
-               }
-             else if (trio_equal_max(CLASS_UPPER, sizeof(CLASS_UPPER) - 1,
-                                     &format[offset]))
-               {
-                 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
-                   if (isupper(i))
-                     characterclass[i]++;
-                 offset += sizeof(CLASS_UPPER) - 1;
-               }
-             else if (trio_equal_max(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1,
-                                     &format[offset]))
-               {
-                 for (i = 0; i < MAX_CHARACTER_CLASS; i++)
-                   if (isxdigit(i))
-                     characterclass[i]++;
-                 offset += sizeof(CLASS_XDIGIT) - 1;
-               }
-             else
-               {
-                 characterclass[(int)ch]++;
-               }
-             break;
-
-           default:
-             characterclass[(int)ch]++;
-             break;
-           }
-         break;
-         
-#endif /* TRIO_EXTENSION */
-         
-       default:
-         characterclass[(int)ch]++;
-         break;
-       }
-    }
-  return 0;
-}
-
-/*************************************************************************
- * TrioReadNumber
- *
- * We implement our own number conversion in preference of strtol and
- * strtoul, because we must handle 'long long' and thousand separators.
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadNumber
-TRIO_ARGS5((self, target, flags, width, base),
-          trio_class_t *self,
-          trio_uintmax_t *target,
-          trio_flags_t flags,
-          int width,
-          int base)
-{
-  trio_uintmax_t number = 0;
-  int digit;
-  int count;
-  BOOLEAN_T isNegative = FALSE;
-  BOOLEAN_T gotNumber = FALSE;
-  int j;
-
-  assert(VALID(self));
-  assert(VALID(self->InStream));
-  assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE));
-
-  if (internalDigitsUnconverted)
-    {
-      /* Lazy evaluation of digits array */
-      memset(internalDigitArray, -1, sizeof(internalDigitArray));
-      for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++)
-       {
-         internalDigitArray[(int)internalDigitsLower[j]] = j;
-         internalDigitArray[(int)internalDigitsUpper[j]] = j;
-       }
-      internalDigitsUnconverted = FALSE;
-    }
-  
-  TrioSkipWhitespaces(self);
-  
-  /* Leading sign */
-  if (self->current == '+')
-    {
-      self->InStream(self, NULL);
-    }
-  else if (self->current == '-')
-    {
-      self->InStream(self, NULL);
-      isNegative = TRUE;
-    }
-  
-  count = self->processed;
-  
-  if (flags & FLAGS_ALTERNATIVE)
-    {
-      switch (base)
-       {
-       case NO_BASE:
-       case BASE_OCTAL:
-       case BASE_HEX:
-       case BASE_BINARY:
-         if (self->current == '0')
-           {
-             self->InStream(self, NULL);
-             if (self->current)
-               {
-                 if ((base == BASE_HEX) &&
-                     (trio_to_upper(self->current) == 'X'))
-                   {
-                     self->InStream(self, NULL);
-                   }
-                 else if ((base == BASE_BINARY) &&
-                          (trio_to_upper(self->current) == 'B'))
-                   {
-                     self->InStream(self, NULL);
-                   }
-               }
-           }
-         else
-           return FALSE;
-         break;
-       default:
-         break;
-       }
-    }
-
-  while (((width == NO_WIDTH) || (self->processed - count < width)) &&
-        (! ((self->current == EOF) || isspace(self->current))))
-    {
-      if (isascii(self->current))
-       {
-         digit = internalDigitArray[self->current];
-         /* Abort if digit is not allowed in the specified base */
-         if ((digit == -1) || (digit >= base))
-           break;
-       }
-#if TRIO_FEATURE_QUOTE
-      else if (flags & FLAGS_QUOTE)
-       {
-         /* Compare with thousands separator */
-         for (j = 0; internalThousandSeparator[j] && self->current; j++)
-           {
-             if (internalThousandSeparator[j] != self->current)
-               break;
-
-             self->InStream(self, NULL);
-           }
-         if (internalThousandSeparator[j])
-           break; /* Mismatch */
-         else
-           continue; /* Match */
-       }
-#endif
-      else
-       break;
-            
-      number *= base;
-      number += digit;
-      gotNumber = TRUE; /* we need at least one digit */
-
-      self->InStream(self, NULL);
-    }
-
-  /* Was anything read at all? */
-  if (!gotNumber)
-    return FALSE;
-  
-  if (target)
-    *target = (isNegative) ? (trio_uintmax_t)(-((trio_intmax_t)number)) : number;
-  return TRUE;
-}
-
-/*************************************************************************
- * TrioReadChar
- */
-TRIO_PRIVATE int
-TrioReadChar
-TRIO_ARGS4((self, target, flags, width),
-          trio_class_t *self,
-          char *target,
-          trio_flags_t flags,
-          int width)
-{
-  int i;
-  char ch;
-  trio_uintmax_t number;
-  
-  assert(VALID(self));
-  assert(VALID(self->InStream));
-
-  for (i = 0;
-       (self->current != EOF) && (i < width);
-       i++)
-    {
-      ch = (char)self->current;
-      self->InStream(self, NULL);
-      if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH))
-       {
-         switch (self->current)
-           {
-           case '\\': ch = '\\'; break;
-           case 'a': ch = '\007'; break;
-           case 'b': ch = '\b'; break;
-           case 'f': ch = '\f'; break;
-           case 'n': ch = '\n'; break;
-           case 'r': ch = '\r'; break;
-           case 't': ch = '\t'; break;
-           case 'v': ch = '\v'; break;
-           default:
-             if (isdigit(self->current))
-               {
-                 /* Read octal number */
-                 if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL))
-                   return 0;
-                 ch = (char)number;
-               }
-             else if (trio_to_upper(self->current) == 'X')
-               {
-                 /* Read hexadecimal number */
-                 self->InStream(self, NULL);
-                 if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX))
-                   return 0;
-                 ch = (char)number;
-               }
-             else
-               {
-                 ch = (char)self->current;
-               }
-             break;
-           }
-       }
-      
-      if (target)
-       target[i] = ch;
-    }
-  return i + 1;
-}
-
-/*************************************************************************
- * TrioReadString
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadString
-TRIO_ARGS4((self, target, flags, width),
-          trio_class_t *self,
-          char *target,
-          trio_flags_t flags,
-          int width)
-{
-  int i;
-  
-  assert(VALID(self));
-  assert(VALID(self->InStream));
-
-  TrioSkipWhitespaces(self);
-    
-  /*
-   * Continue until end of string is reached, a whitespace is encountered,
-   * or width is exceeded
-   */
-  for (i = 0;
-       ((width == NO_WIDTH) || (i < width)) &&
-       (! ((self->current == EOF) || isspace(self->current)));
-       i++)
-    {
-      if (TrioReadChar(self, (target ? &target[i] : 0), flags, 1) == 0)
-       break; /* for */
-    }
-  if (target)
-    target[i] = NIL;
-  return TRUE;
-}
-
-/*************************************************************************
- * TrioReadWideChar
- */
-#if TRIO_FEATURE_WIDECHAR
-TRIO_PRIVATE int
-TrioReadWideChar
-TRIO_ARGS4((self, target, flags, width),
-          trio_class_t *self,
-          trio_wchar_t *target,
-          trio_flags_t flags,
-          int width)
-{
-  int i;
-  int j;
-  int size;
-  int amount = 0;
-  trio_wchar_t wch;
-  char buffer[MB_LEN_MAX + 1];
-  
-  assert(VALID(self));
-  assert(VALID(self->InStream));
-
-  for (i = 0;
-       (self->current != EOF) && (i < width);
-       i++)
-    {
-      if (isascii(self->current))
-       {
-         if (TrioReadChar(self, buffer, flags, 1) == 0)
-           return 0;
-         buffer[1] = NIL;
-       }
-      else
-       {
-         /*
-          * Collect a multibyte character, by enlarging buffer until
-          * it contains a fully legal multibyte character, or the
-          * buffer is full.
-          */
-         j = 0;
-         do
-           {
-             buffer[j++] = (char)self->current;
-             buffer[j] = NIL;
-             self->InStream(self, NULL);
-           }
-         while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j));
-       }
-      if (target)
-       {
-         size = mbtowc(&wch, buffer, sizeof(buffer));
-         if (size > 0)
-           target[i] = wch;
-       }
-      amount += size;
-      self->InStream(self, NULL);
-    }
-  return amount;
-}
-#endif /* TRIO_FEATURE_WIDECHAR */
-
-/*************************************************************************
- * TrioReadWideString
- */
-#if TRIO_FEATURE_WIDECHAR
-TRIO_PRIVATE BOOLEAN_T
-TrioReadWideString
-TRIO_ARGS4((self, target, flags, width),
-          trio_class_t *self,
-          trio_wchar_t *target,
-          trio_flags_t flags,
-          int width)
-{
-  int i;
-  int size;
-  
-  assert(VALID(self));
-  assert(VALID(self->InStream));
-
-  TrioSkipWhitespaces(self);
-
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
-  /* Required by TrioReadWideChar */
-  (void)mblen(NULL, 0);
-#endif
-  
-  /*
-   * Continue until end of string is reached, a whitespace is encountered,
-   * or width is exceeded
-   */
-  for (i = 0;
-       ((width == NO_WIDTH) || (i < width)) &&
-       (! ((self->current == EOF) || isspace(self->current)));
-       )
-    {
-      size = TrioReadWideChar(self, &target[i], flags, 1);
-      if (size == 0)
-       break; /* for */
-
-      i += size;
-    }
-  if (target)
-    target[i] = WCONST('\0');
-  return TRUE;
-}
-#endif /* TRIO_FEATURE_WIDECHAR */
-
-/*************************************************************************
- * TrioReadGroup
- *
- * Reads non-empty character groups.
- *
- * FIXME: characterclass does not work with multibyte characters
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadGroup
-TRIO_ARGS5((self, target, characterclass, flags, width),
-          trio_class_t *self,
-          char *target,
-          int *characterclass,
-          trio_flags_t flags,
-          int width)
-{
-  int ch;
-  int i;
-  
-  assert(VALID(self));
-  assert(VALID(self->InStream));
-
-  ch = self->current;
-  for (i = 0;
-       ((width == NO_WIDTH) || (i < width)) &&
-       (! ((ch == EOF) ||
-          (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0))));
-       i++)
-    {
-      if (target)
-       target[i] = (char)ch;
-      self->InStream(self, &ch);
-    }
-
-  if (i == 0)
-    return FALSE;
-
-  /* Terminate the string if input saved */
-  if (target)
-    target[i] = NIL;
-  return TRUE;
-}
-
-/*************************************************************************
- * TrioReadDouble
- *
- * FIXME:
- *  add long double
- *  handle base
- */
-#if TRIO_FEATURE_FLOAT
-TRIO_PRIVATE BOOLEAN_T
-TrioReadDouble
-TRIO_ARGS4((self, target, flags, width),
-          trio_class_t *self,
-          trio_pointer_t target,
-          trio_flags_t flags,
-          int width)
-{
-  int ch;
-  char doubleString[512];
-  int offset = 0;
-  int start;
-# if TRIO_FEATURE_QUOTE
-  int j;
-# endif
-  BOOLEAN_T isHex = FALSE;
-  trio_long_double_t infinity;
-
-  doubleString[0] = 0;
-  
-  if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1))
-    width = sizeof(doubleString) - 1;
-  
-  TrioSkipWhitespaces(self);
-  
-  /*
-   * Read entire double number from stream. trio_to_double requires
-   * a string as input, but InStream can be anything, so we have to
-   * collect all characters.
-   */
-  ch = self->current;
-  if ((ch == '+') || (ch == '-'))
-    {
-      doubleString[offset++] = (char)ch;
-      self->InStream(self, &ch);
-      width--;
-    }
-
-  start = offset;
-  switch (ch)
-    {
-    case 'n':
-    case 'N':
-      /* Not-a-number */
-      if (offset != 0)
-       break;
-      /* FALLTHROUGH */
-    case 'i':
-    case 'I':
-      /* Infinity */
-      while (isalpha(ch) && (offset - start < width))
-       {
-         doubleString[offset++] = (char)ch;
-         self->InStream(self, &ch);
-       }
-      doubleString[offset] = NIL;
-
-      /* Case insensitive string comparison */
-      if (trio_equal(&doubleString[start], INFINITE_UPPER) ||
-         trio_equal(&doubleString[start], LONG_INFINITE_UPPER))
-       {
-         infinity = ((start == 1) && (doubleString[0] == '-'))
-           ? trio_ninf()
-           : trio_pinf();
-         if (flags & FLAGS_LONGDOUBLE)
-           {
-             *((trio_long_double_t *)target) = infinity;
-           }
-         else if (flags & FLAGS_LONG)
-           {
-             *((double *)target) = infinity;
-           }
-         else
-           {
-             *((float *)target) = infinity;
-           }
-         return TRUE;
-       }
-      if (trio_equal(doubleString, NAN_UPPER))
-       {
-         /* NaN must not have a preceeding + nor - */
-         if (flags & FLAGS_LONGDOUBLE)
-           {
-             *((trio_long_double_t *)target) = trio_nan();
-           }
-         else if (flags & FLAGS_LONG)
-           {
-             *((double *)target) = trio_nan();
-           }
-         else
-           {
-             *((float *)target) = trio_nan();
-           }
-         return TRUE;
-       }
-      return FALSE;
-
-    case '0':
-      doubleString[offset++] = (char)ch;
-      self->InStream(self, &ch);
-      if (trio_to_upper(ch) == 'X')
-       {
-         isHex = TRUE;
-         doubleString[offset++] = (char)ch;
-         self->InStream(self, &ch);
-       }
-      break;
-      
-    default:
-      break;
-    }
-  
-  while ((ch != EOF) && (offset - start < width))
-    {
-      /* Integer part */
-      if (isHex ? isxdigit(ch) : isdigit(ch))
-       {
-         doubleString[offset++] = (char)ch;
-         self->InStream(self, &ch);
-       }
-# if TRIO_FEATURE_QUOTE
-      else if (flags & FLAGS_QUOTE)
-       {
-         /* Compare with thousands separator */
-         for (j = 0; internalThousandSeparator[j] && self->current; j++)
-           {
-             if (internalThousandSeparator[j] != self->current)
-               break;
-
-             self->InStream(self, &ch);
-           }
-         if (internalThousandSeparator[j])
-           break; /* Mismatch */
-         else
-           continue; /* Match */
-       }
-# endif
-      else
-       break; /* while */
-    }
-  if (ch == '.')
-    {
-      /* Decimal part */
-      doubleString[offset++] = (char)ch;
-      self->InStream(self, &ch);
-      while ((isHex ? isxdigit(ch) : isdigit(ch)) &&
-            (offset - start < width))
-       {
-         doubleString[offset++] = (char)ch;
-         self->InStream(self, &ch);
-       }
-    }
-  if (isHex ? (trio_to_upper(ch) == 'P') : (trio_to_upper(ch) == 'E'))
-    {
-      /* Exponent */
-      doubleString[offset++] = (char)ch;
-      self->InStream(self, &ch);
-      if ((ch == '+') || (ch == '-'))
-       {
-         doubleString[offset++] = (char)ch;
-         self->InStream(self, &ch);
-       }
-      while (isdigit(ch) && (offset - start < width))
-       {
-         doubleString[offset++] = (char)ch;
-         self->InStream(self, &ch);
-       }
-    }
-
-  if ((offset == start) || (*doubleString == NIL))
-    return FALSE;
-
-  doubleString[offset] = 0;
-  
-  if (flags & FLAGS_LONGDOUBLE)
-    {
-      *((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL);
-    }
-  else if (flags & FLAGS_LONG)
-    {
-      *((double *)target) = trio_to_double(doubleString, NULL);
-    }
-  else
-    {
-      *((float *)target) = trio_to_float(doubleString, NULL);
-    }
-  return TRUE;
-}
-#endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * TrioReadPointer
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadPointer
-TRIO_ARGS3((self, target, flags),
-          trio_class_t *self,
-          trio_pointer_t *target,
-          trio_flags_t flags)
-{
-  trio_uintmax_t number;
-  char buffer[sizeof(internalNullString)];
-
-  flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING);
-  
-  if (TrioReadNumber(self,
-                    &number,
-                    flags,
-                    POINTER_WIDTH,
-                    BASE_HEX))
-    {
-      if (target)
-       {
-#if defined(TRIO_COMPILER_GCC) || defined(TRIO_COMPILER_MIPSPRO)
-         /*
-          * The strange assignment of number is a workaround for a compiler
-          * warning
-          */
-         *target = &((char *)0)[number];
-#else
-         *target = (trio_pointer_t)number;
-#endif
-       }
-      return TRUE;
-    }
-  else if (TrioReadString(self,
-                         (flags & FLAGS_IGNORE)
-                         ? NULL
-                         : buffer,
-                         0,
-                         sizeof(internalNullString) - 1))
-    {
-      if (trio_equal_case(buffer, internalNullString))
-       {
-         if (target)
-           *target = NULL;
-         return TRUE;
-       }
-    }
-  return FALSE;
-}
-
-/*************************************************************************
- * TrioScanProcess
- */
-TRIO_PRIVATE int
-TrioScanProcess
-TRIO_ARGS3((data, format, parameters),
-          trio_class_t *data,
-          TRIO_CONST char *format,
-          trio_parameter_t *parameters)
-{
-  int status;
-  int assignment;
-  int ch;
-  int offset; /* Offset of format string */
-  int i; /* Offset of current parameter */
-  trio_flags_t flags;
-  int width;
-  int base;
-  trio_pointer_t pointer;
-
-  /* Return on empty format string */
-  if (format[0] == NIL)
-    return 0;
-
-  status = 0;
-  assignment = 0;
-  i = 0;
-  offset = 0;
-  data->InStream(data, &ch);
-
-  for (;;)
-    {
-      /* Skip the parameter entries */
-      while (parameters[i].type == FORMAT_PARAMETER)
-       {
-         assert(i <= MAX_PARAMETERS);
-         i++;
-       }
-
-      /* Compare non conversion-specifier part of format string */
-      while (offset < parameters[i].beginOffset)
-       {
-         if ((CHAR_IDENTIFIER == format[offset]) &&
-             (CHAR_IDENTIFIER == format[offset + 1]))
-           {
-             /* Two % in format matches one % in input stream */
-             if (CHAR_IDENTIFIER == ch)
-               {
-                 data->InStream(data, &ch);
-                 offset += 2;
-                 continue; /* while format chars left */
-               }
-             else
-               {
-                 status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-                 goto end;
-               }
-           }
-         else /* Not an % identifier */
-           {
-             if (isspace((int)format[offset]))
-               {
-                 /* Whitespaces may match any amount of whitespaces */
-                 ch = TrioSkipWhitespaces(data);
-               }
-             else if (ch == format[offset])
-               {
-                 data->InStream(data, &ch);
-               }
-             else
-               {
-                 status = assignment;
-                 goto end;
-               }
-
-             offset++;
-           }
-       }
-
-      if (parameters[i].type == FORMAT_SENTINEL)
-       break;
-
-      if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT))
-       {
-         status = (assignment > 0) ? assignment : EOF;
-         goto end;
-       }
-
-      flags = parameters[i].flags;
-
-      /* Find width */
-      width = parameters[i].width;
-      if (flags & FLAGS_WIDTH_PARAMETER)
-       {
-         /* Get width from parameter list */
-         width = (int)parameters[width].data.number.as_signed;
-       }
-
-      /* Find base */
-      if (NO_BASE != parameters[i].baseSpecifier)
-       {
-         /* Base from specifier has priority */
-         base = parameters[i].baseSpecifier;
-       }
-      else if (flags & FLAGS_BASE_PARAMETER)
-       {
-         /* Get base from parameter list */
-         base = parameters[i].base;
-         base = (int)parameters[base].data.number.as_signed;
-       }
-      else
-       {
-         /* Use base from format string */
-         base = parameters[i].base;
-       }
-
-      switch (parameters[i].type)
-       {
-       case FORMAT_INT:
-         {
-           trio_uintmax_t number;
-
-           if (0 == base)
-             base = BASE_DECIMAL;
-
-           if (!TrioReadNumber(data,
-                               &number,
-                               flags,
-                               width,
-                               base))
-             {
-               status = assignment;
-               goto end;
-             }
-
-           if (!(flags & FLAGS_IGNORE))
-             {
-               assignment++;
-
-               pointer = parameters[i].data.pointer;
-#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
-               if (flags & FLAGS_SIZE_T)
-                 *(size_t *)pointer = (size_t)number;
-               else
-#endif
-#if TRIO_FEATURE_PTRDIFF_T
-               if (flags & FLAGS_PTRDIFF_T)
-                 *(ptrdiff_t *)pointer = (ptrdiff_t)number;
-               else
-#endif
-#if TRIO_FEATURE_INTMAX_T
-               if (flags & FLAGS_INTMAX_T)
-                 *(trio_intmax_t *)pointer = (trio_intmax_t)number;
-               else
-#endif
-               if (flags & FLAGS_QUAD)
-                 *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number;
-               else if (flags & FLAGS_LONG)
-                 *(long int *)pointer = (long int)number;
-               else if (flags & FLAGS_SHORT)
-                 *(short int *)pointer = (short int)number;
-               else
-                 *(int *)pointer = (int)number;
-             }
-         }
-         break; /* FORMAT_INT */
-
-       case FORMAT_STRING:
-#if TRIO_FEATURE_WIDECHAR
-         if (flags & FLAGS_WIDECHAR)
-           {
-             if (!TrioReadWideString(data,
-                                     (flags & FLAGS_IGNORE)
-                                     ? NULL
-                                     : parameters[i].data.wstring,
-                                     flags,
-                                     width))
-               {
-                 status = assignment;
-                 goto end;
-               }
-           }
-         else
-#endif
-           {
-             if (!TrioReadString(data,
-                                 (flags & FLAGS_IGNORE)
-                                 ? NULL
-                                 : parameters[i].data.string,
-                                 flags,
-                                 width))
-               {
-                 status = assignment;
-                 goto end;
-               }
-           }
-         if (!(flags & FLAGS_IGNORE))
-           assignment++;
-         break; /* FORMAT_STRING */
-
-#if TRIO_FEATURE_FLOAT
-       case FORMAT_DOUBLE:
-         {
-           if (flags & FLAGS_IGNORE)
-             {
-               pointer = NULL;
-             }
-           else
-             {
-               pointer = (flags & FLAGS_LONGDOUBLE)
-                 ? (trio_pointer_t)parameters[i].data.longdoublePointer
-                 : (trio_pointer_t)parameters[i].data.doublePointer;
-             }
-           if (!TrioReadDouble(data, pointer, flags, width))
-             {
-               status = assignment;
-               goto end;
-             }
-           if (!(flags & FLAGS_IGNORE))
-             {
-               assignment++;
-             }
-           break; /* FORMAT_DOUBLE */
-         }
-#endif
-
-       case FORMAT_GROUP:
-         {
-           int characterclass[MAX_CHARACTER_CLASS + 1];
-
-           /* Skip over modifiers */
-           while (format[offset] != SPECIFIER_GROUP)
-             {
-               offset++;
-             }
-           /* Skip over group specifier */
-           offset++;
-
-           memset(characterclass, 0, sizeof(characterclass));
-           status = TrioGetCharacterClass(format,
-                                          &offset,
-                                          &flags,
-                                          characterclass);
-           if (status < 0)
-             goto end;
-
-           if (!TrioReadGroup(data,
-                              (flags & FLAGS_IGNORE)
-                              ? NULL
-                              : parameters[i].data.string,
-                              characterclass,
-                              flags,
-                              parameters[i].width))
-             {
-               status = assignment;
-               goto end;
-             }
-           if (!(flags & FLAGS_IGNORE))
-             assignment++;
-         }
-         break; /* FORMAT_GROUP */
-
-       case FORMAT_COUNT:
-         pointer = parameters[i].data.pointer;
-         if (NULL != pointer)
-           {
-             int count = data->processed;
-             if (ch != EOF)
-               count--; /* a character is read, but is not consumed yet */
-#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
-             if (flags & FLAGS_SIZE_T)
-               *(size_t *)pointer = (size_t)count;
-             else
-#endif
-#if TRIO_FEATURE_PTRDIFF_T
-             if (flags & FLAGS_PTRDIFF_T)
-               *(ptrdiff_t *)pointer = (ptrdiff_t)count;
-             else
-#endif
-#if TRIO_FEATURE_INTMAX_T
-             if (flags & FLAGS_INTMAX_T)
-               *(trio_intmax_t *)pointer = (trio_intmax_t)count;
-             else
-#endif
-             if (flags & FLAGS_QUAD)
-               {
-                 *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count;
-               }
-             else if (flags & FLAGS_LONG)
-               {
-                 *(long int *)pointer = (long int)count;
-               }
-             else if (flags & FLAGS_SHORT)
-               {
-                 *(short int *)pointer = (short int)count;
-               }
-             else
-               {
-                 *(int *)pointer = (int)count;
-               }
-           }
-         break; /* FORMAT_COUNT */
-
-       case FORMAT_CHAR:
-#if TRIO_FEATURE_WIDECHAR
-         if (flags & FLAGS_WIDECHAR)
-           {
-             if (TrioReadWideChar(data,
-                                  (flags & FLAGS_IGNORE)
-                                  ? NULL
-                                  : parameters[i].data.wstring,
-                                  flags,
-                                  (width == NO_WIDTH) ? 1 : width) == 0)
-               {
-                 status = assignment;
-                 goto end;
-               }
-           }
-         else
-#endif
-           {
-             if (TrioReadChar(data,
-                              (flags & FLAGS_IGNORE)
-                              ? NULL
-                              : parameters[i].data.string,
-                              flags,
-                              (width == NO_WIDTH) ? 1 : width) == 0)
-               {
-                 status = assignment;
-                 goto end;
-               }
-           }
-         if (!(flags & FLAGS_IGNORE))
-           assignment++;
-         break; /* FORMAT_CHAR */
-
-       case FORMAT_POINTER:
-         if (!TrioReadPointer(data,
-                              (flags & FLAGS_IGNORE)
-                              ? NULL
-                              : (trio_pointer_t *)parameters[i].data.pointer,
-                              flags))
-           {
-             status = assignment;
-             goto end;
-           }
-         if (!(flags & FLAGS_IGNORE))
-           assignment++;
-         break; /* FORMAT_POINTER */
-
-       case FORMAT_PARAMETER:
-         break; /* FORMAT_PARAMETER */
-
-       default:
-         status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-         goto end;
-       }
-
-      ch = data->current;
-      offset = parameters[i].endOffset;
-      i++;
-    }
-
-  status = assignment;
- end:
-  if (data->UndoStream)
-    data->UndoStream(data);
-  return status;
-}
-
-/*************************************************************************
- * TrioScan
- */
-TRIO_PRIVATE int
-TrioScan
-TRIO_ARGS7((source, sourceSize, InStream, UndoStream, format, arglist, argarray),
-          trio_pointer_t source,
-          size_t sourceSize,
-          void (*InStream) TRIO_PROTO((trio_class_t *, int *)),
-          void (*UndoStream) TRIO_PROTO((trio_class_t *)),
-          TRIO_CONST char *format,
-          va_list arglist,
-          trio_pointer_t *argarray)
-{
-  int status;
-  trio_parameter_t parameters[MAX_PARAMETERS];
-  trio_class_t data;
-
-  assert(VALID(InStream));
-  assert(VALID(format));
-
-  memset(&data, 0, sizeof(data));
-  data.InStream = InStream;
-  data.UndoStream = UndoStream;
-  data.location = (trio_pointer_t)source;
-  data.max = sourceSize;
-  data.error = 0;
-
-#if defined(USE_LOCALE)
-  if (NULL == internalLocaleValues)
-    {
-      TrioSetLocale();
-    }
-#endif
-
-  status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray);
-  if (status < 0)
-    return status;
-
-  status = TrioScanProcess(&data, format, parameters);
-  if (data.error != 0)
-    {
-      status = data.error;
-    }
-  return status;
-}
-
-/*************************************************************************
- * TrioInStreamFile
- */
-#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO
-TRIO_PRIVATE void
-TrioInStreamFile
-TRIO_ARGS2((self, intPointer),
-          trio_class_t *self,
-          int *intPointer)
-{
-  FILE *file = (FILE *)self->location;
-
-  assert(VALID(self));
-  assert(VALID(file));
-
-  self->actually.cached = 0;
-
-  /* The initial value of self->current is zero */
-  if (self->current == EOF)
-    {
-      self->error = (ferror(file))
-       ? TRIO_ERROR_RETURN(TRIO_ERRNO, 0)
-       : TRIO_ERROR_RETURN(TRIO_EOF, 0);
-    }
-  else
-    {
-      self->processed++;
-      self->actually.cached++;
-    }
-
-  self->current = fgetc(file);
-
-  if (VALID(intPointer))
-    {
-      *intPointer = self->current;
-    }
-}
-#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */
-
-/*************************************************************************
- * TrioUndoStreamFile
- */
-#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO
-TRIO_PRIVATE void
-TrioUndoStreamFile
-TRIO_ARGS1((self),
-          trio_class_t *self)
-{
-  FILE *file = (FILE *)self->location;
-
-  assert(VALID(self));
-  assert(VALID(file));
-
-  if (self->actually.cached > 0)
-    {
-      assert(self->actually.cached == 1);
-
-      self->current = ungetc(self->current, file);
-      self->actually.cached = 0;
-    }
-}
-#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */
-
-/*************************************************************************
- * TrioInStreamFileDescriptor
- */
-#if TRIO_FEATURE_FD
-TRIO_PRIVATE void
-TrioInStreamFileDescriptor
-TRIO_ARGS2((self, intPointer),
-          trio_class_t *self,
-          int *intPointer)
-{
-  int fd = *((int *)self->location);
-  int size;
-  unsigned char input;
-
-  assert(VALID(self));
-
-  self->actually.cached = 0;
-
-  size = read(fd, &input, sizeof(char));
-  if (size == -1)
-    {
-      self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);
-      self->current = EOF;
-    }
-  else
-    {
-      self->current = (size == 0) ? EOF : input;
-    }
-  if (self->current != EOF)
-    {
-      self->actually.cached++;
-      self->processed++;
-    }
-
-  if (VALID(intPointer))
-    {
-      *intPointer = self->current;
-    }
-}
-#endif /* TRIO_FEATURE_FD */
-
-/*************************************************************************
- * TrioInStreamCustom
- */
-#if TRIO_FEATURE_CLOSURE
-TRIO_PRIVATE void
-TrioInStreamCustom
-TRIO_ARGS2((self, intPointer),
-          trio_class_t *self,
-          int *intPointer)
-{
-  trio_custom_t *data;
-
-  assert(VALID(self));
-  assert(VALID(self->location));
-
-  self->actually.cached = 0;
-
-  data = (trio_custom_t *)self->location;
-
-  self->current = (data->stream.in == NULL)
-    ? NIL
-    : (data->stream.in)(data->closure);
-
-  if (self->current == NIL)
-    {
-      self->current = EOF;
-    }
-  else
-    {
-      self->processed++;
-      self->actually.cached++;
-    }
-
-  if (VALID(intPointer))
-    {
-      *intPointer = self->current;
-    }
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-/*************************************************************************
- * TrioInStreamString
- */
-TRIO_PRIVATE void
-TrioInStreamString
-TRIO_ARGS2((self, intPointer),
-          trio_class_t *self,
-          int *intPointer)
-{
-  unsigned char **buffer;
-
-  assert(VALID(self));
-  assert(VALID(self->location));
-
-  self->actually.cached = 0;
-
-  buffer = (unsigned char **)self->location;
-  self->current = (*buffer)[0];
-  if (self->current == NIL)
-    {
-      self->current = EOF;
-    }
-  else
-    {
-      (*buffer)++;
-      self->processed++;
-      self->actually.cached++;
-    }
-
-  if (VALID(intPointer))
-    {
-      *intPointer = self->current;
-    }
-}
-
-/*************************************************************************
- *
- * Formatted scanning functions
- *
- ************************************************************************/
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_scanf.h"
-#endif
-/** @addtogroup Scanf
-    @{
-*/
-
-/*************************************************************************
- * scanf
- */
-
-/**
-   Scan characters from standard input stream.
-
-   @param format Formatting string.
-   @param ... Arguments.
-   @return Number of scanned characters.
- */
-#if TRIO_FEATURE_STDIO
-TRIO_PUBLIC int
-trio_scanf
-TRIO_VARGS2((format, va_alist),
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list args;
-
-  assert(VALID(format));
-  
-  TRIO_VA_START(args, format);
-  status = TrioScan((trio_pointer_t)stdin, 0,
-                   TrioInStreamFile,
-                   TrioUndoStreamFile,
-                   format, args, NULL);
-  TRIO_VA_END(args);
-  return status;
-}
-#endif /* TRIO_FEATURE_STDIO */
-
-/**
-   Scan characters from standard input stream.
-
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of scanned characters.
- */
-#if TRIO_FEATURE_STDIO
-TRIO_PUBLIC int
-trio_vscanf
-TRIO_ARGS2((format, args),
-          TRIO_CONST char *format,
-          va_list args)
-{
-  assert(VALID(format));
-  
-  return TrioScan((trio_pointer_t)stdin, 0,
-                 TrioInStreamFile,
-                 TrioUndoStreamFile,
-                 format, args, NULL);
-}
-#endif /* TRIO_FEATURE_STDIO */
-
-/**
-   Scan characters from standard input stream.
-
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of scanned characters.
- */
-#if TRIO_FEATURE_STDIO
-TRIO_PUBLIC int
-trio_scanfv
-TRIO_ARGS2((format, args),
-          TRIO_CONST char *format,
-          trio_pointer_t *args)
-{
-  static va_list unused;
-  
-  assert(VALID(format));
-  
-  return TrioScan((trio_pointer_t)stdin, 0,
-                 TrioInStreamFile,
-                 TrioUndoStreamFile,
-                 format, unused, args);
-}
-#endif /* TRIO_FEATURE_STDIO */
-
-/*************************************************************************
- * fscanf
- */
-
-/**
-   Scan characters from file.
-
-   @param file File pointer.
-   @param format Formatting string.
-   @param ... Arguments.
-   @return Number of scanned characters.
- */
-#if TRIO_FEATURE_FILE
-TRIO_PUBLIC int
-trio_fscanf
-TRIO_VARGS3((file, format, va_alist),
-           FILE *file,
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list args;
-
-  assert(VALID(file));
-  assert(VALID(format));
-  
-  TRIO_VA_START(args, format);
-  status = TrioScan((trio_pointer_t)file, 0,
-                   TrioInStreamFile,
-                   TrioUndoStreamFile,
-                   format, args, NULL);
-  TRIO_VA_END(args);
-  return status;
-}
-#endif /* TRIO_FEATURE_FILE */
-
-/**
-   Scan characters from file.
-
-   @param file File pointer.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of scanned characters.
- */
-#if TRIO_FEATURE_FILE
-TRIO_PUBLIC int
-trio_vfscanf
-TRIO_ARGS3((file, format, args),
-          FILE *file,
-          TRIO_CONST char *format,
-          va_list args)
-{
-  assert(VALID(file));
-  assert(VALID(format));
-  
-  return TrioScan((trio_pointer_t)file, 0,
-                 TrioInStreamFile,
-                 TrioUndoStreamFile,
-                 format, args, NULL);
-}
-#endif /* TRIO_FEATURE_FILE */
-
-/**
-   Scan characters from file.
-
-   @param file File pointer.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of scanned characters.
- */
-#if TRIO_FEATURE_FILE
-TRIO_PUBLIC int
-trio_fscanfv
-TRIO_ARGS3((file, format, args),
-          FILE *file,
-          TRIO_CONST char *format,
-          trio_pointer_t *args)
-{
-  static va_list unused;
-  
-  assert(VALID(file));
-  assert(VALID(format));
-  
-  return TrioScan((trio_pointer_t)file, 0,
-                 TrioInStreamFile,
-                 TrioUndoStreamFile,
-                 format, unused, args);
-}
-#endif /* TRIO_FEATURE_FILE */
-
-/*************************************************************************
- * dscanf
- */
-
-/**
-   Scan characters from file descriptor.
-
-   @param fd File descriptor.
-   @param format Formatting string.
-   @param ... Arguments.
-   @return Number of scanned characters.
- */
-#if TRIO_FEATURE_FD
-TRIO_PUBLIC int
-trio_dscanf
-TRIO_VARGS3((fd, format, va_alist),
-           int fd,
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list args;
-
-  assert(VALID(format));
-  
-  TRIO_VA_START(args, format);
-  status = TrioScan((trio_pointer_t)&fd, 0,
-                   TrioInStreamFileDescriptor,
-                   NULL,
-                   format, args, NULL);
-  TRIO_VA_END(args);
-  return status;
-}
-#endif /* TRIO_FEATURE_FD */
-
-/**
-   Scan characters from file descriptor.
-
-   @param fd File descriptor.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of scanned characters.
- */
-#if TRIO_FEATURE_FD
-TRIO_PUBLIC int
-trio_vdscanf
-TRIO_ARGS3((fd, format, args),
-          int fd,
-          TRIO_CONST char *format,
-          va_list args)
-{
-  assert(VALID(format));
-  
-  return TrioScan((trio_pointer_t)&fd, 0,
-                 TrioInStreamFileDescriptor,
-                 NULL,
-                 format, args, NULL);
-}
-#endif /* TRIO_FEATURE_FD */
-
-/**
-   Scan characters from file descriptor.
-
-   @param fd File descriptor.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of scanned characters.
- */
-#if TRIO_FEATURE_FD
-TRIO_PUBLIC int
-trio_dscanfv
-TRIO_ARGS3((fd, format, args),
-          int fd,
-          TRIO_CONST char *format,
-          trio_pointer_t *args)
-{
-  static va_list unused;
-  
-  assert(VALID(format));
-  
-  return TrioScan((trio_pointer_t)&fd, 0,
-                 TrioInStreamFileDescriptor,
-                 NULL,
-                 format, unused, args);
-}
-#endif /* TRIO_FEATURE_FD */
-
-/*************************************************************************
- * cscanf
- */
-#if TRIO_FEATURE_CLOSURE
-TRIO_PUBLIC int
-trio_cscanf
-TRIO_VARGS4((stream, closure, format, va_alist),
-           trio_instream_t stream,
-           trio_pointer_t closure,
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list args;
-  trio_custom_t data;
-
-  assert(VALID(stream));
-  assert(VALID(format));
-  
-  TRIO_VA_START(args, format);
-  data.stream.in = stream;
-  data.closure = closure;
-  status = TrioScan(&data, 0, TrioInStreamCustom, NULL, format, args, NULL);
-  TRIO_VA_END(args);
-  return status;
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-#if TRIO_FEATURE_CLOSURE
-TRIO_PUBLIC int
-trio_vcscanf
-TRIO_ARGS4((stream, closure, format, args),
-          trio_instream_t stream,
-          trio_pointer_t closure,
-          TRIO_CONST char *format,
-          va_list args)
-{
-  trio_custom_t data;
-  
-  assert(VALID(stream));
-  assert(VALID(format));
-
-  data.stream.in = stream;
-  data.closure = closure;
-  return TrioScan(&data, 0, TrioInStreamCustom, NULL, format, args, NULL);
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-#if TRIO_FEATURE_CLOSURE
-TRIO_PUBLIC int
-trio_cscanfv
-TRIO_ARGS4((stream, closure, format, args),
-          trio_instream_t stream,
-          trio_pointer_t closure,
-          TRIO_CONST char *format,
-          trio_pointer_t *args)
-{
-  static va_list unused;
-  trio_custom_t data;
-  
-  assert(VALID(stream));
-  assert(VALID(format));
-
-  data.stream.in = stream;
-  data.closure = closure;
-  return TrioScan(&data, 0, TrioInStreamCustom, NULL, format, unused, args);
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-/*************************************************************************
- * sscanf
- */
-
-/**
-   Scan characters from string.
-
-   @param buffer Input string.
-   @param format Formatting string.
-   @param ... Arguments.
-   @return Number of scanned characters.
- */
-TRIO_PUBLIC int
-trio_sscanf
-TRIO_VARGS3((buffer, format, va_alist),
-           TRIO_CONST char *buffer,
-           TRIO_CONST char *format,
-           TRIO_VA_DECL)
-{
-  int status;
-  va_list args;
-
-  assert(VALID(buffer));
-  assert(VALID(format));
-  
-  TRIO_VA_START(args, format);
-  status = TrioScan((trio_pointer_t)&buffer, 0,
-                   TrioInStreamString,
-                   NULL,
-                   format, args, NULL);
-  TRIO_VA_END(args);
-  return status;
-}
-
-/**
-   Scan characters from string.
-
-   @param buffer Input string.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of scanned characters.
- */
-TRIO_PUBLIC int
-trio_vsscanf
-TRIO_ARGS3((buffer, format, args),
-          TRIO_CONST char *buffer,
-          TRIO_CONST char *format,
-          va_list args)
-{
-  assert(VALID(buffer));
-  assert(VALID(format));
-  
-  return TrioScan((trio_pointer_t)&buffer, 0,
-                 TrioInStreamString,
-                 NULL,
-                 format, args, NULL);
-}
-
-/**
-   Scan characters from string.
-
-   @param buffer Input string.
-   @param format Formatting string.
-   @param args Arguments.
-   @return Number of scanned characters.
- */
-TRIO_PUBLIC int
-trio_sscanfv
-TRIO_ARGS3((buffer, format, args),
-          TRIO_CONST char *buffer,
-          TRIO_CONST char *format,
-          trio_pointer_t *args)
-{
-  static va_list unused;
-  
-  assert(VALID(buffer));
-  assert(VALID(format));
-  
-  return TrioScan((trio_pointer_t)&buffer, 0,
-                 TrioInStreamString,
-                 NULL,
-                 format, unused, args);
-}
-
-#endif /* TRIO_FEATURE_SCANF */
-
-/** @} End of Scanf documentation module */
-
-/*************************************************************************
- * trio_strerror
- */
-TRIO_PUBLIC TRIO_CONST char *
-trio_strerror
-TRIO_ARGS1((errorcode),
-          int errorcode)
-{
-#if TRIO_FEATURE_STRERR
-  /* Textual versions of the error codes */
-  switch (TRIO_ERROR_CODE(errorcode))
-    {
-    case TRIO_EOF:
-      return "End of file";
-    case TRIO_EINVAL:
-      return "Invalid argument";
-    case TRIO_ETOOMANY:
-      return "Too many arguments";
-    case TRIO_EDBLREF:
-      return "Double reference";
-    case TRIO_EGAP:
-      return "Reference gap";
-    case TRIO_ENOMEM:
-      return "Out of memory";
-    case TRIO_ERANGE:
-      return "Invalid range";
-    case TRIO_ECUSTOM:
-      return "Custom error";
-    default:
-      return "Unknown";
-    }
-#else
-  return "Unknown";
-#endif
-}
diff --git a/trio/trio.h b/trio/trio.h
deleted file mode 100644 (file)
index f7cac34..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/*************************************************************************
- *
- * $Id: trio.h,v 1.19 2009/09/13 10:12:22 breese Exp $
- *
- * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- *************************************************************************
- *
- * http://ctrio.sourceforge.net/
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIO_H
-#define TRIO_TRIO_H
-
-#if !defined(WITHOUT_TRIO)
-
-#if WANT_FETCHMAIL_CONFIG_H_FOR_TRIO - 0
-/* if used as part of fetchmail, do not include config.h, as that would break
- * the regression test. */
-
-/*
- * Use autoconf defines if present. Packages using trio must define
- * HAVE_CONFIG_H as a compiler option themselves.
- */
-#if defined(HAVE_CONFIG_H)
-# include <config.h>
-#endif
-#endif
-
-#include "triop.h"
-
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Error codes.
- *
- * Remember to add a textual description to trio_strerror.
- */
-enum {
-  TRIO_EOF      = 1,
-  TRIO_EINVAL   = 2,
-  TRIO_ETOOMANY = 3,
-  TRIO_EDBLREF  = 4,
-  TRIO_EGAP     = 5,
-  TRIO_ENOMEM   = 6,
-  TRIO_ERANGE   = 7,
-  TRIO_ERRNO    = 8,
-  TRIO_ECUSTOM  = 9
-};
-
-/* Error macros */
-#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF)
-#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8)
-#define TRIO_ERROR_NAME(x) trio_strerror(x)
-
-typedef int (*trio_outstream_t) TRIO_PROTO((trio_pointer_t, int));
-typedef int (*trio_instream_t) TRIO_PROTO((trio_pointer_t));
-
-TRIO_CONST char *trio_strerror TRIO_PROTO((int));
-
-/*************************************************************************
- * Print Functions
- */
-
-int trio_printf TRIO_PROTO((TRIO_CONST char *format, ...));
-int trio_vprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-int trio_printfv TRIO_PROTO((TRIO_CONST char *format, void **args));
-
-int trio_fprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
-int trio_vfprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
-int trio_fprintfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
-
-int trio_dprintf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
-int trio_vdprintf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
-int trio_dprintfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
-
-int trio_cprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
-                            TRIO_CONST char *format, ...));
-int trio_vcprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
-                             TRIO_CONST char *format, va_list args));
-int trio_cprintfv TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
-                             TRIO_CONST char *format, void **args));
-
-int trio_sprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, ...));
-int trio_vsprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, va_list args));
-int trio_sprintfv TRIO_PROTO((char *buffer, TRIO_CONST char *format, void **args));
-
-int trio_snprintf TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
-int trio_vsnprintf TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
-                  va_list args));
-int trio_snprintfv TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
-                  void **args));
-
-int trio_snprintfcat TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
-int trio_vsnprintfcat TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
-                      va_list args));
-
-#if defined(TRIO_DEPRECATED)
-char *trio_aprintf TRIO_PROTO((TRIO_CONST char *format, ...));
-char *trio_vaprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-#endif
-
-int trio_asprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, ...));
-int trio_vasprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, va_list args));
-int trio_asprintfv TRIO_PROTO((char **result, TRIO_CONST char *format, trio_pointer_t * args));
-
-/*************************************************************************
- * Scan Functions
- */
-int trio_scanf TRIO_PROTO((TRIO_CONST char *format, ...));
-int trio_vscanf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-int trio_scanfv TRIO_PROTO((TRIO_CONST char *format, void **args));
-
-int trio_fscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
-int trio_vfscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
-int trio_fscanfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
-
-int trio_dscanf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
-int trio_vdscanf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
-int trio_dscanfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
-
-int trio_cscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
-                           TRIO_CONST char *format, ...));
-int trio_vcscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
-                            TRIO_CONST char *format, va_list args));
-int trio_cscanfv TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
-                            TRIO_CONST char *format, void **args));
-
-int trio_sscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, ...));
-int trio_vsscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, va_list args));
-int trio_sscanfv TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, void **args));
-
-/*************************************************************************
- * Locale Functions
- */
-void trio_locale_set_decimal_point TRIO_PROTO((char *decimalPoint));
-void trio_locale_set_thousand_separator TRIO_PROTO((char *thousandSeparator));
-void trio_locale_set_grouping TRIO_PROTO((char *grouping));
-
-/*************************************************************************
- * Renaming
- */
-#ifdef TRIO_REPLACE_STDIO
-/* Replace the <stdio.h> functions */
-#ifndef HAVE_PRINTF
-# undef printf
-# define printf trio_printf
-#endif
-#ifndef HAVE_VPRINTF
-# undef vprintf
-# define vprintf trio_vprintf
-#endif
-#ifndef HAVE_FPRINTF
-# undef fprintf
-# define fprintf trio_fprintf
-#endif
-#ifndef HAVE_VFPRINTF
-# undef vfprintf
-# define vfprintf trio_vfprintf
-#endif
-#ifndef HAVE_SPRINTF
-# undef sprintf
-# define sprintf trio_sprintf
-#endif
-#ifndef HAVE_VSPRINTF
-# undef vsprintf
-# define vsprintf trio_vsprintf
-#endif
-#ifndef HAVE_SNPRINTF
-# undef snprintf
-# define snprintf trio_snprintf
-#endif
-#ifndef HAVE_VSNPRINTF
-# undef vsnprintf
-# define vsnprintf trio_vsnprintf
-#endif
-#ifndef HAVE_SCANF
-# undef scanf
-# define scanf trio_scanf
-#endif
-#ifndef HAVE_VSCANF
-# undef vscanf
-# define vscanf trio_vscanf
-#endif
-#ifndef HAVE_FSCANF
-# undef fscanf
-# define fscanf trio_fscanf
-#endif
-#ifndef HAVE_VFSCANF
-# undef vfscanf
-# define vfscanf trio_vfscanf
-#endif
-#ifndef HAVE_SSCANF
-# undef sscanf
-# define sscanf trio_sscanf
-#endif
-#ifndef HAVE_VSSCANF
-# undef vsscanf
-# define vsscanf trio_vsscanf
-#endif
-/* These aren't stdio functions, but we make them look similar */
-#undef dprintf
-#define dprintf trio_dprintf
-#undef vdprintf
-#define vdprintf trio_vdprintf
-#undef aprintf
-#define aprintf trio_aprintf
-#undef vaprintf
-#define vaprintf trio_vaprintf
-#undef asprintf
-#define asprintf trio_asprintf
-#undef vasprintf
-#define vasprintf trio_vasprintf
-#undef dscanf
-#define dscanf trio_dscanf
-#undef vdscanf
-#define vdscanf trio_vdscanf
-#endif
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* WITHOUT_TRIO */
-
-#endif /* TRIO_TRIO_H */
diff --git a/trio/triodef.h b/trio/triodef.h
deleted file mode 100644 (file)
index 95d41d1..0000000
+++ /dev/null
@@ -1,335 +0,0 @@
-/*************************************************************************
- *
- * $Id: triodef.h,v 1.35 2009/09/20 11:37:14 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIODEF_H
-#define TRIO_TRIODEF_H
-
-/*************************************************************************
- * Compiler support detection
- */
-
-#if defined(__GNUC__)
-# define TRIO_COMPILER_GCC
-#endif
-
-#if defined(__SUNPRO_CC)
-# define TRIO_COMPILER_SUNPRO __SUNPRO_CC
-#else
-# if defined(__SUNPRO_C)
-#  define TRIO_COMPILER_SUNPRO __SUNPRO_C
-# endif
-#endif
-
-#if defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__)
-# define TRIO_COMPILER_XLC
-#else
-# if defined(_AIX) && !defined(__GNUC__)
-#  define TRIO_COMPILER_XLC /* Workaround for old xlc */
-# endif
-#endif
-
-#if defined(__DECC) || defined(__DECCXX)
-# define TRIO_COMPILER_DECC
-#else
-# if defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__)
-#  define TRIO_COMPILER_DECC /* Workaround for old DEC C compilers */
-# endif
-#endif
-
-#if defined(__HP_aCC) || defined(__HP_cc)
-# define TRIO_COMPILER_HP
-#endif
-
-#if defined(sgi) || defined(__sgi)
-# define TRIO_COMPILER_MIPSPRO
-#endif
-
-#if defined(_MSC_VER)
-# define TRIO_COMPILER_MSVC
-#endif
-
-#if defined(__BORLANDC__)
-# define TRIO_COMPILER_BCB
-#endif
-
-/*************************************************************************
- * Platform support detection
- */
-
-#if defined(VMS) || defined(__VMS)
-# define TRIO_PLATFORM_VMS
-#endif
-
-#if defined(unix) || defined(__unix) || defined(__unix__)
-# define TRIO_PLATFORM_UNIX
-#endif
-
-#if defined(TRIO_COMPILER_XLC) || defined(_AIX)
-# define TRIO_PLATFORM_UNIX
-#endif
-
-#if defined(TRIO_COMPILER_DECC) || defined(__osf___)
-# if !defined(TRIO_PLATFORM_VMS)
-#  define TRIO_PLATFORM_UNIX
-# endif
-#endif
-
-#if defined(__NetBSD__)
-# define TRIO_PLATFORM_UNIX
-#endif
-
-#if defined(__Lynx__)
-# define TRIO_PLATFORM_UNIX
-# define TRIO_PLATFORM_LYNX
-#endif
-
-#if defined(__APPLE__) && defined(__MACH__)
-# define TRIO_PLATFORM_UNIX
-#endif
-
-#if defined(__QNX__)
-# define TRIO_PLATFORM_UNIX
-# define TRIO_PLATFORM_QNX
-#endif
-
-#if defined(__CYGWIN__)
-# define TRIO_PLATFORM_UNIX
-#endif
-
-#if defined(AMIGA) && defined(TRIO_COMPILER_GCC)
-# define TRIO_PLATFORM_UNIX
-#endif
-
-#if defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32)
-# define TRIO_PLATFORM_WIN32
-#endif
-
-#if defined(_WIN32_WCE)
-# define TRIO_PLATFORM_WINCE
-#endif
-
-#if defined(mpeix) || defined(__mpexl)
-# define TRIO_PLATFORM_MPEIX
-#endif
-
-#if defined(_AIX)
-# define TRIO_PLATFORM_AIX
-#endif
-
-#if defined(__hpux)
-# define TRIO_PLATFORM_HPUX
-#endif
-
-#if defined(sun) || defined(__sun__)
-# if defined(__SVR4) || defined(__svr4__)
-#  define TRIO_PLATFORM_SOLARIS
-# else
-#  define TRIO_PLATFORM_SUNOS
-# endif
-#endif
-
-/*************************************************************************
- * Standards support detection
- */
-
-#if defined(__STDC__) \
- || defined(_MSC_EXTENSIONS) \
- || defined(TRIO_COMPILER_BCB)
-# define PREDEF_STANDARD_C89
-#endif
-#if defined(__STDC_VERSION__)
-# define PREDEF_STANDARD_C90
-#endif
-#if (__STDC_VERSION__ - 0 >= 199409L)
-# define PREDEF_STANDARD_C94
-#endif
-#if (__STDC_VERSION__ - 0 >= 199901L)
-# define PREDEF_STANDARD_C99
-#endif
-#if defined(TRIO_COMPILER_SUNPRO) && (TRIO_COMPILER_SUNPRO >= 0x420)
-# if !defined(PREDEF_STANDARD_C94)
-#  define PREDEF_STANDARD_C94
-# endif
-#endif
-
-#if defined(__cplusplus)
-# define PREDEF_STANDARD_CXX
-#endif
-#if __cplusplus - 0 >= 199711L
-# define PREDEF_STANDARD_CXX89
-#endif
-
-#if defined(TRIO_PLATFORM_UNIX)
-# include <unistd.h>
-#endif
-
-#if defined(_POSIX_VERSION)
-# define PREDEF_STANDARD_POSIX _POSIX_VERSION
-# if (_POSIX_VERSION >= 199506L)
-#  define PREDEF_STANDARD_POSIX_1996
-# endif
-#endif
-
-#if (_XOPEN_VERSION - 0 >= 3) || defined(_XOPEN_XPG3)
-# define PREDEF_STANDARD_XPG3
-#endif
-#if (_XOPEN_VERSION - 0 >= 4) || defined(_XOPEN_XPG4)
-# define PREDEF_STANDARD_XPG4
-#endif
-#if (_XOPEN_VERSION - 0 > 4) \
- || (defined(_XOPEN_UNIX) && (_XOPEN_VERSION - 0 == 4))
-# define PREDEF_STANDARD_UNIX95
-#endif
-#if (_XOPEN_VERSION - 0 >= 500)
-# define PREDEF_STANDARD_UNIX98
-#endif
-#if (_XOPEN_VERSION - 0 >= 600)
-# define PREDEF_STANDARD_UNIX03
-#endif
-
-/*************************************************************************
- * Generic defines
- */
-
-#if !defined(TRIO_PUBLIC)
-# define TRIO_PUBLIC
-#endif
-#if !defined(TRIO_PRIVATE)
-# define TRIO_PRIVATE static
-#endif
-
-#if !(defined(PREDEF_STANDARD_C89) || defined(PREDEF_STANDARD_CXX))
-# define TRIO_COMPILER_ANCIENT
-#endif
-
-#if defined(TRIO_COMPILER_ANCIENT)
-# define TRIO_CONST
-# define TRIO_VOLATILE
-# define TRIO_SIGNED
-typedef double trio_long_double_t;
-typedef char * trio_pointer_t;
-# define TRIO_SUFFIX_LONG(x) x
-# define TRIO_PROTO(x) ()
-# define TRIO_NOARGS
-# define TRIO_ARGS1(list,a1) list a1;
-# define TRIO_ARGS2(list,a1,a2) list a1; a2;
-# define TRIO_ARGS3(list,a1,a2,a3) list a1; a2; a3;
-# define TRIO_ARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4;
-# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5;
-# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) list a1; a2; a3; a4; a5; a6;
-# define TRIO_ARGS7(list,a1,a2,a3,a4,a5,a6,a7) list a1; a2; a3; a4; a5; a6; a7;
-# define TRIO_VARGS2(list,a1,a2) list a1; a2
-# define TRIO_VARGS3(list,a1,a2,a3) list a1; a2; a3
-# define TRIO_VARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4
-# define TRIO_VARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5
-# define TRIO_VA_DECL va_dcl
-# define TRIO_VA_START(x,y) va_start(x)
-# define TRIO_VA_END(x) va_end(x)
-#else /* ANSI C */
-# define TRIO_CONST const
-# define TRIO_VOLATILE volatile
-# define TRIO_SIGNED signed
-typedef long double trio_long_double_t;
-typedef void * trio_pointer_t;
-# define TRIO_SUFFIX_LONG(x) x ## L
-# define TRIO_PROTO(x) x
-# define TRIO_NOARGS void
-# define TRIO_ARGS1(list,a1) (a1)
-# define TRIO_ARGS2(list,a1,a2) (a1,a2)
-# define TRIO_ARGS3(list,a1,a2,a3) (a1,a2,a3)
-# define TRIO_ARGS4(list,a1,a2,a3,a4) (a1,a2,a3,a4)
-# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) (a1,a2,a3,a4,a5)
-# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) (a1,a2,a3,a4,a5,a6)
-# define TRIO_ARGS7(list,a1,a2,a3,a4,a5,a6,a7) (a1,a2,a3,a4,a5,a6,a7)
-# define TRIO_VARGS2 TRIO_ARGS2
-# define TRIO_VARGS3 TRIO_ARGS3
-# define TRIO_VARGS4 TRIO_ARGS4
-# define TRIO_VARGS5 TRIO_ARGS5
-# define TRIO_VA_DECL ...
-# define TRIO_VA_START(x,y) va_start(x,y)
-# define TRIO_VA_END(x) va_end(x)
-#endif
-
-#if defined(PREDEF_STANDARD_C99) || defined(PREDEF_STANDARD_CXX)
-# define TRIO_INLINE inline
-#else
-# if defined(TRIO_COMPILER_GCC)
-#  define TRIO_INLINE __inline__
-# endif
-# if defined(TRIO_COMPILER_MSVC)
-#  define TRIO_INLINE _inline
-# endif
-# if defined(TRIO_COMPILER_BCB)
-#  define TRIO_INLINE __inline
-# endif
-#endif
-#if !defined(TRIO_INLINE)
-# define TRIO_INLINE
-#endif
-
-/*************************************************************************
- * Workarounds
- */
-
-#if defined(TRIO_PLATFORM_VMS)
-/*
- * Computations done with constants at compile time can trigger these
- * even when compiling with IEEE enabled.
- */
-# pragma message disable (UNDERFLOW, FLOATOVERFL)
-
-# if (__CRTL_VER < 80210001)
-/*
- * Although the compiler supports C99 language constructs, the C
- * run-time library does not contain all C99 functions.
- */
-#  if defined(PREDEF_STANDARD_C99)
-#   undef PREDEF_STANDARD_C99
-#  endif
-# endif
-#endif
-
-/*
- * Not all preprocessors supports the LL token.
- */
-#if defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
-#else
-# define TRIO_COMPILER_SUPPORTS_LL
-#endif
-
-#if defined(__CYGWIN__)
-/*
- * Cygwin defines the macros for hosted C99, but does not support certain
- * long double math functions.
- */
-# include <cygwin/version.h>
-# define TRIO_CYGWIN_VERSION_API CYGWIN_VERSION_API_MAJOR * 1000 + \
-   CYGWIN_VERSION_API_MINOR
-/*
- * Please change the version number below when the Cygwin API supports
- * long double math functions (powl, fmodl, etc.)
- */
-# if TRIO_CYGWIN_VERSION_API < 99999999
-#  define TRIO_NO_FLOORL 1
-#  define TRIO_NO_CEILL 1
-#  define TRIO_NO_POWL 1
-#  define TRIO_NO_FMODL 1
-#  define TRIO_NO_LOG10L 1
-# endif
-#endif
-
-#endif /* TRIO_TRIODEF_H */
diff --git a/trio/trionan.c b/trio/trionan.c
deleted file mode 100644 (file)
index 3016322..0000000
+++ /dev/null
@@ -1,1257 +0,0 @@
-/*************************************************************************
- *
- * $Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************
- *
- * Functions to handle special quantities in floating-point numbers
- * (that is, NaNs and infinity). They provide the capability to detect
- * and fabricate special quantities.
- *
- * Although written to be as portable as possible, it can never be
- * guaranteed to work on all platforms, as not all hardware supports
- * special quantities.
- *
- * The approach used here (approximately) is to:
- *
- *   1. Use C99 functionality when available.
- *   2. Use IEEE 754 bit-patterns if possible.
- *   3. Use platform-specific techniques.
- *
- ************************************************************************/
-
-/*************************************************************************
- * Include files
- */
-#include "triodef.h"
-#include "trionan.h"
-
-#include <math.h>
-#include <string.h>
-#include <limits.h>
-#if !defined(TRIO_PLATFORM_SYMBIAN)
-# include <float.h>
-#endif
-#if defined(TRIO_PLATFORM_UNIX)
-# include <signal.h>
-#endif
-#if defined(TRIO_COMPILER_DECC)
-# include <fp_class.h>
-#endif
-#include <assert.h>
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_nan.h"
-#endif
-/** @addtogroup SpecialQuantities
-    @{
-*/
-
-/*************************************************************************
- * Definitions
- */
-
-#if !defined(TRIO_PUBLIC_NAN)
-# define TRIO_PUBLIC_NAN TRIO_PUBLIC
-#endif
-#if !defined(TRIO_PRIVATE_NAN)
-# define TRIO_PRIVATE_NAN TRIO_PRIVATE
-#endif
-
-#define TRIO_TRUE (1 == 1)
-#define TRIO_FALSE (0 == 1)
-
-/*
- * We must enable IEEE floating-point on Alpha
- */
-#if defined(__alpha) && !defined(_IEEE_FP)
-# if defined(TRIO_COMPILER_DECC)
-#  if defined(TRIO_PLATFORM_VMS)
-#   error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE"
-#  else
-#   if !defined(_CFE)
-#    error "Must be compiled with option -ieee"
-#   endif
-#  endif
-# else
-#  if defined(TRIO_COMPILER_GCC)
-#   error "Must be compiled with option -mieee"
-#  endif
-# endif
-#endif /* __alpha && ! _IEEE_FP */
-
-/*
- * In ANSI/IEEE 754-1985 64-bits double format numbers have the
- * following properties (amoungst others)
- *
- *   o FLT_RADIX == 2: binary encoding
- *   o DBL_MAX_EXP == 1024: 11 bits exponent, where one bit is used
- *     to indicate special numbers (e.g. NaN and Infinity), so the
- *     maximum exponent is 10 bits wide (2^10 == 1024).
- *   o DBL_MANT_DIG == 53: The mantissa is 52 bits wide, but because
- *     numbers are normalized the initial binary 1 is represented
- *     implicitly (the so-called "hidden bit"), which leaves us with
- *     the ability to represent 53 bits wide mantissa.
- */
-#if defined(__STDC_IEC_559__)
-# define TRIO_IEEE_754
-#else
-# if (FLT_RADIX - 0 == 2) && (DBL_MAX_EXP - 0 == 1024) && (DBL_MANT_DIG - 0 == 53)
-#  define TRIO_IEEE_754
-# endif
-#endif
-
-/*
- * Determine which fpclassify_and_sign() function to use.
- */
-#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
-# if defined(PREDEF_STANDARD_C99) && defined(fpclassify)
-#  define TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT
-# else
-#  if defined(TRIO_COMPILER_DECC)
-#   define TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT
-#  else
-#   if defined(TRIO_COMPILER_VISUALC) || defined(TRIO_COMPILER_BORLAND)
-#    define TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT
-#   else
-#    if defined(TRIO_COMPILER_HP) && defined(FP_PLUS_NORM)
-#     define TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT
-#    else
-#     if defined(TRIO_COMPILER_XLC) && defined(FP_PLUS_NORM)
-#      define TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT
-#     else
-#      define TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT
-#     endif
-#    endif
-#   endif
-#  endif
-# endif
-#endif
-
-/*
- * Determine how to generate negative zero.
- */
-#if defined(TRIO_FUNC_NZERO)
-# if defined(TRIO_IEEE_754)
-#  define TRIO_NZERO_IEEE_754
-# else
-#  define TRIO_NZERO_FALLBACK
-# endif
-#endif
-
-/*
- * Determine how to generate positive infinity.
- */
-#if defined(TRIO_FUNC_PINF)
-# if defined(INFINITY) && defined(__STDC_IEC_559__)
-#  define TRIO_PINF_C99_MACRO
-# else
-#  if defined(TRIO_IEEE_754)
-#   define TRIO_PINF_IEEE_754
-#  else
-#   define TRIO_PINF_FALLBACK
-#  endif
-# endif
-#endif
-
-/*
- * Determine how to generate NaN.
- */
-#if defined(TRIO_FUNC_NAN)
-# if defined(PREDEF_STANDARD_C99) && !defined(TRIO_COMPILER_DECC)
-#  define TRIO_NAN_C99_FUNCTION
-# else
-#  if defined(NAN) && defined(__STDC_IEC_559__)
-#   define TRIO_NAN_C99_MACRO
-#  else
-#   if defined(TRIO_IEEE_754)
-#    define TRIO_NAN_IEEE_754
-#   else
-#    define TRIO_NAN_FALLBACK
-#   endif
-#  endif
-# endif
-#endif
-
-/*
- * Resolve internal dependencies.
- */
-#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)
-# define TRIO_FUNC_INTERNAL_ISNAN
-# define TRIO_FUNC_INTERNAL_ISINF
-# if defined(TRIO_IEEE_754)
-#  define TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY
-#  define TRIO_FUNC_INTERNAL_IS_NEGATIVE
-# endif
-#endif
-
-#if defined(TRIO_NZERO_IEEE_754) \
- || defined(TRIO_PINF_IEEE_754) \
- || defined(TRIO_NAN_IEEE_754)
-# define TRIO_FUNC_INTERNAL_MAKE_DOUBLE
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_ISNAN)
-# if defined(PREDEF_STANDARD_XPG3)
-#  define TRIO_INTERNAL_ISNAN_XPG3
-# else
-#  if defined(TRIO_IEEE_754)
-#   define TRIO_INTERNAL_ISNAN_IEEE_754
-#  else
-#   define TRIO_INTERNAL_ISNAN_FALLBACK
-#  endif
-# endif
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_ISINF)
-# if defined(TRIO_IEEE_754)
-#  define TRIO_INTERNAL_ISINF_IEEE_754
-# else
-#  define TRIO_INTERNAL_ISINF_FALLBACK
-# endif
-#endif
-
-/*************************************************************************
- * Constants
- */
-
-#if !defined(TRIO_EMBED_NAN)
-static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $";
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE) \
- || defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY) \
- || defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
-/*
- * Endian-agnostic indexing macro.
- *
- * The value of internalEndianMagic, when converted into a 64-bit
- * integer, becomes 0x0706050403020100 (we could have used a 64-bit
- * integer value instead of a double, but not all platforms supports
- * that type). The value is automatically encoded with the correct
- * endianess by the compiler, which means that we can support any
- * kind of endianess. The individual bytes are then used as an index
- * for the IEEE 754 bit-patterns and masks.
- */
-#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])
-static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)
-/* Mask for the exponent */
-static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
-  0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* Mask for the mantissa */
-static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = {
-  0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-};
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
-/* Mask for the sign bit */
-static TRIO_CONST unsigned char ieee_754_sign_mask[] = {
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-#endif
-
-#if defined(TRIO_NZERO_IEEE_754)
-/* Bit-pattern for negative zero */
-static TRIO_CONST unsigned char ieee_754_negzero_array[] = {
-  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-#endif
-
-#if defined(TRIO_PINF_IEEE_754)
-/* Bit-pattern for infinity */
-static TRIO_CONST unsigned char ieee_754_infinity_array[] = {
-  0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-#endif
-
-#if defined(TRIO_NAN_IEEE_754)
-/* Bit-pattern for quiet NaN */
-static TRIO_CONST unsigned char ieee_754_qnan_array[] = {
-  0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-#endif
-
-
-/*************************************************************************
- * Internal functions
- */
-
-/*
- * internal_make_double
- */
-#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE)
-
-TRIO_PRIVATE_NAN double
-internal_make_double
-TRIO_ARGS1((values),
-          TRIO_CONST unsigned char *values)
-{
-  TRIO_VOLATILE double result;
-  int i;
-
-  for (i = 0; i < (int)sizeof(double); i++) {
-    ((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i];
-  }
-  return result;
-}
-
-#endif
-
-/*
- * internal_is_special_quantity
- */
-#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)
-
-TRIO_PRIVATE_NAN int
-internal_is_special_quantity
-TRIO_ARGS2((number, has_mantissa),
-          double number,
-          int *has_mantissa)
-{
-  unsigned int i;
-  unsigned char current;
-  int is_special_quantity = TRIO_TRUE;
-
-  *has_mantissa = 0;
-
-  for (i = 0; i < (unsigned int)sizeof(double); i++) {
-    current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)];
-    is_special_quantity
-      &= ((current & ieee_754_exponent_mask[i]) == ieee_754_exponent_mask[i]);
-    *has_mantissa |= (current & ieee_754_mantissa_mask[i]);
-  }
-  return is_special_quantity;
-}
-
-#endif
-
-/*
- * internal_is_negative
- */
-#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
-
-TRIO_PRIVATE_NAN int
-internal_is_negative
-TRIO_ARGS1((number),
-          double number)
-{
-  unsigned int i;
-  int is_negative = TRIO_FALSE;
-
-  for (i = 0; i < (unsigned int)sizeof(double); i++) {
-    is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]
-                   & ieee_754_sign_mask[i]);
-  }
-  return is_negative;
-}
-
-#endif
-
-#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)
-
-TRIO_PRIVATE_NAN TRIO_INLINE int
-c99_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
-          double number,
-          int *is_negative)
-{
-  *is_negative = signbit(number);
-  switch (fpclassify(number)) {
-  case FP_NAN:
-    return TRIO_FP_NAN;
-  case FP_INFINITE:
-    return TRIO_FP_INFINITE;
-  case FP_SUBNORMAL:
-    return TRIO_FP_SUBNORMAL;
-  case FP_ZERO:
-    return TRIO_FP_ZERO;
-  default:
-    return TRIO_FP_NORMAL;
-  }
-}
-
-#endif /* TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT */
-
-#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)
-
-TRIO_PRIVATE_NAN TRIO_INLINE int
-decc_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
-         double number,
-         int *is_negative)
-{
-  switch (fp_class(number)) {
-  case FP_QNAN:
-  case FP_SNAN:
-    *is_negative = TRIO_FALSE; /* NaN has no sign */
-    return TRIO_FP_NAN;
-  case FP_POS_INF:
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_INFINITE;
-  case FP_NEG_INF:
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_INFINITE;
-  case FP_POS_DENORM:
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_SUBNORMAL;
-  case FP_NEG_DENORM:
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_SUBNORMAL;
-  case FP_POS_ZERO:
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_ZERO;
-  case FP_NEG_ZERO:
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_ZERO;
-  case FP_POS_NORM:
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_NORMAL;
-  case FP_NEG_NORM:
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_NORMAL;
-  default:
-    *is_negative = (number < 0.0);
-    return TRIO_FP_NORMAL;
-  }
-}
-
-#endif /* TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT */
-
-#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)
-
-TRIO_PRIVATE_NAN int
-ms_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
-         double number,
-         int *is_negative)
-{
-  int result;
-# if defined(TRIO_COMPILER_BORLAND)
-  /*
-   * The floating-point precision may be changed by the Borland _fpclass()
-   * function, so we have to save and restore the floating-point control mask.
-   */
-  unsigned int mask;
-  /* Remember the old mask */
-  mask = _control87(0, 0);
-# endif
-  
-  switch (_fpclass(number)) {
-  case _FPCLASS_QNAN:
-  case _FPCLASS_SNAN:
-    *is_negative = TRIO_FALSE; /* NaN has no sign */
-    result = TRIO_FP_NAN;
-    break;
-  case _FPCLASS_PINF:
-    *is_negative = TRIO_FALSE;
-    result = TRIO_FP_INFINITE;
-    break;
-  case _FPCLASS_NINF:
-    *is_negative = TRIO_TRUE;
-    result = TRIO_FP_INFINITE;
-    break;
-  case _FPCLASS_PD:
-    *is_negative = TRIO_FALSE;
-    result = TRIO_FP_SUBNORMAL;
-    break;
-  case _FPCLASS_ND:
-    *is_negative = TRIO_TRUE;
-    result = TRIO_FP_SUBNORMAL;
-    break;
-  case _FPCLASS_PZ:
-    *is_negative = TRIO_FALSE;
-    result = TRIO_FP_ZERO;
-    break;
-  case _FPCLASS_NZ:
-    *is_negative = TRIO_TRUE;
-    result = TRIO_FP_ZERO;
-    break;
-  case _FPCLASS_PN:
-    *is_negative = TRIO_FALSE;
-    result = TRIO_FP_NORMAL;
-    break;
-  case _FPCLASS_NN:
-    *is_negative = TRIO_TRUE;
-    result = TRIO_FP_NORMAL;
-    break;
-  default:
-    *is_negative = (number < 0.0);
-    result = TRIO_FP_NORMAL;
-    break;
-  }
-  
-# if defined(TRIO_COMPILER_BORLAND)
-  /* Restore the old precision */
-  (void)_control87(mask, MCW_PC);
-# endif
-  
-  return result;
-}
-
-#endif /* TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT */
-
-#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)
-
-TRIO_PRIVATE_NAN TRIO_INLINE int
-hp_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
-         double number,
-         int *is_negative)
-{
-  /*
-   * HP-UX 9.x and 10.x have an fpclassify() function, that is different
-   * from the C99 fpclassify() macro supported on HP-UX 11.x.
-   */
-  switch (fpclassify(number)) {
-  case FP_QNAN:
-  case FP_SNAN:
-    *is_negative = TRIO_FALSE; /* NaN has no sign */
-    return TRIO_FP_NAN;
-  case FP_PLUS_INF:
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_INFINITE;
-  case FP_MINUS_INF:
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_INFINITE;
-  case FP_PLUS_DENORM:
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_SUBNORMAL;
-  case FP_MINUS_DENORM:
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_SUBNORMAL;
-  case FP_PLUS_ZERO:
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_ZERO;
-  case FP_MINUS_ZERO:
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_ZERO;
-  case FP_PLUS_NORM:
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_NORMAL;
-  case FP_MINUS_NORM:
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_NORMAL;
-  default:
-    *is_negative = (number < 0.0);
-    return TRIO_FP_NORMAL;
-  }
-}
-
-#endif /* TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT */
-
-#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)
-
-TRIO_PRIVATE_NAN TRIO_INLINE int
-xlc_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
-         double number,
-         int *is_negative)
-{
-  /*
-   * AIX has class() for C, and _class() for C++
-   */
-# if defined(__cplusplus)
-#  define AIX_CLASS(n) _class(n)
-# else
-#  define AIX_CLASS(n) class(n)
-# endif
-
-  switch (AIX_CLASS(number)) {
-  case FP_QNAN:
-  case FP_SNAN:
-    *is_negative = TRIO_FALSE; /* NaN has no sign */
-    return TRIO_FP_NAN;
-  case FP_PLUS_INF:
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_INFINITE;
-  case FP_MINUS_INF:
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_INFINITE;
-  case FP_PLUS_DENORM:
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_SUBNORMAL;
-  case FP_MINUS_DENORM:
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_SUBNORMAL;
-  case FP_PLUS_ZERO:
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_ZERO;
-  case FP_MINUS_ZERO:
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_ZERO;
-  case FP_PLUS_NORM:
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_NORMAL;
-  case FP_MINUS_NORM:
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_NORMAL;
-  default:
-    *is_negative = (number < 0.0);
-    return TRIO_FP_NORMAL;
-  }
-}
-
-#endif /* TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT */
-
-#if defined(TRIO_FUNC_INTERNAL_ISNAN)
-
-TRIO_PRIVATE_NAN TRIO_INLINE int
-internal_isnan
-TRIO_ARGS1((number),
-          double number)
-{
-# if defined(TRIO_INTERNAL_ISNAN_XPG3) || defined(TRIO_PLATFORM_SYMBIAN)
-  /*
-   * XPG3 defines isnan() as a function.
-   */
-  return isnan(number);
-
-# endif
-  
-# if defined(TRIO_INTERNAL_ISNAN_IEEE_754)
-  
-  /*
-   * Examine IEEE 754 bit-pattern. A NaN must have a special exponent
-   * pattern, and a non-empty mantissa.
-   */
-  int has_mantissa;
-  int is_special_quantity;
-
-  is_special_quantity = internal_is_special_quantity(number, &has_mantissa);
-  
-  return (is_special_quantity && has_mantissa);
-  
-# endif
-
-# if defined(TRIO_INTERNAL_ISNAN_FALLBACK)
-  
-  /*
-   * Fallback solution
-   */
-  int status;
-  double integral, fraction;
-  
-#  if defined(TRIO_PLATFORM_UNIX)
-  void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-#  endif
-  
-  status = (/*
-            * NaN is the only number which does not compare to itself
-            */
-           ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) ||
-           /*
-            * Fallback solution if NaN compares to NaN
-            */
-           ((number != 0.0) &&
-            (fraction = modf(number, &integral),
-             integral == fraction)));
-  
-#  if defined(TRIO_PLATFORM_UNIX)
-  signal(SIGFPE, signal_handler);
-#  endif
-  
-  return status;
-  
-# endif
-}
-
-#endif /* TRIO_FUNC_INTERNAL_ISNAN */
-
-#if defined(TRIO_FUNC_INTERNAL_ISINF)
-
-TRIO_PRIVATE_NAN TRIO_INLINE int
-internal_isinf
-TRIO_ARGS1((number),
-          double number)
-{
-# if defined(TRIO_PLATFORM_SYMBIAN)
-
-  return isinf(number);
-
-# endif
-
-# if defined(TRIO_INTERNAL_ISINF_IEEE_754)
-  /*
-   * Examine IEEE 754 bit-pattern. Infinity must have a special exponent
-   * pattern, and an empty mantissa.
-   */
-  int has_mantissa;
-  int is_special_quantity;
-
-  is_special_quantity = internal_is_special_quantity(number, &has_mantissa);
-  
-  return (is_special_quantity && !has_mantissa)
-    ? ((number < 0.0) ? -1 : 1)
-    : 0;
-
-# endif
-
-# if defined(TRIO_INTERNAL_ISINF_FALLBACK)
-  
-  /*
-   * Fallback solution.
-   */
-  int status;
-  
-#  if defined(TRIO_PLATFORM_UNIX)
-  void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-#  endif
-  
-  double infinity = trio_pinf();
-  
-  status = ((number == infinity)
-           ? 1
-           : ((number == -infinity) ? -1 : 0));
-  
-#  if defined(TRIO_PLATFORM_UNIX)
-  signal(SIGFPE, signal_handler);
-#  endif
-  
-  return status;
-
-# endif
-}
-
-#endif /* TRIO_FUNC_INTERNAL_ISINF */
-
-/*************************************************************************
- * Public functions
- */
-
-#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
-
-TRIO_PUBLIC_NAN int
-trio_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
-          double number,
-          int *is_negative)
-{
-  /* The TRIO_FUNC_xxx_FPCLASSIFY_AND_SIGNBIT macros are mutually exclusive */
-  
-#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)
-
-  return c99_fpclassify_and_signbit(number, is_negative);
-
-#endif
-
-#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)
-
-  return decc_fpclassify_and_signbit(number, is_negative);
-
-#endif
-
-#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)
-
-  return ms_fpclassify_and_signbit(number, is_negative);
-
-#endif
-
-#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)
-
-  return hp_fpclassify_and_signbit(number, is_negative);
-
-#endif
-
-#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)
-
-  return xlc_fpclassify_and_signbit(number, is_negative);
-
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)
-  
-  /*
-   * Fallback solution.
-   */
-  int rc;
-  
-  if (number == 0.0) {
-    /*
-     * In IEEE 754 the sign of zero is ignored in comparisons, so we
-     * have to handle this as a special case by examining the sign bit
-     * directly.
-     */
-# if defined(TRIO_IEEE_754)
-    *is_negative = internal_is_negative(number);
-# else
-    *is_negative = TRIO_FALSE; /* FIXME */
-# endif
-    return TRIO_FP_ZERO;
-  }
-  if (internal_isnan(number)) {
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_NAN;
-  }
-  rc = internal_isinf(number);
-  if (rc != 0) {
-    *is_negative = (rc == -1);
-    return TRIO_FP_INFINITE;
-  }
-  if ((number > 0.0) && (number < DBL_MIN)) {
-    *is_negative = TRIO_FALSE;
-    return TRIO_FP_SUBNORMAL;
-  }
-  if ((number < 0.0) && (number > -DBL_MIN)) {
-    *is_negative = TRIO_TRUE;
-    return TRIO_FP_SUBNORMAL;
-  }
-  *is_negative = (number < 0.0);
-  return TRIO_FP_NORMAL;
-
-#endif
-}
-
-#endif
-
-/**
-   Check for NaN.
-
-   @param number An arbitrary floating-point number.
-   @return Boolean value indicating whether or not the number is a NaN.
-*/
-#if defined(TRIO_FUNC_ISNAN)
-
-TRIO_PUBLIC_NAN int
-trio_isnan
-TRIO_ARGS1((number),
-          double number)
-{
-  int dummy;
-  
-  return (trio_fpclassify_and_signbit(number, &dummy) == TRIO_FP_NAN);
-}
-
-#endif
-
-/**
-   Check for infinity.
-
-   @param number An arbitrary floating-point number.
-   @return 1 if positive infinity, -1 if negative infinity, 0 otherwise.
-*/
-#if defined(TRIO_FUNC_ISINF)
-
-TRIO_PUBLIC_NAN int
-trio_isinf
-TRIO_ARGS1((number),
-          double number)
-{
-  int is_negative;
-  
-  if (trio_fpclassify_and_signbit(number, &is_negative) == TRIO_FP_INFINITE)
-    {
-      return (is_negative) ? -1 : 1;
-    }
-  else
-    {
-      return 0;
-    }
-}
-
-#endif
-
-/**
-   Check for finity.
-
-   @param number An arbitrary floating-point number.
-   @return Boolean value indicating whether or not the number is a finite.
-*/
-#if defined(TRIO_FUNC_ISFINITE)
-
-TRIO_PUBLIC_NAN int
-trio_isfinite
-TRIO_ARGS1((number),
-          double number)
-{
-  int dummy;
-  
-  switch (trio_fpclassify_and_signbit(number, &dummy))
-    {
-    case TRIO_FP_INFINITE:
-    case TRIO_FP_NAN:
-      return 0;
-    default:
-      return 1;
-    }
-}
-
-#endif
-
-/**
-   Examine the sign of a number.
-
-   @param number An arbitrary floating-point number.
-   @return Boolean value indicating whether or not the number has the
-   sign bit set (i.e. is negative).
-*/
-#if defined(TRIO_FUNC_SIGNBIT)
-
-TRIO_PUBLIC_NAN int
-trio_signbit
-TRIO_ARGS1((number),
-          double number)
-{
-  int is_negative;
-  
-  (void)trio_fpclassify_and_signbit(number, &is_negative);
-  return is_negative;
-}
-
-#endif
-
-/**
-   Examine the class of a number.
-
-   @param number An arbitrary floating-point number.
-   @return Enumerable value indicating the class of @p number
-*/
-#if defined(TRIO_FUNC_FPCLASSIFY)
-
-TRIO_PUBLIC_NAN int
-trio_fpclassify
-TRIO_ARGS1((number),
-          double number)
-{
-  int dummy;
-  
-  return trio_fpclassify_and_signbit(number, &dummy);
-}
-
-#endif
-
-/**
-   Generate negative zero.
-
-   @return Floating-point representation of negative zero.
-*/
-#if defined(TRIO_FUNC_NZERO)
-
-TRIO_PUBLIC_NAN double
-trio_nzero(TRIO_NOARGS)
-{
-# if defined(TRIO_NZERO_IEEE_754)
-  
-  return internal_make_double(ieee_754_negzero_array);
-
-# endif
-  
-# if defined(TRIO_NZERO_FALLBACK)
-  
-  TRIO_VOLATILE double zero = 0.0;
-
-  return -zero;
-  
-# endif
-}
-
-#endif
-
-/**
-   Generate positive infinity.
-
-   @return Floating-point representation of positive infinity.
-*/
-#if defined(TRIO_FUNC_PINF)
-
-TRIO_PUBLIC_NAN double
-trio_pinf(TRIO_NOARGS)
-{
-  /* Cache the result */
-  static double pinf_value = 0.0;
-
-  if (pinf_value == 0.0) {
-
-# if defined(TRIO_PINF_C99_MACRO)
-    
-    pinf_value = (double)INFINITY;
-
-# endif
-    
-# if defined(TRIO_PINF_IEEE_754)
-    
-    pinf_value = internal_make_double(ieee_754_infinity_array);
-
-# endif
-
-# if defined(TRIO_PINF_FALLBACK)
-    /*
-     * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used
-     * as infinity. Otherwise we have to resort to an overflow
-     * operation to generate infinity.
-     */
-#  if defined(TRIO_PLATFORM_UNIX)
-    void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-#  endif
-
-    pinf_value = HUGE_VAL;
-    if (HUGE_VAL == DBL_MAX) {
-      /* Force overflow */
-      pinf_value += HUGE_VAL;
-    }
-    
-#  if defined(TRIO_PLATFORM_UNIX)
-    signal(SIGFPE, signal_handler);
-#  endif
-
-# endif
-  }
-  return pinf_value;
-}
-
-#endif
-
-/**
-   Generate negative infinity.
-
-   @return Floating-point value of negative infinity.
-*/
-#if defined(TRIO_FUNC_NINF)
-
-TRIO_PUBLIC_NAN double
-trio_ninf(TRIO_NOARGS)
-{
-  static double ninf_value = 0.0;
-
-  if (ninf_value == 0.0) {
-    /*
-     * Negative infinity is calculated by negating positive infinity,
-     * which can be done because it is legal to do calculations on
-     * infinity (for example,  1 / infinity == 0).
-     */
-    ninf_value = -trio_pinf();
-  }
-  return ninf_value;
-}
-
-#endif
-
-/**
-   Generate NaN.
-
-   @return Floating-point representation of NaN.
-*/
-#if defined(TRIO_FUNC_NAN)
-
-TRIO_PUBLIC_NAN double
-trio_nan(TRIO_NOARGS)
-{
-  /* Cache the result */
-  static double nan_value = 0.0;
-
-  if (nan_value == 0.0) {
-    
-# if defined(TRIO_NAN_C99_FUNCTION) || defined(TRIO_PLATFORM_SYMBIAN)
-    
-    nan_value = nan("");
-
-# endif
-    
-# if defined(TRIO_NAN_C99_MACRO)
-    
-    nan_value = (double)NAN;
-
-# endif
-
-# if defined(TRIO_NAN_IEEE_754)
-    
-    nan_value = internal_make_double(ieee_754_qnan_array);
-
-# endif
-    
-# if defined(TRIO_NAN_FALLBACK)
-    /*
-     * There are several ways to generate NaN. The one used here is
-     * to divide infinity by infinity. I would have preferred to add
-     * negative infinity to positive infinity, but that yields wrong
-     * result (infinity) on FreeBSD.
-     *
-     * This may fail if the hardware does not support NaN, or if
-     * the Invalid Operation floating-point exception is unmasked.
-     */
-#  if defined(TRIO_PLATFORM_UNIX)
-    void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-#  endif
-    
-    nan_value = trio_pinf() / trio_pinf();
-    
-#  if defined(TRIO_PLATFORM_UNIX)
-    signal(SIGFPE, signal_handler);
-#  endif
-
-# endif
-  }
-  return nan_value;
-}
-
-#endif
-
-/** @} SpecialQuantities */
-
-/*************************************************************************
- * For test purposes.
- *
- * Add the following compiler option to include this test code.
- *
- *  Unix : -DSTANDALONE
- *  VMS  : /DEFINE=(STANDALONE)
- */
-#if defined(STANDALONE)
-# include <stdio.h>
-
-static TRIO_CONST char *
-getClassification
-TRIO_ARGS1((type),
-          int type)
-{
-  switch (type) {
-  case TRIO_FP_INFINITE:
-    return "FP_INFINITE";
-  case TRIO_FP_NAN:
-    return "FP_NAN";
-  case TRIO_FP_NORMAL:
-    return "FP_NORMAL";
-  case TRIO_FP_SUBNORMAL:
-    return "FP_SUBNORMAL";
-  case TRIO_FP_ZERO:
-    return "FP_ZERO";
-  default:
-    return "FP_UNKNOWN";
-  }
-}
-
-static void
-print_class
-TRIO_ARGS2((prefix, number),
-          TRIO_CONST char *prefix,
-          double number)
-{
-  printf("%-6s: %s %-15s %g\n",
-        prefix,
-        trio_signbit(number) ? "-" : "+",
-        getClassification(trio_fpclassify(number)),
-        number);
-}
-
-int main(TRIO_NOARGS)
-{
-  double my_nan;
-  double my_pinf;
-  double my_ninf;
-# if defined(TRIO_PLATFORM_UNIX)
-  void (*signal_handler) TRIO_PROTO((int));
-# endif
-
-  my_nan = trio_nan();
-  my_pinf = trio_pinf();
-  my_ninf = trio_ninf();
-
-  print_class("Nan", my_nan);
-  print_class("PInf", my_pinf);
-  print_class("NInf", my_ninf);
-  print_class("PZero", 0.0);
-  print_class("NZero", -0.0);
-  print_class("PNorm", 1.0);
-  print_class("NNorm", -1.0);
-  print_class("PSub", 1.01e-307 - 1.00e-307);
-  print_class("NSub", 1.00e-307 - 1.01e-307);
-  
-  printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
-        my_nan,
-        ((unsigned char *)&my_nan)[0],
-        ((unsigned char *)&my_nan)[1],
-        ((unsigned char *)&my_nan)[2],
-        ((unsigned char *)&my_nan)[3],
-        ((unsigned char *)&my_nan)[4],
-        ((unsigned char *)&my_nan)[5],
-        ((unsigned char *)&my_nan)[6],
-        ((unsigned char *)&my_nan)[7],
-        trio_isnan(my_nan), trio_isinf(my_nan), trio_isfinite(my_nan));
-  printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
-        my_pinf,
-        ((unsigned char *)&my_pinf)[0],
-        ((unsigned char *)&my_pinf)[1],
-        ((unsigned char *)&my_pinf)[2],
-        ((unsigned char *)&my_pinf)[3],
-        ((unsigned char *)&my_pinf)[4],
-        ((unsigned char *)&my_pinf)[5],
-        ((unsigned char *)&my_pinf)[6],
-        ((unsigned char *)&my_pinf)[7],
-        trio_isnan(my_pinf), trio_isinf(my_pinf), trio_isfinite(my_pinf));
-  printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
-        my_ninf,
-        ((unsigned char *)&my_ninf)[0],
-        ((unsigned char *)&my_ninf)[1],
-        ((unsigned char *)&my_ninf)[2],
-        ((unsigned char *)&my_ninf)[3],
-        ((unsigned char *)&my_ninf)[4],
-        ((unsigned char *)&my_ninf)[5],
-        ((unsigned char *)&my_ninf)[6],
-        ((unsigned char *)&my_ninf)[7],
-        trio_isnan(my_ninf), trio_isinf(my_ninf), trio_isfinite(my_ninf));
-  
-# if defined(TRIO_PLATFORM_UNIX)
-  signal_handler = signal(SIGFPE, SIG_IGN);
-# endif
-  
-  my_pinf = DBL_MAX + DBL_MAX;
-  my_ninf = -my_pinf;
-  my_nan = my_pinf / my_pinf;
-
-# if defined(TRIO_PLATFORM_UNIX)
-  signal(SIGFPE, signal_handler);
-# endif
-  
-  printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
-        my_nan,
-        ((unsigned char *)&my_nan)[0],
-        ((unsigned char *)&my_nan)[1],
-        ((unsigned char *)&my_nan)[2],
-        ((unsigned char *)&my_nan)[3],
-        ((unsigned char *)&my_nan)[4],
-        ((unsigned char *)&my_nan)[5],
-        ((unsigned char *)&my_nan)[6],
-        ((unsigned char *)&my_nan)[7],
-        trio_isnan(my_nan), trio_isinf(my_nan), trio_isfinite(my_nan));
-  printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
-        my_pinf,
-        ((unsigned char *)&my_pinf)[0],
-        ((unsigned char *)&my_pinf)[1],
-        ((unsigned char *)&my_pinf)[2],
-        ((unsigned char *)&my_pinf)[3],
-        ((unsigned char *)&my_pinf)[4],
-        ((unsigned char *)&my_pinf)[5],
-        ((unsigned char *)&my_pinf)[6],
-        ((unsigned char *)&my_pinf)[7],
-        trio_isnan(my_pinf), trio_isinf(my_pinf), trio_isfinite(my_pinf));
-  printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
-        my_ninf,
-        ((unsigned char *)&my_ninf)[0],
-        ((unsigned char *)&my_ninf)[1],
-        ((unsigned char *)&my_ninf)[2],
-        ((unsigned char *)&my_ninf)[3],
-        ((unsigned char *)&my_ninf)[4],
-        ((unsigned char *)&my_ninf)[5],
-        ((unsigned char *)&my_ninf)[6],
-        ((unsigned char *)&my_ninf)[7],
-        trio_isnan(my_ninf), trio_isinf(my_ninf), trio_isfinite(my_ninf));
-  
-  return 0;
-}
-#endif
diff --git a/trio/trionan.h b/trio/trionan.h
deleted file mode 100644 (file)
index a38b1cc..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/*************************************************************************
- *
- * $Id: trionan.h,v 1.9 2005/03/27 18:52:45 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIONAN_H
-#define TRIO_TRIONAN_H
-
-#include "triodef.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !defined(TRIO_PUBLIC_NAN)
-# if !defined(TRIO_PUBLIC)
-#  define TRIO_PUBLIC
-# endif
-# define TRIO_PUBLIC_NAN TRIO_PUBLIC
-#endif
-  
-enum {
-  TRIO_FP_INFINITE,
-  TRIO_FP_NAN,
-  TRIO_FP_NORMAL,
-  TRIO_FP_SUBNORMAL,
-  TRIO_FP_ZERO
-};
-
-/*************************************************************************
- * Dependencies
- */
-
-#if defined(TRIO_EMBED_NAN)
-
-/*
- * The application that trionan is embedded in must define which functions
- * it uses.
- *
- * The following resolves internal dependencies.
- */
-  
-# if defined(TRIO_FUNC_ISNAN) \
-  || defined(TRIO_FUNC_ISINF)
-#  if !defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
-#   define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT
-#  endif
-# endif
-
-# if defined(TRIO_FUNC_NAN)
-#  if !defined(TRIO_FUNC_PINF)
-#   define TRIO_FUNC_PINF
-#  endif
-# endif
-  
-# if defined(TRIO_FUNC_NINF)
-#  if !defined(TRIO_FUNC_PINF)
-#   define TRIO_FUNC_PINF
-#  endif
-# endif
-
-#else
-
-/*
- * When trionan is not embedded all all functions are defined.
- */
-  
-# define TRIO_FUNC_NAN
-# define TRIO_FUNC_PINF
-# define TRIO_FUNC_NINF
-# define TRIO_FUNC_NZERO
-# define TRIO_FUNC_ISNAN
-# define TRIO_FUNC_ISINF
-# define TRIO_FUNC_ISFINITE
-# define TRIO_FUNC_SIGNBIT
-# define TRIO_FUNC_FPCLASSIFY
-# define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT
-  
-#endif
-
-/*************************************************************************
- * Functions
- */
-
-/*
- * Return NaN (Not-a-Number).
- */
-#if defined(TRIO_FUNC_NAN)
-TRIO_PUBLIC_NAN double
-trio_nan
-TRIO_PROTO((void));
-#endif
-
-/*
- * Return positive infinity.
- */
-#if defined(TRIO_FUNC_PINF)
-TRIO_PUBLIC_NAN double
-trio_pinf
-TRIO_PROTO((void));
-#endif
-
-/*
- * Return negative infinity.
- */
-#if defined(TRIO_FUNC_NINF)
-TRIO_PUBLIC_NAN double
-trio_ninf
-TRIO_PROTO((void));
-#endif
-
-/*
- * Return negative zero.
- */
-#if defined(TRIO_FUNC_NZERO)
-TRIO_PUBLIC_NAN double
-trio_nzero
-TRIO_PROTO((TRIO_NOARGS));
-#endif
-
-/*
- * If number is a NaN return non-zero, otherwise return zero.
- */
-#if defined(TRIO_FUNC_ISNAN)
-TRIO_PUBLIC_NAN int
-trio_isnan
-TRIO_PROTO((double number));
-#endif
-
-/*
- * If number is positive infinity return 1, if number is negative
- * infinity return -1, otherwise return 0.
- */
-#if defined(TRIO_FUNC_ISINF)
-TRIO_PUBLIC_NAN int
-trio_isinf
-TRIO_PROTO((double number));
-#endif
-
-/*
- * If number is finite return non-zero, otherwise return zero.
- */
-#if defined(TRIO_FUNC_ISFINITE)
-TRIO_PUBLIC_NAN int
-trio_isfinite
-TRIO_PROTO((double number));
-#endif
-
-#if defined(TRIO_FUNC_SIGNBIT)
-TRIO_PUBLIC_NAN int
-trio_signbit
-TRIO_PROTO((double number));
-#endif
-
-#if defined(TRIO_FUNC_FPCLASSIFY)
-TRIO_PUBLIC_NAN int
-trio_fpclassify
-TRIO_PROTO((double number));
-#endif
-
-#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
-TRIO_PUBLIC_NAN int
-trio_fpclassify_and_signbit
-TRIO_PROTO((double number, int *is_negative));
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRIO_TRIONAN_H */
diff --git a/trio/triop.h b/trio/triop.h
deleted file mode 100644 (file)
index fecc37b..0000000
+++ /dev/null
@@ -1,472 +0,0 @@
-/*************************************************************************
- *
- * $Id: triop.h,v 1.18 2009/07/05 10:14:07 breese Exp $
- *
- * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************
- *
- * Private functions, types, etc. used for callback functions.
- *
- * The ref pointer is an opaque type and should remain as such.
- * Private data must only be accessible through the getter and
- * setter functions.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIOP_H
-#define TRIO_TRIOP_H
-
-#include "triodef.h"
-
-#include <stdlib.h>
-#if defined(TRIO_COMPILER_ANCIENT)
-# include <varargs.h>
-#else
-# include <stdarg.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*************************************************************************
- * Supported standards
- */
-
-/*
- * TRIO_C99 (=0 or =1)
- *
- * Define this to 0 to disable C99 format specifier extensions, or
- * define to 1 to enable them.  The format specifiers that are
- * disabled by this switch are labelled with [C99] in the format
- * specifier documentation.
- */
-#if !defined(TRIO_C99)
-# define TRIO_C99 1
-#endif
-
-/*
- * TRIO_BSD (=0 or =1)
- *
- * Define this to 0 to disable BSD format specifier extensions, or
- * define to 1 to enable them.  The format specifiers that are
- * disabled by this switch are labelled with [BSD] in the format
- * specifier documentation.
- */
-#if !defined(TRIO_BSD)
-# define TRIO_BSD 1
-#endif
-
-/*
- * TRIO_GNU (=0 or =1)
- *
- * Define this to 0 to disable GNU format specifier extensions, or
- * define to 1 to enable them.  The format specifiers that are
- * disabled by this switch are labelled with [GNU] in the format
- * specifier documentation.
- */
-#if !defined(TRIO_GNU)
-# define TRIO_GNU 1
-#endif
-
-/*
- * TRIO_MISC (=0 or =1)
- *
- * Define this to 0 to disable miscellaneous format specifier
- * extensions, or define to 1 to enable them.  The format specifiers
- * that are disabled by this switch are labelled with [MISC] in the
- * format specifier documentation.
- */
-#if !defined(TRIO_MISC)
-# define TRIO_MISC 1
-#endif
-
-/*
- * TRIO_UNIX98 (=0 or =1)
- *
- * Define this to 0 to disable UNIX98 format specifier extensions,
- * or define to 1 to enable them.  The format specifiers that are
- * disabled by this switch are labelled with [UNIX98] in the format
- * specifier documentation.
- */
-#if !defined(TRIO_UNIX98)
-# define TRIO_UNIX98 1
-#endif
-  
-/*
- * TRIO_MICROSOFT (=0 or =1)
- *
- * Define this to 0 to disable Microsoft Visual C format specifier
- * extensions, or define to 1 to enable them.  The format specifiers
- * that are disabled by this switch are labelled with [MSVC] in the
- * format specifier documentation.
- */
-#if !defined(TRIO_MICROSOFT)
-# define TRIO_MICROSOFT 1
-#endif
-
-/*
- * TRIO_EXTENSION (=0 or =1)
- *
- * Define this to 0 to disable Trio-specific extensions, or define
- * to 1 to enable them.  This has two effects: it controls whether
- * or not the Trio user-defined formating mechanism
- * (trio_register() etc) is supported, and it enables or disables
- * Trio's own format specifier extensions.  The format specifiers
- * that are disabled by this switch are labelled with [TRIO] in
- * the format specifier documentation.
- */
-#if !defined(TRIO_EXTENSION)
-# define TRIO_EXTENSION 1
-#endif
-
-/*
- * TRIO_DEPRECATED (=0 or =1)
- *
- * Define this to 0 to disable deprecated functionality, or define
- * to 1 to enable them.
- */
-#if !defined(TRIO_DEPRECATED)
-# define TRIO_DEPRECATED 1
-#endif
-
-/*************************************************************************
- * Features
- */
-
-#if defined(TRIO_SNPRINTF_ONLY)
-# define TRIO_FEATURE_SCANF 0
-# define TRIO_FEATURE_FILE 0
-# define TRIO_FEATURE_STDIO 0
-# define TRIO_FEATURE_FD 0
-# define TRIO_FEATURE_DYNAMICSTRING 0
-# define TRIO_FEATURE_CLOSURE 0
-# define TRIO_FEATURE_STRERR 0
-# define TRIO_FEATURE_LOCALE 0
-# define TRIO_EMBED_NAN 1
-# define TRIO_EMBED_STRING 1
-#endif
-  
-/*
- * TRIO_FEATURE_SCANF (=0 or =1)
- *
- * Define this to 0 to disable all the scanf() variants, or define to 1
- * to enable them.
- */
-#if !defined(TRIO_FEATURE_SCANF)
-# define TRIO_FEATURE_SCANF 1
-#endif
-  
-/*
- * TRIO_FEATURE_FILE (=0 or =1)
- *
- * Define this to 0 to disable compilation of the trio_fprintf() and
- * trio_fscanf() family of functions, or define to 1 to enable them.
- *
- * This may be useful on an embedded platform with no filesystem.
- * Note that trio_printf() uses fwrite to write to stdout, so if you
- * do not have an implementation of fwrite() at all then you must also
- * define TRIO_FEATURE_STDIO to 0.
- */
-#if !defined(TRIO_FEATURE_FILE)
-# define TRIO_FEATURE_FILE 1
-#endif
-
-/*
- * TRIO_FEATURE_STDIO (=0 or =1)
- *
- * Define this to 0 to disable compilation of the trio_printf() and
- * trio_scanf() family of functions, or define to 1 to enable them.
- *
- * This may be useful on an embedded platform with no standard I/O.
- */
-#if !defined(TRIO_FEATURE_STDIO)
-# define TRIO_FEATURE_STDIO 1
-#endif
-
-/*
- * TRIO_FEATURE_FD (=0 or =1)
- *
- * Define this to 0 to disable compilation of the trio_dprintf() and
- * trio_dscanf() family of functions, or define to 1 to enable them.
- *
- * This may be useful on an embedded platform with no filesystem, or on
- * a platform that supports file I/O using FILE* but not using raw file
- * descriptors.
- */
-#if !defined(TRIO_FEATURE_FD)
-# define TRIO_FEATURE_FD 1
-#endif
-
-/*
- * TRIO_FEATURE_DYNAMICSTRING (=0 or =1)
- *
- * Define this to 0 to disable compilation of the trio_aprintf() 
- * family of functions, or define to 1 to enable them.
- *
- * If you define both this and TRIO_MINIMAL to 0, then Trio will never
- * call malloc or free.
- */
-#if !defined(TRIO_FEATURE_DYNAMICSTRING)
-# define TRIO_FEATURE_DYNAMICSTRING 1
-#endif
-
-/*
- * TRIO_FEATURE_CLOSURE (=0 or =1)
- *
- * Define this to 0 to disable compilation of the trio_cprintf() and
- * trio_cscanf() family of functions, or define to 1 to enable them.
- *
- * These functions are rarely needed. This saves a (small) amount of code.
- */
-#if !defined(TRIO_FEATURE_CLOSURE)
-# define TRIO_FEATURE_CLOSURE 1
-#endif
-
-/*
- * TRIO_FEATURE_ERRORCODE (=0 or =1)
- *
- * Define this to 0 to return -1 from the print and scan function on
- * error, or define to 1 to return a negative number with debugging
- * information as part of the return code.
- *
- * If enabled, the return code will be a negative number, which encodes
- * an error code and an error location. These can be decoded with the
- * TRIO_ERROR_CODE and TRIO_ERROR_POSITION macros.
- */
-#if defined(TRIO_ERRORS)
-# define TRIO_FEATURE_ERRORCODE TRIO_ERRORS
-#endif
-#if !defined(TRIO_FEATURE_ERRORCODE)
-# define TRIO_FEATURE_ERRORCODE 1
-#endif
-
-/*
- * TRIO_FEATURE_STRERR (=0 or =1)
- *
- * Define this to 0 if you do not use trio_strerror(), or define to 1 if
- * you do use it.
- *
- * This saves a (small) amount of code.
- */
-#if !defined(TRIO_FEATURE_STRERR)
-# define TRIO_FEATURE_STRERR 1
-#endif
-
-/*
- * TRIO_FEATURE_FLOAT (=0 or =1)
- *
- * Define this to 0 to disable all floating-point support, or define
- * to 1 to enable it.
- *
- * This is useful in restricted embedded platforms that do not support
- * floating-point.  Obviously you cannot use floating-point format
- * specifiers if you define this.
- *
- * Do not compile trionan.c if you disable this.
- */
-#if !defined(TRIO_FEATURE_FLOAT)
-# define TRIO_FEATURE_FLOAT 1
-#endif
-
-/*
- * TRIO_FEATURE_LOCALE (=0 or =1)
- *
- * Define this to 0 to disable customized locale support, or define
- * to 1 to enable it.
- *
- * This saves a (small) amount of code.
- */
-#if !defined(TRIO_FEATURE_LOCALE)
-# define TRIO_FEATURE_LOCALE 1
-#endif
-
-/*
- * TRIO_MINIMAL
- *
- * Define this to disable building the public trionan.h and triostr.h.
- * If you define this, then you must not compile trionan.c and triostr.c
- * separately.
- */
-#if defined(TRIO_MINIMAL)
-# if !defined(TRIO_EMBED_NAN)
-#  define TRIO_EMBED_NAN
-# endif
-# if !defined(TRIO_EMBED_STRING)
-#  define TRIO_EMBED_STRING
-# endif
-#endif
-  
-/* Does not work yet. Do not enable */
-#ifndef TRIO_FEATURE_WIDECHAR
-# define TRIO_FEATURE_WIDECHAR 0
-#endif
-
-/*************************************************************************
- * Mapping standards to internal features
- */
-
-#if !defined(TRIO_FEATURE_HEXFLOAT)
-# define TRIO_FEATURE_HEXFLOAT (TRIO_C99 && TRIO_FEATURE_FLOAT)
-#endif
-
-#if !defined(TRIO_FEATURE_LONGDOUBLE)
-# define TRIO_FEATURE_LONGDOUBLE TRIO_FEATURE_FLOAT
-#endif
-
-#if !defined(TRIO_FEATURE_ERRNO)
-# define TRIO_FEATURE_ERRNO TRIO_GNU
-#endif
-
-#if !defined(TRIO_FEATURE_QUAD)
-# define TRIO_FEATURE_QUAD (TRIO_BSD || TRIO_GNU)
-#endif
-
-#if !defined(TRIO_FEATURE_SIZE_T)
-# define TRIO_FEATURE_SIZE_T TRIO_C99
-#endif
-
-#if !defined(TRIO_FEATURE_SIZE_T_UPPER)
-# define TRIO_FEATURE_SIZE_T_UPPER TRIO_GNU
-#endif
-  
-#if !defined(TRIO_FEATURE_PTRDIFF_T)
-# define TRIO_FEATURE_PTRDIFF_T TRIO_C99
-#endif
-
-#if !defined(TRIO_FEATURE_INTMAX_T)
-# define TRIO_FEATURE_INTMAX_T TRIO_C99
-#endif
-
-#if !defined(TRIO_FEATURE_FIXED_SIZE)
-# define TRIO_FEATURE_FIXED_SIZE TRIO_MICROSOFT
-#endif
-
-#if !defined(TRIO_FEATURE_POSITIONAL)
-# define TRIO_FEATURE_POSITIONAL TRIO_UNIX98
-#endif
-
-#if !defined(TRIO_FEATURE_USER_DEFINED)
-# define TRIO_FEATURE_USER_DEFINED TRIO_EXTENSION
-#endif
-
-#if !defined(TRIO_FEATURE_BINARY)
-# define TRIO_FEATURE_BINARY TRIO_EXTENSION
-#endif
-
-#if !defined(TRIO_FEATURE_QUOTE)
-# define TRIO_FEATURE_QUOTE TRIO_EXTENSION
-#endif
-  
-#if !defined(TRIO_FEATURE_STICKY)
-# define TRIO_FEATURE_STICKY TRIO_EXTENSION
-#endif
-  
-#if !defined(TRIO_FEATURE_VARSIZE)
-# define TRIO_FEATURE_VARSIZE TRIO_EXTENSION
-#endif
-
-#if !defined(TRIO_FEATURE_ROUNDING)
-# define TRIO_FEATURE_ROUNDING TRIO_EXTENSION
-#endif
-  
-/*************************************************************************
- * Memory handling
- */
-#ifndef TRIO_MALLOC
-# define TRIO_MALLOC(n) malloc(n)
-#endif
-#ifndef TRIO_REALLOC
-# define TRIO_REALLOC(x,n) realloc((x),(n))
-#endif
-#ifndef TRIO_FREE
-# define TRIO_FREE(x) free(x)
-#endif
-
-
-/*************************************************************************
- * User-defined specifiers
- */
-
-typedef int (*trio_callback_t) TRIO_PROTO((trio_pointer_t));
-
-trio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *name));
-void trio_unregister TRIO_PROTO((trio_pointer_t handle));
-
-TRIO_CONST char *trio_get_format TRIO_PROTO((trio_pointer_t ref));
-TRIO_CONST trio_pointer_t trio_get_argument TRIO_PROTO((trio_pointer_t ref));
-
-/* Modifiers */
-int  trio_get_width TRIO_PROTO((trio_pointer_t ref));
-void trio_set_width TRIO_PROTO((trio_pointer_t ref, int width));
-int  trio_get_precision TRIO_PROTO((trio_pointer_t ref));
-void trio_set_precision TRIO_PROTO((trio_pointer_t ref, int precision));
-int  trio_get_base TRIO_PROTO((trio_pointer_t ref));
-void trio_set_base TRIO_PROTO((trio_pointer_t ref, int base));
-int  trio_get_padding TRIO_PROTO((trio_pointer_t ref));
-void trio_set_padding TRIO_PROTO((trio_pointer_t ref, int is_padding));
-int  trio_get_short TRIO_PROTO((trio_pointer_t ref)); /* h */
-void trio_set_shortshort TRIO_PROTO((trio_pointer_t ref, int is_shortshort));
-int  trio_get_shortshort TRIO_PROTO((trio_pointer_t ref)); /* hh */
-void trio_set_short TRIO_PROTO((trio_pointer_t ref, int is_short));
-int  trio_get_long TRIO_PROTO((trio_pointer_t ref)); /* l */
-void trio_set_long TRIO_PROTO((trio_pointer_t ref, int is_long));
-int  trio_get_longlong TRIO_PROTO((trio_pointer_t ref)); /* ll */
-void trio_set_longlong TRIO_PROTO((trio_pointer_t ref, int is_longlong));
-int  trio_get_longdouble TRIO_PROTO((trio_pointer_t ref)); /* L */
-void trio_set_longdouble TRIO_PROTO((trio_pointer_t ref, int is_longdouble));
-int  trio_get_alternative TRIO_PROTO((trio_pointer_t ref)); /* # */
-void trio_set_alternative TRIO_PROTO((trio_pointer_t ref, int is_alternative));
-int  trio_get_alignment TRIO_PROTO((trio_pointer_t ref)); /* - */
-void trio_set_alignment TRIO_PROTO((trio_pointer_t ref, int is_leftaligned));
-int  trio_get_spacing TRIO_PROTO((trio_pointer_t ref)); /* (space) */
-void trio_set_spacing TRIO_PROTO((trio_pointer_t ref, int is_space));
-int  trio_get_sign TRIO_PROTO((trio_pointer_t ref)); /* + */
-void trio_set_sign TRIO_PROTO((trio_pointer_t ref, int is_showsign));
-#if TRIO_FEATURE_QUOTE
-int  trio_get_quote TRIO_PROTO((trio_pointer_t ref)); /* ' */
-void trio_set_quote TRIO_PROTO((trio_pointer_t ref, int is_quote));
-#endif
-int  trio_get_upper TRIO_PROTO((trio_pointer_t ref));
-void trio_set_upper TRIO_PROTO((trio_pointer_t ref, int is_upper));
-#if TRIO_FEATURE_INTMAX_T
-int  trio_get_largest TRIO_PROTO((trio_pointer_t ref)); /* j */
-void trio_set_largest TRIO_PROTO((trio_pointer_t ref, int is_largest));
-#endif
-#if TRIO_FEATURE_PTRDIFF_T
-int  trio_get_ptrdiff TRIO_PROTO((trio_pointer_t ref)); /* t */
-void trio_set_ptrdiff TRIO_PROTO((trio_pointer_t ref, int is_ptrdiff));
-#endif
-#if TRIO_FEATURE_SIZE_T
-int  trio_get_size TRIO_PROTO((trio_pointer_t ref)); /* z / Z */
-void trio_set_size TRIO_PROTO((trio_pointer_t ref, int is_size));
-#endif
-
-/* Printing */
-int trio_print_ref TRIO_PROTO((trio_pointer_t ref, const char *format, ...));
-int trio_vprint_ref TRIO_PROTO((trio_pointer_t ref, const char *format, va_list args));
-int trio_printv_ref TRIO_PROTO((trio_pointer_t ref, const char *format, trio_pointer_t *args));
-
-void trio_print_int TRIO_PROTO((trio_pointer_t ref, int number));
-void trio_print_uint TRIO_PROTO((trio_pointer_t ref, unsigned int number));
-/*  void trio_print_long TRIO_PROTO((trio_pointer_t ref, long number)); */
-/*  void trio_print_ulong TRIO_PROTO((trio_pointer_t ref, unsigned long number)); */
-void trio_print_double TRIO_PROTO((trio_pointer_t ref, double number));
-void trio_print_string TRIO_PROTO((trio_pointer_t ref, TRIO_CONST char *string));
-void trio_print_pointer TRIO_PROTO((trio_pointer_t ref, trio_pointer_t pointer));
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* TRIO_TRIOP_H */
diff --git a/trio/triostr.c b/trio/triostr.c
deleted file mode 100644 (file)
index ce5cc74..0000000
+++ /dev/null
@@ -1,2385 +0,0 @@
-/*************************************************************************
- *
- * $Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/*************************************************************************
- * Include files
- */
-
-#if defined(HAVE_CONFIG_H)
-# include <config.h>
-#endif
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include "triodef.h"
-#include "triostr.h"
-#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
-# define USE_MATH
-#endif
-#if defined(USE_MATH)
-# include <math.h>
-#endif
-
-/*************************************************************************
- * Definitions
- */
-
-#if !defined(TRIO_PUBLIC_STRING)
-# define TRIO_PUBLIC_STRING TRIO_PUBLIC
-#endif
-#if !defined(TRIO_PRIVATE_STRING)
-# define TRIO_PRIVATE_STRING TRIO_PRIVATE
-#endif
-
-#if !defined(NULL)
-# define NULL 0
-#endif
-#if !defined(NIL)
-# define NIL ((char)0)
-#endif
-#if !defined(FALSE)
-# define FALSE (1 == 0)
-# define TRUE (! FALSE)
-#endif
-#if !defined(BOOLEAN_T)
-# define BOOLEAN_T int
-#endif
-
-#if defined(USE_MATH)
-# if defined(PREDEF_STANDARD_C99)
-#  if defined(TRIO_COMPILER_DECC)
-#   if (TRIO_COMPILER_DECC - 0 > 80000000)
-/*
- * The OSF/1 runtime that comes with the DECC compiler does not support
- * hexfloats conversion.
- */
-#    define USE_STRTOD
-#    define USE_STRTOF
-#   endif
-#  else
-#   define USE_STRTOD
-#   define USE_STRTOF
-#  endif
-# else
-#  if defined(TRIO_COMPILER_VISUALC)
-#   define USE_STRTOD
-#  endif
-#endif
-#endif
-
-#if defined(TRIO_PLATFORM_UNIX)
-# if defined(PREDEF_STANDARD_UNIX95)
-#  define USE_STRCASECMP
-#  define USE_STRNCASECMP
-# endif
-# if defined(TRIO_PLATFORM_SUNOS)
-#  define USE_SYS_ERRLIST
-# else
-#  define USE_STRERROR
-# endif
-# if defined(TRIO_PLATFORM_QNX)
-#  define strcasecmp(x,y) stricmp(x,y)
-#  define strncasecmp(x,y,n) strnicmp(x,y,n)
-# endif
-#endif
-
-#if defined(TRIO_PLATFORM_WIN32)
-# define USE_STRCASECMP
-# if defined(TRIO_PLATFORM_WINCE)
-#  define strcasecmp(x,y) _stricmp(x,y)
-# else
-#  define strcasecmp(x,y) strcmpi(x,y)
-# endif
-#endif
-
-#if !defined(HAVE_CONFIG_H)
-# if !(defined(TRIO_PLATFORM_SUNOS))
-#  define HAVE_TOLOWER
-#  define HAVE_TOUPPER
-# endif
-#endif
-
-#if defined(USE_MATH) && !defined(TRIO_NO_POWL)
-# if !defined(HAVE_POWL)
-#  if defined(PREDEF_STANDARD_C99) \
-   || defined(PREDEF_STANDARD_UNIX03)
-#   define HAVE_POWL
-#  else
-#   if defined(TRIO_COMPILER_VISUALC)
-#    if defined(powl)
-#     define HAVE_POWL
-#    endif
-#   endif
-#  endif
-# endif
-#endif
-
-#if defined(HAVE_POWL)
-# define trio_powl(x,y) powl((x),(y))
-#else
-# define trio_powl(x,y) pow((double)(x),(double)(y))
-#endif
-
-#if defined(TRIO_FUNC_TO_UPPER) \
- || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) \
- || (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) \
- || defined(TRIO_FUNC_MATCH) \
- || defined(TRIO_FUNC_TO_LONG_DOUBLE) \
- || defined(TRIO_FUNC_UPPER)
-# define TRIO_FUNC_INTERNAL_TO_UPPER
-#endif
-
-/*************************************************************************
- * Structures
- */
-
-struct _trio_string_t
-{
-  char *content;
-  size_t length;
-  size_t allocated;
-};
-
-/*************************************************************************
- * Constants
- */
-
-#if !defined(TRIO_EMBED_STRING)
-static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $";
-#endif
-
-/*************************************************************************
- * Static String Functions
- */
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_static.h"
-#endif
-/** @addtogroup StaticStrings
-    @{
-*/
-
-/*
- * internal_duplicate_max
- */
-#if defined(TRIO_FUNC_DUPLICATE) \
- || defined(TRIO_FUNC_DUPLICATE_MAX) \
- || defined(TRIO_FUNC_STRING_DUPLICATE) \
- || defined(TRIO_FUNC_XSTRING_DUPLICATE)
-
-TRIO_PRIVATE_STRING char *
-internal_duplicate_max
-TRIO_ARGS2((source, size),
-          TRIO_CONST char *source,
-          size_t size)
-{
-  char *target;
-
-  assert(source);
-
-  /* Make room for string plus a terminating zero */
-  size++;
-  target = trio_create(size);
-  if (target)
-    {
-      trio_copy_max(target, size, source);
-    }
-  return target;
-}
-
-#endif
-
-/*
- * internal_string_alloc
- */
-#if defined(TRIO_FUNC_STRING_CREATE) \
- || defined(TRIO_FUNC_STRING_DUPLICATE) \
- || defined(TRIO_FUNC_XSTRING_DUPLICATE)
-
-TRIO_PRIVATE_STRING trio_string_t *
-internal_string_alloc(TRIO_NOARGS)
-{
-  trio_string_t *self;
-
-  self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
-  if (self)
-    {
-      self->content = NULL;
-      self->length = 0;
-      self->allocated = 0;
-    }
-  return self;
-}
-
-#endif
-
-/*
- * internal_string_grow
- *
- * The size of the string will be increased by 'delta' characters. If
- * 'delta' is zero, the size will be doubled.
- */
-#if defined(TRIO_FUNC_STRING_CREATE) \
- || defined(TRIO_FUNC_STRING_APPEND) \
- || defined(TRIO_FUNC_XSTRING_APPEND) \
- || defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
-
-TRIO_PRIVATE_STRING BOOLEAN_T
-internal_string_grow
-TRIO_ARGS2((self, delta),
-          trio_string_t *self,
-          size_t delta)
-{
-  BOOLEAN_T status = FALSE;
-  char *new_content;
-  size_t new_size;
-
-  new_size = (delta == 0)
-    ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
-    : self->allocated + delta;
-
-  new_content = (char *)TRIO_REALLOC(self->content, new_size);
-  if (new_content)
-    {
-      self->content = new_content;
-      self->allocated = new_size;
-      status = TRUE;
-    }
-  return status;
-}
-
-#endif
-
-/*
- * internal_string_grow_to
- *
- * The size of the string will be increased to 'length' plus one characters.
- * If 'length' is less than the original size, the original size will be
- * used (that is, the size of the string is never decreased).
- */
-#if defined(TRIO_FUNC_STRING_APPEND) \
- || defined(TRIO_FUNC_XSTRING_APPEND) \
- || defined(TRIO_FUNC_XSTRING_APPEND_MAX)
-
-TRIO_PRIVATE_STRING BOOLEAN_T
-internal_string_grow_to
-TRIO_ARGS2((self, length),
-          trio_string_t *self,
-          size_t length)
-{
-  length++; /* Room for terminating zero */
-  return (self->allocated < length)
-    ? internal_string_grow(self, length - self->allocated)
-    : TRUE;
-}
-
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_TO_UPPER)
-
-TRIO_PRIVATE_STRING TRIO_INLINE int
-internal_to_upper
-TRIO_ARGS1((source),
-          int source)
-{
-# if defined(HAVE_TOUPPER)
-
-  return toupper(source);
-
-# else
-
-  /* Does not handle locales or non-contiguous alphabetic characters */
-  return ((source >= (int)'a') && (source <= (int)'z'))
-    ? source - 'a' + 'A'
-    : source;
-
-# endif
-}
-
-#endif
-
-
-/**
-   Create new string.
-
-   @param size Size of new string.
-   @return Pointer to string, or NULL if allocation failed.
-*/
-#if defined(TRIO_FUNC_CREATE)
-
-TRIO_PUBLIC_STRING char *
-trio_create
-TRIO_ARGS1((size),
-          size_t size)
-{
-  return (char *)TRIO_MALLOC(size);
-}
-
-#endif
-
-/**
-   Destroy string.
-
-   @param string String to be freed.
-*/
-#if defined(TRIO_FUNC_DESTROY)
-
-TRIO_PUBLIC_STRING void
-trio_destroy
-TRIO_ARGS1((string),
-          char *string)
-{
-  if (string)
-    {
-      TRIO_FREE(string);
-    }
-}
-
-#endif
-
-/**
-   Count the number of characters in a string.
-
-   @param string String to measure.
-   @return Number of characters in @p string.
-*/
-#if defined(TRIO_FUNC_LENGTH)
-
-TRIO_PUBLIC_STRING size_t
-trio_length
-TRIO_ARGS1((string),
-          TRIO_CONST char *string)
-{
-  return strlen(string);
-}
-
-#endif
-
-/**
-   Count at most @p max characters in a string.
-
-   @param string String to measure.
-   @param max Maximum number of characters to count.
-   @return The maximum value of @p max and number of characters in @p string.
-*/
-#if defined(TRIO_FUNC_LENGTH_MAX)
-
-TRIO_PUBLIC_STRING size_t
-trio_length_max
-TRIO_ARGS2((string, max),
-          TRIO_CONST char *string,
-          size_t max)
-{
-  size_t i;
-
-  for (i = 0; i < max; ++i)
-    {
-      if (string[i] == 0)
-       break;
-    }
-  return i;
-}
-
-#endif
-
-/**
-   Append @p source at the end of @p target.
-
-   @param target Target string.
-   @param source Source string.
-   @return Boolean value indicating success or failure.
-
-   @pre @p target must point to a memory chunk with sufficient room to
-   contain the @p target string and @p source string.
-   @pre No boundary checking is performed, so insufficient memory will
-   result in a buffer overrun.
-   @post @p target will be zero terminated.
-*/
-#if defined(TRIO_FUNC_APPEND)
-
-TRIO_PUBLIC_STRING int
-trio_append
-TRIO_ARGS2((target, source),
-          char *target,
-          TRIO_CONST char *source)
-{
-  assert(target);
-  assert(source);
-
-  return (strcat(target, source) != NULL);
-}
-
-#endif
-
-/**
-   Append at most @p max characters from @p source to @p target.
-
-   @param target Target string.
-   @param max Maximum number of characters to append.
-   @param source Source string.
-   @return Boolean value indicating success or failure.
-
-   @pre @p target must point to a memory chuck with sufficient room to
-   contain the @p target string and the @p source string (at most @p max
-   characters).
-   @pre No boundary checking is performed, so insufficient memory will
-   result in a buffer overrun.
-   @post @p target will be zero terminated.
-*/
-#if defined(TRIO_FUNC_APPEND_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_append_max
-TRIO_ARGS3((target, max, source),
-          char *target,
-          size_t max,
-          TRIO_CONST char *source)
-{
-  size_t length;
-
-  assert(target);
-  assert(source);
-
-  length = trio_length(target);
-
-  if (max > length)
-    {
-      strncat(target, source, max - length - 1);
-    }
-  return TRUE;
-}
-
-#endif
-
-/**
-   Determine if a string contains a substring.
-
-   @param string String to be searched.
-   @param substring String to be found.
-   @return Boolean value indicating success or failure.
-*/
-#if defined(TRIO_FUNC_CONTAINS)
-
-TRIO_PUBLIC_STRING int
-trio_contains
-TRIO_ARGS2((string, substring),
-          TRIO_CONST char *string,
-          TRIO_CONST char *substring)
-{
-  assert(string);
-  assert(substring);
-
-  return (0 != strstr(string, substring));
-}
-
-#endif
-
-/**
-   Copy @p source to @p target.
-
-   @param target Target string.
-   @param source Source string.
-   @return Boolean value indicating success or failure.
-
-   @pre @p target must point to a memory chunk with sufficient room to
-   contain the @p source string.
-   @pre No boundary checking is performed, so insufficient memory will
-   result in a buffer overrun.
-   @post @p target will be zero terminated.
-*/
-#if defined(TRIO_FUNC_COPY)
-
-TRIO_PUBLIC_STRING int
-trio_copy
-TRIO_ARGS2((target, source),
-          char *target,
-          TRIO_CONST char *source)
-{
-  assert(target);
-  assert(source);
-
-  (void)strcpy(target, source);
-  return TRUE;
-}
-
-#endif
-
-/**
-   Copy at most @p max - 1 characters from @p source to @p target.
-
-   @param target Target string.
-   @param max Maximum number of characters to append (one of which is
-   a NUL terminator).  In other words @p source must point to at least
-   @p max - 1 bytes, but @p target must point to at least @p max
-   bytes.
-   @param source Source string.
-   @return Boolean value indicating success or failure.
-
-   @pre @p target must point to a memory chunk with sufficient room to
-   contain the @p source string and a NUL terminator (at most @p max
-   bytes total).
-   @pre No boundary checking is performed, so insufficient memory will
-   result in a buffer overrun.
-   @post @p target will be zero terminated.
-*/
-#if defined(TRIO_FUNC_COPY_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_copy_max
-TRIO_ARGS3((target, max, source),
-          char *target,
-          size_t max,
-          TRIO_CONST char *source)
-{
-  assert(target);
-  assert(source);
-  assert(max > 0); /* Includes != 0 */
-
-  (void)strncpy(target, source, max - 1);
-  target[max - 1] = (char)0;
-  return TRUE;
-}
-
-#endif
-
-/**
-   Duplicate @p source.
-
-   @param source Source string.
-   @return A copy of the @p source string.
-
-   @post @p target will be zero terminated.
-*/
-#if defined(TRIO_FUNC_DUPLICATE)
-
-TRIO_PUBLIC_STRING char *
-trio_duplicate
-TRIO_ARGS1((source),
-          TRIO_CONST char *source)
-{
-  return internal_duplicate_max(source, trio_length(source));
-}
-
-#endif
-
-/**
-   Duplicate at most @p max characters of @p source.
-
-   @param source Source string.
-   @param max Maximum number of characters to duplicate.
-   @return A copy of the @p source string.
-
-   @post @p target will be zero terminated.
-*/
-#if defined(TRIO_FUNC_DUPLICATE_MAX)
-
-TRIO_PUBLIC_STRING char *
-trio_duplicate_max
-TRIO_ARGS2((source, max),
-          TRIO_CONST char *source,
-          size_t max)
-{
-  size_t length;
-
-  assert(source);
-  assert(max > 0);
-
-  length = trio_length(source);
-  if (length > max)
-    {
-      length = max;
-    }
-  return internal_duplicate_max(source, length);
-}
-
-#endif
-
-/**
-   Compare if two strings are equal.
-
-   @param first First string.
-   @param second Second string.
-   @return Boolean indicating whether the two strings are equal or not.
-
-   Case-insensitive comparison.
-*/
-#if defined(TRIO_FUNC_EQUAL)
-
-TRIO_PUBLIC_STRING int
-trio_equal
-TRIO_ARGS2((first, second),
-          TRIO_CONST char *first,
-          TRIO_CONST char *second)
-{
-  assert(first);
-  assert(second);
-
-  if ((first != NULL) && (second != NULL))
-    {
-# if defined(USE_STRCASECMP)
-      return (0 == strcasecmp(first, second));
-# else
-      while ((*first != NIL) && (*second != NIL))
-       {
-         if (internal_to_upper(*first) != internal_to_upper(*second))
-           {
-             break;
-           }
-         first++;
-         second++;
-       }
-      return ((*first == NIL) && (*second == NIL));
-# endif
-    }
-  return FALSE;
-}
-
-#endif
-
-/**
-   Compare if two strings are equal.
-
-   @param first First string.
-   @param second Second string.
-   @return Boolean indicating whether the two strings are equal or not.
-
-   Case-sensitive comparison.
-*/
-#if defined(TRIO_FUNC_EQUAL_CASE)
-
-TRIO_PUBLIC_STRING int
-trio_equal_case
-TRIO_ARGS2((first, second),
-          TRIO_CONST char *first,
-          TRIO_CONST char *second)
-{
-  assert(first);
-  assert(second);
-
-  if ((first != NULL) && (second != NULL))
-    {
-      return (0 == strcmp(first, second));
-    }
-  return FALSE;
-}
-
-#endif
-
-/**
-   Compare if two strings up until the first @p max characters are equal.
-
-   @param first First string.
-   @param max Maximum number of characters to compare.
-   @param second Second string.
-   @return Boolean indicating whether the two strings are equal or not.
-
-   Case-sensitive comparison.
-*/
-#if defined(TRIO_FUNC_EQUAL_CASE_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_equal_case_max
-TRIO_ARGS3((first, max, second),
-          TRIO_CONST char *first,
-          size_t max,
-          TRIO_CONST char *second)
-{
-  assert(first);
-  assert(second);
-
-  if ((first != NULL) && (second != NULL))
-    {
-      return (0 == strncmp(first, second, max));
-    }
-  return FALSE;
-}
-
-#endif
-
-/**
-   Compare if two strings are equal.
-
-   @param first First string.
-   @param second Second string.
-   @return Boolean indicating whether the two strings are equal or not.
-
-   Collating characters are considered equal.
-*/
-#if defined(TRIO_FUNC_EQUAL_LOCALE)
-
-TRIO_PUBLIC_STRING int
-trio_equal_locale
-TRIO_ARGS2((first, second),
-          TRIO_CONST char *first,
-          TRIO_CONST char *second)
-{
-  assert(first);
-  assert(second);
-
-# if defined(LC_COLLATE)
-  return (strcoll(first, second) == 0);
-# else
-  return trio_equal(first, second);
-# endif
-}
-
-#endif
-
-/**
-   Compare if two strings up until the first @p max characters are equal.
-
-   @param first First string.
-   @param max Maximum number of characters to compare.
-   @param second Second string.
-   @return Boolean indicating whether the two strings are equal or not.
-
-   Case-insensitive comparison.
-*/
-#if defined(TRIO_FUNC_EQUAL_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_equal_max
-TRIO_ARGS3((first, max, second),
-          TRIO_CONST char *first,
-          size_t max,
-          TRIO_CONST char *second)
-{
-  assert(first);
-  assert(second);
-
-  if ((first != NULL) && (second != NULL))
-    {
-# if defined(USE_STRNCASECMP)
-      return (0 == strncasecmp(first, second, max));
-# else
-      /* Not adequately tested yet */
-      size_t cnt = 0;
-      while ((*first != NIL) && (*second != NIL) && (cnt <= max))
-       {
-         if (internal_to_upper(*first) != internal_to_upper(*second))
-           {
-             break;
-           }
-         first++;
-         second++;
-         cnt++;
-       }
-      return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
-# endif
-    }
-  return FALSE;
-}
-
-#endif
-
-/**
-   Provide a textual description of an error code (errno).
-
-   @param error_number Error number.
-   @return Textual description of @p error_number.
-*/
-#if defined(TRIO_FUNC_ERROR)
-
-TRIO_PUBLIC_STRING TRIO_CONST char *
-trio_error
-TRIO_ARGS1((error_number),
-          int error_number)
-{
-# if defined(USE_STRERROR)
-
-  return strerror(error_number);
-
-# else
-#  if defined(USE_SYS_ERRLIST)
-
-  extern char *sys_errlist[];
-  extern int sys_nerr;
-
-  return ((error_number < 0) || (error_number >= sys_nerr))
-    ? "unknown"
-    : sys_errlist[error_number];
-
-#  else
-
-  return "unknown";
-
-#  endif
-# endif
-}
-
-#endif
-
-/**
-   Format the date/time according to @p format.
-
-   @param target Target string.
-   @param max Maximum number of characters to format.
-   @param format Formatting string.
-   @param datetime Date/time structure.
-   @return Number of formatted characters.
-
-   The formatting string accepts the same specifiers as the standard C
-   function strftime.
-*/
-#if defined(TRIO_FUNC_FORMAT_DATE_MAX)
-
-TRIO_PUBLIC_STRING size_t
-trio_format_date_max
-TRIO_ARGS4((target, max, format, datetime),
-          char *target,
-          size_t max,
-          TRIO_CONST char *format,
-          TRIO_CONST struct tm *datetime)
-{
-  assert(target);
-  assert(format);
-  assert(datetime);
-  assert(max > 0);
-
-  return strftime(target, max, format, datetime);
-}
-
-#endif
-
-/**
-   Calculate a hash value for a string.
-
-   @param string String to be calculated on.
-   @param type Hash function.
-   @return Calculated hash value.
-
-   @p type can be one of the following
-   @li @c TRIO_HASH_PLAIN Plain hash function.
-*/
-#if defined(TRIO_FUNC_HASH)
-
-TRIO_PUBLIC_STRING unsigned long
-trio_hash
-TRIO_ARGS2((string, type),
-          TRIO_CONST char *string,
-          int type)
-{
-  unsigned long value = 0L;
-  char ch;
-
-  assert(string);
-
-  switch (type)
-    {
-    case TRIO_HASH_PLAIN:
-      while ( (ch = *string++) != NIL )
-       {
-         value *= 31;
-         value += (unsigned long)ch;
-       }
-      break;
-    default:
-      assert(FALSE);
-      break;
-    }
-  return value;
-}
-
-#endif
-
-/**
-   Find first occurrence of a character in a string.
-
-   @param string String to be searched.
-   @param character Character to be found.
-   @return A pointer to the found character, or NULL if character was not found.
- */
-#if defined(TRIO_FUNC_INDEX)
-
-TRIO_PUBLIC_STRING char *
-trio_index
-TRIO_ARGS2((string, character),
-          TRIO_CONST char *string,
-          int character)
-{
-  assert(string);
-
-  return strchr(string, character);
-}
-
-#endif
-
-/**
-   Find last occurrence of a character in a string.
-
-   @param string String to be searched.
-   @param character Character to be found.
-   @return A pointer to the found character, or NULL if character was not found.
- */
-#if defined(TRIO_FUNC_INDEX_LAST)
-
-TRIO_PUBLIC_STRING char *
-trio_index_last
-TRIO_ARGS2((string, character),
-          TRIO_CONST char *string,
-          int character)
-{
-  assert(string);
-
-  return strchr(string, character);
-}
-
-#endif
-
-/**
-   Convert the alphabetic letters in the string to lower-case.
-
-   @param target String to be converted.
-   @return Number of processed characters (converted or not).
-*/
-#if defined(TRIO_FUNC_LOWER)
-
-TRIO_PUBLIC_STRING int
-trio_lower
-TRIO_ARGS1((target),
-          char *target)
-{
-  assert(target);
-
-  return trio_span_function(target, target, trio_to_lower);
-}
-
-#endif
-
-/**
-   Compare two strings using wildcards.
-
-   @param string String to be searched.
-   @param pattern Pattern, including wildcards, to search for.
-   @return Boolean value indicating success or failure.
-
-   Case-insensitive comparison.
-
-   The following wildcards can be used
-   @li @c * Match any number of characters.
-   @li @c ? Match a single character.
-*/
-#if defined(TRIO_FUNC_MATCH)
-
-TRIO_PUBLIC_STRING int
-trio_match
-TRIO_ARGS2((string, pattern),
-          TRIO_CONST char *string,
-          TRIO_CONST char *pattern)
-{
-  assert(string);
-  assert(pattern);
-
-  for (; ('*' != *pattern); ++pattern, ++string)
-    {
-      if (NIL == *string)
-       {
-         return (NIL == *pattern);
-       }
-      if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern))
-         && ('?' != *pattern))
-       {
-         return FALSE;
-       }
-    }
-  /* two-line patch to prevent *too* much recursiveness: */
-  while ('*' == pattern[1])
-    pattern++;
-
-  do
-    {
-      if ( trio_match(string, &pattern[1]) )
-       {
-         return TRUE;
-       }
-    }
-  while (*string++);
-
-  return FALSE;
-}
-
-#endif
-
-/**
-   Compare two strings using wildcards.
-
-   @param string String to be searched.
-   @param pattern Pattern, including wildcards, to search for.
-   @return Boolean value indicating success or failure.
-
-   Case-sensitive comparison.
-
-   The following wildcards can be used
-   @li @c * Match any number of characters.
-   @li @c ? Match a single character.
-*/
-#if defined(TRIO_FUNC_MATCH_CASE)
-
-TRIO_PUBLIC_STRING int
-trio_match_case
-TRIO_ARGS2((string, pattern),
-          TRIO_CONST char *string,
-          TRIO_CONST char *pattern)
-{
-  assert(string);
-  assert(pattern);
-
-  for (; ('*' != *pattern); ++pattern, ++string)
-    {
-      if (NIL == *string)
-       {
-         return (NIL == *pattern);
-       }
-      if ((*string != *pattern)
-         && ('?' != *pattern))
-       {
-         return FALSE;
-       }
-    }
-  /* two-line patch to prevent *too* much recursiveness: */
-  while ('*' == pattern[1])
-    pattern++;
-
-  do
-    {
-      if ( trio_match_case(string, &pattern[1]) )
-       {
-         return TRUE;
-       }
-    }
-  while (*string++);
-
-  return FALSE;
-}
-
-#endif
-
-/**
-   Execute a function on each character in string.
-
-   @param target Target string.
-   @param source Source string.
-   @param Function Function to be executed.
-   @return Number of processed characters.
-*/
-#if defined(TRIO_FUNC_SPAN_FUNCTION)
-
-TRIO_PUBLIC_STRING size_t
-trio_span_function
-TRIO_ARGS3((target, source, Function),
-          char *target,
-          TRIO_CONST char *source,
-          int (*Function) TRIO_PROTO((int)))
-{
-  size_t count = 0;
-
-  assert(target);
-  assert(source);
-  assert(Function);
-
-  while (*source != NIL)
-    {
-      *target++ = Function(*source++);
-      count++;
-    }
-  return count;
-}
-
-#endif
-
-/**
-   Search for a substring in a string.
-
-   @param string String to be searched.
-   @param substring String to be found.
-   @return Pointer to first occurrence of @p substring in @p string, or NULL
-   if no match was found.
-*/
-#if defined(TRIO_FUNC_SUBSTRING)
-
-TRIO_PUBLIC_STRING char *
-trio_substring
-TRIO_ARGS2((string, substring),
-          TRIO_CONST char *string,
-          TRIO_CONST char *substring)
-{
-  assert(string);
-  assert(substring);
-
-  return strstr(string, substring);
-}
-
-#endif
-
-/**
-   Search for a substring in the first @p max characters of a string.
-
-   @param string String to be searched.
-   @param max Maximum characters to be searched.
-   @param substring String to be found.
-   @return Pointer to first occurrence of @p substring in @p string, or NULL
-   if no match was found.
-*/
-#if defined(TRIO_FUNC_SUBSTRING_MAX)
-
-TRIO_PUBLIC_STRING char *
-trio_substring_max
-TRIO_ARGS3((string, max, substring),
-          TRIO_CONST char *string,
-          size_t max,
-          TRIO_CONST char *substring)
-{
-  size_t count;
-  size_t size;
-  char *result = NULL;
-
-  assert(string);
-  assert(substring);
-
-  size = trio_length(substring);
-  if (size <= max)
-    {
-      for (count = 0; count <= max - size; count++)
-       {
-         if (trio_equal_max(substring, size, &string[count]))
-           {
-             result = (char *)&string[count];
-             break;
-           }
-       }
-    }
-  return result;
-}
-
-#endif
-
-/**
-   Tokenize string.
-
-   @param string String to be tokenized.
-   @param delimiters String containing list of delimiting characters.
-   @return Start of new token.
-
-   @warning @p string will be destroyed.
-*/
-#if defined(TRIO_FUNC_TOKENIZE)
-
-TRIO_PUBLIC_STRING char *
-trio_tokenize
-TRIO_ARGS2((string, delimiters),
-          char *string,
-          TRIO_CONST char *delimiters)
-{
-  assert(delimiters);
-
-  return strtok(string, delimiters);
-}
-
-#endif
-
-/**
-   Convert string to floating-point number.
-
-   @param source String to be converted.
-   @param endp Pointer to end of the converted string.
-   @return A floating-point number.
-
-   The following Extended Backus-Naur form is used
-   @verbatim
-   double        ::= [ <sign> ]
-                     ( <number> |
-                       <number> <decimal_point> <number> |
-                       <decimal_point> <number> )
-                     [ <exponential> [ <sign> ] <number> ]
-   number        ::= 1*( <digit> )
-   digit         ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
-   exponential   ::= ( 'e' | 'E' )
-   sign          ::= ( '-' | '+' )
-   decimal_point ::= '.'
-   @endverbatim
-*/
-#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
-
-/* FIXME: Add EBNF for hex-floats */
-TRIO_PUBLIC_STRING trio_long_double_t
-trio_to_long_double
-TRIO_ARGS2((source, endp),
-          TRIO_CONST char *source,
-          char **endp)
-{
-# if defined(USE_STRTOLD)
-  return strtold(source, endp);
-# else
-  int isNegative = FALSE;
-  int isExponentNegative = FALSE;
-  trio_long_double_t integer = 0.0;
-  trio_long_double_t fraction = 0.0;
-  unsigned long exponent = 0;
-  trio_long_double_t base;
-  trio_long_double_t fracdiv = 1.0;
-  trio_long_double_t value = 0.0;
-
-  /* First try hex-floats */
-  if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
-    {
-      base = 16.0;
-      source += 2;
-      while (isxdigit((int)*source))
-       {
-         integer *= base;
-         integer += (isdigit((int)*source)
-                     ? (*source - '0')
-                     : 10 + (internal_to_upper((int)*source) - 'A'));
-         source++;
-       }
-      if (*source == '.')
-       {
-         source++;
-         while (isxdigit((int)*source))
-           {
-             fracdiv /= base;
-             fraction += fracdiv * (isdigit((int)*source)
-                                    ? (*source - '0')
-                                    : 10 + (internal_to_upper((int)*source) - 'A'));
-             source++;
-           }
-         if ((*source == 'p') || (*source == 'P'))
-           {
-             source++;
-             if ((*source == '+') || (*source == '-'))
-               {
-                 isExponentNegative = (*source == '-');
-                 source++;
-               }
-             while (isdigit((int)*source))
-               {
-                 exponent *= 10;
-                 exponent += (*source - '0');
-                 source++;
-               }
-           }
-       }
-      /* For later use with exponent */
-      base = 2.0;
-    }
-  else /* Then try normal decimal floats */
-    {
-      base = 10.0;
-      isNegative = (*source == '-');
-      /* Skip sign */
-      if ((*source == '+') || (*source == '-'))
-       source++;
-
-      /* Integer part */
-      while (isdigit((int)*source))
-       {
-         integer *= base;
-         integer += (*source - '0');
-         source++;
-       }
-
-      if (*source == '.')
-       {
-         source++; /* skip decimal point */
-         while (isdigit((int)*source))
-           {
-             fracdiv /= base;
-             fraction += (*source - '0') * fracdiv;
-             source++;
-           }
-       }
-      if ((*source == 'e')
-         || (*source == 'E')
-#  if TRIO_MICROSOFT
-         || (*source == 'd')
-         || (*source == 'D')
-#  endif
-         )
-       {
-         source++; /* Skip exponential indicator */
-         isExponentNegative = (*source == '-');
-         if ((*source == '+') || (*source == '-'))
-           source++;
-         while (isdigit((int)*source))
-           {
-             exponent *= (int)base;
-             exponent += (*source - '0');
-             source++;
-           }
-       }
-    }
-
-  value = integer + fraction;
-  if (exponent != 0)
-    {
-      if (isExponentNegative)
-       value /= trio_powl(base, (trio_long_double_t)exponent);
-      else
-       value *= trio_powl(base, (trio_long_double_t)exponent);
-    }
-  if (isNegative)
-    value = -value;
-
-  if (endp)
-    *endp = (char *)source;
-  return value;
-# endif
-}
-
-#endif
-
-/**
-   Convert string to floating-point number.
-
-   @param source String to be converted.
-   @param endp Pointer to end of the converted string.
-   @return A floating-point number.
-
-   See @ref trio_to_long_double.
-*/
-#if defined(TRIO_FUNC_TO_DOUBLE)
-
-TRIO_PUBLIC_STRING double
-trio_to_double
-TRIO_ARGS2((source, endp),
-          TRIO_CONST char *source,
-          char **endp)
-{
-#if defined(USE_STRTOD)
-  return strtod(source, endp);
-#else
-  return (double)trio_to_long_double(source, endp);
-#endif
-}
-
-#endif
-
-/**
-   Convert string to floating-point number.
-
-   @param source String to be converted.
-   @param endp Pointer to end of the converted string.
-   @return A floating-point number.
-
-   See @ref trio_to_long_double.
-*/
-#if defined(TRIO_FUNC_TO_FLOAT)
-
-TRIO_PUBLIC_STRING float
-trio_to_float
-TRIO_ARGS2((source, endp),
-          TRIO_CONST char *source,
-          char **endp)
-{
-#  if defined(USE_STRTOF)
-  return strtof(source, endp);
-#  else
-  return (float)trio_to_long_double(source, endp);
-#  endif
-}
-
-#endif
-
-/**
-   Convert string to signed integer.
-
-   @param string String to be converted.
-   @param endp Pointer to end of converted string.
-   @param base Radix number of number.
-*/
-#if defined(TRIO_FUNC_TO_LONG)
-
-TRIO_PUBLIC_STRING long
-trio_to_long
-TRIO_ARGS3((string, endp, base),
-          TRIO_CONST char *string,
-          char **endp,
-          int base)
-{
-  assert(string);
-  assert((base >= 2) && (base <= 36));
-
-  return strtol(string, endp, base);
-}
-
-#endif
-
-/**
-   Convert one alphabetic letter to lower-case.
-
-   @param source The letter to be converted.
-   @return The converted letter.
-*/
-#if defined(TRIO_FUNC_TO_LOWER)
-
-TRIO_PUBLIC_STRING int
-trio_to_lower
-TRIO_ARGS1((source),
-          int source)
-{
-# if defined(HAVE_TOLOWER)
-
-  return tolower(source);
-
-# else
-
-  /* Does not handle locales or non-contiguous alphabetic characters */
-  return ((source >= (int)'A') && (source <= (int)'Z'))
-    ? source - 'A' + 'a'
-    : source;
-
-# endif
-}
-
-#endif
-
-/**
-   Convert string to unsigned integer.
-
-   @param string String to be converted.
-   @param endp Pointer to end of converted string.
-   @param base Radix number of number.
-*/
-#if defined(TRIO_FUNC_TO_UNSIGNED_LONG)
-
-TRIO_PUBLIC_STRING unsigned long
-trio_to_unsigned_long
-TRIO_ARGS3((string, endp, base),
-          TRIO_CONST char *string,
-          char **endp,
-          int base)
-{
-  assert(string);
-  assert((base >= 2) && (base <= 36));
-
-  return strtoul(string, endp, base);
-}
-
-#endif
-
-/**
-   Convert one alphabetic letter to upper-case.
-
-   @param source The letter to be converted.
-   @return The converted letter.
-*/
-#if defined(TRIO_FUNC_TO_UPPER)
-
-TRIO_PUBLIC_STRING int
-trio_to_upper
-TRIO_ARGS1((source),
-          int source)
-{
-  return internal_to_upper(source);
-}
-
-#endif
-
-/**
-   Convert the alphabetic letters in the string to upper-case.
-
-   @param target The string to be converted.
-   @return The number of processed characters (converted or not).
-*/
-#if defined(TRIO_FUNC_UPPER)
-
-TRIO_PUBLIC_STRING int
-trio_upper
-TRIO_ARGS1((target),
-          char *target)
-{
-  assert(target);
-
-  return trio_span_function(target, target, internal_to_upper);
-}
-
-#endif
-
-/** @} End of StaticStrings */
-
-
-/*************************************************************************
- * Dynamic String Functions
- */
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_dynamic.h"
-#endif
-/** @addtogroup DynamicStrings
-    @{
-*/
-
-/**
-   Create a new dynamic string.
-
-   @param initial_size Initial size of the buffer.
-   @return Newly allocated dynamic string, or NULL if memory allocation failed.
-*/
-#if defined(TRIO_FUNC_STRING_CREATE)
-
-TRIO_PUBLIC_STRING trio_string_t *
-trio_string_create
-TRIO_ARGS1((initial_size),
-          int initial_size)
-{
-  trio_string_t *self;
-
-  self = internal_string_alloc();
-  if (self)
-    {
-      if (internal_string_grow(self,
-                        (size_t)((initial_size > 0) ? initial_size : 1)))
-       {
-         self->content[0] = (char)0;
-         self->allocated = initial_size;
-       }
-      else
-       {
-         trio_string_destroy(self);
-         self = NULL;
-       }
-    }
-  return self;
-}
-
-#endif
-
-/**
-   Deallocate the dynamic string and its contents.
-
-   @param self Dynamic string
-*/
-#if defined(TRIO_FUNC_STRING_DESTROY)
-
-TRIO_PUBLIC_STRING void
-trio_string_destroy
-TRIO_ARGS1((self),
-          trio_string_t *self)
-{
-  assert(self);
-
-  if (self)
-    {
-      trio_destroy(self->content);
-      TRIO_FREE(self);
-    }
-}
-
-#endif
-
-/**
-   Get a pointer to the content.
-
-   @param self Dynamic string.
-   @param offset Offset into content.
-   @return Pointer to the content.
-
-   @p Offset can be zero, positive, or negative. If @p offset is zero,
-   then the start of the content will be returned. If @p offset is positive,
-   then a pointer to @p offset number of characters from the beginning of the
-   content is returned. If @p offset is negative, then a pointer to @p offset
-   number of characters from the ending of the string, starting at the
-   terminating zero, is returned.
-*/
-#if defined(TRIO_FUNC_STRING_GET)
-
-TRIO_PUBLIC_STRING char *
-trio_string_get
-TRIO_ARGS2((self, offset),
-          trio_string_t *self,
-          int offset)
-{
-  char *result = NULL;
-
-  assert(self);
-
-  if (self->content != NULL)
-    {
-      if (self->length == 0)
-       {
-         (void)trio_string_length(self);
-       }
-      if (offset >= 0)
-       {
-         if (offset > (int)self->length)
-           {
-             offset = self->length;
-           }
-       }
-      else
-       {
-         offset += self->length + 1;
-         if (offset < 0)
-           {
-             offset = 0;
-           }
-       }
-      result = &(self->content[offset]);
-    }
-  return result;
-}
-
-#endif
-
-/**
-   Extract the content.
-
-   @param self Dynamic String
-   @return Content of dynamic string.
-
-   The content is removed from the dynamic string. This enables destruction
-   of the dynamic string without deallocation of the content.
-*/
-#if defined(TRIO_FUNC_STRING_EXTRACT)
-
-TRIO_PUBLIC_STRING char *
-trio_string_extract
-TRIO_ARGS1((self),
-          trio_string_t *self)
-{
-  char *result;
-
-  assert(self);
-
-  result = self->content;
-  /* FIXME: Allocate new empty buffer? */
-  self->content = NULL;
-  self->length = self->allocated = 0;
-  return result;
-}
-
-#endif
-
-/**
-   Set the content of the dynamic string.
-
-   @param self Dynamic String
-   @param buffer The new content.
-
-   Sets the content of the dynamic string to a copy @p buffer.
-   An existing content will be deallocated first, if necessary.
-
-   @remark
-   This function will make a copy of @p buffer.
-   You are responsible for deallocating @p buffer yourself.
-*/
-#if defined(TRIO_FUNC_XSTRING_SET)
-
-TRIO_PUBLIC_STRING void
-trio_xstring_set
-TRIO_ARGS2((self, buffer),
-          trio_string_t *self,
-          char *buffer)
-{
-  assert(self);
-
-  trio_destroy(self->content);
-  self->content = trio_duplicate(buffer);
-}
-
-#endif
-
-/*
- * trio_string_size
- */
-#if defined(TRIO_FUNC_STRING_SIZE)
-
-TRIO_PUBLIC_STRING int
-trio_string_size
-TRIO_ARGS1((self),
-          trio_string_t *self)
-{
-  assert(self);
-
-  return self->allocated;
-}
-
-#endif
-
-/*
- * trio_string_terminate
- */
-#if defined(TRIO_FUNC_STRING_TERMINATE)
-
-TRIO_PUBLIC_STRING void
-trio_string_terminate
-TRIO_ARGS1((self),
-          trio_string_t *self)
-{
-  trio_xstring_append_char(self, 0);
-}
-
-#endif
-
-/**
-   Append the second string to the first.
-
-   @param self Dynamic string to be modified.
-   @param other Dynamic string to copy from.
-   @return Boolean value indicating success or failure.
-*/
-#if defined(TRIO_FUNC_STRING_APPEND)
-
-TRIO_PUBLIC_STRING int
-trio_string_append
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          trio_string_t *other)
-{
-  size_t length;
-
-  assert(self);
-  assert(other);
-
-  length = self->length + other->length;
-  if (!internal_string_grow_to(self, length))
-    goto error;
-  trio_copy(&self->content[self->length], other->content);
-  self->length = length;
-  return TRUE;
-
- error:
-  return FALSE;
-}
-
-#endif
-
-
-/*
- * trio_xstring_append
- */
-#if defined(TRIO_FUNC_XSTRING_APPEND)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_append
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          TRIO_CONST char *other)
-{
-  size_t length;
-
-  assert(self);
-  assert(other);
-
-  length = self->length + trio_length(other);
-  if (!internal_string_grow_to(self, length))
-    goto error;
-  trio_copy(&self->content[self->length], other);
-  self->length = length;
-  return TRUE;
-
- error:
-  return FALSE;
-}
-
-#endif
-
-/*
- * trio_xstring_append_char
- */
-#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_append_char
-TRIO_ARGS2((self, character),
-          trio_string_t *self,
-          char character)
-{
-  assert(self);
-
-  if ((int)self->length >= trio_string_size(self))
-    {
-      if (!internal_string_grow(self, 0))
-       goto error;
-    }
-  self->content[self->length] = character;
-  self->length++;
-  return TRUE;
-
- error:
-  return FALSE;
-}
-
-#endif
-
-/*
- * trio_xstring_append_max
- */
-#if defined(TRIO_FUNC_XSTRING_APPEND_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_append_max
-TRIO_ARGS3((self, other, max),
-          trio_string_t *self,
-          TRIO_CONST char *other,
-           size_t max)
-{
-  size_t length;
-
-  assert(self);
-  assert(other);
-
-  length = self->length + trio_length_max(other, max);
-  if (!internal_string_grow_to(self, length))
-    goto error;
-
-  /*
-   * Pass max + 1 since trio_copy_max copies one character less than
-   * this from the source to make room for a terminating zero.
-   */
-  trio_copy_max(&self->content[self->length], max + 1, other);
-  self->length = length;
-  return TRUE;
-
- error:
-  return FALSE;
-}
-
-#endif
-
-/**
-   Search for the first occurrence of second parameter in the first.
-
-   @param self Dynamic string to be modified.
-   @param other Dynamic string to copy from.
-   @return Boolean value indicating success or failure.
-*/
-#if defined(TRIO_FUNC_STRING_CONTAINS)
-
-TRIO_PUBLIC_STRING int
-trio_string_contains
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          trio_string_t *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_contains(self->content, other->content);
-}
-
-#endif
-
-/*
- * trio_xstring_contains
- */
-#if defined(TRIO_FUNC_XSTRING_CONTAINS)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_contains
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          TRIO_CONST char *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_contains(self->content, other);
-}
-
-#endif
-
-/*
- * trio_string_copy
- */
-#if defined(TRIO_FUNC_STRING_COPY)
-
-TRIO_PUBLIC_STRING int
-trio_string_copy
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          trio_string_t *other)
-{
-  assert(self);
-  assert(other);
-
-  self->length = 0;
-  return trio_string_append(self, other);
-}
-
-#endif
-
-
-/*
- * trio_xstring_copy
- */
-#if defined(TRIO_FUNC_XSTRING_COPY)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_copy
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          TRIO_CONST char *other)
-{
-  assert(self);
-  assert(other);
-
-  self->length = 0;
-  return trio_xstring_append(self, other);
-}
-
-#endif
-
-/*
- * trio_string_duplicate
- */
-#if defined(TRIO_FUNC_STRING_DUPLICATE)
-
-TRIO_PUBLIC_STRING trio_string_t *
-trio_string_duplicate
-TRIO_ARGS1((other),
-          trio_string_t *other)
-{
-  trio_string_t *self;
-
-  assert(other);
-
-  self = internal_string_alloc();
-  if (self)
-    {
-      self->content = internal_duplicate_max(other->content, other->length);
-      if (self->content)
-       {
-         self->length = other->length;
-         self->allocated = self->length + 1;
-       }
-      else
-       {
-         self->length = self->allocated = 0;
-       }
-    }
-  return self;
-}
-
-#endif
-
-/*
- * trio_xstring_duplicate
- */
-#if defined(TRIO_FUNC_XSTRING_DUPLICATE)
-
-TRIO_PUBLIC_STRING trio_string_t *
-trio_xstring_duplicate
-TRIO_ARGS1((other),
-          TRIO_CONST char *other)
-{
-  trio_string_t *self;
-
-  assert(other);
-
-  self = internal_string_alloc();
-  if (self)
-    {
-      self->content = internal_duplicate_max(other, trio_length(other));
-      if (self->content)
-       {
-         self->length = trio_length(self->content);
-         self->allocated = self->length + 1;
-       }
-      else
-       {
-         self->length = self->allocated = 0;
-       }
-    }
-  return self;
-}
-
-#endif
-
-/*
- * trio_string_equal
- */
-#if defined(TRIO_FUNC_STRING_EQUAL)
-
-TRIO_PUBLIC_STRING int
-trio_string_equal
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          trio_string_t *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_equal(self->content, other->content);
-}
-
-#endif
-
-
-/*
- * trio_xstring_equal
- */
-#if defined(TRIO_FUNC_XSTRING_EQUAL)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_equal
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          TRIO_CONST char *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_equal(self->content, other);
-}
-
-#endif
-
-/*
- * trio_string_equal_max
- */
-#if defined(TRIO_FUNC_STRING_EQUAL_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_string_equal_max
-TRIO_ARGS3((self, max, other),
-          trio_string_t *self,
-          size_t max,
-          trio_string_t *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_equal_max(self->content, max, other->content);
-}
-#endif
-
-/*
- * trio_xstring_equal_max
- */
-#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_equal_max
-TRIO_ARGS3((self, max, other),
-          trio_string_t *self,
-          size_t max,
-          TRIO_CONST char *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_equal_max(self->content, max, other);
-}
-
-#endif
-
-/*
- * trio_string_equal_case
- */
-#if defined(TRIO_FUNC_STRING_EQUAL_CASE)
-
-TRIO_PUBLIC_STRING int
-trio_string_equal_case
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          trio_string_t *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_equal_case(self->content, other->content);
-}
-
-#endif
-
-/*
- * trio_xstring_equal_case
- */
-#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_equal_case
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          TRIO_CONST char *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_equal_case(self->content, other);
-}
-
-#endif
-
-/*
- * trio_string_equal_case_max
- */
-#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_string_equal_case_max
-TRIO_ARGS3((self, max, other),
-          trio_string_t *self,
-          size_t max,
-          trio_string_t *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_equal_case_max(self->content, max, other->content);
-}
-
-#endif
-
-/*
- * trio_xstring_equal_case_max
- */
-#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_equal_case_max
-TRIO_ARGS3((self, max, other),
-          trio_string_t *self,
-          size_t max,
-          TRIO_CONST char *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_equal_case_max(self->content, max, other);
-}
-
-#endif
-
-/*
- * trio_string_format_data_max
- */
-#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)
-
-TRIO_PUBLIC_STRING size_t
-trio_string_format_date_max
-TRIO_ARGS4((self, max, format, datetime),
-          trio_string_t *self,
-          size_t max,
-          TRIO_CONST char *format,
-          TRIO_CONST struct tm *datetime)
-{
-  assert(self);
-
-  return trio_format_date_max(self->content, max, format, datetime);
-}
-
-#endif
-
-/*
- * trio_string_index
- */
-#if defined(TRIO_FUNC_STRING_INDEX)
-
-TRIO_PUBLIC_STRING char *
-trio_string_index
-TRIO_ARGS2((self, character),
-          trio_string_t *self,
-          int character)
-{
-  assert(self);
-
-  return trio_index(self->content, character);
-}
-
-#endif
-
-/*
- * trio_string_index_last
- */
-#if defined(TRIO_FUNC_STRING_INDEX_LAST)
-
-TRIO_PUBLIC_STRING char *
-trio_string_index_last
-TRIO_ARGS2((self, character),
-          trio_string_t *self,
-          int character)
-{
-  assert(self);
-
-  return trio_index_last(self->content, character);
-}
-
-#endif
-
-/*
- * trio_string_length
- */
-#if defined(TRIO_FUNC_STRING_LENGTH)
-
-TRIO_PUBLIC_STRING int
-trio_string_length
-TRIO_ARGS1((self),
-          trio_string_t *self)
-{
-  assert(self);
-
-  if (self->length == 0)
-    {
-      self->length = trio_length(self->content);
-    }
-  return self->length;
-}
-
-#endif
-
-/*
- * trio_string_lower
- */
-#if defined(TRIO_FUNC_STRING_LOWER)
-
-TRIO_PUBLIC_STRING int
-trio_string_lower
-TRIO_ARGS1((self),
-          trio_string_t *self)
-{
-  assert(self);
-
-  return trio_lower(self->content);
-}
-
-#endif
-
-/*
- * trio_string_match
- */
-#if defined(TRIO_FUNC_STRING_MATCH)
-
-TRIO_PUBLIC_STRING int
-trio_string_match
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          trio_string_t *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_match(self->content, other->content);
-}
-
-#endif
-
-/*
- * trio_xstring_match
- */
-#if defined(TRIO_FUNC_XSTRING_MATCH)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_match
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          TRIO_CONST char *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_match(self->content, other);
-}
-
-#endif
-
-/*
- * trio_string_match_case
- */
-#if defined(TRIO_FUNC_STRING_MATCH_CASE)
-
-TRIO_PUBLIC_STRING int
-trio_string_match_case
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          trio_string_t *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_match_case(self->content, other->content);
-}
-
-#endif
-
-/*
- * trio_xstring_match_case
- */
-#if defined(TRIO_FUNC_XSTRING_MATCH_CASE)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_match_case
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          TRIO_CONST char *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_match_case(self->content, other);
-}
-
-#endif
-
-/*
- * trio_string_substring
- */
-#if defined(TRIO_FUNC_STRING_SUBSTRING)
-
-TRIO_PUBLIC_STRING char *
-trio_string_substring
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          trio_string_t *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_substring(self->content, other->content);
-}
-
-#endif
-
-/*
- * trio_xstring_substring
- */
-#if defined(TRIO_FUNC_XSTRING_SUBSTRING)
-
-TRIO_PUBLIC_STRING char *
-trio_xstring_substring
-TRIO_ARGS2((self, other),
-          trio_string_t *self,
-          TRIO_CONST char *other)
-{
-  assert(self);
-  assert(other);
-
-  return trio_substring(self->content, other);
-}
-
-#endif
-
-/*
- * trio_string_upper
- */
-#if defined(TRIO_FUNC_STRING_UPPER)
-
-TRIO_PUBLIC_STRING int
-trio_string_upper
-TRIO_ARGS1((self),
-          trio_string_t *self)
-{
-  assert(self);
-
-  return trio_upper(self->content);
-}
-
-#endif
-
-/** @} End of DynamicStrings */
diff --git a/trio/triostr.h b/trio/triostr.h
deleted file mode 100644 (file)
index 847fb72..0000000
+++ /dev/null
@@ -1,681 +0,0 @@
-/*************************************************************************
- *
- * $Id: triostr.h,v 1.18 2010/01/26 13:02:02 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIOSTR_H
-#define TRIO_TRIOSTR_H
-
-/*
- * Documentation is located in triostr.c
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "triodef.h"
-#include "triop.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
-  TRIO_HASH_NONE = 0,
-  TRIO_HASH_PLAIN,
-  TRIO_HASH_TWOSIGNED
-};
-
-#if !defined(TRIO_PUBLIC_STRING)
-# if !defined(TRIO_PUBLIC)
-#  define TRIO_PUBLIC
-# endif
-# define TRIO_PUBLIC_STRING TRIO_PUBLIC
-#endif
-
-/*************************************************************************
- * Dependencies
- */
-
-#if defined(TRIO_EMBED_STRING)
-
-/*
- * The application that triostr is embedded in must define which functions
- * it uses.
- *
- * The following resolves internal dependencies.
- */
-  
-# if defined(TRIO_FUNC_XSTRING_SET)
-#  if !defined(TRIO_FUNC_DUPLICATE)
-#   define TRIO_FUNC_DUPLICATE
-#  endif
-# endif
-
-# if defined(TRIO_FUNC_DUPLICATE) \
-  || defined(TRIO_FUNC_DUPLICATE_MAX) \
-  || defined(TRIO_FUNC_STRING_DUPLICATE) \
-  || defined(TRIO_FUNC_XSTRING_DUPLICATE)
-#  if !defined(TRIO_FUNC_CREATE)
-#   define TRIO_FUNC_CREATE
-#  endif
-#  if !defined(TRIO_FUNC_COPY_MAX)
-#   define TRIO_FUNC_COPY_MAX
-#  endif
-# endif
-
-# if defined(TRIO_FUNC_STRING_CREATE)
-#  if !defined(TRIO_FUNC_STRING_DESTROY)
-#   define TRIO_FUNC_STRING_DESTROY
-#  endif
-# endif
-
-# if defined(TRIO_FUNC_STRING_DESTROY) \
-  || defined(TRIO_FUNC_XSTRING_SET)
-#  if !defined(TRIO_FUNC_DESTROY)
-#   define TRIO_FUNC_DESTROY
-#  endif
-# endif
-
-# if defined(TRIO_FUNC_EQUAL_LOCALE) \
-  || defined(TRIO_FUNC_STRING_EQUAL) \
-  || defined(TRIO_FUNC_XSTRING_EQUAL)
-#  if !defined(TRIO_FUNC_EQUAL)
-#   define TRIO_FUNC_EQUAL
-#  endif
-# endif
-
-# if defined(TRIO_FUNC_EQUAL_CASE) \
-  || defined(TRIO_FUNC_STRING_EQUAL_CASE) \
-  || defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
-#  if !defined(TRIO_FUNC_EQUAL_CASE)
-#   define TRIO_FUNC_EQUAL_CASE
-#  endif
-# endif
-
-# if defined(TRIO_FUNC_SUBSTRING_MAX) \
-  || defined(TRIO_FUNC_STRING_EQUAL_MAX) \
-  || defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
-#  if !defined(TRIO_FUNC_EQUAL_MAX)
-#   define TRIO_FUNC_EQUAL_MAX
-#  endif
-# endif
-
-# if defined(TRIO_FUNC_TO_DOUBLE) \
-  || defined(TRIO_FUNC_TO_FLOAT)
-#  if !defined(TRIO_FUNC_TO_LONG_DOUBLE)
-#   define TRIO_FUNC_TO_LONG_DOUBLE
-#  endif
-# endif
-
-# if defined(TRIO_FUNC_STRING_TERMINATE)
-#  if !defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
-#   define TRIO_FUNC_XSTRING_APPEND_CHAR
-#  endif
-# endif
-
-# if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
-#  if !defined(TRIO_FUNC_STRING_SIZE)
-#   define TRIO_FUNC_STRING_SIZE
-#  endif
-# endif
-
-#else
-
-/*
- * When triostr is not embedded all functions are defined.
- */
-
-# define TRIO_FUNC_APPEND
-# define TRIO_FUNC_APPEND_MAX
-# define TRIO_FUNC_CONTAINS
-# define TRIO_FUNC_COPY
-# define TRIO_FUNC_COPY_MAX
-# define TRIO_FUNC_CREATE
-# define TRIO_FUNC_DESTROY
-# define TRIO_FUNC_DUPLICATE
-# define TRIO_FUNC_DUPLICATE_MAX
-# define TRIO_FUNC_EQUAL
-# define TRIO_FUNC_EQUAL_CASE
-# define TRIO_FUNC_EQUAL_CASE_MAX
-# define TRIO_FUNC_EQUAL_LOCALE
-# define TRIO_FUNC_EQUAL_MAX
-# define TRIO_FUNC_ERROR
-# if !defined(TRIO_PLATFORM_WINCE)
-#  define TRIO_FUNC_FORMAT_DATE_MAX
-# endif
-# define TRIO_FUNC_HASH
-# define TRIO_FUNC_INDEX
-# define TRIO_FUNC_INDEX_LAST
-# define TRIO_FUNC_LENGTH
-# define TRIO_FUNC_LENGTH_MAX
-# define TRIO_FUNC_LOWER
-# define TRIO_FUNC_MATCH
-# define TRIO_FUNC_MATCH_CASE
-# define TRIO_FUNC_SPAN_FUNCTION
-# define TRIO_FUNC_SUBSTRING
-# define TRIO_FUNC_SUBSTRING_MAX
-# define TRIO_FUNC_TO_DOUBLE
-# define TRIO_FUNC_TO_FLOAT
-# define TRIO_FUNC_TO_LONG
-# define TRIO_FUNC_TO_LONG_DOUBLE
-# define TRIO_FUNC_TO_LOWER
-# define TRIO_FUNC_TO_UNSIGNED_LONG
-# define TRIO_FUNC_TO_UPPER
-# define TRIO_FUNC_TOKENIZE
-# define TRIO_FUNC_UPPER
-
-# define TRIO_FUNC_STRING_APPEND
-# define TRIO_FUNC_STRING_CONTAINS
-# define TRIO_FUNC_STRING_COPY
-# define TRIO_FUNC_STRING_CREATE
-# define TRIO_FUNC_STRING_DESTROY
-# define TRIO_FUNC_STRING_DUPLICATE
-# define TRIO_FUNC_STRING_EQUAL
-# define TRIO_FUNC_STRING_EQUAL_CASE
-# define TRIO_FUNC_STRING_EQUAL_CASE_MAX
-# define TRIO_FUNC_STRING_EQUAL_MAX
-# define TRIO_FUNC_STRING_EXTRACT
-# if !defined(TRIO_PLATFORM_WINCE)
-#  define TRIO_FUNC_STRING_FORMAT_DATE_MAX
-# endif
-# define TRIO_FUNC_STRING_GET
-# define TRIO_FUNC_STRING_INDEX
-# define TRIO_FUNC_STRING_INDEX_LAST
-# define TRIO_FUNC_STRING_LENGTH
-# define TRIO_FUNC_STRING_LOWER
-# define TRIO_FUNC_STRING_MATCH
-# define TRIO_FUNC_STRING_MATCH_CASE
-# define TRIO_FUNC_STRING_SIZE
-# define TRIO_FUNC_STRING_SUBSTRING
-# define TRIO_FUNC_STRING_TERMINATE
-# define TRIO_FUNC_STRING_UPPER
-
-# define TRIO_FUNC_XSTRING_APPEND
-# define TRIO_FUNC_XSTRING_APPEND_CHAR
-# define TRIO_FUNC_XSTRING_APPEND_MAX
-# define TRIO_FUNC_XSTRING_CONTAINS
-# define TRIO_FUNC_XSTRING_COPY
-# define TRIO_FUNC_XSTRING_DUPLICATE
-# define TRIO_FUNC_XSTRING_EQUAL
-# define TRIO_FUNC_XSTRING_EQUAL_CASE
-# define TRIO_FUNC_XSTRING_EQUAL_CASE_MAX
-# define TRIO_FUNC_XSTRING_EQUAL_MAX
-# define TRIO_FUNC_XSTRING_MATCH
-# define TRIO_FUNC_XSTRING_MATCH_CASE
-# define TRIO_FUNC_XSTRING_SET
-# define TRIO_FUNC_XSTRING_SUBSTRING
-
-#endif
-
-
-/*************************************************************************
- * String functions
- */
-
-#if defined(TRIO_FUNC_APPEND)
-TRIO_PUBLIC_STRING int
-trio_append
-TRIO_PROTO((char *target, TRIO_CONST char *source));
-#endif
-
-#if defined(TRIO_FUNC_APPEND_MAX)
-TRIO_PUBLIC_STRING int
-trio_append_max
-TRIO_PROTO((char *target, size_t max, TRIO_CONST char *source));
-#endif
-
-#if defined(TRIO_FUNC_CONTAINS)
-TRIO_PUBLIC_STRING int
-trio_contains
-TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring));
-#endif
-
-#if defined(TRIO_FUNC_COPY)
-TRIO_PUBLIC_STRING int
-trio_copy
-TRIO_PROTO((char *target, TRIO_CONST char *source));
-#endif
-
-#if defined(TRIO_FUNC_COPY_MAX)
-TRIO_PUBLIC_STRING int
-trio_copy_max
-TRIO_PROTO((char *target, size_t max, TRIO_CONST char *source));
-#endif
-
-#if defined(TRIO_FUNC_CREATE)
-TRIO_PUBLIC_STRING char *
-trio_create
-TRIO_PROTO((size_t size));
-#endif
-
-#if defined(TRIO_FUNC_DESTROY)
-TRIO_PUBLIC_STRING void
-trio_destroy
-TRIO_PROTO((char *string));
-#endif
-
-#if defined(TRIO_FUNC_DUPLICATE)
-TRIO_PUBLIC_STRING char *
-trio_duplicate
-TRIO_PROTO((TRIO_CONST char *source));
-#endif
-
-#if defined(TRIO_FUNC_DUPLICATE_MAX)
-TRIO_PUBLIC_STRING char *
-trio_duplicate_max
-TRIO_PROTO((TRIO_CONST char *source, size_t max));
-#endif
-
-#if defined(TRIO_FUNC_EQUAL)
-TRIO_PUBLIC_STRING int
-trio_equal
-TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second));
-#endif
-
-#if defined(TRIO_FUNC_EQUAL_CASE)
-TRIO_PUBLIC_STRING int
-trio_equal_case
-TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second));
-#endif
-
-#if defined(TRIO_FUNC_EQUAL_CASE_MAX)
-TRIO_PUBLIC_STRING int
-trio_equal_case_max
-TRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second));
-#endif
-
-#if defined(TRIO_FUNC_EQUAL_LOCALE)
-TRIO_PUBLIC_STRING int
-trio_equal_locale
-TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second));
-#endif
-
-#if defined(TRIO_FUNC_EQUAL_MAX)
-TRIO_PUBLIC_STRING int
-trio_equal_max
-TRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second));
-#endif
-
-#if defined(TRIO_FUNC_ERROR)
-TRIO_PUBLIC_STRING TRIO_CONST char *
-trio_error
-TRIO_PROTO((int));
-#endif
-
-#if defined(TRIO_FUNC_FORMAT_DATE_MAX)
-TRIO_PUBLIC_STRING size_t
-trio_format_date_max
-TRIO_PROTO((char *target, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime));
-#endif
-
-#if defined(TRIO_FUNC_HASH)
-TRIO_PUBLIC_STRING unsigned long
-trio_hash
-TRIO_PROTO((TRIO_CONST char *string, int type));
-#endif
-
-#if defined(TRIO_FUNC_INDEX)
-TRIO_PUBLIC_STRING char *
-trio_index
-TRIO_PROTO((TRIO_CONST char *string, int character));
-#endif
-
-#if defined(TRIO_FUNC_INDEX_LAST)
-TRIO_PUBLIC_STRING char *
-trio_index_last
-TRIO_PROTO((TRIO_CONST char *string, int character));
-#endif
-
-#if defined(TRIO_FUNC_LENGTH)
-TRIO_PUBLIC_STRING size_t
-trio_length
-TRIO_PROTO((TRIO_CONST char *string));
-#endif
-
-#if defined(TRIO_FUNC_LENGTH_MAX)
-TRIO_PUBLIC_STRING size_t
-trio_length_max
-TRIO_PROTO((TRIO_CONST char *string, size_t max));
-#endif
-
-#if defined(TRIO_FUNC_LOWER)
-TRIO_PUBLIC_STRING int
-trio_lower
-TRIO_PROTO((char *target));
-#endif
-
-#if defined(TRIO_FUNC_MATCH)
-TRIO_PUBLIC_STRING int
-trio_match
-TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern));
-#endif
-
-#if defined(TRIO_FUNC_MATCH_CASE)
-TRIO_PUBLIC_STRING int
-trio_match_case
-TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern));
-#endif
-
-#if defined(TRIO_FUNC_SPAN_FUNCTION)
-TRIO_PUBLIC_STRING size_t
-trio_span_function
-TRIO_PROTO((char *target, TRIO_CONST char *source, int (*Function) TRIO_PROTO((int))));
-#endif
-
-#if defined(TRIO_FUNC_SUBSTRING)
-TRIO_PUBLIC_STRING char *
-trio_substring
-TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring));
-#endif
-
-#if defined(TRIO_FUNC_SUBSTRING_MAX)
-TRIO_PUBLIC_STRING char *
-trio_substring_max
-TRIO_PROTO((TRIO_CONST char *string, size_t max, TRIO_CONST char *substring));
-#endif
-
-#if defined(TRIO_FUNC_TO_DOUBLE)
-TRIO_PUBLIC_STRING double
-trio_to_double
-TRIO_PROTO((TRIO_CONST char *source, char **endp));
-#endif
-
-#if defined(TRIO_FUNC_TO_FLOAT)
-TRIO_PUBLIC_STRING float
-trio_to_float
-TRIO_PROTO((TRIO_CONST char *source, char **endp));
-#endif
-
-#if defined(TRIO_FUNC_TO_LONG)
-TRIO_PUBLIC_STRING long
-trio_to_long
-TRIO_PROTO((TRIO_CONST char *source, char **endp, int base));
-#endif
-
-#if defined(TRIO_FUNC_TO_LOWER)
-TRIO_PUBLIC_STRING int
-trio_to_lower
-TRIO_PROTO((int source));
-#endif
-
-#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
-TRIO_PUBLIC_STRING trio_long_double_t
-trio_to_long_double
-TRIO_PROTO((TRIO_CONST char *source, char **endp));
-#endif
-
-#if defined(TRIO_FUNC_TO_UNSIGNED_LONG)
-TRIO_PUBLIC_STRING unsigned long
-trio_to_unsigned_long
-TRIO_PROTO((TRIO_CONST char *source, char **endp, int base));
-#endif
-
-#if defined(TRIO_FUNC_TO_UPPER)
-TRIO_PUBLIC_STRING int
-trio_to_upper
-TRIO_PROTO((int source));
-#endif
-
-#if defined(TRIO_FUNC_TOKENIZE)
-TRIO_PUBLIC_STRING char *
-trio_tokenize
-TRIO_PROTO((char *string, TRIO_CONST char *delimiters));
-#endif
-
-#if defined(TRIO_FUNC_UPPER)
-TRIO_PUBLIC_STRING int
-trio_upper
-TRIO_PROTO((char *target));
-#endif
-
-/*************************************************************************
- * Dynamic string functions
- */
-
-/*
- * Opaque type for dynamic strings
- */
-
-typedef struct _trio_string_t trio_string_t;
-
-#if defined(TRIO_FUNC_STRING_APPEND)
-TRIO_PUBLIC_STRING int
-trio_string_append
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_CONTAINS)
-TRIO_PUBLIC_STRING int
-trio_string_contains
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_COPY)
-TRIO_PUBLIC_STRING int
-trio_string_copy
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_CREATE)
-TRIO_PUBLIC_STRING trio_string_t *
-trio_string_create
-TRIO_PROTO((int initial_size));
-#endif
-
-#if defined(TRIO_FUNC_STRING_DESTROY)
-TRIO_PUBLIC_STRING void
-trio_string_destroy
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_STRING_DUPLICATE)
-TRIO_PUBLIC_STRING trio_string_t *
-trio_string_duplicate
-TRIO_PROTO((trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_EQUAL)
-TRIO_PUBLIC_STRING int
-trio_string_equal
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_EQUAL_MAX)
-TRIO_PUBLIC_STRING int
-trio_string_equal_max
-TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *second));
-#endif
-
-#if defined(TRIO_FUNC_STRING_EQUAL_CASE)
-TRIO_PUBLIC_STRING int
-trio_string_equal_case
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)
-TRIO_PUBLIC_STRING int
-trio_string_equal_case_max
-TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_EXTRACT)
-TRIO_PUBLIC_STRING char *
-trio_string_extract
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)
-TRIO_PUBLIC_STRING size_t
-trio_string_format_date_max
-TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime));
-#endif
-
-#if defined(TRIO_FUNC_STRING_GET)
-TRIO_PUBLIC_STRING char *
-trio_string_get
-TRIO_PROTO((trio_string_t *self, int offset));
-#endif
-
-#if defined(TRIO_FUNC_STRING_INDEX)
-TRIO_PUBLIC_STRING char *
-trio_string_index
-TRIO_PROTO((trio_string_t *self, int character));
-#endif
-
-#if defined(TRIO_FUNC_STRING_INDEX_LAST)
-TRIO_PUBLIC_STRING char *
-trio_string_index_last
-TRIO_PROTO((trio_string_t *self, int character));
-#endif
-
-#if defined(TRIO_FUNC_STRING_LENGTH)
-TRIO_PUBLIC_STRING int
-trio_string_length
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_STRING_LOWER)
-TRIO_PUBLIC_STRING int
-trio_string_lower
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_STRING_MATCH)
-TRIO_PUBLIC_STRING int
-trio_string_match
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_MATCH_CASE)
-TRIO_PUBLIC_STRING int
-trio_string_match_case
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_SIZE)
-TRIO_PUBLIC_STRING int
-trio_string_size
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_STRING_SUBSTRING)
-TRIO_PUBLIC_STRING char *
-trio_string_substring
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_TERMINATE)
-TRIO_PUBLIC_STRING void
-trio_string_terminate
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_STRING_UPPER)
-TRIO_PUBLIC_STRING int
-trio_string_upper
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_APPEND)
-TRIO_PUBLIC_STRING int
-trio_xstring_append
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
-TRIO_PUBLIC_STRING int
-trio_xstring_append_char
-TRIO_PROTO((trio_string_t *self, char character));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_APPEND_MAX)
-TRIO_PUBLIC_STRING int
-trio_xstring_append_max
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other, size_t max));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_CONTAINS)
-TRIO_PUBLIC_STRING int
-trio_xstring_contains
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_COPY)
-TRIO_PUBLIC_STRING int
-trio_xstring_copy
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_DUPLICATE)
-TRIO_PUBLIC_STRING trio_string_t *
-trio_xstring_duplicate
-TRIO_PROTO((TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_EQUAL)
-TRIO_PUBLIC_STRING int
-trio_xstring_equal
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
-TRIO_PUBLIC_STRING int
-trio_xstring_equal_max
-TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
-TRIO_PUBLIC_STRING int
-trio_xstring_equal_case
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)
-TRIO_PUBLIC_STRING int
-trio_xstring_equal_case_max
-TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_MATCH)
-TRIO_PUBLIC_STRING int
-trio_xstring_match
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_MATCH_CASE)
-TRIO_PUBLIC_STRING int
-trio_xstring_match_case
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_SET)
-TRIO_PUBLIC_STRING void
-trio_xstring_set
-TRIO_PROTO((trio_string_t *self, char *buffer));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_SUBSTRING)
-TRIO_PUBLIC_STRING char *
-trio_xstring_substring
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRIO_TRIOSTR_H */
index dedad326a44a872f4f1b44fff9d518dd5d9bf80e..07c5d2a970d51bd6b4e9f3f29f7afed8c1636204 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "config.h" /* import AC_C_CONST effects */
 #include "norm_charmap.h"
+#include "fetchmail.h"
 
 #include <string.h>
 
diff --git a/uid.c b/uid.c
index 8a775b9c63f48b60997f834f2d0f4f86f92bbe20..d069d7d0484b5b2bdeb1c01170fd5187762d537b 100644 (file)
--- a/uid.c
+++ b/uid.c
@@ -1,32 +1,12 @@
 /**
- * \file uid.c -- UIDL handling for POP3 servers without LAST
+ * \file uid.c
+ * UID list handling (currently, only for POP3)
  *
  * For license terms, see the file COPYING in this directory.
- */
-
-#include "config.h"
-
-#include <sys/stat.h>
-#include <errno.h>
-#include <stdio.h>
-#include <limits.h>
-#if defined(STDC_HEADERS)
-#include <stdlib.h>
-#include <string.h>
-#endif
-#if defined(HAVE_UNISTD_H)
-#include <unistd.h>
-#endif
-
-#include "fetchmail.h"
-#include "i18n.h"
-#include "sdump.h"
-
-/*
- * Machinery for handling UID lists live here.  This is mainly to support
- * RFC1725/RFC1939-conformant POP3 servers without a LAST command, but may also
- * be useful for making the IMAP4 querying logic UID-oriented, if a future
- * revision of IMAP forces me to.
+ *
+ * Machinery for handling UID lists live here.  This is currently used
+ * by POP3, but may also be useful for making the IMAP4 querying logic
+ * UID-oriented.
  *
  * These functions are also used by the rest of the code to maintain
  * string lists.
  * Note: some comparisons (those used for DNS address lists) are caseblind!
  */
 
+#include "config.h"
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <stdio.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "fetchmail.h"
+#include "gettext.h"
+#include "sdump.h"
+
 int dofastuidl = 0;
 
 #ifdef POP3_ENABLE
 /** UIDs associated with un-queried hosts */
 static struct idlist *scratchlist;
 
+static int dump_saved_uid(struct uid_db_record *rec, void *unused)
+{
+    char *t;
+
+    (void)unused;
+
+    t = sdump(rec->id, rec->id_len);
+    report_build(stdout, " %s", t);
+    free(t);
+
+    return 0;
+}
+
 /** Read saved IDs from \a idfile and attach to each host in \a hostlist. */
 void initialize_saved_lists(struct query *hostlist, const char *idfile)
 {
@@ -117,9 +124,9 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile)
     /* make sure lists are initially empty */
     for (ctl = hostlist; ctl; ctl = ctl->next) {
        ctl->skipped = (struct idlist *)NULL;
-       ctl->oldsaved = (struct idlist *)NULL;
-       ctl->newsaved = (struct idlist *)NULL;
-       ctl->oldsavedend = &ctl->oldsaved;
+
+       init_uid_db(&ctl->oldsaved);
+       init_uid_db(&ctl->newsaved);
     }
 
     errno = 0;
@@ -156,10 +163,10 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile)
        while (fgets(buf, POPBUFSIZE, tmpfp) != (char *)NULL)
        {
            /*
-            * At this point, we assume the bug has two fields -- a user@host 
+            * At this point, we assume the bug has two fields -- a user@host
             * part, and an ID part. Either field may contain spurious @ signs.
-            * The previous version of this code presumed one could split at 
-            * the rightmost '@'.  This is not correct, as InterMail puts an 
+            * The previous version of this code presumed one could split at
+            * the rightmost '@'.  This is not correct, as InterMail puts an
             * '@' in the UIDL.
             */
 
@@ -173,7 +180,7 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile)
             * instead of a Message-ID, as GMX's (www.gmx.net) POP3
             * StreamProxy V1.0 does.
             *
-            * this is one other trick. The userhost part 
+            * this is one other trick. The userhost part
             * may contain ' ' in the user part, at least in
             * the lotus notes case.
             * So we start looking for the '@' after which the
@@ -189,7 +196,7 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile)
                    if ((*delimp1 != ' ') && (*delimp1 != '\t'))
                        break;
 
-               /* 
+               /*
                 * It should be safe to assume that id starts after
                 * the " " - after all, we're writing the " "
                 * ourselves in write_saved_lists() :-)
@@ -212,15 +219,15 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile)
                *atsign = '\0';
                host = atsign + 1;
 
-               /* find proper list and save it */
+               /* find uidl db and save it */
                for (ctl = hostlist; ctl; ctl = ctl->next) {
                    if (strcasecmp(host, ctl->server.queryname) == 0
                            && strcasecmp(user, ctl->remotename) == 0) {
-                       save_str(&ctl->oldsaved, id, UID_SEEN);
+                       uid_db_insert(&ctl->oldsaved, id, UID_SEEN);
                        break;
                    }
                }
-               /* 
+               /*
                 * If it's not in a host we're querying,
                 * save it anyway.  Otherwise we'd lose UIDL
                 * information any time we queried an explicit
@@ -246,16 +253,14 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile)
 
        for (ctl = hostlist; ctl; ctl = ctl->next)
            {
-               report_build(stdout, GT_("Old UID list from %s:"), 
+               report_build(stdout, GT_("Old UID list from %s:"),
                             ctl->server.pollname);
-               idp = ctl->oldsaved;
-               if (!idp)
+
+               if (!uid_db_n_records(&ctl->oldsaved))
                    report_build(stdout, GT_(" <empty>"));
-               else for (idp = ctl->oldsaved; idp; idp = idp->next) {
-                   char *t = sdump(idp->id, strlen(idp->id)-1);
-                   report_build(stdout, " %s\n", t);
-                   free(t);
-               }
+               else
+                   traverse_uid_db(&ctl->oldsaved, dump_saved_uid, NULL);
+
                report_complete(stdout, "\n");
            }
 
@@ -271,15 +276,20 @@ void initialize_saved_lists(struct query *hostlist, const char *idfile)
     }
 }
 
+static int mark_as_expunged_if(struct uid_db_record *rec, void *unused)
+{
+    (void)unused;
+
+    if (rec->status == UID_DELETED) rec->status = UID_EXPUNGED;
+    return 0;
+}
+
 /** Assert that all UIDs marked deleted in query \a ctl have actually been
 expunged. */
 void expunge_uids(struct query *ctl)
 {
-    struct idlist *idl;
-
-    for (idl = dofastuidl ? ctl->oldsaved : ctl->newsaved; idl; idl = idl->next)
-       if (idl->val.status.mark == UID_DELETED)
-           idl->val.status.mark = UID_EXPUNGED;
+    traverse_uid_db(dofastuidl ? &ctl->oldsaved : &ctl->newsaved,
+                    mark_as_expunged_if, NULL);
 }
 
 static const char *str_uidmark(int mark)
@@ -303,30 +313,46 @@ static const char *str_uidmark(int mark)
        }
 }
 
-static void dump_list(const struct idlist *idp)
+static int dump_uid_db_record(struct uid_db_record *rec, void *arg)
 {
-       if (!idp) {
+       unsigned *n_recs;
+       char *t;
+
+       n_recs = (unsigned int *)arg;
+       --*n_recs;
+
+       t = sdump(rec->id, rec->id_len);
+       report_build(stdout, " %s = %s%s", t, str_uidmark(rec->status), *n_recs ? "," : "");
+       free(t);
+
+       return 0;
+}
+
+static void dump_uid_db(struct uid_db *db)
+{
+       unsigned n_recs;
+
+       n_recs = uid_db_n_records(db);
+       if (!n_recs) {
                report_build(stdout, GT_(" <empty>"));
-       } else while (idp) {
-           char *t = sdump(idp->id, strlen(idp->id));
-           report_build(stdout, " %s = %s%s", t, str_uidmark(idp->val.status.mark), idp->next ? "," : "");
-           free(t);
-           idp = idp->next;
+               return;
        }
+
+       traverse_uid_db(db, dump_uid_db_record, &n_recs);
 }
 
-/* finish a query */
-void uid_swap_lists(struct query *ctl) 
+/** Finish a successful query */
+void uid_swap_lists(struct query *ctl)
 {
     /* debugging code */
     if (outlevel >= O_DEBUG)
     {
        if (dofastuidl) {
            report_build(stdout, GT_("Merged UID list from %s:"), ctl->server.pollname);
-           dump_list(ctl->oldsaved);
+           dump_uid_db(&ctl->oldsaved);
        } else {
            report_build(stdout, GT_("New UID list from %s:"), ctl->server.pollname);
-           dump_list(ctl->newsaved);
+           dump_uid_db(&ctl->newsaved);
        }
        report_complete(stdout, "\n");
     }
@@ -347,15 +373,10 @@ void uid_swap_lists(struct query *ctl)
      * with UIDLs from that account in .fetchids, there is no way for
      * them to ever get garbage-collected.
      */
-    if (ctl->newsaved)
+    if (uid_db_n_records(&ctl->newsaved))
     {
-       /* old state of mailbox may now be irrelevant */
-       struct idlist *temp = ctl->oldsaved;
-       if (outlevel >= O_DEBUG)
-           report(stdout, GT_("swapping UID lists\n"));
-       ctl->oldsaved = ctl->newsaved;
-       ctl->newsaved = (struct idlist *) NULL;
-       free_str_list(&temp);
+       swap_uid_db_data(&ctl->newsaved, &ctl->oldsaved);
+       clear_uid_db(&ctl->newsaved);
     }
     /* in fast uidl, there is no need to swap lists: the old state of
      * mailbox cannot be discarded! */
@@ -363,7 +384,7 @@ void uid_swap_lists(struct query *ctl)
        report(stdout, GT_("not swapping UID lists, no UIDs seen this query\n"));
 }
 
-/* finish a query which had errors */
+/** Finish a query which had errors */
 void uid_discard_new_list(struct query *ctl)
 {
     /* debugging code */
@@ -372,29 +393,54 @@ void uid_discard_new_list(struct query *ctl)
        /* this is now a merged list! the mails which were seen in this
         * poll are marked here. */
        report_build(stdout, GT_("Merged UID list from %s:"), ctl->server.pollname);
-       dump_list(ctl->oldsaved);
+       dump_uid_db(&ctl->oldsaved);
        report_complete(stdout, "\n");
     }
 
-    if (ctl->newsaved)
+    if (uid_db_n_records(&ctl->newsaved))
     {
        /* new state of mailbox is not reliable */
        if (outlevel >= O_DEBUG)
            report(stdout, GT_("discarding new UID list\n"));
-       free_str_list(&ctl->newsaved);
-       ctl->newsaved = (struct idlist *) NULL;
+       clear_uid_db(&ctl->newsaved);
     }
 }
 
 /** Reset the number associated with each id */
 void uid_reset_num(struct query *ctl)
 {
-    struct idlist *idp;
-    for (idp = ctl->oldsaved; idp; idp = idp->next)
-       idp->val.status.num = 0;
+    reset_uid_db_nums(&ctl->oldsaved);
 }
 
 /** Write list of seen messages, at end of run. */
+static int count_seen_deleted(struct uid_db_record *rec, void *arg)
+{
+    if (rec->status == UID_SEEN || rec->status == UID_DELETED)
+       ++*(long *)arg;
+    return 0;
+}
+
+struct write_saved_info {
+    struct query *ctl;
+    FILE *fp;
+};
+
+static int write_uid_db_record(struct uid_db_record *rec, void *arg)
+{
+    struct write_saved_info *info;
+    int rc;
+
+    if (!(rec->status == UID_SEEN || rec->status == UID_DELETED))
+       return 0;
+
+    info = (struct write_saved_info *)arg;
+    rc = fprintf(info->fp, "%s@%s %s\n",
+                info->ctl->remotename, info->ctl->server.queryname,
+                rec->id);
+    return rc < 0 ? -1 : 0;
+}
+
+/** Write new list of UIDs (state) to \a idfile. */
 void write_saved_lists(struct query *hostlist, const char *idfile)
 {
     long       idcount;
@@ -404,12 +450,8 @@ void write_saved_lists(struct query *hostlist, const char *idfile)
 
     /* if all lists are empty, nuke the file */
     idcount = 0;
-    for (ctl = hostlist; ctl; ctl = ctl->next) {
-       for (idp = ctl->oldsaved; idp; idp = idp->next)
-           if (idp->val.status.mark == UID_SEEN
-                   || idp->val.status.mark == UID_DELETED)
-               idcount++;
-    }
+    for (ctl = hostlist; ctl; ctl = ctl->next)
+       traverse_uid_db(&ctl->oldsaved, count_seen_deleted, &idcount);
 
     /* either nuke the file or write updated last-seen IDs */
     if (!idcount && !scratchlist)
@@ -428,19 +470,22 @@ void write_saved_lists(struct query *hostlist, const char *idfile)
            report(stdout, GT_("Writing fetchids file.\n"));
        (void)unlink(newnam); /* remove file/link first */
        if ((tmpfp = fopen(newnam, "w")) != (FILE *)NULL) {
+           struct write_saved_info info;
            int errflg = 0;
+
+           info.fp = tmpfp;
+
            for (ctl = hostlist; ctl; ctl = ctl->next) {
-               for (idp = ctl->oldsaved; idp; idp = idp->next)
-                   if (idp->val.status.mark == UID_SEEN
-                               || idp->val.status.mark == UID_DELETED)
-                       if (fprintf(tmpfp, "%s@%s %s\n",
-                           ctl->remotename, ctl->server.queryname, idp->id) < 0) {
-                           int e = errno;
-                           report(stderr, GT_("Write error on fetchids file %s: %s\n"), newnam, strerror(e));
-                           errflg = 1;
-                           goto bailout;
-                       }
+               info.ctl = ctl;
+
+               if (traverse_uid_db(&ctl->oldsaved, write_uid_db_record, &info) < 0) {
+                   int e = errno;
+                   report(stderr, GT_("Write error on fetchids file %s: %s\n"), newnam, strerror(e));
+                   errflg = 1;
+                   goto bailout;
+               }
            }
+
            for (idp = scratchlist; idp; idp = idp->next)
                if (EOF == fputs(idp->id, tmpfp)) {
                            int e = errno;
@@ -452,7 +497,7 @@ void write_saved_lists(struct query *hostlist, const char *idfile)
 bailout:
            (void)fflush(tmpfp); /* return code ignored, we check ferror instead */
            errflg |= ferror(tmpfp);
-           fclose(tmpfp);
+           errflg |= fclose(tmpfp);
            /* if we could write successfully, move into place;
             * otherwise, drop */
            if (errflg) {
diff --git a/uid_db.c b/uid_db.c
new file mode 100644 (file)
index 0000000..14a081d
--- /dev/null
+++ b/uid_db.c
@@ -0,0 +1,593 @@
+/*
+  POP3 UID db
+
+       Copyright (c) 2010 MAD Partners, Ltd. (rweikusat@mssgmbh.com)
+
+       This file is being published in accordance with the GPLv2 terms
+       contained in the COPYING file being part of the fetchmail
+       6.3.17 release, including the OpenSSL exemption.
+*/
+
+/*  includes */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <strings.h>  // ffs() lives here
+
+#include "xmalloc.h"
+#include "uid_db.h"
+
+/*  constants */
+enum {
+    MIN_RECORDS =      16      /* arbitrary */
+};
+
+/*  types */
+struct pat_node {
+    struct pat_node *ptrs_[3];
+
+    /*
+      The bit mask is stored in the nodes (as opposed to the
+      offset, which is (re-)calculated on demand) because
+      calculating the mask is a non-trivial operation (at
+      least on x86).
+     */
+    unsigned bit_ndx, bit_mask;
+
+    struct uid_db_record *rec;
+};
+
+/*
+  The idea behind this is that the 'left' pointer of
+  a node is accessible as ptrs(np)[-1] and the right
+  one a ptrs(np)[1]. This implies that no separate codepaths
+  for 'symmetric left- and right-cases' are needed.
+*/
+#define ptrs(np) ((np)->ptrs_ + 1)
+
+/*  routines */
+/**  various helpers */
+static inline unsigned bit_ofs(unsigned bit_ndx)
+{
+    return bit_ndx >> 3;
+}
+
+static inline unsigned bit_mask(unsigned bit_ndx)
+{
+    return 1 << (bit_ndx & 7);
+}
+
+/**  PATRICIA trie insertion */
+/***  walkers */
+static struct pat_node *walk_down(struct uid_db *db, struct uid_db_record *rec,
+                                 struct pat_node ***edgep, struct pat_node **parentp)
+{
+    /*
+      Find the pat node whose id is 'most similar' to the id
+      stored in rec->id. Return a pointer to this node.
+      'parentp' and 'edgep' are output-only parameters which
+      will point to the parent of returned node and to the edge
+      pointer going from the parent to the returned node after
+      the call has returned.
+
+      This routine is intended for inserts only.
+     */
+    struct pat_node *cur, **edge;
+    unsigned bit_ndx, v = 0, ofs;
+
+    cur = db->pat_root;
+    ofs = -1;
+    do {
+       bit_ndx = cur->bit_ndx;
+
+       if (bit_ofs(bit_ndx) != ofs) {
+           ofs = bit_ofs(bit_ndx);
+           v = ofs < rec->id_len ? rec->id[ofs] : 0;
+       }
+
+       edge = ptrs(cur) + (v & cur->bit_mask ? 1 : -1);
+    } while ((cur = *edge) && cur->bit_ndx > bit_ndx);
+
+    *parentp =
+       (struct pat_node *)
+       ((unsigned char *)edge - (v & bit_mask(bit_ndx) ?
+                                 offsetof(struct pat_node, ptrs_[2])
+                                 : offsetof(struct pat_node, ptrs_[0])));
+    *edgep = edge;
+    return cur;
+}
+
+static inline struct pat_node *walk_up(unsigned diff_ndx, struct pat_node **parent)
+{
+    /*
+      Walk the chain of parent pointers starting with *parent until a node
+      is found whose parent has a bit_ndx smaller than diff_ndx. Return
+      a pointer to this node and update *parent to point to its parent.
+    */
+    struct pat_node *p, *np;
+
+    np = *parent;
+
+    while ((p = *ptrs(np)) && p->bit_ndx > diff_ndx)
+       np = p;
+
+    *parent = p;
+    return np;
+}
+
+/***  bit fiddling */
+static inline unsigned first_set_bit_in_char(unsigned v)
+{
+    return ffs(v) - 1;
+}
+
+static int find_first_diff_bit(struct uid_db_record const *r0,
+                              struct uid_db_record const *r1)
+{
+    /*
+      Return the bit_ndx of the first differing bit in
+      r0->id and r1->id or -1 if the strings are identical.
+    */
+    struct uid_db_record const *long_id;
+    unsigned ofs, max;
+    unsigned char v;
+
+    max = r0->id_len;
+    if (max > r1->id_len) {
+       max = r1->id_len;
+       long_id = r0;
+    } else
+       long_id = r1;
+
+    ofs = 0;
+    do
+       v = r0->id[ofs] ^ r1->id[ofs];
+    while (!v && ++ofs < max);
+
+    if (!v) {
+       if (r0->id_len == r1->id_len) return -1;
+       v = long_id->id[ofs];
+    }
+
+    return first_set_bit_in_char(v) + ofs * 8;
+}
+
+static inline unsigned bit_set(unsigned bit_ndx, struct uid_db_record const *rec)
+{
+    /*
+      Return non-zero if the bit corresponding with bit_ndx is set
+      in rec->id
+    */
+    unsigned ofs;
+
+    ofs = bit_ofs(bit_ndx);
+    if (ofs >= rec->id_len) return 0;
+    return rec->id[ofs] & bit_mask(bit_ndx);
+}
+
+/***  node allocation */
+static struct pat_node *get_pat_node(struct uid_db_record *rec)
+{
+    /*
+      Allocate a pat_node, set its rec pointer to rec and the
+      next pointer of rec to NULL. Return pointer to the pat_node.
+    */
+    struct pat_node *np;
+
+    np = (struct pat_node *)xmalloc(sizeof(*np));
+    np->rec = rec;
+    rec->next = NULL;
+    return np;
+}
+
+static struct pat_node *get_standalone_node(struct uid_db_record *rec)
+{
+    /*
+      Return a pat_node suitable for being inserted on the 'left edge'
+      of the trie, ie either linked to a node whose left pointer was zero
+      or being inserted as root node into an empty trie. The bit_ndx of
+      the pat_node is set to the index corresponding with the highest
+      set bit in rec->id.
+
+      NB: This is a bad choice when UIDs share a common prefix because
+      this implies that the root node will cause a bit to be tested which
+      is non-zero in all other nodes, adding a theoretically redundant
+      level to the trie. This is (to the best of my knowledge) un-
+      fortunately unavoidable if nodes with different key lengths need
+      to be supported.
+    */
+    struct pat_node *np;
+
+    np = get_pat_node(rec);
+    np->bit_ndx = first_set_bit_in_char(*rec->id);
+    np->bit_mask = bit_mask(np->bit_ndx);
+    return np;
+}
+
+/***  various helpers */
+#if 0
+static inline int record_id_equal(struct uid_db_record const *r0,
+                                 struct uid_db_record const *r1)
+{
+    return
+       r0->id_len == r1->id_len
+       && memcmp(r0->id, r1->id, r0->id_len) == 0;
+}
+#endif
+
+static struct uid_db_record *append_to_list(struct uid_db_record **recp,
+                                           struct uid_db_record *rec)
+{
+    /*
+      Append the uid_db_record pointed to by rec to the uid_db_record
+      list accessible as *recp and return rec.
+    */
+    while (*recp) recp = &(*recp)->next;
+    *recp = rec;
+
+    rec->next = NULL;
+    return rec;
+}
+
+/***  insert routine */
+static struct uid_db_record *pat_insert(struct uid_db *db,
+                                       struct uid_db_record *rec)
+{
+    /*
+      Insert the record pointed to by rec in the (potentially empty)
+      PATRICIA trie pointed to by db->pat_root and return rec.
+    */
+    struct pat_node *np, *closest, *parent, **edge;
+    int me, bit_ndx;
+
+    if (!db->pat_root) {
+       np = get_standalone_node(rec);
+       ptrs(np)[-1] = *ptrs(np) = NULL;
+       ptrs(np)[1] = np;
+
+       db->pat_root = np;
+       return rec;
+    }
+
+    closest = walk_down(db, rec, &edge, &parent);
+
+    if (closest) {
+       bit_ndx = find_first_diff_bit(closest->rec, rec);
+       if (bit_ndx < 0)
+           return append_to_list(&closest->rec->next, rec);
+
+       np = get_pat_node(rec);
+       np->bit_ndx = bit_ndx;
+       np->bit_mask = bit_mask(bit_ndx);
+    } else
+       np = get_standalone_node(rec);
+
+    if (parent->bit_ndx > np->bit_ndx) {
+       closest = walk_up(np->bit_ndx, &parent);
+
+       if (!parent) edge = &db->pat_root;
+       else edge = ptrs(parent)[-1] == closest ?
+                ptrs(parent) - 1 : ptrs(parent) + 1;
+       *ptrs(closest) = np;
+    }
+
+    *edge = np;
+    *ptrs(np) = parent;
+
+    me = bit_set(np->bit_ndx, rec) ? 1 : -1;
+    ptrs(np)[me] = np;
+    ptrs(np)[-me] = closest;
+
+    return rec;
+}
+
+/**  general db insertion */
+static struct uid_db_record *get_uid_db_record(char const *id, unsigned status)
+{
+    /*
+      Allocate a uid_db_record structure and set its id pointer to a
+      dynamically allocated copy of id. The status member of the
+      new record is set to status and its message number to zero (invalid).
+      A pointer to it is then returned.
+     */
+    struct uid_db_record *rec;
+    size_t id_len;
+
+    rec = (struct uid_db_record *)xmalloc(sizeof(*rec));
+
+    id_len = strlen(id);
+    rec->id = (char *)memcpy(xmalloc(id_len + 1), id, id_len + 1);
+    rec->id_len = id_len;
+    rec->status = status;
+    rec->num = 0;
+
+    return rec;
+}
+
+static void insert_into_records(struct uid_db *db,
+                               struct uid_db_record *rec)
+{
+    /*
+      Insert rec into the records array of the uid_db pointed
+      to by db. The array is grown as necessary and the
+      corresponding state variables of the db are updated
+      accordingly. The pos member of rec is set to its position
+      in the array.
+    */
+    unsigned next, want;
+
+    next = db->records_next;
+
+    if (next == db->records_max) {
+       want = db->records_max *= 2;
+       db->records = (struct uid_db_record **)xrealloc(db->records, want * sizeof(rec));
+    }
+
+    rec->pos = next;
+    db->records[next] = rec;
+    db->records_next = next + 1;
+}
+
+struct uid_db_record *uid_db_insert(struct uid_db *db,
+                                   char const *id, unsigned status)
+{
+    /*
+      Create an uid_db_record whose id is id and whose status is
+      status and insert it into the uid_db pointed to by db.
+      Return a pointer to the newly created record.
+    */
+    struct uid_db_record *rec;
+
+    rec = get_uid_db_record(id, status);
+    insert_into_records(db, rec);
+    return pat_insert(db, rec);
+}
+
+/**  message number index */
+void set_uid_db_num(struct uid_db *db, struct uid_db_record *rec,
+                   unsigned num)
+{
+    /*
+      Set the message number of the record pointed to by rec to num
+      and insert it into the num_ndx of the uid_db pointed to by db
+      at position corresponding with num. The num_ndx lookup array
+      is grown as needed. Message numbers are expected to 'generally'
+      be recorded in ascending order and hence, no provisions are
+      made to deal with the potentially quadratic complexity of
+      inserting a sequence of numbers into an array such that it
+      needs to be grown continuously.
+    */
+    struct num_ndx *num_ndx;
+    unsigned have, want;
+
+    num_ndx = &db->num_ndx;
+
+    if (num_ndx->end_value > num) {
+       have = num_ndx->pos_0_value - num_ndx->end_value + 1;
+       want = num_ndx->pos_0_value - num + 1;
+       num_ndx->end_value = num;
+
+       num_ndx->records = (struct uid_db_record **)xrealloc(num_ndx->records, want * sizeof(rec));
+       do num_ndx->records[--want] = NULL; while (want > have);
+    }
+
+    num_ndx->records[uid_db_num_ofs(num_ndx, num)] = rec;
+}
+
+void reset_uid_db_nums(struct uid_db *db)
+{
+    /*
+      Reset the message numbers of all uid_db_records stored
+      in the uid_db pointed to by db. The corresponding num_ndx
+      lookup array is afterwards freed and the num_ndx end_value
+      adjusted in order to indicate an 'empty' message number
+      index.
+    */
+    struct uid_db_record **rec;
+    struct num_ndx *num_ndx;
+    unsigned ndx;
+
+    num_ndx = &db->num_ndx;
+
+    if (num_ndx->end_value < num_ndx->pos_0_value) {
+       ndx = num_ndx->pos_0_value - num_ndx->end_value;
+       while (ndx) {
+           rec = num_ndx->records + --ndx;
+           if (*rec) (*rec)->num = 0;
+       }
+
+       num_ndx->end_value = num_ndx->pos_0_value + 1;
+
+       free(num_ndx->records);
+       num_ndx->records = NULL;
+    }
+}
+
+/**  search routines */
+struct uid_db_record *find_uid_by_id(struct uid_db *db, char const *id)
+{
+    /*
+      Search for an uid_db_record whose id is id in the uid_db pointed
+      to by db and return a pointer to it or NULL if no such record was
+      found.
+    */
+    struct pat_node *np;
+    struct uid_db_record *rec;
+    unsigned v = 0, bit_ndx, ofs;
+    size_t len;
+
+    np = db->pat_root;
+    if (np) {
+       len = strlen(id);
+       ofs = -1;
+       do {
+           bit_ndx = np->bit_ndx;
+
+           if (bit_ofs(bit_ndx) != ofs) {
+               ofs = bit_ofs(bit_ndx);
+               v = ofs < len ? id[ofs] : 0;
+           }
+
+           np = ptrs(np)[v & np->bit_mask ? 1 : -1];
+       } while (np && np->bit_ndx > bit_ndx);
+
+       if (!np) return NULL;
+
+       rec = np->rec;
+       return rec->id_len == len && memcmp(id, rec->id, len) == 0 ?
+           rec : NULL;
+    }
+
+    return NULL;
+}
+
+struct uid_db_record *last_uid_in_db(struct uid_db *db, char const *id)
+{
+    /*
+      Return a pointer to the 'last' (insert order) uid_db_record
+      contained in the uid_db pointed to by db whose id is id or
+      NULL if no such record exists.
+    */
+    struct uid_db_record *rec;
+
+    rec = find_uid_by_id(db, id);
+    if (!rec) return NULL;
+
+    while (rec->next) rec = rec->next;
+    return rec;
+}
+
+/**  destruction */
+static void free_uid_list(struct uid_db_record *rec)
+{
+    if (!rec) return;
+
+    /*
+      Free the list of uid_db_records starting with
+      the record pointed to by rec.
+    */
+    if (rec->next) free_uid_list(rec->next);
+
+    xfree(rec->id);
+    xfree(rec);
+}
+
+static void free_pat_trie(struct pat_node *np)
+{
+    /*
+      Free the PATRCIA-trie pointed to by np and all
+      uid_db_records contained in it.
+
+      The algorithm implemented below is:
+
+       1. Load the left pointer of the node pointed to by
+          np into next.
+
+       2. If the result is not NULL,
+               2a) Set the left pointer to NULL.
+               2b) Goto 1 if next points to a child of np.
+
+       3. Load the right pointer of the node pointed to by
+          np into next.
+
+       4. If the result is not NULL,
+               4a) Set the right pointer to NULL.
+               4b) Goto 1 id next points to a child of np.
+
+       5. Load next with the parent pointer of np.
+
+       6. Free np->rec and np.
+
+       7. Set np to next and goto 1 if it is not null.
+    */
+    struct pat_node *next;
+
+    do {
+        next = ptrs(np)[-1];
+        if (next) {
+            ptrs(np)[-1] = NULL;
+            if (next->bit_ndx > np->bit_ndx) continue;
+        }
+
+        next = ptrs(np)[1];
+        if (next) {
+            ptrs(np)[1] = NULL;
+            if (next->bit_ndx > np->bit_ndx) continue;
+        }
+
+        next = *ptrs(np);
+
+        free_uid_list(np->rec);
+        free(np);
+    } while ((np = next));
+}
+
+void free_uid_db(struct uid_db *db)
+{
+    /*
+      Free all dynamically allocated memory of the uid_db
+      pointed to by db. The structure is not reinitialized.
+    */
+    if (db->pat_root) free_pat_trie(db->pat_root);
+
+    xfree(db->records);
+    xfree(db->num_ndx.records);
+}
+
+/**  various public interfaces */
+void init_uid_db(struct uid_db *db)
+{
+    /*
+      Initialize the uid_db structure pointed to by db 'properly'
+      such that it represents an empty database. An array of
+      size MIN_RECORDS is allocated and assigned to db->records.
+    */
+    struct num_ndx *num_ndx;
+
+    db->pat_root = NULL;
+
+    db->records = (struct uid_db_record **)xmalloc(MIN_RECORDS * sizeof(*db->records));
+    db->records_max = MIN_RECORDS;
+    db->records_next = 0;
+
+    num_ndx = &db->num_ndx;
+    num_ndx->pos_0_value = num_ndx->end_value = -1;
+    num_ndx->records = NULL;
+}
+
+void swap_uid_db_data(struct uid_db *db_0, struct uid_db *db_1)
+{
+    struct uid_db tmp;
+
+    tmp = *db_0;
+    *db_0 = *db_1;
+    *db_1 = tmp;
+}
+
+int traverse_uid_db(struct uid_db *db,
+                    uid_db_traversal_routine *r, void *arg)
+{
+    /*
+      Traverses the struct uid_db records array in insert order,
+      invoking the subroutine pointed to by r with a pointer to
+      each record and the arg pointer as arguments. If the return
+      value of that is non-zero, traverse_uid_db immediately returns
+      with this value. Otherwise, zero is returned after the last
+      record was visited.
+
+      The uid_db_traversal_routine must not modify the uid_db during
+      traversal.
+    */
+    struct uid_db_record **recs;
+    unsigned ndx, max;
+    int rc;
+
+    rc = 0;
+    ndx = 0;
+    max = db->records_next;
+    recs = db->records;
+    while (ndx < max && (rc = r(recs[ndx], arg)) == 0)
+       ++ndx;
+
+    return rc;
+}
diff --git a/uid_db.h b/uid_db.h
new file mode 100644 (file)
index 0000000..f76f740
--- /dev/null
+++ b/uid_db.h
@@ -0,0 +1,141 @@
+/*
+  POP3 UID database
+
+       Copyright (c) 2010 MAD Partners, Ltd. (rweikusat@mssgmbh.com)
+
+       This file is being published in accordance with the GPLv2 terms
+       contained in the COPYING file being part of the fetchmail
+       6.3.17 release, including the OpenSSL exemption.
+*/
+#ifndef fetchmail_uid_db_h
+#define fetchmail_uid_db_h
+
+/*  includes */
+#include <stddef.h>
+
+/*  types */
+struct uid_db_record {
+    char *id;
+    size_t id_len;
+
+    /*
+      num      -       message number assigned by server
+      status   -       message status (eg seen, deleted, ...)
+      pos      -       position in record list
+    */
+    unsigned num, status, pos;
+
+    struct uid_db_record *next;
+};
+
+struct num_ndx {
+    /*
+      Used to find uid records by message number.
+
+      pos_0_value      -       highest message number
+      end_value                -       lowest known message number
+
+      Grows downwards because the fastuidl-code may record
+      message numbers in non-ascending order but the
+      lookup array should ideally only be large enough to
+      store pointers to interesting ('new') messages.
+    */
+    struct uid_db_record **records;
+    unsigned pos_0_value, end_value;
+};
+
+struct uid_db
+{
+    struct pat_node *pat_root;
+
+    struct uid_db_record **records;
+    unsigned records_max, records_next;
+
+    struct num_ndx num_ndx;
+};
+
+typedef int uid_db_traversal_routine(struct uid_db_record *, void *);
+
+/*  routines */
+/**  initialization/ finalization */
+void init_uid_db(struct uid_db *db);
+
+void free_uid_db(struct uid_db *db);
+
+static inline void clear_uid_db(struct uid_db *db)
+{
+    free_uid_db(db);
+    init_uid_db(db);
+}
+
+/**  message number index handling */
+static inline unsigned uid_db_num_ofs(struct num_ndx const *num_ndx, unsigned num)
+{
+    return num_ndx->pos_0_value - num;
+}
+
+void set_uid_db_num(struct uid_db *db, struct uid_db_record *rec,
+                   unsigned num);
+
+static inline void set_uid_db_num_pos_0(struct uid_db *db, unsigned num)
+{
+    db->num_ndx.pos_0_value = num;
+    db->num_ndx.end_value = num + 1;
+}
+
+void reset_uid_db_nums(struct uid_db *db);
+
+/**  various uidl db manipulatiors */
+struct uid_db_record *uid_db_insert(struct uid_db *db,
+                                   char const *id, unsigned status);
+
+void swap_uid_db_data(struct uid_db *db_0, struct uid_db *db_1);
+
+/**  search routines */
+struct uid_db_record *find_uid_by_id(struct uid_db *db, char const *id);
+
+static inline struct uid_db_record *
+find_uid_by_num(struct uid_db *db, unsigned num)
+{
+    struct num_ndx *num_ndx;
+
+    num_ndx = &db->num_ndx;
+    return num >= num_ndx->end_value ?
+       num_ndx->records[uid_db_num_ofs(num_ndx, num)] : NULL;
+}
+
+static inline struct uid_db_record *
+find_uid_by_pos(struct uid_db *db, unsigned pos)
+{
+    return pos < db->records_next ? db->records[pos] : NULL;
+}
+
+static inline struct uid_db_record *
+first_uid_in_db(struct uid_db *db, char const *id)
+{
+    return find_uid_by_id(db, id);
+}
+
+struct uid_db_record *last_uid_in_db(struct uid_db *db, char const *id);
+
+/**  various accessors */
+static inline unsigned uid_db_n_records(struct uid_db const *db)
+{
+    return db->records_next;
+}
+
+/*
+  Traverses the struct uid_db records array in insert order,
+  invoking the subroutine pointed to by r with a pointer to
+  each record and the arg pointer as arguments. If the return
+  value of that is non-zero, traverse_uid_db immediately returns
+  with this value. Otherwise, zero is returned after the last
+  record was visited.
+
+  The uid_db_traversal_routine must not modify the uid_db during
+  traversal.
+*/
+int traverse_uid_db(struct uid_db *db,
+                   uid_db_traversal_routine *r, void *arg);
+
+#endif
index f799ff92f51b5a22836a9135c43f9b4df8878bfb..070d7945aee16f0c4cad27e53e3cd66fb6dfb02f 100644 (file)
--- a/unmime.c
+++ b/unmime.c
@@ -19,7 +19,7 @@
 #include <stdio.h>
 #include <ctype.h>
 #include "fetchmail.h"
-#include "i18n.h"
+#include "gettext.h"
 
 static unsigned char unhex(unsigned char c)
 {
@@ -459,7 +459,7 @@ int MimeBodyType(char *hdrs, int WantDecode)
 
        /* Check Content-Type to see if this is a multipart message */
        if ( (CntType != NULL) &&
-               ((strncasecmp(CntType, "multipart/mixed", 16) == 0) ||
+               ((strncasecmp(CntType, "multipart/mixed", 15) == 0) ||
                 (strncasecmp(CntType, "message/", 8) == 0)) ) {
 
            char *p1 = GetBoundary(CntType);
@@ -469,7 +469,6 @@ int MimeBodyType(char *hdrs, int WantDecode)
                   the boundary string */
                strcpy(MultipartDelimiter, "--");
                strlcat(MultipartDelimiter, p1, sizeof(MultipartDelimiter));
-               MultipartDelimiter[sizeof(MultipartDelimiter)-1] = '\0';
                BodyType = (MSG_IS_8BIT | MSG_NEEDS_DECODE);
            }
        }
index c2ca4a66e932a32d99716d851914b13ca05da6f0..6107564d93eb51731e966c89eec8c396e7fed3b8 100644 (file)
--- a/xmalloc.c
+++ b/xmalloc.c
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
-#if defined(STDC_HEADERS)
 #include  <stdlib.h>
-#endif
 #include "fetchmail.h"
-#include "i18n.h"
+#include "gettext.h"
 
-#if defined(HAVE_VOIDPOINTER)
-#define XMALLOCTYPE void
-#else
-#define XMALLOCTYPE char
-#endif
-
-XMALLOCTYPE *
-xmalloc (size_t n)
+void *xmalloc (size_t n)
 {
-    XMALLOCTYPE *p;
+    void *p;
 
-    p = (XMALLOCTYPE *) malloc(n);
-    if (p == (XMALLOCTYPE *) 0)
+    p = (void *) malloc(n);
+    if (p == (void *) 0)
     {
        report(stderr, GT_("malloc failed\n"));
        abort();
@@ -36,13 +27,12 @@ xmalloc (size_t n)
     return(p);
 }
 
-XMALLOCTYPE *
-xrealloc (XMALLOCTYPE *p, size_t n)
+void *xrealloc (void *p, size_t n)
 {
     if (p == 0)
        return xmalloc (n);
-    p = (XMALLOCTYPE *) realloc(p, n);
-    if (p == (XMALLOCTYPE *) 0)
+    p = (void *) realloc(p, n);
+    if (p == (void *) 0)
     {
        report(stderr, GT_("realloc failed\n"));
        abort();
@@ -58,17 +48,6 @@ char *xstrdup(const char *s)
     return p;
 }
 
-#if !defined(HAVE_STRDUP)
-char *strdup(const char *s)
-{
-    char *p;
-    p = (char *) malloc(strlen(s)+1);
-    if (p)
-           strcpy(p,s);
-    return p;
-}
-#endif /* !HAVE_STRDUP */
-
 char *xstrndup(const char *s, size_t len)
 {
     char *p;
@@ -81,4 +60,5 @@ char *xstrndup(const char *s, size_t len)
     return p;
 }
 
+
 /* xmalloc.c ends here */
index 818358285033195e1033b222188508468a32bb0a..3766043df0203473c303947ecbbe60dc88d49738 100644 (file)
--- a/xmalloc.h
+++ b/xmalloc.h
@@ -6,17 +6,12 @@
 #include "config.h"
 
 /* xmalloc.c */
-#if defined(HAVE_VOIDPOINTER)
-#define XMALLOCTYPE void
-#else
-#define XMALLOCTYPE char
-#endif
 
 /** Allocate \a n characters of memory, abort program on failure. */
-XMALLOCTYPE *xmalloc(size_t n);
+void *xmalloc(size_t n);
 
 /** Reallocate \a n characters of memory, abort program on failure. */
-XMALLOCTYPE *xrealloc(/*@null@*/ XMALLOCTYPE *, size_t n);
+void *xrealloc(/*@null@*/ void *, size_t n);
 
 /** Free memory at position \a p and set pointer \a p to NULL afterwards. */
 #define xfree(p) { if (p) { free(p); } (p) = 0; }